U
    
W[3                     @   s0  d Z ddlmZ ddlmZ ddlZddlmZmZm	Z	 ddl
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 ddlmZ ddlZG dd dejj j!Z"eddG dd deZ#G dd deZ$G dd de%Z&G dd de%Z'G dd de%Z(G dd de%Z)dS ) z2
Tests for L{twisted.application.runner._runner}.
    )SIGTERM)BytesION)attribattrsFactory)LogLevelLogPublisherLogBeginnerFileLogObserverFilteringLogObserverLogLevelFilterPredicate)MemoryReactor   )_runner   )
ExitStatus)PIDFileNonePIDFile)Runner   )DummyFilePathc                   @   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 Zd#d!d"Zd S )$RunnerTestsz
    Tests for L{Runner}.
    c                 C   s   t  | _t | _| td| j | td| j d| _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  z{}
zutf-8stderrglobalLogBeginner)	DummyExitr   	DummyKillr   patchr   pidformatencodepidFileContentr   stdoutr   DummyStandardIOZstdioDummyWarningsModulewarningsr   ZglobalLogPublisherr	   r   self r)   M/usr/lib/python3/dist-packages/twisted/application/runner/test/test_runner.py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_runInOrderE   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exitedr3   
assertTruer(   r:   r7   r)   r)   r*   test_runUsesPIDFileW   s    zRunnerTests.test_runUsesPIDFilec                 C   sT   t 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>o       z4RunnerTests.test_runAlreadyRunning.<locals>.<lambda>r9   zAlready running.N)r   r   r"   Z	isRunningr   r   r3   r4   r   statusr   	EX_CONFIGmessager@   r)   r)   r*   test_runAlreadyRunningh   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.   r4   r   callsr<   r   r>   r6   r)   r)   r*   test_killNotRequestedx   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.   r4   r   rI   r   rE   r   EX_USAGErG   r6   r)   r)   r*    test_killRequestedWithoutPIDFile   s
    z,RunnerTests.test_killRequestedWithoutPIDFilec                 C   sd   t 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   r:   N)r   r   r"   r   r   r.   r4   r   rI   r   r   r   rE   r   EX_OKassertIdenticalrG   r@   r)   r)   r*   test_killRequestedWithPIDFile   s    z)RunnerTests.test_killRequestedWithPIDFilec                 C   sX   t 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}.
        Nc                   S   s   t tjdd S )NzPermission denied)OSErrorerrnoZEACCESr)   r)   r)   r*   read   s    z?RunnerTests.test_killRequestedWithPIDFileCantRead.<locals>.readTrM   zUnable to read PID file.)r   r   rS   r   r   r.   r4   r   rE   r   EX_IOERRrG   )r(   r:   rS   r7   r)   r)   r*   %test_killRequestedWithPIDFileCantRead   s    z1RunnerTests.test_killRequestedWithPIDFileCantReadc                 C   sJ   t 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}.
        rD   TrM   Invalid PID file.Nr   r   r   r   r.   r4   r   rE   r   
EX_DATAERRrG   r@   r)   r)   r*   "test_killRequestedWithPIDFileEmpty   s
    z.RunnerTests.test_killRequestedWithPIDFileEmptyc                 C   sJ   t 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 **TrM   rV   NrW   r@   r)   r)   r*   %test_killRequestedWithPIDFileNotAnInt   s
    z1RunnerTests.test_killRequestedWithPIDFileNotAnIntc                    s   t  }G  fdddt | 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	 | j | 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                       s   e Zd Z fddZdS )z2RunnerTests.test_startLogging.<locals>.LogBeginnerc                    s
   | _ d S N)	observers)r(   r\   r	   r)   r*   beginLoggingTo   s    zARunnerTests.test_startLogging.<locals>.LogBeginner.beginLoggingToN)__name__
__module____qualname__r^   r)   r]   r)   r*   r	      s   r	   r   c                       s    e Zd Zdd f fdd	ZdS )z?RunnerTests.test_startLogging.<locals>.MockFilteringLogObserverc                 S   s   d S r[   r)   )Zeventr)   r)   r*   rC      rD   zHRunnerTests.test_startLogging.<locals>.MockFilteringLogObserver.<lambda>c                    s    | _ | _t| ||| d S r[   )observer
predicatesr   __init__)r(   rb   rc   ZnegativeObserverMockFilteringLogObserverr)   r*   rd      s       zHRunnerTests.test_startLogging.<locals>.MockFilteringLogObserver.__init__Nr_   r`   ra   rd   r)   re   r)   r*   rf      s   rf   r   c                       s   e Zd Z fddZdS )z:RunnerTests.test_startLogging.<locals>.MockFileLogObserverc                    s   | _ t| |t d S r[   )outFiler
   rd   str)r(   rh   MockFileLogObserverr)   r*   rd      s    zCRunnerTests.test_startLogging.<locals>.MockFileLogObserver.__init__Nrg   r)   rj   r)   r*   rk      s   rk   )r-   defaultLogLevellogFileZfileLogObserverFactoryr   r   N)r   objectr   r   r   r
   r   r   r   Zcriticalr/   r4   lenr\   ZassertIsInstancerc   r   rO   rl   rb   rh   )r(   rm   r7   r)   )r	   rk   rf   r*   test_startLogging   s@    
  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   r0   r?   ZhasRun)r(   r-   r7   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.
        whenRunningr0   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}.
        rr   Nrs   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}.
        r1   Nrs   r'   r)   r)   r*   test_reactorExitedWithArguments3  s    z+RunnerTests.test_reactorExitedWithArgumentsNc                    s   |dkr|}t t t t d}g   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.
        @type methodName: L{str}

        @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.
        @type callerName: L{str}
        N)abcc                     s     |  d S r[   )append)	argumentsZargumentsSeenr)   r*   hookP  s    z#RunnerTests._testHook.<locals>.hookz{}Argumentsr-   r   r   )	dictrn   r    copyr   r   getattrr4   ro   )r(   Z
methodNameZ
callerNamer|   r~   ZrunnerArgumentsr7   Z
hookCallerr)   r}   r*   rt   ;  s      
zRunnerTests._testHook)N)r_   r`   ra   __doc__r+   r8   rA   rH   rJ   rL   rP   rU   rY   rZ   rp   rq   ru   rv   rw   rt   r)   r)   r)   r*   r      s"   "Jr   T)frozenc                   @   s>   e Zd ZdZeeedZdd Zdd Z	dd Z
d	d
 ZdS )r2   zg
    Stub for L{Runner}.

    Keep track of calls to some methods without actually doing anything.
    )defaultc                 C   s   | j d d S )Nr.   r5   r{   r'   r)   r)   r*   r.   l  s    zDummyRunner.killIfRequestedc                 C   s   | j d d S )Nr/   r   r'   r)   r)   r*   r/   p  s    zDummyRunner.startLoggingc                 C   s   | j d d S )Nr0   r   r'   r)   r)   r*   r0   t  s    zDummyRunner.startReactorc                 C   s   | j d d S )Nr1   r   r'   r)   r)   r*   r1   x  s    zDummyRunner.reactorExitedN)r_   r`   ra   r   r   r   listr5   r.   r/   r0   r1   r)   r)   r)   r*   r2   a  s   r2   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r;   z]
    Stub for L{PIDFile}.

    Tracks context manager entry/exit without doing anything.
    c                 C   s   t |  d| _d| _d S NF)r   rd   r=   r>   r'   r)   r)   r*   rd     s    
zDummyPIDFile.__init__c                 C   s
   d| _ | S rB   )r=   r'   r)   r)   r*   	__enter__  s    zDummyPIDFile.__enter__c                 C   s
   d| _ d S rB   r>   )r(   ZexcTypeZexcValue	tracebackr)   r)   r*   __exit__  s    zDummyPIDFile.__exit__N)r_   r`   ra   r   rd   r   r   r)   r)   r)   r*   r;   }  s   r;   c                   @   s"   e Zd ZdZdd ZdddZdS )r   zs
    Stub for L{exit} that remembers whether it's been called and, if it has,
    what arguments it was given.
    c                 C   s
   d| _ d S r   r   r'   r)   r)   r*   rd     s    zDummyExit.__init__Nc                 C   s    | j r
t|| _|| _d| _ d S rB   )r>   AssertionErrorrE   rG   )r(   rE   rG   r)   r)   r*   __call__  s    
zDummyExit.__call__)Nr_   r`   ra   r   rd   r   r)   r)   r)   r*   r     s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )r   zv
    Stub for L{os.kill} that remembers whether it's been called and, if it has,
    what arguments it was given.
    c                 C   s
   g | _ d S r[   )rI   r'   r)   r)   r*   rd     s    zDummyKill.__init__c                 C   s   | j ||f d S r[   )rI   r{   )r(   r   Zsigr)   r)   r*   r     s    zDummyKill.__call__Nr   r)   r)   r)   r*   r     s   r   c                   @   s   e Zd ZdZdd ZdS )r$   zQ
    Stub for L{sys} which provides L{BytesIO} streams as stdout and stderr.
    c                 C   s   || _ || _d S r[   )r#   r   )r(   r#   r   r)   r)   r*   rd     s    zDummyStandardIO.__init__N)r_   r`   ra   r   rd   r)   r)   r)   r*   r$     s   r$   c                   @   s   e Zd ZdZdd ZdS )r%   zV
    Stub for L{warnings} which provides a C{showwarning} method that is a no-op.
    c                  O   s   dS )z\
        Do nothing.

        @param args: ignored.
        @param kwargs: ignored.
        Nr)   )argskwargsr)   r)   r*   showwarning  s    zDummyWarningsModule.showwarningN)r_   r`   ra   r   r   r)   r)   r)   r*   r%     s   r%   )*r   signalr   ior   rR   attrr   r   r   Ztwisted.loggerr   r   r	   r
   r   r   Ztwisted.test.proto_helpersr   r7   r   _exitr   Z_pidfiler   r   r   Ztest_pidfiler   Ztwisted.trial.unittestZtwistedZtrialZunittestZTestCaser   r2   r;   rn   r   r   r$   r%   r)   r)   r)   r*   <module>   s,      E