U
    n5{ink  ã                   @  s  d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
mZ ddlmZ ddlmZmZmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddl m!Z! eeƒG dd„ dƒƒZ"G dd„ deeƒZ#G dd„ de!j$ƒZ%G dd„ de!j&ƒZ'dS )z&
Tests for L{twisted.runner.procmon}.
é    )ÚannotationsN)ÚAnyStrÚMappingÚOptionalÚSequenceÚUnion)Úimplementer)ÚProcessDoneÚProcessExitedAlreadyÚProcessTerminated)ÚIProcessProtocolÚIProcessTransport)ÚClock)ÚMemoryReactor)ÚglobalLogPublisher)ÚFailure)ÚLoggingProtocolÚProcessMonitor)Úunittestc                   @  s6   e Zd ZdZdZdZdZddd„Zdd„ Zd	d
„ Z	dS )ÚDummyProcessa   
    An incomplete and fake L{IProcessTransport} implementation for testing how
    L{ProcessMonitor} behaves when its monitored processes exit.

    @ivar _terminationDelay: the delay in seconds after which the DummyProcess
        will appear to exit when it receives a TERM signal
    é   Nr   c                 C  s@   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d S ©N)
ÚprotoÚ_reactorÚ_executableÚ_argsÚ_environmentÚ_pathZ_uidZ_gidZ_usePTYZ	_childFDs)ÚselfÚreactorÚ
executableÚargsÚenvironmentÚpathr   ÚuidÚgidÚusePTYÚchildFDs© r(   úD/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/runner/test/test_procmon.pyÚ__init__)   s    zDummyProcess.__init__c                 C  sL   | j dfddœ}| jdkr tƒ ‚||krH|| \}}| j || j|¡| _dS )añ  
        A partial implementation of signalProcess which can only handle TERM and
        KILL signals.
         - When a TERM signal is given, the dummy process will appear to exit
           after L{DummyProcess._terminationDelay} seconds with exit code 0
         - When a KILL signal is given, the dummy process will appear to exit
           immediately with exit code 1.

        @param signalID: The signal name or number to be issued to the process.
        @type signalID: C{str}
        r   ©r   r   )ÚTERMÚKILLN)Ú_terminationDelayÚpidr
   r   Z	callLaterÚprocessEndedZ_signalHandler)r   ZsignalIDÚparamsÚdelayÚstatusr(   r(   r)   ÚsignalProcessB   s    
  ÿzDummyProcess.signalProcessc                 C  s,   d| _ ttdœ}| j t|| |ƒƒ¡ dS )zC
        Deliver the process ended event to C{self.proto}.
        Nr+   )r/   r	   r   r   r0   r   )r   r3   Z	statusMapr(   r(   r)   r0   Y   s
    þzDummyProcess.processEnded)NNr   N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r/   r   r.   r*   r4   r0   r(   r(   r(   r)   r      s   
    õ
r   c                   @  sR   e Zd ZU dZded< ded< ddœdd	„Zddddddddddddœ
dd„Zd
S )ÚDummyProcessReactorzÉ
    @ivar spawnedProcesses: a list that keeps track of the fake process
        instances built by C{spawnProcess}.

    @ivar spawnProcessException: An exception which spawnProcess() will raise.
    zlist[DummyProcess]ÚspawnedProcesseszException | NoneÚspawnProcessExceptionÚNone©Úreturnc                 C  s$   t  | ¡ t | ¡ g | _d | _d S r   )r   r*   r   r:   r;   ©r   r(   r(   r)   r*   p   s    

zDummyProcessReactor.__init__NFr   zUnion[bytes, str]zSequence[Union[bytes, str]]z!Optional[Mapping[AnyStr, AnyStr]]zUnion[None, bytes, str]zOptional[int]Úboolz'Optional[Mapping[int, Union[int, str]]]r   )
ÚprocessProtocolr    r!   Úenvr#   r$   r%   r&   r'   r>   c
                 C  sD   | j dk	r| j ‚t| |||||||||	ƒ
}
| |
¡ | j |
¡ |
S )zz
        Fake L{reactor.spawnProcess}, that logs all the process
        arguments and returns a L{DummyProcess}.
        N)r;   r   ZmakeConnectionr:   Úappend)r   rA   r    r!   rB   r#   r$   r%   r&   r'   Úprocr(   r(   r)   ÚspawnProcessv   s"    
ö
z DummyProcessReactor.spawnProcess)NNNNFN)r5   r6   r7   r8   Ú__annotations__r*   rE   r(   r(   r(   r)   r9   e   s   
      ör9   c                   @  s,  e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zddœd d!„Zddœd"d#„Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Z d>d?„ Z!d@dA„ Z"dBdC„ Z#dDdE„ Z$dFdG„ Z%dHS )IÚProcmonTestsz&
    Tests for L{ProcessMonitor}.
    c                 C  s2   t ƒ | _t| jd�| _d| j_d| j_d| j_dS )zL
        Create an L{ProcessMonitor} wrapped around a fake reactor.
        ©r   é   é
   N)r9   r   r   ÚpmÚminRestartDelayÚmaxRestartDelayÚ	thresholdr?   r(   r(   r)   ÚsetUpŸ   s
    zProcmonTests.setUpc                 C  sL   | j jdddgddi d� t| j ƒ}|  d|¡ |  d|¡ |  d|¡ d	S )
z+
        Repr includes all details
        ÚfooÚarg1Úarg2r   rI   ©r$   r%   rB   Ú1Ú2N)rK   Ú
addProcessÚreprÚassertIn©r   Zrepresentationr(   r(   r)   Útest_reprLooksGood©   s
    
zProcmonTests.test_reprLooksGoodc                 C  s<   | j jdddgi d� t| j ƒ}|  d|¡ |  d|¡ dS )z·
        Repr does not include unneeded details.

        Values of attributes that just mean "inherit from launching
        process" do not appear in the repr of a process.
        rP   rQ   rR   )rB   ú(ú)N)rK   rV   rW   ÚassertNotInrY   r(   r(   r)   Útest_simpleReprLooksGood³   s    
z%ProcmonTests.test_simpleReprLooksGoodc                 C  sD   | j jdddgddi d� |  | j  ¡ d dddgddi fi¡ dS )	zW
        The list of monitored processes must be included in the pickle state.
        rP   rQ   rR   r   rI   rS   Ú	processesN)rK   rV   ÚassertEqualÚ__getstate__r?   r(   r(   r)   Útest_getStateIncludesProcesses¿   s
     ÿz+ProcmonTests.test_getStateIncludesProcessesc                 C  s   |   d| j ¡ ¡ dS )z~
        The private L{ProcessMonitor._reactor} instance variable should not be
        included in the pickle state.
        r   N)r]   rK   ra   r?   r(   r(   r)   Útest_getStateExcludesReactorÈ   s    z)ProcmonTests.test_getStateExcludesReactorc                 C  s~   | j jdddgddi d� |  | j ji ¡ |  | j jdddgddi fi¡ | j  ¡  | j d¡ |  t| j j 	¡ ƒdg¡ dS )	z‡
        L{ProcessMonitor.addProcess} only starts the named program if
        L{ProcessMonitor.startService} has been called.
        rP   rQ   rR   r   rI   rS   r   N)
rK   rV   r`   Ú	protocolsr_   ÚstartServicer   ÚadvanceÚlistÚkeysr?   r(   r(   r)   Útest_addProcessÏ   s     
zProcmonTests.test_addProcessc              	   C  s>   | j jdddgddi d� | jt| j jdddgddi d� dS )z|
        L{ProcessMonitor.addProcess} raises a C{KeyError} if a process with the
        given name already exists.
        rP   rQ   rR   r   rI   rS   N)rK   rV   ÚassertRaisesÚKeyErrorr?   r(   r(   r)   Ú test_addProcessDuplicateKeyErrorÛ   s          ÿz-ProcmonTests.test_addProcessDuplicateKeyErrorc                 C  sP   ddi}| j  ¡  | j jddgdd|d� | j d¡ |  | jjd j|¡ dS )	zƒ
        L{ProcessMonitor.addProcess} takes an C{env} parameter that is passed to
        L{IReactorProcess.spawnProcess}.
        ZKEYÚvaluerP   r   rI   rS   r   N)rK   re   rV   r   rf   r`   r:   r   )r   ZfakeEnvr(   r(   r)   Útest_addProcessEnvå   s
    
zProcmonTests.test_addProcessEnvc                 C  sD   | j  ¡  | j jddgdd� | j d¡ |  | jjd jd¡ dS )zƒ
        L{ProcessMonitor.addProcess} takes an C{cwd} parameter that is passed
        to L{IReactorProcess.spawnProcess}.
        rP   z	/mnt/lala)Úcwdr   N)rK   re   rV   r   rf   r`   r:   r   r?   r(   r(   r)   Útest_addProcessCwdð   s    
zProcmonTests.test_addProcessCwdc                 C  sR   | j  ¡  | j  ddg¡ |  t| j jƒd¡ | j  d¡ |  t| j jƒd¡ dS )zm
        L{ProcessMonitor.removeProcess} removes the process from the public
        processes list.
        rP   r   r   N)rK   re   rV   r`   Úlenr_   ÚremoveProcessr?   r(   r(   r)   Útest_removeProcessú   s
    
zProcmonTests.test_removeProcessc                 C  s    | j  ¡  |  t| j jd¡ dS )zz
        L{ProcessMonitor.removeProcess} raises a C{KeyError} if the given
        process name isn't recognised.
        rP   N)rK   re   rj   rk   rr   r?   r(   r(   r)   Ú!test_removeProcessUnknownKeyError  s    
z.ProcmonTests.test_removeProcessUnknownKeyErrorc                 C  sH   | j  ddg¡ | j  d¡ |  | j jd t¡ |  d| j j ¡ ¡ dS )a  
        When a process has been started, an instance of L{LoggingProtocol} will
        be added to the L{ProcessMonitor.protocols} dict and the start time of
        the process will be recorded in the L{ProcessMonitor.timeStarted}
        dictionary.
        rP   N)	rK   rV   ÚstartProcessZassertIsInstancerd   r   rX   ÚtimeStartedrh   r?   r(   r(   r)   Útest_startProcess  s    zProcmonTests.test_startProcessc                 C  s2   | j  ddg¡ | j  d¡ |  | j  d¡¡ dS )zr
        L{ProcessMonitor.startProcess} silently returns if the named process is
        already started.
        rP   N)rK   rV   ru   ÚassertIsNoner?   r(   r(   r)   Útest_startProcessAlreadyStarted  s    z,ProcmonTests.test_startProcessAlreadyStartedc                 C  s   |   t| jjd¡ dS )zy
        L{ProcessMonitor.startProcess} raises a C{KeyError} if the given
        process name isn't recognised.
        rP   N)rj   rk   rK   ru   r?   r(   r(   r)   Ú test_startProcessUnknownKeyError"  s    z-ProcmonTests.test_startProcessUnknownKeyErrorr<   r=   c                 C  sr   t tjt tj¡ƒ| j_d| j_d| j_	| j 
ddg¡ | j d¡ |  | jjd d¡ |  t|  t ¡ƒd¡ dS )z
        L{IReactorProcess.spawnProcess} might raise C{OSError}, ensure it
        is caught and process is restarted.
        é{   rP   r   N)ÚOSErrorÚerrnoÚEAGAINÚosÚstrerrorr   r;   rK   rL   rM   rV   ru   ÚassertEqualsr2   rq   ZflushLoggedErrorsr?   r(   r(   r)   Ú%test_startProcessSpawnCaughtException)  s     
ÿz2ProcmonTests.test_startProcessSpawnCaughtExceptionc                 C  s2   t dƒ| j_| j ddg¡ |  t | jjd¡ dS )zy
        L{IReactorProcess.spawnProcess} might raise C{OSError}, ensure other
        exceptions are not caught.
        zJust another exceptionrP   N)ÚSystemErrorr   r;   rK   rV   rj   ru   r?   r(   r(   r)   Ú'test_startProcessSpawnUncaughtException9  s    z4ProcmonTests.test_startProcessSpawnUncaughtExceptionc                 C  s�   | j  ¡  | j  ddg¡ |  d| j j¡ d }| j jd j_| j | j j	¡ | j  
d¡ | j |¡ | j d¡ |  | j ¡ | j jd ¡ dS )zm
        L{ProcessMonitor.stopProcess} immediately sends a TERM signal to the
        named process.
        rP   r   r   N)rK   re   rV   rX   rd   Ú	transportr.   r   rf   rN   ÚstopProcessr`   Úsecondsrv   )r   Z	timeToDier(   r(   r)   Ú"test_stopProcessNaturalTerminationB  s    
z/ProcmonTests.test_stopProcessNaturalTerminationc                 C  sÄ   | j  ¡  | j  ddg¡ |  d| j j¡ | j | j j¡ | j jd j}| j j	d |_
| j  d¡ | j | j j	d ¡ |  d| j jd ¡ | j d¡ | j ddg¡ |  | j ¡ | j jd ¡ dS )z•
        L{ProcessMonitor.stopProcess} kills a process which fails to terminate
        naturally within L{ProcessMonitor.killTime} seconds.
        rP   r   g        r   N)rK   re   rV   rX   rd   r   rf   rN   r…   ÚkillTimer.   r†   r`   rv   Zpumpr‡   )r   rD   r(   r(   r)   Útest_stopProcessForcedKill`  s    
z'ProcmonTests.test_stopProcessForcedKillc                 C  s   |   t| jjd¡ dS )zx
        L{ProcessMonitor.stopProcess} raises a C{KeyError} if the given process
        name isn't recognised.
        rP   N)rj   rk   rK   r†   r?   r(   r(   r)   Útest_stopProcessUnknownKeyError}  s    z,ProcmonTests.test_stopProcessUnknownKeyErrorc                 C  s&   | j  ddg¡ |  | j  d¡¡ dS )zá
        L{ProcessMonitor.stopProcess} silently returns if the named process
        is already stopped. eg Process has crashed and a restart has been
        rescheduled, but in the meantime, the service is stopped.
        rP   N)rK   rV   rx   r†   r?   r(   r(   r)   Útest_stopProcessAlreadyStopped„  s    z+ProcmonTests.test_stopProcessAlreadyStoppedc                 C  sì   g }|   tj|j¡ t |j¡ | j ddg¡ | j ¡  | j 	d¡ |  
d| jj¡ | j 	| jj¡ | jjd  d¡ |  t|ƒd¡ |d d }|d d }|d d }|d d }|  |d	¡ |  |d
¡ |  |d¡ |  |d¡ dS )zS
        Getting a complete output line on stdout generates a log message.
        rP   r   ó   hello world!
r   Úlog_namespaceÚstreamÚtagÚlineú%twisted.runner.procmon.ProcessMonitorÚstdoutúhello world!N)Ú
addCleanupr   ÚremoveObserverrC   ÚaddObserverrK   rV   re   r   rf   rX   rd   rN   ÚoutReceivedr�   rq   ©r   ÚeventsÚ	namespacer�   r�   r‘   r(   r(   r)   Útest_outputReceivedCompleteLine�  s$    
z,ProcmonTests.test_outputReceivedCompleteLinec                 C  sì   g }|   tj|j¡ t |j¡ | j ddg¡ | j ¡  | j 	d¡ |  
d| jj¡ | j 	| jj¡ | jjd  d¡ |  t|ƒd¡ |d d }|d d }|d d }|d d }|  |d	¡ |  |d
¡ |  |d¡ |  |d¡ dS )zS
        Getting a complete output line on stderr generates a log message.
        rP   r   r�   r   rŽ   r�   r�   r‘   r’   Ústderrr”   N)r•   r   r–   rC   r—   rK   rV   re   r   rf   rX   rd   rN   ZerrReceivedr�   rq   r™   r(   r(   r)   Ú!test_ouputReceivedCompleteErrLine¨  s$    
z.ProcmonTests.test_ouputReceivedCompleteErrLinec                 C  sè   g }|   tj|j¡ t |j¡ | j ddg¡ | j ¡  | j 	d¡ |  
d| jj¡ | j 	| jj¡ | jjd  d¡ |  t|ƒd¡ |d }|d }|d }|d }|d }|  |d	¡ |  |d
¡ |  |d¡ |  |tdƒ¡ dS )zN
        Getting invalid UTF-8 results in the repr of the raw message
        rP   r   s   ÿhello world!
r   rŽ   r�   r�   r‘   r’   r“   s   ÿhello world!N)r•   r   r–   rC   r—   rK   rV   re   r   rf   rX   rd   rN   r˜   r�   rq   rW   )r   rš   Úmessager›   r�   r�   Úoutputr(   r(   r)   Ú*test_outputReceivedCompleteLineInvalidUTF8Ã  s&    
z7ProcmonTests.test_outputReceivedCompleteLineInvalidUTF8c                 C  s  g }|   tj|j¡ t |j¡ | j ddg¡ | j ¡  | j 	d¡ |  
d| jj¡ | j 	| jj¡ | jjd  d¡ |  t|ƒd¡ | jjd  ttdƒƒ¡ |  t|ƒd¡ |d d }|d d }|d d }|d d }|  |d	¡ |  |d
¡ |  |d¡ |  |d¡ dS )zM
        Getting partial line results in no events until process end
        rP   r   s   hello world!r   rŽ   r�   r�   r‘   r’   r“   r”   N)r•   r   r–   rC   r—   rK   rV   re   r   rf   rX   rd   rN   r˜   r�   rq   r0   r   r	   r™   r(   r(   r)   Útest_outputReceivedPartialLineß  s(    
z+ProcmonTests.test_outputReceivedPartialLinec                 C  s�   | j  ddg¡ | j  ¡  | j d¡ |  d| j j¡ | j | j j¡ | j jd  t	t
dƒƒ¡ |  d| j j¡ | j d¡ |  d| j j¡ dS )z¤
        L{ProcessMonitor.processExit} should immediately restart a process
        if it has been running longer than L{ProcessMonitor.threshold} seconds.
        rP   r   N)rK   rV   re   r   rf   rX   rd   rN   r0   r   r	   r]   r?   r(   r(   r)   Ú#test_connectionLostLongLivedProcessü  s    
z0ProcmonTests.test_connectionLostLongLivedProcessc                 C  s–   | j  ddg¡ | j  ¡  | j d¡ | j  d¡ |  d| j j¡ | j jd }|  | 	¡ ¡ | j | j j
d jj¡ |  | 	¡ ¡ |  d| j j¡ dS )zž
        L{ProcessMonitor.processExit} cancels a scheduled process killer and
        deletes the DelayedCall from the L{ProcessMonitor.murder} list.
        rP   r   N)rK   rV   re   r   rf   r†   rX   ZmurderÚ
assertTrueÚactiverd   r…   r.   ÚassertFalser]   )r   ZdelayedCallr(   r(   r)   Útest_connectionLostMurderCancel  s    
z,ProcmonTests.test_connectionLostMurderCancelc                 C  sj   | j  ¡  | j  ddg¡ |  d| j j¡ | j jd j d¡ | j | j jd jj	¡ |  
d| j j¡ dS )z•
        L{ProcessMonitor.processExit} removes the corresponding
        ProcessProtocol instance from the L{ProcessMonitor.protocols} list.
        rP   r-   N)rK   re   rV   rX   rd   r…   r4   r   rf   r.   r]   r?   r(   r(   r)   Ú#test_connectionLostProtocolDeletion%  s    
z0ProcmonTests.test_connectionLostProtocolDeletionc                 C  sŒ   d| j _d| j _| j  ¡  | j  ddg¡ |  | j jd | j j¡ | j | j j	d ¡ | j j
d  ttdƒƒ¡ |  | j jd | j j¡ dS )zz
        L{ProcessMonitor.processExit} will wait at least minRestartDelay s
        and at most maxRestartDelay s
        rI   é   rP   r   r   N)rK   rL   rM   re   rV   r`   r2   r   rf   rN   rd   r0   r   r	   r?   r(   r(   r)   Ú%test_connectionLostMinMaxRestartDelay1  s    
z2ProcmonTests.test_connectionLostMinMaxRestartDelayc                 C  s�   | j  ¡  | j  ddg¡ | j | j jd ¡ |  d| j j¡ |  | j j	d | j j
¡ | j jd  ttdƒƒ¡ |  | j j	d | j j
d ¡ dS )zy
        L{ProcessMonitor.processExit} doubles the restart delay each time
        the process dies too quickly.
        rP   r   r   rI   N)rK   re   rV   r   rf   rN   rX   rd   r`   r2   rL   r0   r   r	   r?   r(   r(   r)   Ú&test_connectionLostBackoffDelayDoublesA  s    
z3ProcmonTests.test_connectionLostBackoffDelayDoublesc                 C  s:   | j  ddg¡ | j  ¡  | j d¡ |  d| j j¡ dS )zP
        L{ProcessMonitor.startService} starts all monitored processes.
        rP   r   N)rK   rV   re   r   rf   rX   rd   r?   r(   r(   r)   Útest_startServiceO  s    
zProcmonTests.test_startServicec                 C  s˜   | j  ddg¡ | j  ddg¡ | j  ¡  | j | j j¡ |  d| j j¡ |  d| j j¡ | j d¡ | j  ¡  | j | j j	d ¡ |  
i | j j¡ dS )zT
        L{ProcessMonitor.stopService} should stop all monitored processes.
        rP   Úbarr   N)rK   rV   re   r   rf   rN   rX   rd   ÚstopServicer‰   r`   r?   r(   r(   r)   Útest_stopServiceZ  s    

zProcmonTests.test_stopServicec                 C  sl   | j  ddg¡ | j  ¡  | j d¡ | j  ¡  | j d¡ t| jjƒ}| ¡ }|  	|g ¡ |  
|j¡ dS )zR
        L{ProcessMonitor.restartAll} succeeds when there is one process.
        rP   r   N)rK   rV   re   r   rf   Z
restartAllrg   r:   Úpopr�   rx   r/   )r   r_   Z	myProcessr(   r(   r)   Ú!test_restartAllRestartsOneProcessp  s    

z.ProcmonTests.test_restartAllRestartsOneProcessc                 C  sš   | j  ddg¡ | j  ¡  | j | j j¡ |  d| j j¡ | j d¡ | j jd  t	t
dƒƒ¡ |  | j jd  ¡ ¡ | j  ¡  |  | j jd  ¡ ¡ dS )ze
        L{ProcessMonitor.stopService} should cancel any scheduled process
        restarts.
        rP   r   r   N)rK   rV   re   r   rf   rN   rX   rd   r0   r   r	   r¤   Zrestartr¥   r®   r¦   r?   r(   r(   r)   Útest_stopServiceCancelRestarts€  s    

z+ProcmonTests.test_stopServiceCancelRestartsc                 C  sx   d| j _d| j _| j  ¡  | j  ddg¡ | j d¡ | j  d¡ | j d¡ | j  ¡  | j d¡ |  	| j j
i ¡ dS )ze
        L{ProcessMonitor.stopService} should cancel all scheduled process
        restarts.
        é   rP   r   é   N)rK   rN   rL   re   rV   r   rf   r†   r®   r`   rd   r?   r(   r(   r)   Ú(test_stopServiceCleanupScheduledRestarts”  s    

z5ProcmonTests.test_stopServiceCleanupScheduledRestartsN)&r5   r6   r7   r8   rO   rZ   r^   rb   rc   ri   rl   rn   rp   rs   rt   rw   ry   rz   r‚   r„   rˆ   rŠ   r‹   rŒ   rœ   rž   r¡   r¢   r£   r§   r¨   rª   r«   r¬   r¯   r±   r²   rµ   r(   r(   r(   r)   rG   š   sF   

	

			rG   c                   @  s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚDeprecationTestszQ
    Tests that check functionality that should be deprecated is deprecated.
    c                 C  s   t ƒ | _t| jd�| _dS )z5
        Create reactor and process monitor.
        rH   N)r9   r   r   rK   r?   r(   r(   r)   rO   ±  s    zDeprecationTests.setUpc                 C  sx   | j  ddg¡ | j j}|  t|ƒd¡ |  ¡ }d}|D ]$}|  |d t¡ d|d kr8d}q8|  |dt	|ƒ› �¡ d	S )
a   
        _Process.toTuple is deprecated.

        When getting the deprecated processes property, the actual
        data (kept in the class _Process) is converted to a tuple --
        which produces a DeprecationWarning per process so converted.
        rP   r   FÚcategoryZtoTuplerŸ   Tzno tuple deprecation found:N)
rK   rV   r_   r�   rq   ÚflushWarningsÚassertIsÚDeprecationWarningr¤   rW   )r   ZmyprocessesÚwarningsZfoundToTupleÚwarningr(   r(   r)   Útest_toTuple¸  s    zDeprecationTests.test_toTuplec                 C  sF   | j j}|  |i ¡ |  ¡ }| d¡}|  |d t¡ |  |g ¡ dS )a  
        Accessing L{ProcessMonitor.processes} results in deprecation warning

        Even when there are no processes, and thus no process is converted
        to a tuple, accessing the L{ProcessMonitor.processes} property
        should generate its own DeprecationWarning.
        r   r·   N)rK   r_   r�   r¸   r°   r¹   rº   )r   ZmyProcessesr»   Úfirstr(   r(   r)   Útest_processesË  s    
zDeprecationTests.test_processesc                 C  s2   t  | j¡ |  ¡ }|D ]}|  |d t¡ qdS )zO
        Pickling an L{ProcessMonitor} results in deprecation warnings
        r·   N)ÚpickleÚdumpsrK   r¸   r¹   rº   )r   r»   r¼   r(   r(   r)   Útest_getstateÚ  s    zDeprecationTests.test_getstateN)r5   r6   r7   r8   rO   r½   r¿   rÂ   r(   r(   r(   r)   r¶   ¬  s
   r¶   )(r8   Ú
__future__r   r}   r   rÀ   Útypingr   r   r   r   r   Zzope.interfacer   Ztwisted.internet.errorr	   r
   r   Ztwisted.internet.interfacesr   r   Ztwisted.internet.taskr   Ztwisted.internet.testingr   Ztwisted.loggerr   Ztwisted.python.failurer   Ztwisted.runner.procmonr   r   Ztwisted.trialr   r   r9   ZTestCaserG   ZSynchronousTestCaser¶   r(   r(   r(   r)   Ú<module>   s.   J5    