
    Vh8                        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ejX                  jZ                  j\                        Z/ ed       G d de+             Z0 G d de)      Z1 G d d      Z2 G d d      Z3 G d d      Z4 G d d       Z5y)!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                       e Zd ZdZddee   dee   f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edee   ddfdZy)RunnerTestsz
    Tests for L{Runner}.
    Ncontentreturnc                 ^    t        | j                               }||j                  |       |S N)r   mktemp
setContent)selfr$   filePaths      [/home/dcms/DCMS/lib/python3.12/site-packages/twisted/application/runner/test/test_runner.pyr+   zRunnerTests.filePath'   s+    DKKM*(    c                    t               | _        t               | _        | j	                  t
        d| j                         | j	                  t
        d| j                         d| _        | j                   dj                         | _        t               | _
        t               | _        t        | j                  | j                        | _        t               | _        t!               | _        t%        | j"                  | j                  j                  | j                  | j                        | _        | j	                  t
        d| j                         | j	                  t
        d| j&                         y )Nexitkilli9  
stderrglobalLogBeginner)	DummyExitr/   	DummyKillr0   patchr   pidencodepidFileContentr   stdoutr2   DummyStandardIOstdioDummyWarningsModulewarningsr   globalLogPublisherr   r3   r*   s    r,   setUpzRunnerTests.setUp-   s     K	K	

7FDII.

7FDII. !%
"o446
 jj$T[[$++>
+-"..!,##JJJJMM	"
 	

7Hdkk2

7/1G1GHr-   c                     t        t                     }|j                          | j                  |j                  g d       y)zD
        L{Runner.run} calls the expected methods in order.
        reactor)killIfRequestedstartLoggingstartReactorreactorExitedN)DummyRunnerr   runassertEqualcalledMethodsr*   runners     r,   test_runInOrderzRunnerTests.test_runInOrderO   s5     ]_5

  	
r-   c                 :   t               }t        t               |      }| j                  |j                         | j                  |j
                         |j                          | j                  |j                         | j                  |j
                         y)z;
        L{Runner.run} uses the provided PID file.
        rD   pidFileN)DummyPIDFiler!   r   assertFalseenteredexitedrJ   
assertTruer*   rR   rN   s      r,   test_runUsesPIDFilezRunnerTests.test_runUsesPIDFile`   sf     .A)(

('r-   c                 Z   t        | j                  | j                              }d |_        t	        t               |      }|j                          | j                  | j                  j                  t        j                         | j                  | j                  j                  d       y)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                       yNT r]   r-   r,   <lambda>z4RunnerTests.test_runAlreadyRunning.<locals>.<lambda>w       r-   rQ   zAlready running.N)r    r+   r9   	isRunningr!   r   rJ   rK   r/   statusr   	EX_CONFIGmessagerX   s      r,   test_runAlreadyRunningz"RunnerTests.test_runAlreadyRunningp   sw     $--(;(;<=(A

)):+?+?@**,>?r-   c                     t        t                     }|j                          | j                  | j                  j
                  g        | j                  | j                  j                         y)z
        L{Runner.killIfRequested} when C{kill} is false doesn't exit and
        doesn't indiscriminately murder anyone.
        rC   N)	r!   r   rE   rK   r0   callsrT   r/   rV   rM   s     r,   test_killNotRequestedz!RunnerTests.test_killNotRequested   sL    
 0 "-))*r-   c                 N   t        t               d      }|j                          | j                  | j                  j
                  g        | j                  | j                  j                  t        j                         | j                  | j                  j                  d       y)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)rD   r0   zNo PID file specified.N)r!   r   rE   rK   r0   rf   r/   ra   r   EX_USAGErc   rM   s     r,    test_killRequestedWithoutPIDFilez,RunnerTests.test_killRequestedWithoutPIDFile   sq     d; "-)):+>+>?**,DEr-   c                    t        | j                  | j                              }t        t	               d|      }|j                          | j                  | j                  j                  | j                  t        fg       | j                  | j                  j                  t        j                         | j                  | j                  j                   d       y)z
        L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile}
        performs a targeted killing of the appropriate process.
        TrD   r0   rR   N)r    r+   r9   r!   r   rE   rK   r0   rf   r7   r   r/   ra   r   EX_OKassertIdenticalrc   rX   s      r,   test_killRequestedWithPIDFilez)RunnerTests.test_killRequestedWithPIDFile   s    
 $--(;(;<=dGL DHHg+>*?@)):+;+;<TYY..5r-   c                 Z   t        | j                  d            }dt        fd}||_        t	        t               d|      }|j                          | j                  | j                  j                  t        j                         | j                  | j                  j                  d       y)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                  6    t        t        j                  d      )NzPermission denied)OSErrorerrnoEACCESr]   r-   r,   readz?RunnerTests.test_killRequestedWithPIDFileCantRead.<locals>.read   s    %,,(;<<r-   Trl   zUnable to read PID file.)r    r+   intru   r!   r   rE   rK   r/   ra   r   EX_IOERRrc   )r*   rR   ru   rN   s       r,   %test_killRequestedWithPIDFileCantReadz1RunnerTests.test_killRequestedWithPIDFileCantRead   s    
 $---.	=c 	= dGL )):+>+>?**,FGr-   c                 8   t        | j                  d            }t        t               d|      }|j	                          | j                  | j                  j                  t        j                         | j                  | j                  j                  d       y)z
        L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile}
        containing no value exits with L{ExitStatus.EX_DATAERR}.
        r-   Trl   Invalid PID file.Nr    r+   r!   r   rE   rK   r/   ra   r   
EX_DATAERRrc   rX   s      r,   "test_killRequestedWithPIDFileEmptyz.RunnerTests.test_killRequestedWithPIDFileEmpty   sn    
 $--,-dGL )):+@+@A**,?@r-   c                 8   t        | j                  d            }t        t               d|      }|j	                          | j                  | j                  j                  t        j                         | j                  | j                  j                  d       y)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 **Trl   rz   Nr{   rX   s      r,   %test_killRequestedWithPIDFileNotAnIntz1RunnerTests.test_killRequestedWithPIDFileNotAnInt   so    
 $--(KLMdGL )):+@+@A**,?@r-   c                 `   t               } G fdd      | j                  t        d                G fddt              | j                  t        d        G fddt              t        t               t        j                  |	      }|j                          | j                  t        j                        d
       | j                  j                  d   t               | j                  t        j                        d
       | j                  j                  d   t               | j!                  j                  d   j"                  t        j                         t%        j&                        }| j                  |       | j!                  |j(                  |       y)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                   >    e Zd ZU g Zee   ed<   dee   ddf fdZy)2RunnerTests.test_startLogging.<locals>.LogBeginner	observersr%   Nc                 &    t        |      _        y r'   )listr   )r*   r   r   s     r,   beginLoggingTozARunnerTests.test_startLogging.<locals>.LogBeginner.beginLoggingTo   s    (,Y%r-   )	__name__
__module____qualname__r   r   r   __annotations__r   r   )r   s   r,   r   r      s*    ,.ItL).80F 84 8r-   r   r3   c            	       n    e Zd ZU dZee   ed<   g Zee	   ed<    e
ed       fdedee	   deddf fdZy)?RunnerTests.test_startLogging.<locals>.MockFilteringLogObserverNobserver
predicatesc                      y r'   r]   )events    r,   r^   zHRunnerTests.test_startLogging.<locals>.MockFilteringLogObserver.<lambda>   r_   r-   negativeObserverr%   c                 d    |_         t        |      _        t        j                  | |||       y r'   )r   r   r   r   __init__)r*   r   r   r   MockFilteringLogObservers       r,   r   zHRunnerTests.test_startLogging.<locals>.MockFilteringLogObserver.__init__   s4     5=(16::6F(3$--(J0@r-   )r   r   r   r   r	   r   r   r   r   r   r   r   r   )r   s   r,   r   r      s`    /3Hh|,38:J45: 26lDV1W	
&
 %%<=
 #/	

 
r-   r   r   c                   8    e Zd ZU dZee   ed<   deddf fdZy):RunnerTests.test_startLogging.<locals>.MockFileLogObserverNoutFiler%   c                 J    |_         t        j                  | |t               y r'   )r   r   r   str)r*   r   MockFileLogObservers     r,   r   zCRunnerTests.test_startLogging.<locals>.MockFileLogObserver.__init__   s    .5#+((w<r-   )r   r   r   r   r	   r
   r   r   )r   s   r,   r   r      s%    (,GXf%,= =4 =r-   r   )rD   defaultLogLevellogFilefileLogObserverFactory   r   N)r   r6   r   r   r   r!   r   r   criticalrF   rK   lenr   assertIsInstancer   r   rn   r   r   r   r   )r*   r   rN   r   r   r   r   s       @@@r,   test_startLoggingzRunnerTests.test_startLogging   sg    *
	8 	8 	

7/?	'; 	  	

724LM	=/ 	= !O$--#6	
 	 	[223Q7k33A68LM 	5@@A1E$//24K	
 	$//2BBHDUDU	

 +-E-N-NOh(;< 	X--w7r-   c                     t               }t        |      }|j                          | j                  |j                         y)ze
        L{Runner.startReactor} with the C{reactor} argument runs the given
        reactor.
        rC   N)r   r!   rG   rW   hasRun)r*   rD   rN   s      r,   test_startReactorWithReactorz(RunnerTests.test_startReactorWithReactor  s1    
  /('r-   c                 (    | j                  dd       y)z
        L{Runner.startReactor} ensures that C{whenRunning} is called with
        C{whenRunningArguments} when the reactor is running.
        whenRunningrG   N	_testHookr@   s    r,   test_startReactorWhenRunningz(RunnerTests.test_startReactorWhenRunning&  s    
 	}n5r-   c                 &    | j                  d       y)zb
        L{Runner.whenRunning} calls C{whenRunning} with
        C{whenRunningArguments}.
        r   Nr   r@   s    r,   test_whenRunningWithArgumentsz)RunnerTests.test_whenRunningWithArguments-  s    
 	}%r-   c                 &    | j                  d       y)zf
        L{Runner.whenRunning} calls C{reactorExited} with
        C{reactorExitedArguments}.
        rH   Nr   r@   s    r,   test_reactorExitedWithArgumentsz+RunnerTests.test_reactorExitedWithArguments4  s    
 	'r-   
methodName
callerNamec                 X   ||}t        t               t               t                     }g dt        ddffd}||| d|j                         i}t        d
dt	               i|}t        ||      } |        | j                  t              d       | j                  d	   |       y)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                  (    j                  |        y r'   )append)r   argumentsSeens    r,   hookz#RunnerTests._testHook.<locals>.hookN  s      +r-   	ArgumentsrD   r   r   r]   )dictobjectcopyr!   r   getattrrK   r   )	r*   r   r   r   r   runnerArgumentsrN   
hookCallerr   s	           @r,   r   zRunnerTests._testHook;  s     #J68vx68<		,f 	, 	, l)$inn&6
  
!O
'6
 VZ0
]+Q/q)95r-   r'   r%   N)r   r   r   __doc__r	   bytesr   r   r+   rA   rO   rY   rd   rg   rj   ro   rx   r}   r   r   r   r   r   r   r   r]   r-   r,   r#   r#   "   s     8C=  ID
"( @	+F6H$
A
AK8Z	(6&("6C "6Xc] "6d "6r-   r#   T)frozenc                   V    e Zd ZdZ eee    ee            Z	ddZ
ddZddZddZy)	rI   zg
    Stub for L{Runner}.

    Keep track of calls to some methods without actually doing anything.
    )typedefaultNc                 :    | j                   j                  d       y )NrE   rL   r   r@   s    r,   rE   zDummyRunner.killIfRequestedj  s    !!"34r-   c                 :    | j                   j                  d       y )NrF   r   r@   s    r,   rF   zDummyRunner.startLoggingm      !!.1r-   c                 :    | j                   j                  d       y )NrG   r   r@   s    r,   rG   zDummyRunner.startReactorp  r   r-   c                 :    | j                   j                  d       y )NrH   r   r@   s    r,   rH   zDummyRunner.reactorExiteds  s    !!/2r-   r   )r   r   r   r   r   r   r   r   r   rL   rE   rF   rG   rH   r]   r-   r,   rI   rI   `  s1     S	74=AM5223r-   rI   c                   P    e Zd ZdZd
dZddZdeee      dee   dee	   ddfd	Z
y)rS   z]
    Stub for L{PIDFile}.

    Tracks context manager entry/exit without doing anything.
    r%   Nc                 J    t        j                  |        d| _        d| _        y NF)r   r   rU   rV   r@   s    r,   r   zDummyPIDFile.__init__~  s    T"r-   c                     d| _         | S r\   )rU   r@   s    r,   	__enter__zDummyPIDFile.__enter__  s    r-   excTypeexcValue	tracebackc                     d| _         y r\   rV   )r*   r   r   r   s       r,   __exit__zDummyPIDFile.__exit__  s     r-   r   )r%   rS   )r   r   r   r   r   r   r	   r   BaseExceptionr   r   r]   r-   r,   rS   rS   w  sP    $}-. =) M*	
 
r-   rS   c                   @    e Zd ZdZddZ	 d	deeef   dee	   ddfdZ
y)
r4   zy
    Stub for L{_exit.exit} that remembers whether it's been called and, if it has,
    what arguments it was given.
    r%   Nc                     d| _         y r   r   r@   s    r,   r   zDummyExit.__init__  s	    r-   ra   rc   c                 J    | j                   rJ || _        || _        d| _         y r\   )rV   ra   rc   )r*   ra   rc   s      r,   __call__zDummyExit.__call__  s%     ;;r-   r   r'   )r   r   r   r   r   r   rv   r   r	   r   r   r]   r-   r,   r4   r4     s=    
 HLCO,7?}	r-   r4   c                   ,    e Zd ZdZddZdededdfdZy)	r5   zv
    Stub for L{os.kill} that remembers whether it's been called and, if it has,
    what arguments it was given.
    r%   Nc                     g | _         y r'   )rf   r@   s    r,   r   zDummyKill.__init__  s	    ,.
r-   r7   sigc                 >    | j                   j                  ||f       y r'   )rf   r   )r*   r7   r   s      r,   r   zDummyKill.__call__  s    

3*%r-   r   )r   r   r   r   r   rv   r   r]   r-   r,   r5   r5     s&    
/&C &c &d &r-   r5   c                   $    e Zd ZdZdededdfdZy)r;   zR
    Stub for L{sys} which provides L{StringIO} streams as stdout and stderr.
    r:   r2   r%   Nc                      || _         || _        y r'   )r:   r2   )r*   r:   r2   s      r,   r   zDummyStandardIO.__init__  s    r-   )r   r   r   r   r
   r   r]   r-   r,   r;   r;     s!    v v $ r-   r;   c                   $    e Zd ZdZdededdfdZy)r=   zV
    Stub for L{warnings} which provides a C{showwarning} method that is a no-op.
    argskwargsr%   Nc                       y)z\
        Do nothing.

        @param args: ignored.
        @param kwargs: ignored.
        Nr]   )r   r   s     r,   showwarningzDummyWarningsModule.showwarning  r_   r-   )r   r   r   r   r   r   r]   r-   r,   r=   r=     s!    3 # $ r-   r=   )6r   rs   ior   signalr   typesr   typingr   r   r   r	   r
   r   r   r   r   attrr   r   r   twisted.trial.unittesttwistedtwisted.internet.testingr   twisted.loggerr   r   r   r   r   r   r   twisted.python.filepathr   rN   r   _exitr   _pidfiler   r    r!   trialunittestTestCaser#   rI   rS   r4   r5   r;   r=   r]   r-   r,   <module>r      s        R R R ' '  2   -   + {6'--((11 {6|	 d3& 3 3,; 4 &
& 
&  r-   