U
    n5{i¸8  ã                   @   sd  d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	m
Z
mZmZmZmZmZmZmZ ddlmZmZmZ ddlZddlmZ dd	lmZmZmZmZmZm Z 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+ G dd„ dej,j-j.ƒZ/edd�G dd„ de+ƒƒZ0G dd„ de)ƒZ1G dd„ dƒZ2G dd„ dƒZ3G dd„ dƒZ4G dd „ d ƒZ5dS )!z2
Tests for L{twisted.application.runner._runner}.
é    N)ÚStringIO)ÚSIGTERM)ÚTracebackType)	ÚAnyÚIterableÚListÚOptionalÚTextIOÚTupleÚTypeÚUnionÚcast)ÚFactoryÚattribÚattrs)ÚMemoryReactor)ÚFileLogObserverÚFilteringLogObserverÚILogObserverÚLogBeginnerÚLogLevelÚLogLevelFilterPredicateÚLogPublisher)ÚFilePathé   )Ú_runneré   )Ú
ExitStatus)ÚNonePIDFileÚPIDFile)ÚRunnerc                   @   s  e Zd ZdZd(ee ee dœdd„Zddœdd„Z	ddœd	d
„Z
ddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd „Zddœd!d"„Zddœd#d$„Zd)eee dd%œd&d'„ZdS )*ÚRunnerTestsz
    Tests for L{Runner}.
    N)ÚcontentÚreturnc                 C   s"   t |  ¡ ƒ}|d k	r| |¡ |S ©N)r   ÚmktempZ
setContent)Úselfr"   ÚfilePath© r(   úO/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/application/runner/test/test_runner.pyr'   '   s    
zRunnerTests.filePath©r#   c                 C   s¶   t ƒ | _tƒ | _|  td| j¡ |  td| j¡ d| _| j› d� ¡ | _t	ƒ | _
t	ƒ | _t| j
| jƒ| _tƒ | _tƒ | _t| j| jj| j| jƒ| _|  td| j¡ |  td| j¡ d S )NÚexitÚkilli9  Ú
ÚstderrÚglobalLogBeginner)Ú	DummyExitr+   Ú	DummyKillr,   Úpatchr   ÚpidÚencodeÚpidFileContentr   Ústdoutr.   ÚDummyStandardIOZstdioÚDummyWarningsModuleÚwarningsr   ZglobalLogPublisherr   r/   ©r&   r(   r(   r)   ÚsetUp-   s&    üzRunnerTests.setUpc                 C   s.   t tƒ d�}| ¡  |  |jddddg¡ dS )zD
        L{Runner.run} calls the expected methods in order.
        ©ÚreactorÚkillIfRequestedÚstartLoggingÚstartReactorÚreactorExitedN)ÚDummyRunnerr   ÚrunÚassertEqualÚcalledMethods©r&   Úrunnerr(   r(   r)   Útest_runInOrderO   s    üþzRunnerTests.test_runInOrderc                 C   sP   t ƒ }ttƒ |d�}|  |j¡ |  |j¡ | ¡  |  |j¡ |  |j¡ dS )z;
        L{Runner.run} uses the provided PID file.
        ©r=   ÚpidFileN)ÚDummyPIDFiler    r   ÚassertFalseÚenteredÚexitedrC   Ú
assertTrue©r&   rJ   rG   r(   r(   r)   Útest_runUsesPIDFile`   s    zRunnerTests.test_runUsesPIDFilec                 C   sV   t |  | j¡ƒ}dd„ |_ttƒ |d�}| ¡  |  | jj	t
j¡ |  | jjd¡ dS )z²
        L{Runner.run} exits with L{ExitStatus.EX_USAGE} and the expected
        message if a process is already running that corresponds to the given
        PID file.
        c                   S   s   dS ©NTr(   r(   r(   r(   r)   Ú<lambda>w   ó    z4RunnerTests.test_runAlreadyRunning.<locals>.<lambda>rI   zAlready running.N)r   r'   r5   Z	isRunningr    r   rC   rD   r+   Ústatusr   Ú	EX_CONFIGÚmessagerP   r(   r(   r)   Útest_runAlreadyRunningp   s    
z"RunnerTests.test_runAlreadyRunningc                 C   s6   t tƒ d�}| ¡  |  | jjg ¡ |  | jj¡ dS )z‚
        L{Runner.killIfRequested} when C{kill} is false doesn't exit and
        doesn't indiscriminately murder anyone.
        r<   N)	r    r   r>   rD   r,   ÚcallsrL   r+   rN   rF   r(   r(   r)   Útest_killNotRequested   s    z!RunnerTests.test_killNotRequestedc                 C   sL   t tƒ dd�}| ¡  |  | jjg ¡ |  | jjtj	¡ |  | jj
d¡ dS )zÞ
        L{Runner.killIfRequested} when C{kill} is true but C{pidFile} is
        L{nonePIDFile} exits with L{ExitStatus.EX_USAGE} and the expected
        message; and also doesn't indiscriminately murder anyone.
        T)r=   r,   zNo PID file specified.N)r    r   r>   rD   r,   rY   r+   rU   r   ÚEX_USAGErW   rF   r(   r(   r)   Ú test_killRequestedWithoutPIDFileŠ   s
    z,RunnerTests.test_killRequestedWithoutPIDFilec                 C   sf   t |  | j¡ƒ}ttƒ d|d�}| ¡  |  | jj| j	t
fg¡ |  | jjtj¡ |  | jjd¡ dS )z—
        L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile}
        performs a targeted killing of the appropriate process.
        T©r=   r,   rJ   N)r   r'   r5   r    r   r>   rD   r,   rY   r3   r   r+   rU   r   ÚEX_OKÚassertIdenticalrW   rP   r(   r(   r)   Útest_killRequestedWithPIDFile—   s    z)RunnerTests.test_killRequestedWithPIDFilec                 C   s`   t |  d¡ƒ}tdœdd„}||_ttƒ d|d�}| ¡  |  | jj	t
j¡ |  | jjd¡ dS )z•
        L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile}
        that it can't read exits with L{ExitStatus.EX_IOERR}.
        Nr*   c                   S   s   t tjdƒ‚d S )NzPermission denied)ÚOSErrorÚerrnoÚEACCESr(   r(   r(   r)   Úread«   s    z?RunnerTests.test_killRequestedWithPIDFileCantRead.<locals>.readTr]   zUnable to read PID file.)r   r'   Úintrd   r    r   r>   rD   r+   rU   r   ÚEX_IOERRrW   )r&   rJ   rd   rG   r(   r(   r)   Ú%test_killRequestedWithPIDFileCantRead¤   s    z1RunnerTests.test_killRequestedWithPIDFileCantReadc                 C   sL   t |  d¡ƒ}ttƒ d|d�}| ¡  |  | jjtj	¡ |  | jj
d¡ dS )z˜
        L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile}
        containing no value exits with L{ExitStatus.EX_DATAERR}.
        rT   Tr]   úInvalid PID file.N©r   r'   r    r   r>   rD   r+   rU   r   Ú
EX_DATAERRrW   rP   r(   r(   r)   Ú"test_killRequestedWithPIDFileEmpty¶   s
    z.RunnerTests.test_killRequestedWithPIDFileEmptyc                 C   sL   t |  d¡ƒ}ttƒ d|d�}| ¡  |  | jjtj	¡ |  | jj
d¡ dS )z£
        L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile}
        containing a non-integer value exits with L{ExitStatus.EX_DATAERR}.
        s    ** totally not a number, dude **Tr]   rh   Nri   rP   r(   r(   r)   Ú%test_killRequestedWithPIDFileNotAnIntÂ   s
    z1RunnerTests.test_killRequestedWithPIDFileNotAnIntc                    s  t ƒ }G ‡ fdd„dƒ‰ |  tdˆ ƒ ¡ G ‡fdd„dtƒ‰|  tdˆ¡ G ‡fdd„dtƒ‰ttƒ tj|ˆd	�}| 	¡  |  
tˆ jƒd
¡ |  ˆ jd t¡ |  
tˆjƒd
¡ |  ˆjd t¡ |  ˆjd jtj¡ tˆˆjƒ}|  |ˆ¡ |  |j|¡ dS )zÛ
        L{Runner.startLogging} sets up a filtering observer with a log level
        predicate set to the given log level that contains a file observer of
        the given type which writes to the given file.
        c                       s6   e Zd ZU g Zee ed< ee ddœ‡ fdd„ZdS )z2RunnerTests.test_startLogging.<locals>.LogBeginnerÚ	observersN)rm   r#   c                    s   t |ƒˆ _d S r$   )Úlistrm   )r&   rm   ©r   r(   r)   ÚbeginLoggingToÜ   s    zARunnerTests.test_startLogging.<locals>.LogBeginner.beginLoggingTo)	Ú__name__Ú
__module__Ú__qualname__rm   r   r   Ú__annotations__r   rp   r(   ro   r(   r)   r   Ù   s   
r   r/   c                       sX   e Zd ZU dZee ed< g Zee	 ed< e
edd„ ƒfeee	 eddœ‡ fdd„ZdS )	z?RunnerTests.test_startLogging.<locals>.MockFilteringLogObserverNÚobserverÚ
predicatesc                 S   s   d S r$   r(   )Úeventr(   r(   r)   rS   ë   rT   zHRunnerTests.test_startLogging.<locals>.MockFilteringLogObserver.<lambda>)ru   rv   ÚnegativeObserverr#   c                    s$   |ˆ _ t|ƒˆ _t | |||¡ d S r$   )ru   rn   rv   r   Ú__init__)r&   ru   rv   rx   ©ÚMockFilteringLogObserverr(   r)   ry   ç   s    
   ÿzHRunnerTests.test_startLogging.<locals>.MockFilteringLogObserver.__init__)rq   rr   rs   ru   r   r   rt   rv   r   r   r   r   ry   r(   rz   r(   r)   r{   ã   s   
üûr{   r   c                       s2   e Zd ZU dZee ed< eddœ‡ fdd„ZdS )z:RunnerTests.test_startLogging.<locals>.MockFileLogObserverNÚoutFile)r|   r#   c                    s   |ˆ _ t | |t¡ d S r$   )r|   r   ry   Ústr)r&   r|   ©ÚMockFileLogObserverr(   r)   ry   ú   s    zCRunnerTests.test_startLogging.<locals>.MockFileLogObserver.__init__)rq   rr   rs   r|   r   r	   rt   ry   r(   r~   r(   r)   r   ÷   s   
r   )r=   ÚdefaultLogLevelÚlogFileZfileLogObserverFactoryé   r   N)r   r2   r   r   r   r    r   r   Úcriticalr?   rD   Úlenrm   ZassertIsInstancerv   r   r_   r€   r   ru   r|   )r&   r�   rG   ru   r(   )r   r   r{   r)   Útest_startLoggingÎ   s6    ü ÿ
 ÿzRunnerTests.test_startLoggingc                 C   s(   t ƒ }t|d�}| ¡  |  |j¡ dS )ze
        L{Runner.startReactor} with the C{reactor} argument runs the given
        reactor.
        r<   N)r   r    r@   rO   ZhasRun)r&   r=   rG   r(   r(   r)   Útest_startReactorWithReactor  s    
z(RunnerTests.test_startReactorWithReactorc                 C   s   |   dd¡ dS )z�
        L{Runner.startReactor} ensures that C{whenRunning} is called with
        C{whenRunningArguments} when the reactor is running.
        ÚwhenRunningr@   N©Ú	_testHookr:   r(   r(   r)   Útest_startReactorWhenRunning&  s    z(RunnerTests.test_startReactorWhenRunningc                 C   s   |   d¡ dS )zb
        L{Runner.whenRunning} calls C{whenRunning} with
        C{whenRunningArguments}.
        r‡   Nrˆ   r:   r(   r(   r)   Útest_whenRunningWithArguments-  s    z)RunnerTests.test_whenRunningWithArgumentsc                 C   s   |   d¡ dS )zf
        L{Runner.whenRunning} calls C{reactorExited} with
        C{reactorExitedArguments}.
        rA   Nrˆ   r:   r(   r(   r)   Útest_reactorExitedWithArguments4  s    z+RunnerTests.test_reactorExitedWithArguments)Ú
methodNameÚ
callerNamer#   c                    s–   |dkr|}t tƒ tƒ tƒ d�}g ‰ tddœ‡ fdd„}|||› d�| ¡ i}tf dtƒ i|—Ž}t||ƒ}|ƒ  |  tˆ ƒd¡ |  ˆ d	 |¡ dS )
aÊ  
        Verify that the named hook is run with the expected arguments as
        specified by the arguments used to create the L{Runner}, when the
        specified caller is invoked.

        @param methodName: The name of the hook to verify.

        @param callerName: The name of the method that is expected to cause the
            hook to be called.
            If C{None}, use the L{Runner} method with the same name as the
            hook.
        N)ÚaÚbÚc)Ú	argumentsr#   c                     s   ˆ   | ¡ d S r$   )Úappend)r’   ©ZargumentsSeenr(   r)   ÚhookN  s    z#RunnerTests._testHook.<locals>.hookÚ	Argumentsr=   r‚   r   )ÚdictÚobjectÚcopyr    r   ÚgetattrrD   r„   )r&   r�   rŽ   r’   r•   ZrunnerArgumentsrG   Z
hookCallerr(   r”   r)   r‰   ;  s&      þÿÿ
zRunnerTests._testHook)N)N)rq   rr   rs   Ú__doc__r   Úbytesr   r}   r'   r;   rH   rQ   rX   rZ   r\   r`   rg   rk   rl   r…   r†   rŠ   r‹   rŒ   r‰   r(   r(   r(   r)   r!   "   s$   "Mr!   T)Úfrozenc                   @   s\   e Zd ZdZeee eeƒd�Z	ddœdd„Z
ddœdd„Zddœd	d
„Zddœdd„ZdS )rB   zg
    Stub for L{Runner}.

    Keep track of calls to some methods without actually doing anything.
    )ÚtypeÚdefaultNr*   c                 C   s   | j  d¡ d S )Nr>   ©rE   r“   r:   r(   r(   r)   r>   j  s    zDummyRunner.killIfRequestedc                 C   s   | j  d¡ d S )Nr?   r    r:   r(   r(   r)   r?   m  s    zDummyRunner.startLoggingc                 C   s   | j  d¡ d S )Nr@   r    r:   r(   r(   r)   r@   p  s    zDummyRunner.startReactorc                 C   s   | j  d¡ d S )NrA   r    r:   r(   r(   r)   rA   s  s    zDummyRunner.reactorExited)rq   rr   rs   r›   r   r   r}   r   rn   rE   r>   r?   r@   rA   r(   r(   r(   r)   rB   `  s   rB   c                   @   sP   e Zd ZdZddœdd„Zd dœdd„Zeee  ee ee	 ddœd	d
„Z
dS )rK   z]
    Stub for L{PIDFile}.

    Tracks context manager entry/exit without doing anything.
    Nr*   c                 C   s   t  | ¡ d| _d| _d S ©NF)r   ry   rM   rN   r:   r(   r(   r)   ry   ~  s    
zDummyPIDFile.__init__c                 C   s
   d| _ | S rR   )rM   r:   r(   r(   r)   Ú	__enter__„  s    zDummyPIDFile.__enter__)ÚexcTypeÚexcValueÚ	tracebackr#   c                 C   s
   d| _ d S rR   ©rN   )r&   r£   r¤   r¥   r(   r(   r)   Ú__exit__ˆ  s    zDummyPIDFile.__exit__)rq   rr   rs   r›   ry   r¢   r   r   ÚBaseExceptionr   r§   r(   r(   r(   r)   rK   w  s   
ûrK   c                   @   s>   e Zd ZdZddœdd„Zd	eeef ee	 ddœdd„Z
dS )
r0   zy
    Stub for L{_exit.exit} that remembers whether it's been called and, if it has,
    what arguments it was given.
    Nr*   c                 C   s
   d| _ d S r¡   r¦   r:   r(   r(   r)   ry   —  s    zDummyExit.__init__)rU   rW   r#   c                 C   s    | j r
t‚|| _|| _d| _ d S rR   )rN   ÚAssertionErrorrU   rW   )r&   rU   rW   r(   r(   r)   Ú__call__š  s    
zDummyExit.__call__)N)rq   rr   rs   r›   ry   r   re   r   r   r}   rª   r(   r(   r(   r)   r0   ‘  s    ÿ
 þr0   c                   @   s0   e Zd ZdZddœdd„Zeeddœdd„ZdS )	r1   zv
    Stub for L{os.kill} that remembers whether it's been called and, if it has,
    what arguments it was given.
    Nr*   c                 C   s
   g | _ d S r$   )rY   r:   r(   r(   r)   ry   ª  s    zDummyKill.__init__)r3   Úsigr#   c                 C   s   | j  ||f¡ d S r$   )rY   r“   )r&   r3   r«   r(   r(   r)   rª   ­  s    zDummyKill.__call__)rq   rr   rs   r›   ry   re   rª   r(   r(   r(   r)   r1   ¤  s   r1   c                   @   s"   e Zd ZdZeeddœdd„ZdS )r7   zR
    Stub for L{sys} which provides L{StringIO} streams as stdout and stderr.
    N)r6   r.   r#   c                 C   s   || _ || _d S r$   )r6   r.   )r&   r6   r.   r(   r(   r)   ry   ¶  s    zDummyStandardIO.__init__)rq   rr   rs   r›   r	   ry   r(   r(   r(   r)   r7   ±  s   r7   c                   @   s"   e Zd ZdZeeddœdd„ZdS )r8   zV
    Stub for L{warnings} which provides a C{showwarning} method that is a no-op.
    N)ÚargsÚkwargsr#   c                  O   s   dS )z\
        Do nothing.

        @param args: ignored.
        @param kwargs: ignored.
        Nr(   )r¬   r­   r(   r(   r)   ÚshowwarningÀ  s    zDummyWarningsModule.showwarning)rq   rr   rs   r›   r   r®   r(   r(   r(   r)   r8   »  s   r8   )6r›   rb   Úior   Úsignalr   Útypesr   Útypingr   r   r   r   r	   r
   r   r   r   Úattrr   r   r   Ztwisted.trial.unittestZtwistedZtwisted.internet.testingr   Ztwisted.loggerr   r   r   r   r   r   r   Ztwisted.python.filepathr   rG   r   Ú_exitr   Z_pidfiler   r   r    ZtrialZunittestZTestCaser!   rB   rK   r0   r1   r7   r8   r(   r(   r(   r)   Ú<module>   s0   ,$	  @
