Ϫf8dZddlZddlmZddlmZddlmZddlm Z m Z m Z m Z m Z mZmZmZmZddlmZmZmZddlZddlmZdd lmZmZmZmZmZm Z m!Z!dd l"m#Z#d d l$m%Z%d dl&m'Z'd dl(m)Z)m*Z*d dl%m+Z+GddejXjZj\Z/edGdde+Z0Gdde)Z1GddZ2GddZ3GddZ4Gdd Z5y)!z2 Tests for L{twisted.application.runner._runner}. N)StringIO)SIGTERM) TracebackType) AnyIterableListOptionalTextIOTupleTypeUnioncast)Factoryattribattrs) MemoryReactor)FileLogObserverFilteringLogObserver ILogObserver LogBeginnerLogLevelLogLevelFilterPredicate LogPublisher)FilePath)_runner) ExitStatus) NonePIDFilePIDFile)RunnerceZdZdZddeedeefdZddZ ddZ ddZ dd Z dd Z dd Zdd Zdd ZddZddZddZddZddZddZddZddedeeddfdZy) RunnerTestsz Tests for L{Runner}. Ncontentreturnc^t|j}||j||SN)rmktemp setContent)selfr$filePaths M/usr/lib/python3/dist-packages/twisted/application/runner/test/test_runner.pyr+zRunnerTests.filePath's+DKKM*      (ct|_t|_|j t d|j|j t d|jd|_|j dj|_t|_ t|_ t|j|j|_ t|_t!|_t%|j"|jj|j|j|_|j t d|j|j t d|j&y)Nexitkilli9 stderrglobalLogBeginner) DummyExitr/ DummyKillr0patchrpidencodepidFileContentrstdoutr2DummyStandardIOstdioDummyWarningsModulewarningsrglobalLogPublisherrr3r*s r,setUpzRunnerTests.setUp-sK K  7FDII. 7FDII.!% "o446 j j $T[[$++> +- "..!,  # # JJ   JJ MM "  7Hdkk2 7/1G1GHr-ctt}|j|j|jgdy)zD L{Runner.run} calls the expected methods in order. reactor)killIfRequested startLogging startReactor reactorExitedN) DummyRunnerrrun assertEqual calledMethodsr*runners r,test_runInOrderzRunnerTests.test_runInOrderOs5]_5      r-c:t}tt|}|j|j|j|j |j |j|j|j|j y)z; L{Runner.run} uses the provided PID file. rDpidFileN) DummyPIDFiler!r assertFalseenteredexitedrJ assertTruer*rRrNs r,test_runUsesPIDFilezRunnerTests.test_runUsesPIDFile`sf. A ) (  ( 'r-cZt|j|j}d|_t t |}|j |j|jjtj|j|jjdy)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. cyNTr]r-r,z4RunnerTests.test_runAlreadyRunning..wr-rQzAlready running.N) r r+r9 isRunningr!rrJrKr/statusr EX_CONFIGmessagerXs r,test_runAlreadyRunningz"RunnerTests.test_runAlreadyRunningpsw $--(;(;<=( A  )):+?+?@ **,>?r-ctt}|j|j|jj g|j |jjy)z L{Runner.killIfRequested} when C{kill} is false doesn't exit and doesn't indiscriminately murder anyone. rCN) r!rrErKr0callsrTr/rVrMs r,test_killNotRequestedz!RunnerTests.test_killNotRequestedsL  0  "- ))*r-cNttd}|j|j|jj g|j|j jtj|j|j jdy)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)rDr0zNo PID file specified.N) r!rrErKr0rfr/rarEX_USAGErcrMs r, test_killRequestedWithoutPIDFilez,RunnerTests.test_killRequestedWithoutPIDFilesq  d;  "- )):+>+>? **,DEr-ct|j|j}tt d|}|j |j |jj|jtfg|j |jjtj|j|jj dy)z L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile} performs a targeted killing of the appropriate process. TrDr0rRN)r r+r9r!rrErKr0rfr7rr/rarEX_OKassertIdenticalrcrXs r,test_killRequestedWithPIDFilez)RunnerTests.test_killRequestedWithPIDFiles $--(;(;<= dGL  DHHg+>*?@ )):+;+;< TYY..5r-cZt|jd}dtfd}||_t t d|}|j |j|jjtj|j|jjdy)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%c6ttjd)NzPermission denied)OSErrorerrnoEACCESr]r-r,readz?RunnerTests.test_killRequestedWithPIDFileCantRead..reads%,,(;< +>? **,FGr-c8t|jd}ttd|}|j |j |j jtj|j |j jdy)z L{Runner.killIfRequested} when C{kill} is true and given a C{pidFile} containing no value exits with L{ExitStatus.EX_DATAERR}. r-TrlInvalid PID file.N r r+r!rrErKr/rar EX_DATAERRrcrXs r,"test_killRequestedWithPIDFileEmptyz.RunnerTests.test_killRequestedWithPIDFileEmptysn $--,- dGL  )):+@+@A **,?@r-c8t|jd}ttd|}|j |j |j jtj|j |j jdy)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 **TrlrzNr{rXs r,%test_killRequestedWithPIDFileNotAnIntz1RunnerTests.test_killRequestedWithPIDFileNotAnIntso $--(KLM dGL  )):+@+@A **,?@r-c`t}Gfdd|jtdGfddt|jtdGfddtt t tj| }|j|jtjd |jjd t|jtjd |jjd t|j!jd j"tjt%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>eZdZUgZeeed<deeddffd Zy)2RunnerTests.test_startLogging..LogBeginner observersr%Nc&t|_yr')listr)r*rrs r,beginLoggingTozARunnerTests.test_startLogging..LogBeginner.beginLoggingTos(,Y %r-) __name__ __module__ __qualname__rrr__annotations__rr)rsr,rrs*,.ItL) . 80F 84 8r-rr3c neZdZUdZeeed<gZee ed<e edfdede e deddffd Z y)?RunnerTests.test_startLogging..MockFilteringLogObserverNobserver predicatescyr'r])events r,r^zHRunnerTests.test_startLogging..MockFilteringLogObserver.r_r-negativeObserverr%cd|_t|_tj||||yr')rrrr__init__)r*rrrMockFilteringLogObservers r,rzHRunnerTests.test_startLogging..MockFilteringLogObserver.__init__s4 5=(16::6F(3$--(J0@r-) rrrrr rrrrrrrr)rsr,rrs`/3Hh|, 38:J45 : 26lDV1W & %%<= #/   r-rrc8eZdZUdZeeed<deddffd Zy):RunnerTests.test_startLogging..MockFileLogObserverNoutFiler%cJ|_tj||tyr')rrrstr)r*rMockFileLogObservers r,rzCRunnerTests.test_startLogging..MockFileLogObserver.__init__s.5#+((w.hookNs   +r- ArgumentsrDrrr])dictobjectcopyr!rgetattrrKr) r*rrrrrunnerArgumentsrN hookCallerrs @r,rzRunnerTests._testHook;s  #J68vx68<   ,f , , l) $inn&6  !O '6 VZ0   ]+Q/ q)95r-r'r%N)rrr__doc__r bytesrrr+rArOrYrdrgrjrorxr}rrrrrrrr]r-r,r#r#"s8C= ID "( @ + F 6H$ A AK8Z (6&("6C"6Xc]"6d"6r-r#T)frozencVeZdZdZeeeeeZ ddZ ddZ ddZ ddZ y) rIzg Stub for L{Runner}. Keep track of calls to some methods without actually doing anything. )typedefaultNc:|jjdy)NrErLrr@s r,rEzDummyRunner.killIfRequestedjs !!"34r-c:|jjdy)NrFrr@s r,rFzDummyRunner.startLoggingm !!.1r-c:|jjdy)NrGrr@s r,rGzDummyRunner.startReactorprr-c:|jjdy)NrHrr@s r,rHzDummyRunner.reactorExitedss !!/2r-r)rrrrrrrrrrLrErFrGrHr]r-r,rIrI`s1 S 74=AM5223r-rIcPeZdZdZd dZd dZdeeedeedee ddfd Z y) rSz] Stub for L{PIDFile}. Tracks context manager entry/exit without doing anything. r%NcJtj|d|_d|_yNF)rrrUrVr@s r,rzDummyPIDFile.__init__~sT"  r-cd|_|Sr\)rUr@s r, __enter__zDummyPIDFile.__enter__s  r-excTypeexcValue tracebackcd|_yr\rV)r*rrrs r,__exit__zDummyPIDFile.__exit__s  r-r)r%rS) rrrrrrr r BaseExceptionrrr]r-r,rSrSwsP  $}-.=)M*   r-rSc@eZdZdZddZ d deeefdee ddfdZ y) r4zy Stub for L{_exit.exit} that remembers whether it's been called and, if it has, what arguments it was given. r%Ncd|_yrrr@s r,rzDummyExit.__init__s  r-rarccJ|jrJ||_||_d|_yr\)rVrarc)r*rarcs r,__call__zDummyExit.__call__s%;;   r-rr') rrrrrr rvrr rrr]r-r,r4r4s= HLCO,7?} r-r4c,eZdZdZddZdededdfdZy) r5zv Stub for L{os.kill} that remembers whether it's been called and, if it has, what arguments it was given. r%Ncg|_yr')rfr@s r,rzDummyKill.__init__s ,. r-r7sigc>|jj||fyr')rfr)r*r7rs r,rzDummyKill.__call__s 3*%r-r)rrrrrrvrr]r-r,r5r5s& /&C&c&d&r-r5c$eZdZdZdededdfdZy)r;zR Stub for L{sys} which provides L{StringIO} streams as stdout and stderr. r:r2r%Nc ||_||_yr')r:r2)r*r:r2s r,rzDummyStandardIO.__init__s  r-)rrrrr rr]r-r,r;r;s!vv$r-r;c$eZdZdZdededdfdZy)r=zV Stub for L{warnings} which provides a C{showwarning} method that is a no-op. argskwargsr%Ncy)z\ Do nothing. @param args: ignored. @param kwargs: ignored. Nr])rrs r, showwarningzDummyWarningsModule.showwarningr_r-)rrrrrrr]r-r,r=r=s! 3 # $ r-r=)6rrsiorsignalrtypesrtypingrrrr r r r r rattrrrrtwisted.trial.unittesttwistedtwisted.internet.testingrtwisted.loggerrrrrrrrtwisted.python.filepathrrNr_exitr_pidfilerr r!trialunittestTestCaser#rIrSr4r5r;r=r]r-r,rs RRR''2-+{6'--((11{6| d3&33,;4& & &   r-