
    h$!                    V   S r SSKrSSKrSSKrSSKrSSKrSSKr SSKrSSK	r
\
r	\rSSKJr  SSKJr  SSKJr  SSKJr  SSKJrJrJr  SSKJrJrJr  SS	KJr  SS
KJr  SSK J!r!  SSK"J#r#J$r$  SSK%J&r&  SSK'J(r(  SSK)J*r*J+r+J,r,  SSK-J.r.  SSK/J0r0  SSK1J2r2  SSK3J*r4J5r5  SSK6J7r7  SSK8J9r9  SSK:J;r;  SSK<J=r=  SSK>J?r?  SSK@JArA  \7" S5      rB\B(       a
  SSKCJDrDJErEJFrF  \7" S5      rG\7" S5      rH\7" S5      rI\7" S5      rJS  rK " S! S"5      rL " S# S$\R                  5      rN " S% S&\=R                  5      rP " S' S(\A5      rQ\" \B(       + S)5       " S* S+\A5      5       rR " S, S-\A5      rS " S. S/5      rT " S0 S1\R                  5      rV " S2 S3\A5      rW\" \B(       + S)5       " S4 S5\A5      5       rX\" \B(       + S)5       " S6 S7\A5      5       rY\" \B(       + S)5       " S8 S9\A5      5       rZ " S: S;5      r[\" \#5       " S< S=\[5      5       r\ " S> S?5      r] " S@ SA\A5      r^SB r_SC r` " SD SE\A5      ra\" \B(       + S)5       " SF SG\A5      5       rb\" \B(       + SH5       " SI SJ\A5      5       rc\" \$5       " SK SL\(5      5       rd " SM SN\=R                  5      reSO rf " SP SQ\A5      rgg! \ a    Sr	Sr GNf = f)RzE
Tests for L{twisted.application.app} and L{twisted.scripts.twistd}.
    N)StringIO)skipIf)implementer)verifyObject)internetloggerplugin)appreactorsservice)IServiceMaker)ReactorBase)Deferred)IReactorDaemonize_ISupportsExitSignalCapturing)AlternateReactor)MemoryReactor)ILogObserverglobalLogBeginnerglobalLogPublisher)util)Componentized)UserDatabase)r   textFromEventDict)requireModule)platformType)
UsageError)twistd)MockOS)TestCaseztwisted.scripts._twistd_unix)UnixApplicationRunnerUnixAppLoggercheckPIDztwisted.python.syslogprofilepstatscProfilec           	        ^^^ [         R                  [        R                  " 5       5      n[        R                  [        R                  " 5       5      m[        5       nUR                  XR                  UTUR                  UR                  UR                  5        UUU4S jnU " [         SUR                  5        U " [        SU5        U " [         SUR                  5        g)a=  
Patch L{pwd.getpwnam} so that it behaves as though only one user exists
and patch L{grp.getgrnam} so that it behaves as though only one group
exists.

@param patch: A function like L{TestCase.patch} which will be used to
    install the fake implementations.

@type user: C{str}
@param user: The name of the single user which will exist.

@type uid: C{int}
@param uid: The UID of the single user which will exist.

@type group: C{str}
@param group: The name of the single user which will exist.

@type gid: C{int}
@param gid: The GID of the single group which will exist.
c                    > [        T5      nTXR                  TR                  5      '   TXR                  TR                  5      '   [	        U5      nTU0U    $ N)listindexgr_namegr_gidtuple)nameresultgidgrentgroups     _/root/1688_scrapy/alibaba-scraper/venv/lib/python3.13/site-packages/twisted/test/test_twistd.pygetgrnam#patchUserDatabase.<locals>.getgrnamd   sN    e.3||EMM*+-0||ELL)*vvt$$    getpwnamr5   getpwuidN)pwdr9   osgetuidgrpgetgrgidgetgidr   addUser	pw_passwdpw_gecospw_dirpw_shellr8   )	patchuseruidr3   r1   pwentdatabaser5   r2   s	      ``   @r4   patchUserDatabaserJ   C   s    2 LL%ELL%E~HoosCu~~% 
#z8,,-	#z8$	#z8,,-r7   c                   "    \ rS rSrSrSrS rSrg)MockServiceMakerp   zG
A non-implementation of L{twisted.application.service.IServiceMaker}.
ueoac                 Z    Xl         [        R                  " 5       U l        U R                  $ )zM
Take a L{usage.Options} instance and return a
L{service.IService} provider.
)optionsr   ServiceselfrP   s     r4   makeServiceMockServiceMaker.makeServicew   s!    
 (||r7   )rP   r   N)__name__
__module____qualname____firstlineno____doc__tapnamerT   __static_attributes__ r7   r4   rL   rL   p   s     Gr7   rL   c                       \ rS rSrSrS rSrg)CrippledAppLogger   z"
@see: CrippledApplicationRunner.
c                     g r)   r]   rS   applications     r4   startCrippledAppLogger.start       r7   r]   N)rV   rW   rX   rY   rZ   rd   r\   r]   r7   r4   r_   r_      s    r7   r_   c                   (    \ rS rSrSr\rS rS rSr	g)CrippledApplicationRunner   z
An application runner that cripples the platform-specific runner and
nasty side-effect-having code so that we can use it without actually
running any environment-affecting code.
c                     g r)   r]   rS   s    r4   preApplication(CrippledApplicationRunner.preApplication   rf   r7   c                     g r)   r]   rk   s    r4   postApplication)CrippledApplicationRunner.postApplication   rf   r7   r]   N)
rV   rW   rX   rY   rZ   r_   loggerFactoryrl   ro   r\   r]   r7   r4   rh   rh      s     &Mr7   rh   c                       \ rS rSrSrS rS rS rS rS r	\
" \(       + S5      S	 5       r\
" \(       + S5      S
 5       r\
" \(       + S5      S 5       rS rS rS rS rSrg)ServerOptionsTests   zL
Non-platform-specific tests for the platform-specific ServerOptions class.
c                 (  ^ ^^^^  " S S5      nU" S5      mU" S5      mU" S5      mU" S5      mUUUUU 4S jn[         R                  " 5       nT R                  UR                  [        R
                  5        X#l        UR                  nTTTT/n[        XE5       Hs  u  pgUu  ppT R                  XR                  5        T R                  U	5        T R                  U
" 5       UR                  5      4  T R                  XR                  5        Mu     g)	zP
subCommands is built from IServiceMaker plugins, and is sorted
alphabetically.
c                        \ rS rSrS rS rSrg)7ServerOptionsTests.test_subCommands.<locals>.FakePlugin   c                 8    Xl         SU-   U l        SU-   U l        g )Nzoptions for description of )r[   _optionsdescriptionrS   r/   s     r4   __init__@ServerOptionsTests.test_subCommands.<locals>.FakePlugin.__init__   s     # . 5#4t#; r7   c                     U R                   $ r)   )r{   rk   s    r4   rP   ?ServerOptionsTests.test_subCommands.<locals>.FakePlugin.options   s    }}$r7   )r{   r|   r[   N)rV   rW   rX   rY   r~   rP   r\   r]   r7   r4   
FakePluginrw      s    <
%r7   r   applebananacoconutdonutc              3   Z   >#    TR                  U [        5        Tv   Tv   Tv   Tv   g 7fr)   )assertEqualr   )	interfacer   r   r   r   rS   s    r4   
getPlugins7ServerOptionsTests.test_subCommands.<locals>.getPlugins   s*     Y6MLKKs   (+N)r   ServerOptionsr   _getPluginsr	   r   subCommandszipr[   assertIsNoner{   r|   )rS   r   r   configr   expectedOrder
subCommandexpectedCommandr/   shortcutparserClassdocumentationr   r   r   r   s   `           @@@@r4   test_subCommands#ServerOptionsTests.test_subCommands   s    	% 	% 7#H%Y'7#	 	 %%'++V->->?' ((7+.{+J'J9C6DKT#:#:;h'[]O,D,DEF],G,GH ,Kr7   c                 d  ^ ^^^^	^
^  " S S5      nU" S5      mU" S5      mU" S5      mU" S5      m	UUUU	4S jn[         R                  " 5       nT R                  UR                  [        R
                  5        X#l        [        5       Ul        T R                  [        UR                  S/5        UR                  R                  5       m
/ mTTTT	4 H/  nU
UU 4S	 jnU" UR                  5        U" UR                  5        M1     T R                  T[        T5      S
R                  T
5      5        g)z@
Reactor names are listed alphabetically by I{--help-reactors}.
c                       \ rS rSrS rSrg)GServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstaller   c                 :    SU-   U l         SU-   U l        SU l        g )Nzname of rz   ztwisted.internet.default)	shortNamer|   
moduleNamer}   s     r4   r~   PServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstaller.__init__   s"    !+d!2#4t#; "<r7   )r|   r   r   N)rV   rW   rX   rY   r~   r\   r]   r7   r4   FakeReactorInstallerr      s    =r7   r   r   r   r   r   c               3   .   >#    Tv   Tv   Tv   T v   g 7fr)   r]   )r   r   r   r   s   r4   getReactorTypesBServerOptionsTests.test_sortedReactorHelp.<locals>.getReactorTypes   s     MLKKs   z--help-reactorsc                 j   > TR                  U T5        TR                  TR                  U 5      5        g r)   )assertInappendr+   )s
helpOutputindexesrS   s    r4   getIndex;ServerOptionsTests.test_sortedReactorHelp.<locals>.getIndex   s(    a,z//23r7   z9reactor descriptions were not in alphabetical order: {!r}N)r   r   r   _getReactorTypesr   r   r   messageOutputassertRaises
SystemExitparseOptionsgetvaluer   r|   sortedformat)rS   r   r   r   reactorr   r   r   r   r   r   r   s   `     @@@@@@r4   test_sortedReactorHelp)ServerOptionsTests.test_sortedReactorHelp   s   
	= 	= %W-%h/&y1$W-	 	 %%'00(2J2JK"1'z*f&9&9<M;NO))224
fgu4G4 W&&'W(() 5 	7OGNN	
r7   c                     [         R                  " 5       nSUl        UR                  5         U R	                  US   5        g)zC
postOptions should set no_save to True when a subcommand is used.
rN   no_saveN)r   r   r   postOptions
assertTruerS   r   s     r4   &test_postOptionsSubCommandCausesNoSave9ServerOptionsTests.test_postOptionsSubCommandCausesNoSave   s7     %%'"y)*r7   c                 v    [         R                  " 5       nUR                  5         U R                  US   5        g)zB
If no sub command is used, postOptions should not touch no_save.
r   N)r   r   r   assertFalser   s     r4   (test_postOptionsNoSubCommandSavesAsUsual;ServerOptionsTests.test_postOptionsNoSubCommandSavesAsUsual  s1     %%'	*+r7   c                     [         R                  " 5       n[        U5      n[        R                  R
                   H  nU R                  X25        M     g)zY
All the profilers that can be used in L{app.AppProfiler} are listed in
the help output.
N)r   r   strr
   AppProfiler	profilersr   )rS   r   r   profilers       r4   test_listAllProfilers(ServerOptionsTests.test_listAllProfilers
  s;    
 %%'[
11HMM(/ 2r7   twistd unix not availablec                 V    [         R                  " 5       nU R                  US   5        g)z7
The default value for the C{umask} option is L{None}.
umaskN)r   r   r   r   s     r4   test_defaultUmask$ServerOptionsTests.test_defaultUmask  s$    
 %%'&/*r7   c                     [         R                  " 5       nUR                  SS/5        U R                  US   S5        UR                  SS/5        U R                  US   S5        g)zP
The value given for the C{umask} option is parsed as an octal integer
literal.
--umask123r   S   0123N)r   r   r   r   r   s     r4   
test_umaskServerOptionsTests.test_umask  s`     %%'Y./"-Y/0"-r7   c                 t    [         R                  " 5       nU R                  [        UR                  SS/5        g)z
If a value is given for the C{umask} option which cannot be parsed as
an integer, L{UsageError} is raised by L{ServerOptions.parseOptions}.
r   abcdefN)r   r   r   r   r   r   s     r4   test_invalidUmask$ServerOptionsTests.test_invalidUmask(  s/     %%'*f&9&9Ix;PQr7   c                    [         R                  " 5       nU R                  [        UR                  SS/5      nU R                  UR                  S   R                  S5      5        U R                  SUR                  S   5        g)zA
C{--logger} with an unimportable module raises a L{UsageError}.
--loggerzno.such.module.I.hoper   zeLogger 'no.such.module.I.hope' could not be imported: 'no.such.module.I.hope' does not name an object
N	r   r   r   r   r   r   args
startswithassertNotInrS   r   es      r4   &test_unimportableConfiguredLogObserver9ServerOptionsTests.test_unimportableConfiguredLogObserver1  sy     %%'++j:Q-R
 	FF1I  B	
 	qvvay)r7   c                    [         R                  " 5       nU R                  [        UR                  SS/5      nU R                  UR                  S   R                  S5      5        U R                  SUR                  S   5        g)z@
C{--logger} with a non-existent object raises a L{UsageError}.
r   ztwisted.test.test_twistd.FOOBARr   z{Logger 'twisted.test.test_twistd.FOOBAR' could not be imported: module 'twisted.test.test_twistd' has no attribute 'FOOBAR'r   Nr   r   s      r4   *test_badAttributeWithConfiguredLogObserver=ServerOptionsTests.test_badAttributeWithConfiguredLogObserverA  sz     %%':;

 	FF1I  ,	
 	qvvay)r7   c                 r   SSK Jn  [        S:X  a  SnOSnSR                  X!R                  UR                  5      n[        5       n[        R                  " US9nU R                  [        UR                  S/5      nU R                  UR                  S	5        U R                  UR                  5       U5        g	)
z"
C{--version} prints the version.
r   )	copyrightwin32z(the Twisted Windows runner)z(the Twisted daemon)ztwistd {} {}
{}
stdoutz	--versionN)twistedr   r   r   versionr   r   r   r   r   r   assertIscoder   r   )rS   r   r/   expectedOutputr   r   r   s          r4   test_versionServerOptionsTests.test_versionT  s     	&7"1D)D-44##Y%8%8
 %%V4j&*=*=}Maffd#*N;r7   c                     [        5       n[        R                  " US9nU R                  [        UR
                  S/5        g)z9
Command is printed when an invalid option is requested.
r   z	web --fooN)r   r   r   r   r   r   )rS   r   r   s      r4   !test_printSubCommandForUsageError4ServerOptionsTests.test_printSubCommandForUsageErrorh  s5     %%V4*f&9&9K=Ir7   r]   N)rV   rW   rX   rY   rZ   r   r   r   r   r   r   _twistd_unixr   r   r   r   r   r   r   r\   r]   r7   r4   rs   rs      s    )IV-
^+,0 9:+ ;+ 9:	. ;	. 9:R ;R* *&<(Jr7   rs   r   c                   6    \ rS rSrSrS rS rS rS rS r	Sr
g	)
CheckPIDTestsir  z
Tests for L{checkPID}.
c                 ^    U R                  [        R                  SS 5        [        S5        g)z'
Nonexistent PID file is not an error.
existsc                     gNFr]   )_s    r4   <lambda>.CheckPIDTests.test_notExists.<locals>.<lambda>|  s    r7   znon-existent PID fileN)rE   r;   pathr#   rk   s    r4   test_notExistsCheckPIDTests.test_notExistsx  s!     	

277Ho6()r7   c                     U R                  5       n[        US5       nUR                  S5        SSS5        U R                  [        [
        U5      nU R                  SUR                  5        g! , (       d  f       NF= f)z9
Non-numeric content in a PID file causes a system exit.
wznon-numericNznon-numeric value)mktempopenwriter   r   r#   r   r   )rS   pidfilefr   s       r4   test_nonNumericCheckPIDTests.test_nonNumeric  s\     ++-'31GGM"  j(G<)1662  s   A//
A=c                 4   U R                  5       n[        US5       nUR                  S5        SSS5        S nU R                  [        SU5        U R                  [        [        U5      nU R                  SUR                  5        g! , (       d  f       N`= f)z5
Another running twistd server causes a system exit.
r  42Nc                     g r)   r]   pidsigs     r4   kill/CheckPIDTests.test_anotherRunning.<locals>.kill  s    r7   r  zAnother twistd server)
r  r  r	  rE   r;   r   r   r#   r   r   rS   r
  r  r  r   s        r4   test_anotherRunning!CheckPIDTests.test_anotherRunning  sr     ++-'31GGDM  	 	

2vt$j(G<-qvv6  s   B		
Bc                 v   U R                  5       n[        US5       nUR                  [        [        R
                  " 5       S-   5      5        SSS5        S nU R                  [        SU5        [        U5        U R                  [        R                  R                  U5      5        g! , (       d  f       Nb= f)z:
Stale PID file is removed without causing a system exit.
r     Nc                 6    [        [        R                  S5      eNfake)OSErrorerrnoESRCHr  s     r4   r  &CheckPIDTests.test_stale.<locals>.kill      %++v..r7   r  )r  r  r	  r   r;   getpidrE   r#   r   r  r   )rS   r
  r  r  s       r4   
test_staleCheckPIDTests.test_stale  s~     ++-'31GGC		a()  	/ 	

2vt$01  s   1B**
B8c                    U R                  5       n[        US5       nUR                  S5        SSS5        S nU R                  [        SU5        U R                  [        [        U5      nU R                  UR                  S5        U R                  UR                  S   R                  S5      5        g! , (       d  f       N= f)zx
An unexpected L{OSError} when checking the validity of a
PID in a C{pidfile} terminates the process via L{SystemExit}.
r  3581Nc                 6    [        [        R                  S5      er  r  r  EBADFr  s     r4   r  2CheckPIDTests.test_unexpectedOSError.<locals>.kill  r"  r7   r  r   zCan't check status of PID)r  r  r	  rE   r;   r   r   r#   assertIsNotr   r   r   r   r  s        r4   test_unexpectedOSError$CheckPIDTests.test_unexpectedOSError  s    
 ++-'31GGFO  	/ 	

2vt$j(G<&q	,,-HIJ  s   B66
Cr]   N)rV   rW   rX   rY   rZ   r  r  r  r$  r-  r\   r]   r7   r4   r   r   r  s!    *372Kr7   r   c                   $    \ rS rSrSrS rS rSrg)TapFileTestsi  zE
Test twistd-related functionality that requires a tap file on disk.
c                     U R                  5       U l        [        U R                  S5       n[        R                  " [
        R                  " S5      U5        SSS5        g! , (       d  f       g= f)z@
Create a trivial Application and put it in a tap file on disk.
wbHi!N)r  tapfiler  pickledumpr   Application)rS   r  s     r4   setUpTapFileTests.setUp  sF     {{}$,,%KK++E2A6 &%%s   ,A!!
A/c                     [         R                  " 5       nUR                  SU R                  /5        [	        U5      R                  5       nU R                  [        R                  " U5      R                  S5        g)zv
Ensure that the createOrGetApplication call that 'twistd -f foo.tap'
makes will load the Application out of foo.tap.
z-fr3  N)
r   r   r   r4  rh   createOrGetApplicationr   r   IServicer/   )rS   r   rc   s      r4   &test_createOrGetApplicationWithTapFile3TapFileTests.test_createOrGetApplicationWithTapFile  s]    
 %%'T4<<01/7NNP))+6;;UCr7   )r4  N)rV   rW   rX   rY   rZ   r8  r=  r\   r]   r7   r4   r0  r0    s    7Dr7   r0  c                   *    \ rS rSrSrS rS rS rSrg)TestLoggerFactoryi  z0
A logger factory for L{TestApplicationRunner}.
c                     Xl         g r)   runner)rS   rC  s     r4   r~   TestLoggerFactory.__init__  s    r7   c                     U R                   R                  R                  S5        [        U R                   S5      U R                   l        g)z3
Save the logging start on the C{runner} instance.
logrc   N)rC  orderr   hasattrhadApplicationLogObserverrb   s     r4   rd   TestLoggerFactory.start  s3     	  '07]0S-r7   c                     g)z
Don't log anything.
Nr]   rk   s    r4   stopTestLoggerFactory.stop      r7   rB  N)	rV   rW   rX   rY   rZ   r~   rd   rL  r\   r]   r7   r4   r@  r@    s    Tr7   r@  c                   *    \ rS rSrSrS rS rS rSrg)TestApplicationRunneri  zT
An ApplicationRunner which tracks the environment in which its methods are
called.
c                 p    [         R                  R                  X5        / U l        [	        U 5      U l        g r)   )r
   ApplicationRunnerr~   rG  r@  r   rR   s     r4   r~   TestApplicationRunner.__init__  s)    &&t5
'-r7   c                 \    U R                   R                  S5        [        U S5      U l        g )Nprerc   )rG  r   rH  hadApplicationPreApplicationrk   s    r4   rl   $TestApplicationRunner.preApplication  s#    

% ,3D-,H)r7   c                 \    U R                   R                  S5        [        U S5      U l        g )Npostrc   )rG  r   rH  hadApplicationPostApplicationrk   s    r4   ro   %TestApplicationRunner.postApplication  s#    

&!-4T=-I*r7   )rZ  rV  r   rG  N)	rV   rW   rX   rY   rZ   r~   rl   ro   r\   r]   r7   r4   rP  rP    s    
.
IJr7   rP  c                       \ rS rSrSrS rS rS rS r\	" \
" \SS5      (       + S	5      S
 5       r\	" \
" \SS5      (       + S	5      S 5       rS rS rS rS rSrg)ApplicationRunnerTestsi  zJ
Non-platform-specific tests for the platform-specific ApplicationRunner.
c                     [         R                  " 5       n[        5       U l        SU R                  0Ul        [        5       Ul        SUl        Xl        g )Ntest_command)	r   r   rL   serviceMakerloadedPluginsobject
subOptionsr   r   r   s     r4   r8  ApplicationRunnerTests.setUp  sE    %%',. .0A0AB"H*r7   c                 h   [        U R                  5      nUR                  5         U R                  U R                  R
                  U R                  R                  S5        U R                  U R                  R                  [        R                  " UR                  5      R                  S   S5        g)z
Ensure that a twistd plugin gets used in appropriate ways: it
is passed its Options instance, and the service it returns is
added to the application.
zKServiceMaker.makeService needs to be passed the correct sub Command object.r   zPServiceMaker.makeService's result needs to be set as a child of the Application.N)rh   r   runr   r`  rP   rc  r   r<  rc   services)rS   arunners     r4   ,test_applicationRunnerGetsCorrectApplicationCApplicationRunnerTests.test_applicationRunnerGetsCorrectApplication  s     ,DKK8%%KK"""	
 	%%W001::1="	
r7   c                 ,   [        U R                  5      nUR                  5         U R                  UR                  5        U R                  UR                  5        U R                  UR                  5        U R                  UR                  / SQ5        g)zn
Test thet preApplication and postApplication methods are
called by ApplicationRunner.run() when appropriate.
)rU  rF  rY  N)
rP  r   rf  r   rV  r   rZ  rI  r   rG  )rS   r   s     r4   test_preAndPostApplication1ApplicationRunnerTests.test_preAndPostApplication  sh    
 "$++.	778778334"89r7   c           	        ^ U R                   R                  U5        / m " U4S jS[        R                  5      n[	        [
        R                  [
        R                  5       " U4S jS5      5       nU" 5       n[        [
        R                  U5        [        [
        R                  U5        U" U R                   5      nUR                  5         Xgl
        UR                  5         U R                  TSSSSX#4S	S
/5        g)z
Assert that given a particular command line, an application is started
as a particular UID/GID.

@param argv: A list of strings giving the options to parse.
@param uid: An integer giving the expected UID.
@param gid: An integer giving the expected GID.
c                   @   > \ rS rSrU 4S jrU 4S jrU 4S jrS rSrg)\ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunneri7  c                 (   > TR                  S5        g )Nenvironmentr   )rS   chrootrundirnodaemonr   r
  eventss         r4   setupEnvironmentmApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.setupEnvironment8  s    m,r7   c                 .   > TR                  SXU45        g )N
privilegesrs  )rS   euidrG   r1   rw  s       r4   shedPrivilegeskApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.shedPrivileges;  s    |T<=r7   c                 (   > TR                  S5        g )Nr   rs  )rS   r   	oldstdout	oldstderrrw  s       r4   startReactoriApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.startReactor>  s    i(r7   c                     g r)   r]   )rS   r
  s     r4   	removePIDfApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.removePIDA      r7   r]   N)	rV   rW   rX   rY   rx  r}  r  r  r\   rw  s   r4   FakeUnixApplicationRunnerrp  7  s    ->)r7   r  c                   ^   > \ rS rSrSrSrSrSrSrSr	S r
S rS rU 4S jrU 4S jrS rS	rg)
NApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeServiceiD  Nc                     g r)   r]   r}   s     r4   setNameVApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setNameM  r  r7   c                     g r)   r]   )rS   parents     r4   setServiceParent_ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setServiceParentP  r  r7   c                     g r)   r]   rk   s    r4   disownServiceParentbApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.disownServiceParentS  r  r7   c                 (   > TR                  S5        g )NprivilegedStartServicers  rS   rw  s    r4   r  eApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.privilegedStartServiceV  s    67r7   c                 (   > TR                  S5        g )NstartServicers  r  s    r4   r  [ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.startServiceY  s    n-r7   c                     g r)   r]   rk   s    r4   stopServiceZApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.stopService\  r  r7   r]   )rV   rW   rX   rY   r  runningr/   processNamerG   r1   r  r  r  r  r  r  r\   r  s   r4   FakeServicer  D  s?    FGDKCC8.r7   r  rr  r  r{  Fr  r   N)r   r   r   _SomeApplicationRunnerr   r   r<  IProcessr   rl   rc   ro   r   )	rS   argvrG   r1   r  r  rc   rC  rw  s	           @r4   "_applicationStartsWithConfiguredID9ApplicationRunnerTests._applicationStartsWithConfiguredID*  s     	  &	(E(E 	 
W%%w'7'7	8	 	 
9	4 "mW%%{3W%%{3*4;;7( (uc/		
r7   setuidNz5Platform does not support --uid/--gid twistd options.c                 \    SnSnU R                  S[        U5      S[        U5      /X5        g)z
L{postApplication} should change the UID and GID to the values
specified as numeric strings by the configuration after running
L{service.IService.privilegedStartService} and before running
L{service.IService.startService}.
    --uid--gidN)r  r   )rS   rG   r1   s      r4   .test_applicationStartsWithConfiguredNumericIDsEApplicationRunnerTests.test_applicationStartsWithConfiguredNumericIDss  s2     //c#hS2C	
r7   c                 n    SnSnSnSn[        U R                  XX45        U R                  SUSU/X$5        g)z
L{postApplication} should change the UID and GID to the values
specified as user and group names by the configuration after running
L{service.IService.privilegedStartService} and before running
L{service.IService.startService}.
foor  barr  r  r  N)rJ   rE   r  )rS   rF   rG   r3   r1   s        r4   +test_applicationStartsWithConfiguredNameIDsBApplicationRunnerTests.test_applicationStartsWithConfiguredNameIDs  sD     $**d<//dGU+S	
r7   c                     [        5       n[        R                  " SSSS.5      nUR                  USS5        U R	                  UR
                  S5        g)z'
L{startReactor} calls L{reactor.run}.
Fr$   r$   r   debugNz'startReactor did not call reactor.run())DummyReactorr
   rR  r  r   calledrS   r   rC  s      r4   test_startReactorRunsTheReactor6ApplicationRunnerTests.test_startReactorRunsTheReactor  sL     .&&9uE
 	GT40(QRr7   c                     [        5       nU R                  [        SU5        [        R                  " SSSS.5      nUR                  SSS5        U R                  UR                  5        g)z>
L{ApplicationRunner} chooses a reactor if none is specified.
r   Fr$   r  N)r  rE   r   r
   rR  r  r   r  r  s      r4   *test_applicationRunnerChoosesReactorIfNoneAApplicationRunnerTests.test_applicationRunnerChoosesReactorIfNone  sY     .

8Y0&&9uE
 	D$-'r7   c                      " S S[         5      nU" 5       n[        R                  " SSSS.5      nUR                  USS5        U R	                  SUR
                  5        g)zO
If the reactor exits with a signal, the application runner caches
the signal.
c                   $    \ rS rSrSrS rS rSrg)[ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignali  g
A dummy reactor, providing a C{run} method, and setting the
_exitSignal attribute to a nonzero value.
c                     gz
Dummy method, does nothing.
Nr]   rk   s    r4   installWakerhApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.installWaker  rN  r7   c                     SU l         g)z:
A fake run method setting _exitSignal to a nonzero value
   N_exitSignalrk   s    r4   rf  _ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.run  s     $% r7   r  NrV   rW   rX   rY   rZ   r  rf  r\   r]   r7   r4   DummyReactorWithSignalr    s    

%r7   r  Fr$   r  Nr  )r   r
   rR  r  assertEqualsr  )rS   r  r   rC  s       r4   $test_applicationRunnerCapturesSignal;ApplicationRunnerTests.test_applicationRunnerCapturesSignal  s\    	%[ 	%" )*&&9uE
 	GT40!V//0r7   c                      " S S5      nU" 5       n[         R                  " SSSS.5      nUR                  USS5        U R                  SUR                  5        g)z
The runner sets its _exitSignal instance attribute to None if
the reactor does not implement L{_ISupportsExitSignalCapturing}.
c                   $    \ rS rSrSrS rS rSrg)iApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttributei  r  c                     gr  r]   rk   s    r4   r  vApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.installWaker  rN  r7   c                     SU l         g)zR
A fake run method setting _exitSignal to a nonzero value
that should be ignored.
r  Nr  rk   s    r4   rf  mApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.run  s    
 $% r7   r  Nr  r]   r7   r4   #DummyReactorWithExitSignalAttributer    s    

%r7   r  Fr$   r  N)r
   rR  r  r  r  )rS   r  r   rC  s       r4   %test_applicationRunnerIgnoresNoSignal<ApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal  sZ    	% 	%$ 67&&9uE
 	GT40$ 2 23r7   )r   r`  )rV   rW   rX   rY   rZ   r8  ri  rl  r  r   getattrr;   r  r  r  r  r  r  r\   r]   r7   r4   r]  r]    s    
,
:G
R B$''?
	
 B$''?
	
 	S
(1<4r7   r]  c                   n    \ rS rSrSr\" 5       rS rS rS r	S r
S rS rS	 rS
 rS rS rS rS rSrg)*UnixApplicationRunnerSetupEnvironmentTestsi  a  
Tests for L{UnixApplicationRunner.setupEnvironment}.

@ivar root: The root of the filesystem, or C{unset} if none has been
    specified with a call to L{os.chroot} (patched for this TestCase with
    L{UnixApplicationRunnerSetupEnvironmentTests.chroot}).

@ivar cwd: The current working directory of the process, or C{unset} if
    none has been specified with a call to L{os.chdir} (patched for this
    TestCase with L{UnixApplicationRunnerSetupEnvironmentTests.chdir}).

@ivar mask: The current file creation mask of the process, or C{unset} if
    none has been specified with a call to L{os.umask} (patched for this
    TestCase with L{UnixApplicationRunnerSetupEnvironmentTests.umask}).

@ivar daemon: A boolean indicating whether daemonization has been performed
    by a call to L{_twistd_unix.daemonize} (patched for this TestCase with
    L{UnixApplicationRunnerSetupEnvironmentTests}.
c                   ^  T R                   T l        T R                   T l        T R                   T l        ST l        [
        R                  " 5       T l        T R                  [
        SU 4S j5        T R                  [
        SU 4S j5        T R                  [
        SU 4S j5        [        [        R                  " 5       5      T l        T R                  T R                  l        g )NFrt  c                    > [        TSU 5      $ )Nrootsetattrr  rS   s    r4   r   BUnixApplicationRunnerSetupEnvironmentTests.setUp.<locals>.<lambda>  s    gdFD.Ir7   chdirc                    > [        TSU 5      $ )Ncwdr  r  s    r4   r   r    s    WT5$-Gr7   r   c                    > [        TSU 5      $ )Nmaskr  )r  rS   s    r4   r   r    s    WT64-Hr7   )unsetr  r  r  daemonr;   r#  r  rE   r!   r   r   rC  	daemonizerk   s   `r4   r8  0UnixApplicationRunnerSetupEnvironmentTests.setUp  s    JJ	::JJ	99;

2x!IJ

2w GH

2w HI+F,@,@,BC $r7   c                 J   ^  ST l         T R                  [        SU 4S j5        g)z
Indicate that daemonization has happened and change the PID so that the
value written to the pidfile can be tested in the daemonization case.
Tr#  c                  "   > T R                   S-   $ Nr  )r  rk   s   r4   r   FUnixApplicationRunnerSetupEnvironmentTests.daemonize.<locals>.<lambda>  s    Ar7   N)r  rE   r;   rS   r   s   ` r4   r  4UnixApplicationRunnerSetupEnvironmentTests.daemonize  s    
 

2x!56r7   c                 z    U R                   R                  SSSSS5        U R                  U R                  S5        g)z
L{UnixApplicationRunner.setupEnvironment} changes the root of the
filesystem if passed a non-L{None} value for the C{chroot} parameter.
/foo/bar.TN)rC  rx  r   r  rk   s    r4   test_chroot6UnixApplicationRunnerSetupEnvironmentTests.test_chroot  s2    
 	$$ZdD$GJ/r7   c                     U R                   R                  SSSSS5        U R                  U R                  U R                  5        g)z
L{UnixApplicationRunner.setupEnvironment} does not change the root of
the filesystem if passed L{None} for the C{chroot} parameter.
Nr  T)rC  rx  r   r  r  rk   s    r4   test_noChroot8UnixApplicationRunnerSetupEnvironmentTests.test_noChroot!  s4    
 	$$T3dDAdii,r7   c                 z    U R                   R                  SSSSS5        U R                  U R                  S5        g)z
L{UnixApplicationRunner.setupEnvironment} changes the working directory
of the process to the path given for the C{rundir} parameter.
Nr  T)rC  rx  r   r  rk   s    r4   test_changeWorkingDirectoryFUnixApplicationRunnerSetupEnvironmentTests.test_changeWorkingDirectory)  s2    
 	$$T:tT4H:.r7   c                     [        [        5       5         U R                  R                  SSSSS5        SSS5        U R	                  U R
                  5        g! , (       d  f       N*= f)zw
L{UnixApplicationRunner.setupEnvironment} daemonizes the process if
C{False} is passed for the C{nodaemon} parameter.
Nr  F)r   FakeDaemonizingReactorrC  rx  r   r  rk   s    r4   test_daemonize9UnixApplicationRunnerSetupEnvironmentTests.test_daemonize1  sH    
 467KK((sE4F 8$ 87s    A
A&c                 x    U R                   R                  SSSSS5        U R                  U R                  5        g)z~
L{UnixApplicationRunner.setupEnvironment} does not daemonize the
process if C{True} is passed for the C{nodaemon} parameter.
Nr  T)rC  rx  r   r  rk   s    r4   test_noDaemonize;UnixApplicationRunnerSetupEnvironmentTests.test_noDaemonize:  s0    
 	$$T3dDA%r7   c                    U R                  5       nU R                  R                  SSSSU5        [        US5       n[	        UR                  5       5      nSSS5        U R                  WU R                  5        g! , (       d  f       N+= f)zw
L{UnixApplicationRunner.setupEnvironment} writes the process's PID to
the file specified by the C{pidfile} parameter.
Nr  Trb)r  rC  rx  r  intreadr   r  rS   r
  r  r  s       r4   test_nonDaemonPIDFile@UnixApplicationRunnerSetupEnvironmentTests.test_nonDaemonPIDFileB  sf    
 ++-$$T3dGD'4 Aaffh-C !dhh' ! s   A;;
B	c                 x   U R                  5       n[        [        5       5         U R                  R	                  SSSSU5        SSS5        [        US5       n[        UR                  5       5      nSSS5        U R                  WU R                  S-   5        g! , (       d  f       N\= f! , (       d  f       N?= f)z
L{UnixApplicationRunner.setupEnvironment} writes the daemonized
process's PID to the file specified by the C{pidfile} parameter if
C{nodaemon} is C{False}.
Nr  Fr  r  )
r  r   r  rC  rx  r  r	  r
  r   r  r  s       r4   test_daemonPIDFile=UnixApplicationRunnerSetupEnvironmentTests.test_daemonPIDFileM  s     ++-467KK((sE4I 8'4 Aaffh-C !dhhl+	 87  s    BB+
B(+
B9c                     [        [        5       5         U R                  R                  SSSSS5        SSS5        U R	                  U R
                  S5        g! , (       d  f       N+= f)zw
L{UnixApplicationRunner.setupEnvironment} changes the process umask to
the value specified by the C{umask} parameter.
Nr  F{   r   r  rC  rx  r   r  rk   s    r4   r   5UnixApplicationRunnerSetupEnvironmentTests.test_umaskZ  sL    
 467KK((sE3E 8C( 87    A
A'c                     U R                   R                  SSSSS5        U R                  U R                  U R                  5        g)z
L{UnixApplicationRunner.setupEnvironment} doesn't change the process
umask if L{None} is passed for the C{umask} parameter and C{True} is
passed for the C{nodaemon} parameter.
Nr  T)rC  rx  r   r  r  rk   s    r4   test_noDaemonizeNoUmaskBUnixApplicationRunnerSetupEnvironmentTests.test_noDaemonizeNoUmaskc  s4     	$$T3dDAdii,r7   c                     [        [        5       5         U R                  R                  SSSSS5        SSS5        U R	                  U R
                  S5        g! , (       d  f       N+= f)z
L{UnixApplicationRunner.setupEnvironment} changes the process umask to
C{0077} if L{None} is passed for the C{umask} parameter and C{False} is
passed for the C{nodaemon} parameter.
Nr  F?   r  rk   s    r4   test_daemonizedNoUmaskAUnixApplicationRunnerSetupEnvironmentTests.test_daemonizedNoUmaskl  sL     467KK((sE4F 8E* 87r  )r  r  r  r  r  rC  N)rV   rW   rX   rY   rZ   rb  r  r8  r  r  r  r  r  r  r  r  r   r  r  r\   r]   r7   r4   r  r    sL    ( HE
/70-/%&	(,)-+r7   r  c                   <    \ rS rSrSrS rS rS rS rS r	S r
S	rg
)*UnixApplicationRunnerStartApplicationTestsiw  z6
Tests for L{UnixApplicationRunner.startApplication}.
c                   ^ [         R                  " 5       nUR                  / SQ5        [        R                  " S5      n[        U5      U l        / mU4S jn[        R                  " U R                  R                  5      R                  n[        R                  " U5      R                  nUR                  5       nUR                  S5        U R                  XE5        U R                  [
        SU5        U R                  [
        SS 5        U R                  [        SS	 5        U R                  R!                  U5        U R                  T/ S
Q5        g)z
L{UnixApplicationRunner.startApplication} calls
L{UnixApplicationRunner.setupEnvironment} with the chroot, rundir,
nodaemon, umask, and pidfile parameters from the configuration it is
constructed with.
)	
--nodaemonr   0070z--chroot/foo/chrootz--rundir/foo/rundir	--pidfile/foo/pidfiletest_setupEnvironmentc                 .   > TR                  XX4U45        g r)   )extend)rS   rt  ru  rv  r   r
  r   s         r4   fakeSetupEnvironment^UnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.fakeSetupEnvironment  s    KK'BCr7   rS   rx  r}  c                      g r)   r]   akws     r4   r   RUnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.<lambda>  s    Tr7   startApplicationc                      g r)   r]   r,  s     r4   r   r/    s    Tr7   )r"  r#  T8   r%  N)r   r   r   r   r7  r!   rC  inspect	signaturerx  
parameterscopypopr   rE   r
   r0  )rS   rP   rc   r)  setupEnvironmentParametersfakeSetupEnvironmentParametersr   s         @r4   r&  @UnixApplicationRunnerStartApplicationTests.test_setupEnvironment}  s    &&(
	
 ))*AB+G4	D &-%6%6KK((&

* 	# *1):): *

* 	' *H)L)L)N&&**623T

(*<>RS

(*:<QR

3*,AB$$[1WXr7   c                 |   ^  U 4S jnT R                  [        SU5        [        0 5      nUR                  SSS5        g)zN
L{UnixApplicationRunner.shedPrivileges} switches the user ID
of the process.
c                 r   > TR                  U S5        TR                  US5        TR                  US5        g )N   6   #   r   )rG   r1   r|  rS   s      r4   switchUIDPassUUnixApplicationRunnerStartApplicationTests.test_shedPrivileges.<locals>.switchUIDPass  s3    S#&S"%T2&r7   	switchUIDr?  r=  r>  N)rE   r   r!   r}  )rS   rA  rC  s   `  r4   test_shedPrivileges>UnixApplicationRunnerStartApplicationTests.test_shedPrivileges  s6    	'
 	

<m<&r*b#r*r7   c                     S n[        0 5      nU R                  [        SU5        U R                  [        UR
                  SSS5      nU R                  UR                  S5        g)z
An unexpected L{OSError} when calling
L{twisted.scripts._twistd_unix.shedPrivileges}
terminates the process via L{SystemExit}.
c                 6    [        [        R                  S5      er  r)  )rG   r1   r|  s      r4   switchUIDFailZUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesError.<locals>.switchUIDFail  r"  r7   rC  r?  r=  Nr  )r!   rE   r   r   r   r}  r   r   )rS   rH  rC  excs       r4   test_shedPrivilegesErrorCUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesError  sU    	/ 'r*

<m<
F,A,A2sDQ1%r7   c                   ^ ^^ [        T R                  UTUT5        U UU4S jnU U4S jnU U4S jnT R                  [        SU5        T R                  [        SU5        T R                  [        SU5        [        R
                  " 5       n	U	R                  SS[        T5      S	U/5        [        R                  " S
5      n
[        U	5      T l        [        U	5      nUR                  U
5        g)zR
Common code for tests which try to pass the the UID to
L{UnixApplicationRunner}.
c                 N   > TR                  U T5        TR                  UT5        g r)   r@  )rG   r1   rS   	wantedGid	wantedUids     r4   
initgroupsFUnixApplicationRunnerStartApplicationTests._setUID.<locals>.initgroups  s#    S),S),r7   c                 *   > TR                  U T5        g r)   r@  )rG   rS   rP  s    r4   r  BUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setuid      S),r7   c                 *   > TR                  U T5        g r)   r@  )r1   rS   rO  s    r4   setgidBUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setgid  rU  r7   rQ  r  rW  r   r  r$  r&  N)rJ   rE   r   r;   r   r   r   r   r   r7  r!   rC  r0  )rS   
wantedUserrP  wantedGrouprO  pidFilerQ  r  rW  rP   rc   rC  s   ` ` `       r4   _setUID2UnixApplicationRunnerStartApplicationTests._setUID  s    
 	$**j)[)T	-	-	- 	

4z2

2x(

2x(&&(7C	NKI	
 ))*AB+G4&w/,r7   c                 P    U R                  SSSSU R                  5       S-   5        g)z
Starting an application with L{UnixApplicationRunner} configured
with a UID and no GUID will result in the GUID being
set to the default GUID for that UID.
r  i  r  i  z_test_setUidWithoutGid.pidN)r\  r  rk   s    r4   test_setUidWithoutGid@UnixApplicationRunnerStartApplicationTests.test_setUidWithoutGid  s'     	4dkkm6R&R	
r7   c                     [         R                  " 5       nU R                  SUSSS5        U R                  5       nSR	                  X5      nU R                  X2S   S   5        U R                  S[        U5      U5        g	)
zb
If the specified UID is the same as the current UID of the process,
then a warning is displayed.
morefoomorebari  ztest_setUidSameAsCurrentUid.pidz\tried to drop privileges and setuid {} but uid is already {}; should we be root? Continuing.r   messager  N)r;   r<   r\  flushWarningsr   r   len)rS   
currentUidwarningsShownexpectedWarnings       r4   test_setUidSameAsCurrentUidFUnixApplicationRunnerStartApplicationTests.test_setUidSameAsCurrentUid  s|    
 YY[
z9d4U	
 **,--3VJ-K 	 	*:9*EFC.>r7   rB  N)rV   rW   rX   rY   rZ   r&  rD  rK  r\  r_  rj  r\   r]   r7   r4   r  r  w  s'    2Yh+&-<
?r7   r  c                   $    \ rS rSrSrS rS rSrg)#UnixApplicationRunnerRemovePIDTestsi
  z/
Tests for L{UnixApplicationRunner.removePID}.
c                 X   [        0 5      nU R                  5       n[        R                  " U5        [        R                  R                  US5      n[        US5      R                  5         UR                  U5        U R                  [        R                  R                  U5      5        g)zX
L{UnixApplicationRunner.removePID} deletes the file the name of
which is passed to it.
zfoo.pidr  N)r!   r  r;   makedirsr  joinr  closer  r   r   )rS   rC  r  r
  s       r4   test_removePID2UnixApplicationRunnerRemovePIDTests.test_removePID  su    
 'r*{{}
D'',,tY/Wc  "!01r7   c                 
   [        0 5      nUR                  S5        U R                  [        5      nU R	                  [        U5      S5        U R	                  US   R                  R                  [        R                  5        g)zZ
Calling L{UnixApplicationRunner.removePID} with a non-existent filename
logs an OSError.
fakepidr  r   N)	r!   r  flushLoggedErrorsr  r   rf  valuer  ENOENT)rS   rC  errorss      r4   test_removePIDErrors8UnixApplicationRunnerRemovePIDTests.test_removePIDErrors  sb    
 'r*#''0Va(..=r7   r]   N)rV   rW   rX   rY   rZ   rr  rz  r\   r]   r7   r4   rm  rm  
  s    2	>r7   rm  c                   0    \ rS rSrSrS rS rS rS rSr	g)	FakeNonDaemonizingReactori)  a{  
A dummy reactor, providing C{beforeDaemonize} and C{afterDaemonize}
methods, but not announcing this, and logging whether the methods have been
called.

@ivar _beforeDaemonizeCalled: if C{beforeDaemonize} has been called or not.
@type _beforeDaemonizeCalled: C{bool}
@ivar _afterDaemonizeCalled: if C{afterDaemonize} has been called or not.
@type _afterDaemonizeCalled: C{bool}
c                      SU l         SU l        g r   )_beforeDaemonizeCalled_afterDaemonizeCalledrk   s    r4   r~   "FakeNonDaemonizingReactor.__init__5  s    &+#%*"r7   c                     SU l         g NT)r  rk   s    r4   beforeDaemonize)FakeNonDaemonizingReactor.beforeDaemonize9  s
    &*#r7   c                     SU l         g r  )r  rk   s    r4   afterDaemonize(FakeNonDaemonizingReactor.afterDaemonize<  s
    %)"r7   c                     g)z
Skip event registration.
Nr]   )rS   r   r.  s      r4   addSystemEventTrigger/FakeNonDaemonizingReactor.addSystemEventTrigger?  rN  r7   )r  r  N)
rV   rW   rX   rY   rZ   r~   r  r  r  r\   r]   r7   r4   r}  r}  )  s    	++*r7   r}  c                       \ rS rSrSrSrg)r  iE  z
A dummy reactor, providing C{beforeDaemonize} and C{afterDaemonize}
methods, announcing this, and logging whether the methods have been called.
r]   N)rV   rW   rX   rY   rZ   r\   r]   r7   r4   r  r  E  s    r7   r  c                   "    \ rS rSrSrSrS rSrg)r  iM  z
A dummy reactor, only providing a C{run} method and checking that it
has been called.

@ivar called: if C{run} has been called or not.
@type called: C{bool}
Fc                 J    U R                   (       a  [        S5      eSU l         g)zF
A fake run method, checking that it's been called one and only time.
zAlready calledTN)r  RuntimeErrorrk   s    r4   rf  DummyReactor.runX  s     ;;/00r7   )r  N)rV   rW   rX   rY   rZ   r  rf  r\   r]   r7   r4   r  r  M  s     Fr7   r  c                      \ rS rSrSr\" \(       + S5      S 5       rS r\" \(       + S5      S 5       r	S r
\" \(       + S5      S 5       r\" \(       + S	5      S
 5       r\" \(       + S	5      S 5       rS rS rS rS rSrg)AppProfilingTestsia  z
Tests for L{app.AppProfiler}.
zprofile module not availablec                    [         R                  " 5       nU R                  5       US'   SUS'   [        R                  " U5      n[        5       nUR                  U5        U R                  UR                  5        [        US   5       nUR                  5       nSSS5        U R                  SW5        U R                  SU5        g! , (       d  f       N3= f)zt
L{app.ProfileRunner.run} should call the C{run} method of the reactor
and save profile data in the specified file.
r$   r   NzDummyReactor.runfunction callsr   r   r  r
   r   r  rf  r   r  r  r
  r   rS   r   r   r   r  datas         r4   test_profileAppProfilingTests.test_profilef  s     %%' KKMy&z??6*.W'&#$668D %($/&- %$   C
Cc                     [        5       nU R                  [        SU5      nU" U5      nUR                  5         UR	                  5         UR                  5       nU R                  SU5        U R                  SU5        g )Nr   r  z(run))r   rE   sysprint_statsrestorer   r   )rS   
statsClassr$   outr   statsr  s          r4   
_testStatsAppProfilingTests._testStatsz  sg    j C3/ 7#||~&-gt$r7   c                 F   [         R                  " 5       nU R                  5       US'   SUS'   SUS'   [        R                  " U5      n[        5       nUR                  U5        U R                  UR                  5        U R                  [        R                  US   5        g)z
With the C{savestats} option specified, L{app.ProfileRunner.run}
should save the raw stats object instead of a summary output.
r$   r   T	savestatsNr   r   r  r
   r   r  rf  r   r  r  r%   StatsrS   r   r   r   s       r4   test_profileSaveStats'AppProfilingTests.test_profileSaveStats  s~     %%' KKMy&z"{??6*.W'fY&78r7   c                    [         R                  R                  5       n[        R                  " 5       nSUS'   [
        R                  " U5      nS[         R                  S'    U R                  [        UR                  S5        [         R                  R                  5         [         R                  R                  U5        g! [         R                  R                  5         [         R                  R                  U5        f = f)zn
When the C{profile} module is not present, L{app.ProfilerRunner.run}
should raise a C{SystemExit} exception.
r$   r   Nr  modulesr6  r   r   r
   r   r   r   rf  clearupdaterS   savedModulesr   r   s       r4   test_withoutProfile%AppProfilingTests.test_withoutProfile  s    
 {{'')%%'&z??6*!%I	-j(,,=KKKK|, KKKK|,   #!C ?Dc                     " S S[         R                  5      nU R                  [         SU5        [        R                  " 5       nU R                  5       US'   SUS'   [        R                  " U5      n[        5       n[        R                  nU R                  [        UR                  U5        U R                  [        R                  U5        g)zm
When an error happens during the print of the stats, C{sys.stdout}
should be restored to its initial value.
c                       \ rS rSrS rSrg)GAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfilei  c                     [        S5      e)NBoomr  rk   s    r4   r  SAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfile.print_stats  s    "6**r7   r]   N)rV   rW   rX   rY   r  r\   r]   r7   r4   ErroneousProfiler    s    +r7   r  Profiler$   r   N)r$   r  rE   r   r   r  r
   r   r  r  r   r   r  rf  r   )rS   r  r   r   r   	oldStdouts         r4   test_profilePrintStatsError-AppProfilingTests.test_profilePrintStatsError  s    	+w 	+ 	

7I'78%%' KKMy&z??6*.JJ	,g>cjj),r7   zcProfile module not availablec                    [         R                  " 5       nU R                  5       US'   SUS'   [        R                  " U5      n[        5       nUR                  U5        U R                  UR                  5        [        US   5       nUR                  5       nSSS5        U R                  SW5        U R                  SU5        g! , (       d  f       N3= f)zu
L{app.CProfileRunner.run} should call the C{run} method of the
reactor and save profile data in the specified file.
r$   r&   r   Nrf  r  r  r  s         r4   test_cProfileAppProfilingTests.test_cProfile  s     %%' KKMy'z??6*.W'&#$668D %eT"&- %$r  c                 F   [         R                  " 5       nU R                  5       US'   SUS'   SUS'   [        R                  " U5      n[        5       nUR                  U5        U R                  UR                  5        U R                  [        R                  US   5        g)z
With the C{savestats} option specified,
L{app.CProfileRunner.run} should save the raw stats object
instead of a summary output.
r$   r&   r   Tr  Nr  r  s       r4   test_cProfileSaveStats(AppProfilingTests.test_cProfileSaveStats  s~     %%' KKMy'z"{??6*.W'fY&78r7   c                    [         R                  R                  5       nS[         R                  S'   [        R                  " 5       nSUS'   [
        R                  " U5      n U R                  [        UR                  S5        [         R                  R                  5         [         R                  R                  U5        g! [         R                  R                  5         [         R                  R                  U5        f = f)z
When the C{cProfile} module is not present,
L{app.CProfileRunner.run} should raise a C{SystemExit}
exception and log the C{ImportError}.
Nr&   r   r  r  s       r4   test_withoutCProfile&AppProfilingTests.test_withoutCProfile  s     {{'')"&J%%''z??6*	-j(,,=KKKK|, KKKK|,r  c                     [         R                  " 5       nU R                  5       US'   SUS'   U R                  [        [
        R                  U5      nU R                  [        U5      S5        g)zY
Check that L{app.AppProfiler} raises L{SystemExit} when given an
unknown profiler name.
r$   foobarr   z!Unsupported profiler name: foobarN)	r   r   r  r   r   r
   r   r   r   )rS   r   errors      r4   test_unknownProfiler&AppProfilingTests.test_unknownProfiler  sY    
 %%' KKMy%z!!*coovFU%HIr7   c                 h    [         R                  " 0 5      nU R                  UR                  S5        g)zE
L{app.Profiler} defaults to the cprofile profiler if not specified.
cprofileNr
   r   r   r   rS   r   s     r4   test_defaultProfiler&AppProfilingTests.test_defaultProfiler  s(     ??2&**J7r7   c                 l    [         R                  " SS05      nU R                  UR                  S5        g)zM
The case of the profiler name passed to L{app.AppProfiler} is not
relevant.
r   CprOfiler  Nr  r  s     r4   test_profilerNameCaseInsentive0AppProfilingTests.test_profilerNameCaseInsentive  s-    
 ??J
#;<**J7r7   r]   N)rV   rW   rX   rY   rZ   r   r$   r  r  r  r  r  r&   r  r  r  r  r  r  r\   r]   r7   r4   r  r  a  s     K78. 9.&%" K789 99"-$ K78- 9-, L9:. ;.& L9:9 ;9$-$
J88r7   r  c                 X   ^^ / m[         R                  mUU4S jnU " [         SU5        T$ )z
Patch L{logger.textFileLogObserver} to record every call and keep a
reference to the passed log file for tests.

@param patch: a callback for patching (usually L{TestCase.patch}).

@return: the list that keeps track of the log files.
@rtype: C{list}
c                 >   > TR                  U 5        T" U /UQ70 UD6$ r)   rs  )logFiler   kwargslogFilesoldFileLogObservers      r4   observer+_patchTextFileLogObserver.<locals>.observer(  s$     !';D;F;;r7   textFileLogObserver)r   r  )rE   r  r  r  s     @@r4   _patchTextFileLogObserverr    s/     H33< 
&'2Or7   c                 T   ^ / m " U4S jS5      nU R                  [        SU5        T$ )zi
Make fake syslog, and return list to which prefix and then log
messages will be appended if it is used.
c                   .   > \ rS rSrU 4S jrU 4S jrSrg)(_setupSyslog.<locals>.fakesyslogobserveri7  c                 (   > TR                  U5        g r)   rs  )rS   prefixlogMessagess     r4   r~   1_setupSyslog.<locals>.fakesyslogobserver.__init__8  s    v&r7   c                 (   > TR                  U5        g r)   rs  )rS   	eventDictr  s     r4   emit-_setupSyslog.<locals>.fakesyslogobserver.emit;  s    y)r7   r]   N)rV   rW   rX   rY   r~   r  r\   )r  s   r4   fakesyslogobserverr  7  s    	'	* 	*r7   r  SyslogObserver)rE   syslog)testCaser  r  s     @r4   _setupSyslogr  0  s.    
 K* * NN6+-?@r7   c                       \ rS rSrSrS rS rS rS rS r	S r
0 \R                  4S	 jrS
 rS rS rS r\" \(       + S5      \" \(       + S5      S 5       5       rS rS rS rS rS rS rSrg)AppLoggerTestsiB  zv
Tests for L{app.AppLogger}.

@ivar observers: list of observers installed during the tests.
@type observers: C{list}
c                 N   ^  / T l         U 4S jnT R                  [        SU5        g)zp
Override L{globaLogBeginner.beginLoggingTo} so that we can trace the
observers installed in C{self.observers}.
c                 z   > U  H4  nTR                   R                  U5        [        R                  " U5        M6     g r)   )	observersr   r   addObserver)r  r  rS   s     r4   beginLoggingTo,AppLoggerTests.setUp.<locals>.beginLoggingToQ  s-    %%%h/"..x8 &r7   r  N)r  rE   r   )rS   r  s   ` r4   r8  AppLoggerTests.setUpJ  s%    
 	9
 	

$&6Gr7   c                 V    U R                    H  n[        R                  " U5        M     g)z!
Remove all installed observers.
N)r  r   removeObserverrS   r  s     r4   tearDownAppLoggerTests.tearDownX  s      H--h7 'r7   c                 H    [        [        5       " S S5      5       nU" 5       $ )z
Make a new observer which captures all logs sent to it.

@return: An observer that stores all logs sent to it.
@rtype: Callable that implements L{ILogObserver}.
c                       \ rS rSr/ rS rSrg)2AppLoggerTests._makeObserver.<locals>.TestObserverig  c                 :    U R                   R                  U5        g r)   )_logsr   )rS   events     r4   __call__;AppLoggerTests._makeObserver.<locals>.TestObserver.__call__k  s    

!!%(r7   r]   N)rV   rW   rX   rY   r  r  r\   r]   r7   r4   TestObserverr  g  s    E)r7   r	  )r   r   )rS   r	  s     r4   _makeObserverAppLoggerTests._makeObserver_  s*     
\	"	) 	) 
#	) ~r7   c                     U R                  U R                  U/5        U R                  SUR                  S   S   5        U R                  SUR                  S   S   5        g)zw
Ensure that initial C{twistd} logs are written to logs.

@param observer: The observer made by L{self._makeObserver).
starting upr   
log_formatzreactor classr  N)r   r  r   r  r  s     r4   _checkObserverAppLoggerTests._checkObserverp  sR     	(4mX^^A%6|%DEox~~a'8'FGr7   c                    ^ [         R                  " 0 5      nU R                  5       mU4S jUl        UR                  " [        5       5        U R                  T5        g)z|
L{app.AppLogger.start} calls L{globalLogBeginner.addObserver}, and then
writes some messages about twistd and the reactor.
c                     > T $ r)   r]   r  s   r4   r   +AppLoggerTests.test_start.<locals>.<lambda>  s    r7   N)r
   	AppLoggerr
  _getLogObserverrd   r   r  )rS   r   r  s     @r4   
test_startAppLoggerTests.test_startz  sE    
 r"%%'!1]_%H%r7   c                     [        5       nU R                  5       nUR                  [        U5        [        R
                  " 0 5      nUR                  " U5        U R                  U5        g)z
When the L{ILogObserver} component is available on the application,
that object will be used as the log observer instead of constructing a
new one.
N)r   r
  setComponentr   r
   r  rd   r  )rS   rc   r  r   s       r4   $test_startUsesApplicationLogObserver3AppLoggerTests.test_startUsesApplicationLogObserver  sQ     $o%%'  x8r"[!H%r7   c                    ^ U R                  5       mSU4S j0nUR                  U5        U" U5      nUR                  " U5        T$ )a  
Set up an AppLogger which exercises the C{logger} configuration option.

@type application: L{Componentized}
@param application: The L{Application} object to pass to
    L{app.AppLogger.start}.
@type extraLogArgs: C{dict}
@param extraLogArgs: extra values to pass to AppLogger.
@type appLogger: L{AppLogger} class, or a subclass
@param appLogger: factory for L{AppLogger} instances.

@rtype: C{list}
@return: The logs accumulated by the log observer.
r   c                     > T $ r)   r]   r  s   r4   r   7AppLoggerTests._setupConfiguredLogger.<locals>.<lambda>  s    Xr7   )r
  r  rd   )rS   rc   extraLogArgs	appLoggerlogArgsr   r  s         @r4   _setupConfiguredLogger%AppLoggerTests._setupConfiguredLogger  sE    " %%'-.|$7#[!r7   c                 X    [        5       nU R                  U R                  U5      5        g)z
When the C{logger} key is specified in the configuration dictionary
(i.e., when C{--logger} is passed to twistd), the initial log observer
will be the log observer returned from the callable which the value
refers to in FQPN form.
N)r   r  r#  rb   s     r4   #test_startUsesConfiguredLogObserver2AppLoggerTests.test_startUsesConfiguredLogObserver  s$     $oD77DEr7   c                     U R                  5       n[        5       nUR                  [        U5        U R	                  U R                  U5      5        U R                  UR                  / 5        g)zS
C{--logger} takes precedence over a L{ILogObserver} component set on
Application.
N)r
  r   r  r   r  r#  r   r  )rS   r  rc   s      r4   (test_configuredLogObserverBeatsComponent7AppLoggerTests.test_configuredLogObserverBeatsComponent  sV    
 %%'#o  x8D77DE,r7   c                     / n[        5       nUR                  [        UR                  5        U R	                  U R                  U5      5        U R                  U/ 5        g)zY
C{--logger} takes precedence over a L{LegacyILogObserver} component
set on Application.
N)r   r  LegacyILogObserverr   r  r#  r   )rS   nonlogsrc   s      r4   .test_configuredLogObserverBeatsLegacyComponent=AppLoggerTests.test_configuredLogObserverBeatsLegacyComponent  sN    
 #o  !3W^^DD77DE"%r7   c                 >   / nU R                  5       n[        5       nUR                  [        U5        UR                  [        UR
                  5        [        R                  " 0 5      nUR                  " U5        U R                  U5        U R                  U/ 5        g)z_
A L{ILogObserver} takes precedence over a L{LegacyILogObserver}
component set on Application.
N)r
  r   r  r   r,  r   r
   r  rd   r  r   )rS   r-  r  rc   r   s        r4   .test_loggerComponentBeatsLegacyLoggerComponent=AppLoggerTests.test_loggerComponentBeatsLegacyLoggerComponent  s{    
 %%'#o  x8  !3W^^Dr"[!H%"%r7   r   zsyslog not availablec                     [        U 5      n[        5       nU R                  U R                  USS0[        5      5        U R                  U/ 5        g)zH
C{--logger} takes precedence over a C{--syslog} command line
argument.
r  TN)r  r   r  r#  r"   r   )rS   logsrc   s      r4   %test_configuredLogObserverBeatsSyslog4AppLoggerTests.test_configuredLogObserverBeatsSyslog  sL     D!#o''h5E}U	
 	r"r7   c                     [        5       nU R                  5       nU R                  U R                  USS05      5        U R	                  [
        R                  R                  U5      5        g)zI
C{--logger} takes precedence over a C{--logfile} command line
argument.
logfiler  N)r   r  r  r#  r   r;   r  r   )rS   rc   r  s      r4   &test_configuredLogObserverBeatsLogfile5AppLoggerTests.test_configuredLogObserverBeatsLogfile  sV    
 $o{{}''i5HI	
 	-.r7   c                    [         R                  " SS05      n[        U R                  5      nUR                  " 5         U R                  [        U5      S5        U R                  US   [        R                  5        [         R                  " SS05      nUR                  " 5         U R                  [        U5      S5        U R                  US   [        R                  5        g)zz
When logfile is empty or set to C{-}, L{app.AppLogger._getLogObserver}
returns a log observer pointing at C{sys.stdout}.
r8  -r  r    r  N)
r
   r  r  rE   r  r   rf  r   r  r   )rS   r   r  s      r4   test_getLogObserverStdout(AppLoggerTests.test_getLogObserverStdout  s    
 	3/0,TZZ8 X*hqk3::.	2/ X*hqk3::.r7   c                    [        U R                  5      nU R                  5       n[        R                  " SU05      nUR                  5       nU R                  UR                  R                  5        U R                  [        U5      S5        U R                  US   R                  [        R                  R                  U5      5        g)z}
When passing the C{logfile} option, L{app.AppLogger._getLogObserver}
returns a log observer pointing at the specified path.
r8  r  r   N)r  rE   r  r
   r  r  
addCleanup_outFilerq  r   rf  r  r;   abspath)rS   r  filenamesutr  s        r4   test_getLogObserverFile&AppLoggerTests.test_getLogObserverFile  s    
 -TZZ8;;=mmY12&&())//0X*!))277??8+DEr7   c                 V  ^ / m[        5       nU4S jnU R                  [        SU5        [        R                  " 0 5      nXl        UR                  " 5         U R                  TU/5        UR                  " 5         U R                  TU/5        U R                  UR
                  5        g)z
L{app.AppLogger.stop} removes the observer created in C{start}, and
reinitialize its C{_observer} so that if C{stop} is called several
times it doesn't break.
c                 (   > TR                  U 5        g r)   rs  )r  removeds    r4   remove(AppLoggerTests.test_stop.<locals>.remove   s    NN8$r7   r  N)	rb  rE   r   r
   r  	_observerrL  r   r   )rS   r  rK  r   rJ  s       @r4   	test_stopAppLoggerTests.test_stop  s     8	% 	

%'7@r"#8*-8*-&**+r7   c                 l  ^^ / m[         R                  " 0 5      n[        [        5       " U4S jS5      5       mU4S jUl        UR
                  " [        5       5        U R                  S[        TS   5      5        U R                  U R                  /5      nU R                  [        U5      SU5        g)z\
L{app.AppLogger} using a legacy logger observer still works, wrapping
it in a compat shim.
c                   &   > \ rS rSrSrU 4S jrSrg);AppLoggerTests.test_legacyObservers.<locals>.LoggerObserveri4  z@
An observer which implements the legacy L{LegacyILogObserver}.
c                 (   > TR                  U5        g)z
Add C{x} to the logs list.
Nrs  )rS   xr4  s     r4   r  DAppLoggerTests.test_legacyObservers.<locals>.LoggerObserver.__call__:  s     Ar7   r]   N)rV   rW   rX   rY   rZ   r  r\   r4  s   r4   LoggerObserverrR  4  s     r7   rW  c                     > T " 5       $ r)   r]   )rW  s   r4   r   5AppLoggerTests.test_legacyObservers.<locals>.<lambda>@  s    .*:r7   r  r   N)r
   r  r   r,  _observerFactoryrd   r   r   r   re  test_legacyObserversr   rf  )rS   r   warningsrW  r4  s      @@r4   r[  #AppLoggerTests.test_legacyObservers,  s    
 r"	'	(		 		 
)		 #;]_%m%6tAw%?@%%t'@'@&ABX84r7   c                 \  ^ / m[         R                  " 0 5      nU4S jUl        UR                  " [	        5       5        U R                  S[        TS   5      5        U R                  U R                  /5      nU R                  US   S   S5        U R                  [        U5      SU5        g)z
L{app.AppLogger} using a logger observer which does not implement
L{ILogObserver} or L{LegacyILogObserver} will be wrapped in a compat
shim and raise a L{DeprecationWarning}.
c                     > T R                   $ r)   rs  rV  s   r4   r   AAppLoggerTests.test_unmarkedObserversDeprecated.<locals>.<lambda>O  s	    r7   r  r   rd  aZ  Passing a logger factory which makes log observers which do not implement twisted.logger.ILogObserver or twisted.python.log.ILogObserver to twisted.application.app.AppLogger was deprecated in Twisted 16.2. Please use a factory that produces twisted.logger.ILogObserver (or the legacy twisted.python.log.ILogObserver) implementing objects instead.r  N)r
   r  r  rd   r   r   r   re   test_unmarkedObserversDeprecatedr   rf  )rS   r   r\  r4  s      @r4   ra  /AppLoggerTests.test_unmarkedObserversDeprecatedG  s     r"!4]_%m%6tAw%?@%%t'L'L&MNQK	"0	
 	X84r7   )r  N)rV   rW   rX   rY   rZ   r8  r  r
  r  r  r  r
   r  r#  r&  r)  r.  r1  r   r   r  r5  r9  r>  rF  rN  r[  ra  r\   r]   r7   r4   r  r  B  s    H8"H	&& )+cmm0F	-	&&" 9:J./
# 0 ;
#
//&F,*565r7   r  c                   d    \ rS rSrSrS rS rS rS rS r	S r
\" \(       + S	5      S
 5       rSrg)UnixAppLoggerTestsie  zg
Tests for L{UnixAppLogger}.

@ivar signals: list of signal handlers installed.
@type signals: C{list}
c                 N   ^  / T l         U 4S jnT R                  [        SU5        g)z[
Fake C{signal.signal} for not installing the handlers but saving them
in C{self.signals}.
c                 >   > TR                   R                  X45        g r)   )signalsr   )r  r  rS   s     r4   
fakeSignal,UnixAppLoggerTests.setUp.<locals>.fakeSignalu  s    LL)r7   signalN)rg  rE   rj  )rS   rh  s   ` r4   r8  UnixAppLoggerTests.setUpn  s#    
 	* 	

68Z0r7   c                    [        U R                  5      n[        SSS.5      nUR                  " 5         U R	                  [        U5      S5        U R                  US   [        R                  5        [        SSS.5      nUR                  " 5         U R	                  [        U5      S5        U R                  US   [        R                  5        g)	z
When non-daemonized and C{logfile} is empty or set to C{-},
L{UnixAppLogger._getLogObserver} returns a log observer pointing at
C{sys.stdout}.
r<  Tr8  rv  r  r   r=  r  N)	r  rE   r"   r  r   rf  r   r  r   )rS   r  r   s      r4   r>  ,UnixAppLoggerTests.test_getLogObserverStdoutz  s     -TZZ83DAB X*hqk3::.24@A X*hqk3::.r7   c                     [        SSS.5      nU R                  [        UR                  5      nU R	                  [        U5      S5        g)zg
When daemonized and C{logfile} is set to C{-},
L{UnixAppLogger._getLogObserver} raises C{SystemExit}.
r<  Frm  z&Daemons cannot log to stdout, exiting!N)r"   r   r   r  r   r   )rS   r   r  s      r4   test_getLogObserverStdoutDaemon2UnixAppLoggerTests.test_getLogObserverStdoutDaemon  s@    
 3EBC!!*f.D.DEU%MNr7   c                   ^ [        U R                  5      nU R                  5       n[        SU05      nUR	                  5       nU R                  UR                  R                  5        U R                  [        U5      S5        U R                  US   R                  [        R                  R                  U5      5        U R                  [        U R                  5      S5        U R                  U R                  S   S   [        R                  5        [!        5       mU4S jnXQS   l        U R                  S   S   nU" SS5        T$ )z
When C{logfile} contains a file name, L{app.AppLogger._getLogObserver}
returns a log observer pointing at the specified path, and a signal
handler rotating the log is installed.
r8  r  r   c                  (   > T R                  S 5        g r)   )callback)ds   r4   rotate:UnixAppLoggerTests.test_getLogObserverFile.<locals>.rotate  s    JJtr7   N)r  rE   r  r"   r  rA  rB  rq  r   rf  r  r;   rC  rg  rj  SIGUSR1r   rv  )rS   r  rD  rE  r  rv  	rotateLogru  s          @r4   rF  *UnixAppLoggerTests.test_getLogObserverFile  s    -TZZ8;;=Y12&&())//0X*!))277??8+DET\\*A.a+V^^<J	 $LLOA&	$r7   c                   ^  U 4S jnT R                  [        SU5        T R                  5       n[        SU05      nUR	                  5       nT R                  UR                  R                  5        T R                  T R                  / 5        g)za
If a signal handler is already installed,
L{UnixAppLogger._getLogObserver} doesn't override it.
c                 X   > TR                  U [        R                  5        [        5       $ r)   )r   rj  rx  rb  )r  rS   s    r4   fakeGetSignalVUnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandler.<locals>.fakeGetSignal  s    S&..18Or7   	getsignalr8  N)
rE   rj  r  r"   r  rA  rB  rq  r   rg  )rS   r}  rD  rE  r  s   `    r4   ,test_getLogObserverDontOverrideSignalHandler?UnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandler  sn    	 	

6;6;;=Y12&&())//0r*r7   c                 d   [        U R                  5      n[        SSS.5      nUR                  " 5       nU R	                  UR
                  R                  5        U R                  [        U5      S5        U R                  US   R                  [        R                  R                  S5      5        g)z
When daemonized and C{logfile} is empty, the observer returned by
L{UnixAppLogger._getLogObserver} points at C{twistd.log} in the current
directory.
r=  Frm  r  r   z
twistd.logN)r  rE   r"   r  rA  rB  rq  r   rf  r  r;   rC  )rS   r  r   r  s       r4   test_getLogObserverDefaultFile1UnixAppLoggerTests.test_getLogObserverDefaultFile  s     -TZZ825AB))+))//0X*!))277??<+HIr7   r   c                     [        U 5      n[        SSS.5      nUR                  " 5       nU R                  US/5        U" SS05        U R                  USSS0/5        g)zz
If C{syslog} is set to C{True}, L{UnixAppLogger._getLogObserver} starts
a L{syslog.SyslogObserver} with given C{prefix}.
Tztest-prefix)r  r  r-  bN)r  r"   r  r   )rS   r4  r   r  s       r4   test_getLogObserverSyslog,UnixAppLoggerTests.test_getLogObserverSyslog  sb     D!$-HI))+/#sSz:;r7   )rg  N)rV   rW   rX   rY   rZ   r8  r>  rp  rF  r  r  r   r   r  r\   r]   r7   r4   rd  rd  e  sF    
1/$O<+&J 9:
< ;
<r7   rd  z!twistd unix support not availablec                   x    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rSrg)DaemonizeTestsi  z@
Tests for L{_twistd_unix.UnixApplicationRunner} daemonization.
c                    [        5       U l        [        R                  " 5       U l        U R                  [        SU R                  5        [        R                  U R                  5      U l        [        R                  " S5      U R                  l        [        R                  U R                  l        [        R                  U R                  l        S U R                  l        g )Nr;   r3  c                      g r)   r]   )r   s    r4   r   &DaemonizeTests.setUp.<locals>.<lambda>  s    r7   )r   mockosr   r   r   rE   r   r!   rC  r   r7  rc   r  r   r  stderrr  r  rk   s    r4   r8  DaemonizeTests.setUp  s    h**,

<t{{3"88E")"5"5e"< #

 #

#5 r7   c                 2   [        [        5       5         U R                  R                  5         SSS5        U R	                  U R
                  R                  / SQ5        U R	                  U R
                  R                  SS/5        g! , (       d  f       N_= f)z_
When double fork succeeded in C{daemonize}, the child process writes
B{0} to the status pipe.
N)r  r  r   r  forkTsetsidr  )r	     0unlinkz
twistd.pidr  )r   r  rC  ro   r   r  actionsclosedrk   s    r4   test_successDaemonizeTests.test_success  sn    
 467KK'') 8KK	
 	++b"X6 87s   B
Bc                    SU R                   l        SU R                   l        [        [	        5       5         U R                  [        U R                  R                  5        SSS5        U R                  U R                   R                  / SQ5        U R                  U R                   R                  S/5        g! , (       d  f       N^= f)zp
The parent process initiating the C{daemonize} call reads data from the
status pipe and then exit the process.
Fr  N)r  r  r  r
  d   exitr   r  r  )r  childreadDatar   r  r   SystemErrorrC  ro   r   r  r  rk   s    r4   test_successInParent#DaemonizeTests.test_successInParent  s    
 "#467k4;;+F+FG 8KK
	
 	++bT2 87s   +B99
Cc                   ^ / mU4S jnXR                   l        [        [        5       5         U R                  R                  5         SSS5        U R                  U R                   R                  / SQ5        U R                  U R                   R                  SS/5        U R                  SS/T5        g! , (       d  f       Ns= f)zj
If the C{os.write} call to the status pipe raises an B{EINTR} error,
the process child retries to write.
c                 z   > TR                  X45        [        T5      S:X  a  [        [        R                  5      eg r  r   rf  r  r  EINTR)fdr  writtens     r4   raisingWrite6DaemonizeTests.test_successEINTR.<locals>.raisingWrite$  s1    NNB:&7|q ekk** !r7   N)r  r  r  r  r  r  r  r  )r  r  )	r  r	  r   r  rC  ro   r   r  r  )rS   r  r  s     @r4   test_successEINTR DaemonizeTests.test_successEINTR  s    
 	+
 )467KK'') 8KK
	
 	++b"X6*j17; 87s   B55
Cc                   ^ / mU4S jnXR                   l        SU R                   l        [        [	        5       5         U R                  [        U R                  R                  5        SSS5        U R                  U R                   R                  / SQ5        U R                  U R                   R                  S/5        U R                  SS/T5        g! , (       d  f       Nr= f)zg
If the C{os.read} call on the status pipe raises an B{EINTR} error, the
parent child retries to read.
c                 z   > TR                  X45        [        T5      S:X  a  [        [        R                  5      eg)Nr  r  r  )r  sizer
  s     r4   raisingRead=DaemonizeTests.test_successInParentEINTR.<locals>.raisingReadA  s.    KK
#4yA~ekk**r7   FN)r  r  r  r  r  r  )r  r  )r  r
  r  r   r  r   r  rC  ro   r   r  r  )rS   r  r
  s     @r4   test_successInParentEINTR(DaemonizeTests.test_successInParentEINTR:  s    
 	 '!467k4;;+F+FG 8KK		
 	++bT2)Y/6 87s   +C
C#c                   ^  " U4S jS[         R                  5      nU" 5       nUR                  U R                  R                  5        [        [        5       5         U R                  [        U R                  R                  5        SSS5        U R                  U R                  R                  SSSSSSS	U4S
/5        U R                  U R                  R                  SS	/5        g! , (       d  f       Ng= f)z
Assert L{UnixApplicationRunner.postApplication} writes
C{reported} to its status pipe if the service raises an
exception whose message is C{raised}.
c                   "   > \ rS rSrU 4S jrSrg)6DaemonizeTests.assertErrorWritten.<locals>.FakeServicei_  c                    > [        T5      er)   r  )rS   raiseds    r4   r  CDaemonizeTests.assertErrorWritten.<locals>.FakeService.startService`  s    "6**r7   r]   N)rV   rW   rX   rY   r  r\   )r  s   r4   r  r  _  s    + +r7   r  Nr  r  r  r  r	  r  r  r  )r   rQ   r  rC  rc   r   r  r   r  ro   r   r  r  r  )rS   r  reportedr  errorServices    `   r4   assertErrorWritten!DaemonizeTests.assertErrorWrittenX  s    	+'// 	+ #}%%dkk&=&=>467lDKK,G,GH 8KK "h'(	
 	++b"X6 87s   +C))
C7c                 $    U R                  SSS9  g)zl
If an error happens during daemonization, the child process writes the
exception error to the status pipe.
zSomething is wrongs"   1 RuntimeError: Something is wrongr  r  Nr  rk   s    r4   
test_errorDaemonizeTests.test_errorv  s    
 	'2W 	  	
r7   c                 $    U R                  SSS9  g)z
If an error happens during daemonization, and that error's
message is Unicode, the child encodes the message as ascii
with backslash Unicode code points.
u   •s   1 RuntimeError: \u2022r  Nr  rk   s    r4   test_unicodeError DaemonizeTests.test_unicodeError  s     	x:TUr7   c                    SU R                   l        XR                   l        [        5       nU R	                  [
        SU5        [        [        5       5         U R                  [        U R                  R                  5        SSS5        U R                  UR                  5       U5        U R                  U R                   R                  U5        U R                  U R                   R                  S/5        g! , (       d  f       N|= f)z
Make L{os.read} appear to return C{readData}, and assert that
L{UnixApplicationRunner.postApplication} writes
C{errorMessage} to standard error and executes the calls
against L{os} functions specified in C{mockOSActions}.
F
__stderr__Nr  )r  r  r  r   rE   r  r   r  r   r  rC  ro   r   r   r  r  )rS   r  errorMessagemockOSActionserrorIOs        r4   assertErrorInParentBehavior*DaemonizeTests.assertErrorInParentBehavior  s     "'*

3g.467k4;;+F+FG 8))+\:,,m<++bT2	 87s   +C77
Dc                 *    U R                  SS/ SQS9  g)z
When the child writes an error message to the status pipe
during daemonization, the parent writes the repr of the
message to C{stderr} and exits with non-zero status code.
s    1 Exception: An identified errorzgAn error has occurred: b'Exception: An identified error'
Please look at log file for more information.
r  r  r  r  )r  r  r  r  r  r  Nr  rk   s    r4   test_errorInParent!DaemonizeTests.test_errorInParent  s%     	((8B 	) 	
r7   c                 *    U R                  SS/ SQS9  g)z
When the child writes a non-ASCII error message to the status
pipe during daemonization, the parent writes the repr of the
message to C{stderr} and exits with a non-zero status code.
s   1 Exception: zXAn error has occurred: b'Exception: \xff'
Please look at log file for more information.
r  r  Nr  rk   s    r4   test_nonASCIIErrorInParent)DaemonizeTests.test_nonASCIIErrorInParent  s%     	(()B 	) 	
r7   c                 n    SnSR                  S5      nU R                  USR                  U5      / SQS9  g)z
When the child writes a non-ASCII error message to the status
pipe during daemonization, and that message is too longer, the
parent writes the repr of the truncated message to C{stderr}
and exits with a non-zero status code.
d   1 RuntimeError: \u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022zb'RuntimeError: {}'zb\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022zHAn error has occurred: {}
Please look at log file for more information.
r  r  N)r   r  )rS   truncatedMessagereportedMessages      r4   &test_errorInParentWithTruncatedUnicode5DaemonizeTests.test_errorInParentWithTruncatedUnicode  sL     A 066G((%BBH&#C 	) 	
r7   c                 $    U R                  SSS9  g)zc
If an error occurs during daemonization and its message is too
long, it's truncated by the child.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsd   1 RuntimeError: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr  Nr  rk   s    r4   test_errorMessageTruncated)DaemonizeTests.test_errorMessageTruncated  s    
 	'F 	  	
r7   c                 $    U R                  SSS9  g)z
If an error occurs during daemonization and its message is
unicode and too long, it's truncated by the child, even if
this splits a unicode escape sequence.
uZ   ••••••••••••••••••••••••••••••r  r  Nr  rk   s    r4   !test_unicodeErrorMessageTruncated0DaemonizeTests.test_unicodeErrorMessageTruncated  s     	 : 	  	
r7   c                     [        5       nU R                  R                  U5        U R                  UR                  5        U R                  UR
                  5        g)z
C{daemonize} indeed calls L{IReactorDaemonize.beforeDaemonize} and
L{IReactorDaemonize.afterDaemonize} if the reactor implements
L{IReactorDaemonize}.
N)r  rC  r  r   r  r  r  s     r4   test_hooksCalledDaemonizeTests.test_hooksCalled  sB     )*g&667556r7   c                     [        5       nU R                  R                  U5        U R                  UR                  5        U R                  UR
                  5        g)z
C{daemonize} does NOT call L{IReactorDaemonize.beforeDaemonize} or
L{IReactorDaemonize.afterDaemonize} if the reactor does NOT implement
L{IReactorDaemonize}.
N)r}  rC  r  r   r  r  r  s     r4   test_hooksNotCalled"DaemonizeTests.test_hooksNotCalled   sF     ,-g&778667r7   )r   r  rC  N)rV   rW   rX   rY   rZ   r8  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r\   r]   r7   r4   r  r    sX    67*3,<:7<7<
V3"
,
,
:
	
	7	8r7   r  c                   L    \ rS rSrSr\S 5       r\R                  S 5       rSrg)SignalCapturingMemoryReactori  z}
MemoryReactor that implements the _ISupportsExitSignalCapturing interface,
all other operations identical to MemoryReactor.
c                     U R                   $ r)   _valrk   s    r4   r  (SignalCapturingMemoryReactor._exitSignal  s    yyr7   c                     Xl         g r)   r  )rS   vals     r4   r  r    s    	r7   r  N)	rV   rW   rX   rY   rZ   propertyr  setterr\   r]   r7   r4   r  r    s5    
    r7   r  c                   <   ^  \ rS rSrSr\rU 4S jrS rS r	Sr
U =r$ )StubApplicationRunnerWithSignali  z
An application runner that uses a SignalCapturingMemoryReactor and
has a _signalValue attribute that it will set in the reactor.

@ivar _signalValue: The signal value to set on the reactor's _exitSignal
    attribute.
c                 2   > [         TU ]  U5        S U l        g r)   )superr~   _signalValue)rS   r   	__class__s     r4   r~   (StubApplicationRunnerWithSignal.__init__'  s      r7   c                     g)z
Does nothing.
Nr]   rk   s    r4   rl   .StubApplicationRunnerWithSignal.preApplication+  rN  r7   c                     [        5       nU R                  Ul        U R                  U[        R
                  [        R                  5        g)zH
Instantiate a SignalCapturingMemoryReactor and start it
in the runner.
N)r  r  r  r  r  r   r  r  s     r4   ro   /StubApplicationRunnerWithSignal.postApplication0  s4    
 /0"//'3::szz:r7   )r  )rV   rW   rX   rY   rZ   r_   rq   r~   rl   ro   r\   __classcell__)r   s   @r4   r  r    s#     &M!
; ;r7   r  c                    ^  U 4S jnU$ )a)  
Create a factory function to instantiate a
StubApplicationRunnerWithSignal that will report signum as the captured
signal..

@param signum: The integer signal number or None
@type signum: C{int} or C{None}

@return: A factory function to create stub runners.
@rtype: stubApplicationRunnerFactory
c                 ,   > [        U 5      nTUl        U$ )aw  
Create a StubApplicationRunnerWithSignal using a reactor that
implements _ISupportsExitSignalCapturing and whose _exitSignal
attribute is set to signum.

@param config: The runner configuration, platform dependent.
@type config: L{twisted.scripts.twistd.ServerOptions}

@return: A runner to use for the test.
@rtype: twisted.test.test_twistd.StubApplicationRunnerWithSignal
)r  r  )r   rC  signums     r4   stubApplicationRunnerFactoryIstubApplicationRunnerFactoryCreator.<locals>.stubApplicationRunnerFactoryG  s     18$r7   r]   )r	  r
  s   ` r4   #stubApplicationRunnerFactoryCreatorr  :  s      ('r7   c                   0    \ rS rSrSrS rS rS rS rSr	g)	ExitWithSignalTestsiZ  z7
Tests for L{twisted.application.app._exitWithSignal}.
c                   ^  [         R                  " 5       T l        S[        5       0T R                  l        [        5       T R                  l        ST R                  l        SS/T l        U 4S jnT R                  [        SU5        g)z=
Set up the server options and a fake for use by test cases.
r_  Nc                 B   > U TR                   S'   UTR                   S'   g)z
Fake method to capture arguments passed to os.kill.

@param pid: The pid of the process being killed.

@param sig: The signal sent to the process.
r   r  N)fakeKillArgs)r  r  rS   s     r4   fakeKill+ExitWithSignalTests.setUp.<locals>.fakeKillj  s%     $'Da #&Da r7   r  )r   r   r   rL   ra  rb  rc  r   r  rE   r;   )rS   r  s   ` r4   r8  ExitWithSignalTests.setUp`  sg     **,%35E5G$H!!'!/!4L		' 	

2vx(r7   c                   ^ SS/mU4S jnU R                  [        SU5        [        R                  " [        R                  5        U R                  TS   [        R                  5        U R                  TS   [        R                  5        U R                  U R                  S   [        R                  " 5       5        U R                  U R                  S   [        R                  5        g)z
exitWithSignal replaces the existing signal handler with the default
handler and sends the replaced signal to the current process.
Nc                    > U TS'   UTS'   g )Nr   r  r]   )r  handlerfakeSignalArgss     r4   fake_signal<ExitWithSignalTests.test_exitWithSignal.<locals>.fake_signal  s     #N1 'N1r7   rj  r   r  )
rE   rj  r
   _exitWithSignalSIGINTr  SIG_DFLr  r;   r#  )rS   r  r  s     @r4   test_exitWithSignal'ExitWithSignalTests.test_exitWithSignalw  s     	( 	

68[1FMM*.+V]];.+V^^<$++A.		<$++A.>r7   c                     U R                  [        S[        S5      5        [        R                  " U R                  5        U R                  U R                  S   5        U R                  U R                  S   5        g)zJ
_exitWithSignal is not called if the runner does not exit with a
signal.
r  Nr   r  )rE   r   r  runAppr   r   r  rk   s    r4   test_normalExit#ExitWithSignalTests.test_normalExit  sc    
 	

,.QRV.W	
 	dkk"$++A./$++A./r7   c                 ^   U R                  [        S[        [        R                  5      5        [        R
                  " U R                  5        U R                  U R                  S   [        R                  " 5       5        U R                  U R                  S   [        R                  5        g)z@
_exitWithSignal is called when the runner exits with a signal.
r  r   r  N)rE   r   r  rj  r  r!  r   r  r  r;   r#  rk   s    r4   test_runnerExitsWithSignal.ExitWithSignalTests.test_runnerExitsWithSignal  st     	

$/>	

 	dkk"$++A.		<$++A.>r7   )r   r  N)
rV   rW   rX   rY   rZ   r8  r  r"  r%  r\   r]   r7   r4   r  r  Z  s    ).?(
0?r7   r  )hrZ   r  r3  r;   r5  rj  r  r=   _grpr:   _pwdImportErrorior   unittestr   zope.interfacer   zope.interface.verifyr   r   r   r   r	   twisted.applicationr
   r   r   twisted.application.servicer   twisted.internet.baser   twisted.internet.deferr   twisted.internet.interfacesr   r   #twisted.internet.test.modulehelpersr   twisted.internet.testingr   twisted.loggerr   r   r   twisted.pythonr   twisted.python.componentsr   twisted.python.fakepwdr   twisted.python.logr,  r   twisted.python.reflectr   twisted.python.runtimer   twisted.python.usager   twisted.scriptsr   twisted.test.test_processr   twisted.trial.unittestr    r   twisted.scripts._twistd_unixr!   r"   r#   r  r$   r%   r&   rJ   rL   r  r_   r  rh   rs   r   r0  r@  rR  rP  r]  r  r  rm  r}  r  r  r  r  r  r  rd  r  r  r  r  r  r]   r7   r4   <module>rA     s  
   	   

 C
C   & . , , 6 6 5 - + X @ 2 N N  3 / T 0 / + " , +;<  
.	/
	
"	x	 $*.Z "  = =  UJ UJp L56CKH CK 7CKLD8 D0 *JC11 J(p4X p4f L56F+ F+ 7F+R L56O? O? 7O?d L56>( > 7>< 8 6    (w8 w8t*$`5X `5F	 L56y< y< 7y<x L=>f8X f8 ?f8R	 *+=  ,;f&C&C ;<(@H?( H?OB  
C
Cs   J 
J('J(