+
    Dfj$!                    \   R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt ^ RIt^ RI	t
]
t	]t^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHtHtHt ^ RIHtHtHt ^ RIHt ^ R	IHt ^ R
I H!t! ^ RI"H#t#H$t$ ^ RI%H&t& ^ RI'H(t( ^ RI)H*t*H+t+H,t, ^ RI-H.t. ^ RI/H0t0 ^ RI1H2t2 ^ RI3H*t4H5t5 ^ RI6H7t7 ^ RI8H9t9 ^ RI:H;t; ^ RI<H=t= ^ RI>H?t? ^ RI@HAtA ]7! R4      tB]B'       d   ^ RICHDtDHEtEHFtF ]7! R4      tG]7! R4      tH]7! R4      tI]7! R4      tJR tK ! R  R!4      tL ! R" R#]P                  4      tN ! R$ R%]=P                  4      tP ! R& R']A4      tQ]! ]B'       * R(4       ! R) R*]A4      4       tR ! R+ R,]A4      tS ! R- R.4      tT ! R/ R0]P                  4      tV ! R1 R2]A4      tW]! ]B'       * R(4       ! R3 R4]A4      4       tX]! ]B'       * R(4       ! R5 R6]A4      4       tY]! ]B'       * R(4       ! R7 R8]A4      4       tZ ! R9 R:4      t[]! ]#4       ! R; R<][4      4       t\ ! R= R>4      t] ! R? R@]A4      t^RA t_RB t` ! RC RD]A4      ta]! ]B'       * R(4       ! RE RF]A4      4       tb]! ]B'       * RG4       ! RH RI]A4      4       tc]! ]$4       ! RJ RK](4      4       td ! RL RM]=P                  4      teRN tf ! RO RP]A4      tgR#   ] d	    Rt	Rt ELi ; i)QzE
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           	       aaa \         P                  \        P                  ! 4       4      p\        P                  \        P                  ! 4       4      o\        4       pVP                  WP                  VSVP                  VP                  VP                  4       VVV3R lpV ! \         RVP                  4       V ! \        RV4       V ! \         RVP                  4       R# )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                    < \        S4      pSWP                  SP                  4      &   SWP                  SP                  4      &   \	        V4      pSV/V ,          # N)listindexgr_namegr_gidtuple)nameresultgidgrentgroups   & :/usr/lib/python3/dist-packages/twisted/test/test_twistd.pygetgrnam#patchUserDatabase.<locals>.getgrnamd   sN    e.3||EMM*+-0||ELL)*vvt$$    getpwnamr4   getpwuidN)pwdr8   osgetuidgrpgetgrgidgetgidr   addUser	pw_passwdpw_gecospw_dirpw_shellr7   )	patchuseruidr2   r0   pwentdatabaser4   r1   s	   &&&ff   @r3   patchUserDatabaserI   C   s    2 LL%ELL%E~HoosCu~~% 
#z8,,-	#z8$	#z8,,-r6   c                   .   a  ] tR t^pt o RtRtR tRtV tR# )MockServiceMakerzG
A non-implementation of L{twisted.application.service.IServiceMaker}.
ueoac                Z    Wn         \        P                  ! 4       V n        V P                  # )zM
Take a L{usage.Options} instance and return a
L{service.IService} provider.
)optionsr   ServiceselfrN   s   &&r3   makeServiceMockServiceMaker.makeServicew   s!    
 (||r6   )rN   r   N)	__name__
__module____qualname____firstlineno____doc__tapnamerR   __static_attributes____classdictcell____classdict__s   @r3   rK   rK   p   s      G r6   rK   c                   *   a  ] tR t^t o RtR tRtV tR# )CrippledAppLoggerz"
@see: CrippledApplicationRunner.
c                    R # r(    rQ   applications   &&r3   startCrippledAppLogger.start       r6   ra   N)rT   rU   rV   rW   rX   rd   rZ   r[   r\   s   @r3   r_   r_      s      r6   r_   c                   4   a  ] tR t^t o Rt]tR tR tRt	V t
R# )CrippledApplicationRunnerz
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                    R # r(   ra   rQ   s   &r3   preApplication(CrippledApplicationRunner.preApplication   rf   r6   c                    R # r(   ra   rj   s   &r3   postApplication)CrippledApplicationRunner.postApplication   rf   r6   ra   N)rT   rU   rV   rW   rX   r_   loggerFactoryrk   rn   rZ   r[   r\   s   @r3   rh   rh      s       &M r6   rh   c                      a  ] tR t^t o RtR tR tR tR tR t	]
! ]'       * R4      R 4       t]
! ]'       * R4      R	 4       t]
! ]'       * R4      R
 4       tR tR tR tR tRtV tR# )ServerOptionsTestszL
Non-platform-specific tests for the platform-specific ServerOptions class.
c                *  a aaaa  ! R R4      pV! R4      oV! R4      oV! R4      oV! R4      oVVVVV 3R lp\         P                  ! 4       pS P                  VP                  \        P
                  4       W#n        VP                  pSSSS.p\        WE4       Fs  w  rgVw  rrS P                  WP                  4       S P                  V	4       S P                  V
! 4       VP                  4      3 S P                  WP                  4       Ku  	  R# )	zP
subCommands is built from IServiceMaker plugins, and is sorted
alphabetically.
c                   ,   a  ] tR t^t o R tR tRtV tR# )7ServerOptionsTests.test_subCommands.<locals>.FakePluginc                J    Wn         R V,           V n        RV,           V n        R# )zoptions for description of N)rY   _optionsdescriptionrQ   r.   s   &&r3   __init__@ServerOptionsTests.test_subCommands.<locals>.FakePlugin.__init__   s     # . 5#4t#; r6   c                    V P                   # r(   )rx   rj   s   &r3   rN   ?ServerOptionsTests.test_subCommands.<locals>.FakePlugin.options   s    }}$r6   )rx   ry   rY   N)rT   rU   rV   rW   r{   rN   rZ   r[   r\   s   @r3   
FakePluginru      s     <
% %r6   r   applebananacoconutdonutc              3   \   <"   SP                  V \        4       Sx  Sx  Sx  Sx  R # 5ir(   )assertEqualr   )	interfacer   r   r   r   rQ   s   &r3   
getPlugins7ServerOptionsTests.test_subCommands.<locals>.getPlugins   s*     Y6MLKKs   ),N)r   ServerOptionsr   _getPluginsr   r   subCommandsziprY   assertIsNonerx   ry   )rQ   r   r   configr   expectedOrder
subCommandexpectedCommandr.   shortcutparserClassdocumentationr   r   r   r   s   f           @@@@r3   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r6   c                f  a aaaa	a
a  ! R R4      pV! R4      oV! R4      oV! R4      oV! R4      o	VVVV	3R lp\         P                  ! 4       pS P                  VP                  \        P
                  4       W#n        \        4       Vn        S P                  \        VP                  R.4       VP                  P                  4       o
. oSSSS	3 F/  pV
VV 3R	 lpV! VP                  4       V! VP                  4       K1  	  S P                  S\        S4      R
P                  S
4      4       R# )z@
Reactor names are listed alphabetically by I{--help-reactors}.
c                   &   a  ] tR t^t o R tRtV tR# )GServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstallerc                L    R V,           V n         RV,           V n        RV n        R# )zname of rw   ztwisted.internet.defaultN)	shortNamery   
moduleNamerz   s   &&r3   r{   PServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstaller.__init__   s"    !+d!2#4t#; "<r6   )ry   r   r   N)rT   rU   rV   rW   r{   rZ   r[   r\   s   @r3   FakeReactorInstallerr      s     = =r6   r   r   r   r   r   c               3   0   <"   Sx  Sx  Sx  S x  R # 5ir(   ra   )r   r   r   r   s   r3   getReactorTypesBServerOptionsTests.test_sortedReactorHelp.<locals>.getReactorTypes   s     MLKKs   z--help-reactorsc                 l   < SP                  V S4       SP                  SP                  V 4      4       R # r(   )assertInappendr*   )s
helpOutputindexesrQ   s   &r3   getIndex;ServerOptionsTests.test_sortedReactorHelp.<locals>.getIndex   s(    a,z//23r6   z9reactor descriptions were not in alphabetical order: {!r}N)r   r   r   _getReactorTypesr
   r   r   messageOutputassertRaises
SystemExitparseOptionsgetvaluer   ry   sortedformat)rQ   r   r   r   reactorr   r   r   r   r   r   r   s   f     @@@@@@r3   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	
r6   c                    \         P                  ! 4       pRVn        VP                  4        V P	                  VR,          4       R# )zC
postOptions should set no_save to True when a subcommand is used.
rL   no_saveN)r   r   r   postOptions
assertTruerQ   r   s   & r3   &test_postOptionsSubCommandCausesNoSave9ServerOptionsTests.test_postOptionsSubCommandCausesNoSave   s7     %%'"y)*r6   c                    \         P                  ! 4       pVP                  4        V P                  VR,          4       R# )zB
If no sub command is used, postOptions should not touch no_save.
r   N)r   r   r   assertFalser   s   & r3   (test_postOptionsNoSubCommandSavesAsUsual;ServerOptionsTests.test_postOptionsNoSubCommandSavesAsUsual  s1     %%'	*+r6   c                    \         P                  ! 4       p\        V4      p\        P                  P
                   F  pV P                  W24       K  	  R# )zY
All the profilers that can be used in L{app.AppProfiler} are listed in
the help output.
N)r   r   strr	   AppProfiler	profilersr   )rQ   r   r   profilers   &   r3   test_listAllProfilers(ServerOptionsTests.test_listAllProfilers
  s;    
 %%'[
11HMM(/ 2r6   twistd unix not availablec                `    \         P                  ! 4       pV P                  VR,          4       R# )z7
The default value for the C{umask} option is L{None}.
umaskN)r   r   r   r   s   & r3   test_defaultUmask$ServerOptionsTests.test_defaultUmask  s$    
 %%'&/*r6   c                    \         P                  ! 4       pVP                  RR.4       V P                  VR,          ^S4       VP                  RR.4       V P                  VR,          ^S4       R# )zP
The value given for the C{umask} option is parsed as an octal integer
literal.
--umask123r   0123N)r   r   r   r   r   s   & r3   
test_umaskServerOptionsTests.test_umask  s`     %%'Y./"-Y/0"-r6   c                v    \         P                  ! 4       pV P                  \        VP                  RR.4       R# )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   & r3   test_invalidUmask$ServerOptionsTests.test_invalidUmask(  s/     %%'*f&9&9Ix;PQr6   c                   \         P                  ! 4       pV P                  \        VP                  RR.4      pV P                  VP                  ^ ,          P                  R4      4       V P                  RVP                  ^ ,          4       R# )zA
C{--logger} with an unimportable module raises a L{UsageError}.
--loggerzno.such.module.I.hopezeLogger '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rQ   r   es   &  r3   &test_unimportableConfiguredLogObserver9ServerOptionsTests.test_unimportableConfiguredLogObserver1  sy     %%'++j:Q-R
 	FF1I  B	
 	qvvay)r6   c                   \         P                  ! 4       pV P                  \        VP                  RR.4      pV P                  VP                  ^ ,          P                  R4      4       V P                  RVP                  ^ ,          4       R# )z@
C{--logger} with a non-existent object raises a L{UsageError}.
r   ztwisted.test.test_twistd.FOOBARz{Logger 'twisted.test.test_twistd.FOOBAR' could not be imported: module 'twisted.test.test_twistd' has no attribute 'FOOBAR'r   Nr   r   s   &  r3   *test_badAttributeWithConfiguredLogObserver=ServerOptionsTests.test_badAttributeWithConfiguredLogObserverA  sz     %%':;

 	FF1I  ,	
 	qvvay)r6   c                |   ^ RI Hp \        R8X  d   RpMRpRP                  W!P                  VP                  4      p\        4       p\        P                  ! VR7      pV P                  \        VP                  R.4      pV P                  VP                  R4       V P                  VP                  4       V4       R# )	z"
C{--version} prints the version.
)	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   )rQ   r   r.   expectedOutputr   r   r   s   &      r3   test_versionServerOptionsTests.test_versionT  s     	&7"1D)D-44##Y%8%8
 %%V4j&*=*=}Maffd#*N;r6   c                    \        4       p\        P                  ! VR7      pV P                  \        VP
                  R.4       R# )z9
Command is printed when an invalid option is requested.
r   z	web --fooN)r   r   r   r   r   r   )rQ   r   r   s   &  r3   !test_printSubCommandForUsageError4ServerOptionsTests.test_printSubCommandForUsageErrorh  s5     %%V4*f&9&9K=Ir6   ra   N)rT   rU   rV   rW   rX   r   r   r   r   r   r   _twistd_unixr   r   r   r   r   r   r   rZ   r[   r\   s   @r3   rr   rr      s     )IV-
^+,0 9:+ ;+ 9:	. ;	. 9:R ;R* *&<(J Jr6   rr   r   c                   B   a  ] tR tRt o RtR tR tR tR tR t	Rt
V tR	# )
CheckPIDTestsir  z
Tests for L{checkPID}.
c                `    V P                  \        P                  RR 4       \        R4       R# )z'
Nonexistent PID file is not an error.
existsc                     R # )Fra   )_s   &r3   <lambda>.CheckPIDTests.test_notExists.<locals>.<lambda>|  s    r6   znon-existent PID fileN)rD   r:   pathr"   rj   s   &r3   test_notExistsCheckPIDTests.test_notExistsx  s!     	

277Ho6()r6   c                   V P                  4       p\        VR4      ;_uu_ 4       pVP                  R4       RRR4       V P                  \        \
        V4      pV P                  RVP                  4       R#   + '       g   i     LI; i)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   )rQ   pidfilefr   s   &   r3   test_nonNumericCheckPIDTests.test_nonNumeric  s_     ++-'31GGM"  j(G<)1662  s   A88B	c                J   V P                  4       p\        VR4      ;_uu_ 4       pVP                  R4       RRR4       R pV P                  \        RV4       V P                  \        \        V4      pV P                  RVP                  4       R#   + '       g   i     Lc; i)z5
Another running twistd server causes a system exit.
r   42Nc                     R # r(   ra   pidsigs   &&r3   kill/CheckPIDTests.test_anotherRunning.<locals>.kill  s    r6   r  zAnother twistd server)
r  r  r  rD   r:   r   r   r"   r   r   rQ   r  r  r  r   s   &    r3   test_anotherRunning!CheckPIDTests.test_anotherRunning  su     ++-'31GGDM  	 	

2vt$j(G<-qvv6  s   BB"	c                   V P                  4       p\        VR4      ;_uu_ 4       pVP                  \        \        P
                  ! 4       ^,           4      4       RRR4       R pV P                  \        RV4       \        V4       V P                  \        P                  P                  V4      4       R#   + '       g   i     Le; i)z:
Stale PID file is removed without causing a system exit.
r   Nc                 6    \        \        P                  R 4      hfake)OSErrorerrnoESRCHr  s   &&r3   r  &CheckPIDTests.test_stale.<locals>.kill      %++v..r6   r  )r  r  r  r   r:   getpidrD   r"   r   r   r   )rQ   r  r  r  s   &   r3   
test_staleCheckPIDTests.test_stale  s     ++-'31GGC		a()  	/ 	

2vt$01  s   5B77C	c                   V P                  4       p\        VR4      ;_uu_ 4       pVP                  R4       RRR4       R pV P                  \        RV4       V P                  \        \        V4      pV P                  VP                  R4       V P                  VP                  ^ ,          P                  R4      4       R#   + '       g   i     L; i)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    \        \        P                  R 4      hr  r  r  EBADFr  s   &&r3   r  2CheckPIDTests.test_unexpectedOSError.<locals>.kill  r  r6   r  zCan't check status of PID)r  r  r  rD   r:   r   r   r"   assertIsNotr   r   r   r   r  s   &    r3   test_unexpectedOSError$CheckPIDTests.test_unexpectedOSError  s    
 ++-'31GGFO  	/ 	

2vt$j(G<&q	,,-HIJ  s   CC	ra   N)rT   rU   rV   rW   rX   r   r  r  r  r&  rZ   r[   r\   s   @r3   r   r   r  s*     *372K Kr6   r   c                   0   a  ] tR tRt o RtR tR tRtV tR# )TapFileTestsi  zE
Test twistd-related functionality that requires a tap file on disk.
c                    V P                  4       V n        \        V P                  R4      ;_uu_ 4       p\        P                  ! \
        P                  ! R4      V4       RRR4       R#   + '       g   i     R# ; i)z@
Create a trivial Application and put it in a tap file on disk.
wbHi!N)r  tapfiler  pickledumpr   Application)rQ   r  s   & r3   setUpTapFileTests.setUp  sL     {{}$,,%%KK++E2A6 &%%%s   ,A**A;	c                    \         P                  ! 4       pVP                  RV P                  .4       \	        V4      P                  4       pV P                  \        P                  ! V4      P                  R4       R# )zv
Ensure that the createOrGetApplication call that 'twistd -f foo.tap'
makes will load the Application out of foo.tap.
z-fr,  N)
r   r   r   r-  rh   createOrGetApplicationr   r   IServicer.   )rQ   r   rc   s   &  r3   &test_createOrGetApplicationWithTapFile3TapFileTests.test_createOrGetApplicationWithTapFile  s]    
 %%'T4<<01/7NNP))+6;;UCr6   )r-  N)	rT   rU   rV   rW   rX   r1  r6  rZ   r[   r\   s   @r3   r)  r)    s     7D Dr6   r)  c                   6   a  ] tR tRt o RtR tR tR tRtV t	R# )TestLoggerFactoryi  z0
A logger factory for L{TestApplicationRunner}.
c                    Wn         R # r(   runner)rQ   r<  s   &&r3   r{   TestLoggerFactory.__init__  s    r6   c                    V P                   P                  P                  R4       \        V P                   R4      V P                   n        R# )z3
Save the logging start on the C{runner} instance.
logrc   N)r<  orderr   hasattrhadApplicationLogObserverrb   s   &&r3   rd   TestLoggerFactory.start  s3     	  '07]0S-r6   c                    R# )z
Don't log anything.
Nra   rj   s   &r3   stopTestLoggerFactory.stop      r6   r;  N)
rT   rU   rV   rW   rX   r{   rd   rE  rZ   r[   r\   s   @r3   r9  r9    s     T r6   r9  c                   6   a  ] tR tRt o RtR tR tR tRtV t	R# )TestApplicationRunneri  zT
An ApplicationRunner which tracks the environment in which its methods are
called.
c                r    \         P                  P                  W4       . V n        \	        V 4      V n        R # r(   )r	   ApplicationRunnerr{   r@  r9  r   rP   s   &&r3   r{   TestApplicationRunner.__init__  s)    &&t5
'-r6   c                ^    V P                   P                  R 4       \        V R4      V n        R# )prerc   N)r@  r   rA  hadApplicationPreApplicationrj   s   &r3   rk   $TestApplicationRunner.preApplication  s#    

% ,3D-,H)r6   c                ^    V P                   P                  R 4       \        V R4      V n        R# )postrc   N)r@  r   rA  hadApplicationPostApplicationrj   s   &r3   rn   %TestApplicationRunner.postApplication  s#    

&!-4T=-I*r6   )rS  rO  r   r@  N)
rT   rU   rV   rW   rX   r{   rk   rn   rZ   r[   r\   s   @r3   rI  rI    s!     
.
IJ Jr6   rI  c                      a  ] tR tRt o RtR tR tR tR t]	! ]
! ]RR4      '       * R	4      R
 4       t]	! ]
! ]RR4      '       * R	4      R 4       tR tR tR tR tRtV tR# )ApplicationRunnerTestsi  zJ
Non-platform-specific tests for the platform-specific ApplicationRunner.
c                    \         P                  ! 4       p\        4       V n        R V P                  /Vn        \        4       Vn        R Vn        Wn        R# )test_commandN)	r   r   rK   serviceMakerloadedPluginsobject
subOptionsr   r   r   s   & r3   r1  ApplicationRunnerTests.setUp  sE    %%',. .0A0AB"H*r6   c                r   \        V P                  4      pVP                  4        V P                  V P                  P
                  V P                  P                  R4       V P                  V P                  P                  \        P                  ! VP                  4      P                  ^ ,          R4       R# )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.zPServiceMaker.makeService's result needs to be set as a child of the Application.N)rh   r   runr   rY  rN   r\  r   r5  rc   services)rQ   arunners   & r3   ,test_applicationRunnerGetsCorrectApplicationCApplicationRunnerTests.test_applicationRunnerGetsCorrectApplication  s     ,DKK8%%KK"""	
 	%%W001::1="	
r6   c                .   \        V P                  4      pVP                  4        V P                  VP                  4       V P                  VP                  4       V P                  VP                  4       V P                  VP                  . RO4       R# )zn
Test thet preApplication and postApplication methods are
called by ApplicationRunner.run() when appropriate.
N)rN  r?  rR  )
rI  r   r_  r   rO  r   rS  rB  r   r@  )rQ   r   s   & r3   test_preAndPostApplication1ApplicationRunnerTests.test_preAndPostApplication  sh    
 "$++.	778778334"89r6   c           	       a V P                   P                  V4       . o ! V3R lR\        P                  4      p\	        \
        P                  \
        P                  4       ! V3R lR4      4       pV! 4       p\        \
        P                  V4       \        \
        P                  V4       V! V P                   4      pVP                  4        Wgn
        VP                  4        V P                  SRRRRW#3R	R
.4       R# )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                   L   <a  ] tR tRt o V3R ltV3R ltV3R ltR tRtV t	R# )\ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunneri7  c                *   < SP                  R 4       R# )environmentNr   )rQ   chrootrundirnodaemonr   r  eventss   &&&&&&r3   setupEnvironmentmApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.setupEnvironment8  s    m,r6   c                0   < SP                  R WV34       R# )
privilegesNrl  )rQ   euidrF   r0   rp  s   &&&&r3   shedPrivilegeskApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.shedPrivileges;  s    |T<=r6   c                *   < SP                  R 4       R# )r   Nrl  )rQ   r   	oldstdout	oldstderrrp  s   &&&&r3   startReactoriApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.startReactor>  s    i(r6   c                    R # r(   ra   )rQ   r  s   &&r3   	removePIDfApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.removePIDA      r6   ra   N)
rT   rU   rV   rW   rq  rv  r{  r~  rZ   r[   r]   rp  s   @r3   FakeUnixApplicationRunnerri  7  s     ->) r6   r  c                   j   <a  ] tR tRt o RtRtRtRtRtRt	R t
R tR tV3R ltV3R ltR tR	tV tR# )
NApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeServiceiD  Nc                    R # r(   ra   rz   s   &&r3   setNameVApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setNameM  r  r6   c                    R # r(   ra   )rQ   parents   &&r3   setServiceParent_ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setServiceParentP  r  r6   c                    R # r(   ra   rj   s   &r3   disownServiceParentbApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.disownServiceParentS  r  r6   c                *   < SP                  R 4       R# )privilegedStartServiceNrl  rQ   rp  s   &r3   r  eApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.privilegedStartServiceV  s    67r6   c                *   < SP                  R 4       R# )startServiceNrl  r  s   &r3   r  [ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.startServiceY  s    n-r6   c                    R # r(   ra   rj   s   &r3   stopServiceZApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.stopService\  r  r6   ra   )rT   rU   rV   rW   r  runningr.   processNamerF   r0   r  r  r  r  r  r  rZ   r[   r  s   @r3   FakeServicer  D  sF     FGDKCC8. r6   r  rk  r  rt  Fr  r   N)r   r   r   _SomeApplicationRunnerr   r   r5  IProcessr   rk   rc   rn   r   )	rQ   argvrF   r0   r  r  rc   r<  rp  s	   &&&&    @r3   "_applicationStartsWithConfiguredID9ApplicationRunnerTests._applicationStartsWithConfiguredID*  s     	  &	(E(E 	 
W%%w'7'7	8	 	 
9	4 "mW%%{3W%%{3*4;;7( (uc/		
r6   setuidNz5Platform does not support --uid/--gid twistd options.c                ^    RpRpV P                  R\        V4      R\        V4      .W4       R# )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   )rQ   rF   r0   s   &  r3   .test_applicationStartsWithConfiguredNumericIDsEApplicationRunnerTests.test_applicationStartsWithConfiguredNumericIDss  s2     //c#hS2C	
r6   c                p    RpRpRpRp\        V P                  WW44       V P                  RVRV.W$4       R# )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)rI   rD   r  )rQ   rE   rF   r2   r0   s   &    r3   +test_applicationStartsWithConfiguredNameIDsBApplicationRunnerTests.test_applicationStartsWithConfiguredNameIDs  sD     $**d<//dGU+S	
r6   c                    \        4       p\        P                  ! RRRRRR/4      pVP                  VRR4       V P	                  VP
                  R4       R# )z'
L{startReactor} calls L{reactor.run}.
r#   Fr   debugNz'startReactor did not call reactor.run())DummyReactorr	   rK  r{  r   calledrQ   r   r<  s   &  r3   test_startReactorRunsTheReactor6ApplicationRunnerTests.test_startReactorRunsTheReactor  sR     .&&z9guE
 	GT40(QRr6   c                    \        4       pV P                  \        RV4       \        P                  ! RRRRRR/4      pVP                  RRR4       V P                  VP                  4       R# )z>
L{ApplicationRunner} chooses a reactor if none is specified.
r   r#   Fr   r  N)r  rD   r   r	   rK  r{  r   r  r  s   &  r3   *test_applicationRunnerChoosesReactorIfNoneAApplicationRunnerTests.test_applicationRunnerChoosesReactorIfNone  s_     .

8Y0&&z9guE
 	D$-'r6   c                     ! R R\         4      pV! 4       p\        P                  ! RRRRRR/4      pVP                  VRR4       V P	                  ^VP
                  4       R# )zO
If the reactor exits with a signal, the application runner caches
the signal.
c                   0   a  ] tR tRt o RtR tR tRtV tR# )[ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignali  g
A dummy reactor, providing a C{run} method, and setting the
_exitSignal attribute to a nonzero value.
c                    R# z
Dummy method, does nothing.
Nra   rj   s   &r3   installWakerhApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.installWaker  rG  r6   c                    ^V n         R# )z:
A fake run method setting _exitSignal to a nonzero value
N_exitSignalrj   s   &r3   r_  _ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.run  s     $% r6   r  N	rT   rU   rV   rW   rX   r  r_  rZ   r[   r\   s   @r3   DummyReactorWithSignalr    s     

% %r6   r  r#   Fr   r  N)r   r	   rK  r{  assertEqualsr  )rQ   r  r   r<  s   &   r3   $test_applicationRunnerCapturesSignal;ApplicationRunnerTests.test_applicationRunnerCapturesSignal  sb    	%[ 	%" )*&&z9guE
 	GT40!V//0r6   c                     ! R R4      pV! 4       p\         P                  ! RRRRRR/4      pVP                  VRR4       V P                  RVP                  4       R# )z
The runner sets its _exitSignal instance attribute to None if
the reactor does not implement L{_ISupportsExitSignalCapturing}.
c                   0   a  ] tR tRt o RtR tR tRtV tR# )iApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttributei  r  c                    R# r  ra   rj   s   &r3   r  vApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.installWaker  rG  r6   c                    ^V n         R# )zR
A fake run method setting _exitSignal to a nonzero value
that should be ignored.
Nr  rj   s   &r3   r_  mApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.run  s    
 $% r6   r  Nr  r\   s   @r3   #DummyReactorWithExitSignalAttributer    s     

% %r6   r  r#   Fr   r  N)r	   rK  r{  r  r  )rQ   r  r   r<  s   &   r3   %test_applicationRunnerIgnoresNoSignal<ApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal  s`    	% 	%$ 67&&z9guE
 	GT40$ 2 23r6   )r   rY  )rT   rU   rV   rW   rX   r1  rb  re  r  r   getattrr:   r  r  r  r  r  r  rZ   r[   r\   s   @r3   rV  rV    s     
,
:G
R B$''?
	
 B$''?
	
 	S
(1<4 4r6   rV  c                   z   a  ] tR tRt o Rt]! 4       tR tR tR t	R t
R tR tR	 tR
 tR tR tR tR tRtV tR# )*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                  a  S P                   S n        S P                   S n        S P                   S n        R S n        \
        P                  ! 4       S n        S P                  \
        RV 3R l4       S P                  \
        RV 3R l4       S P                  \
        RV 3R l4       \        \        P                  ! 4       4      S n        S P                  S P                  n        R# )Frm  c                    < \        SR V 4      # )rootsetattrr   rQ   s   &r3   r   BUnixApplicationRunnerSetupEnvironmentTests.setUp.<locals>.<lambda>  s    gdFD.Ir6   chdirc                    < \        SR V 4      # )cwdr  r  s   &r3   r   r    s    WT5$-Gr6   r   c                    < \        SR V 4      # )maskr  )r  rQ   s   &r3   r   r    s    WT64-Hr6   N)unsetr  r  r  daemonr:   r  r  rD   r    r   r   r<  	daemonizerj   s   fr3   r1  0UnixApplicationRunnerSetupEnvironmentTests.setUp  s    JJ	::JJ	99;

2x!IJ

2w GH

2w HI+F,@,@,BC $r6   c                L   a  RS n         S P                  \        RV 3R l4       R# )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                  *   < S P                   ^,           # )   )r  rj   s   r3   r   FUnixApplicationRunnerSetupEnvironmentTests.daemonize.<locals>.<lambda>  s    Ar6   N)r  rD   r:   rQ   r   s   f&r3   r  4UnixApplicationRunnerSetupEnvironmentTests.daemonize  s    
 

2x!56r6   c                |    V P                   P                  RRRRR4       V P                  V P                  R4       R# )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)r<  rq  r   r  rj   s   &r3   test_chroot6UnixApplicationRunnerSetupEnvironmentTests.test_chroot  s2    
 	$$ZdD$GJ/r6   c                    V P                   P                  RRRRR4       V P                  V P                  V P                  4       R# )z
L{UnixApplicationRunner.setupEnvironment} does not change the root of
the filesystem if passed L{None} for the C{chroot} parameter.
Nr  T)r<  rq  r   r  r  rj   s   &r3   test_noChroot8UnixApplicationRunnerSetupEnvironmentTests.test_noChroot!  s4    
 	$$T3dDAdii,r6   c                |    V P                   P                  RRRRR4       V P                  V P                  R4       R# )z
L{UnixApplicationRunner.setupEnvironment} changes the working directory
of the process to the path given for the C{rundir} parameter.
Nr  T)r<  rq  r   r  rj   s   &r3   test_changeWorkingDirectoryFUnixApplicationRunnerSetupEnvironmentTests.test_changeWorkingDirectory)  s2    
 	$$T:tT4H:.r6   c           	         \        \        4       4      ;_uu_ 4        V P                  P                  RRRRR4       RRR4       V P	                  V P
                  4       R#   + '       g   i     L-; i)zw
L{UnixApplicationRunner.setupEnvironment} daemonizes the process if
C{False} is passed for the C{nodaemon} parameter.
Nr  F)r   FakeDaemonizingReactorr<  rq  r   r  rj   s   &r3   test_daemonize9UnixApplicationRunnerSetupEnvironmentTests.test_daemonize1  sK    
 4677KK((sE4F 8$ 87s    A!!A1	c                z    V P                   P                  RRRRR4       V P                  V P                  4       R# )z~
L{UnixApplicationRunner.setupEnvironment} does not daemonize the
process if C{True} is passed for the C{nodaemon} parameter.
Nr  T)r<  rq  r   r  rj   s   &r3   test_noDaemonize;UnixApplicationRunnerSetupEnvironmentTests.test_noDaemonize:  s0    
 	$$T3dDA%r6   c                .   V P                  4       pV P                  P                  RRRRV4       \        VR4      ;_uu_ 4       p\	        VP                  4       4      pRRR4       V P                  XV P                  4       R#   + '       g   i     L.; i)zw
L{UnixApplicationRunner.setupEnvironment} writes the process's PID to
the file specified by the C{pidfile} parameter.
Nr  Trb)r  r<  rq  r  intreadr   r  rQ   r  r  r  s   &   r3   test_nonDaemonPIDFile@UnixApplicationRunnerSetupEnvironmentTests.test_nonDaemonPIDFileB  si    
 ++-$$T3dGD'4  Aaffh-C !dhh' ! s   BB	c           	        V P                  4       p\        \        4       4      ;_uu_ 4        V P                  P	                  RRRRV4       RRR4       \        VR4      ;_uu_ 4       p\        VP                  4       4      pRRR4       V P                  XV P                  ^,           4       R#   + '       g   i     Lk; i  + '       g   i     LH; i)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<  rq  r  r   r  r   r  r  s   &   r3   test_daemonPIDFile=UnixApplicationRunnerSetupEnvironmentTests.test_daemonPIDFileM  s     ++-4677KK((sE4I 8'4  Aaffh-C !dhhl+	 87  s    B/(C/B?	C	c           	         \        \        4       4      ;_uu_ 4        V P                  P                  RRR^{R4       RRR4       V P	                  V P
                  ^{4       R#   + '       g   i     L.; i)zw
L{UnixApplicationRunner.setupEnvironment} changes the process umask to
the value specified by the C{umask} parameter.
Nr  Fr   r  r<  rq  r   r  rj   s   &r3   r   5UnixApplicationRunnerSetupEnvironmentTests.test_umaskZ  sO    
 4677KK((sE3E 8C( 87    A""A2	c                    V P                   P                  RRRRR4       V P                  V P                  V P                  4       R# )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)r<  rq  r   r  r  rj   s   &r3   test_noDaemonizeNoUmaskBUnixApplicationRunnerSetupEnvironmentTests.test_noDaemonizeNoUmaskc  s4     	$$T3dDAdii,r6   c           	         \        \        4       4      ;_uu_ 4        V P                  P                  RRRRR4       RRR4       V P	                  V P
                  ^?4       R#   + '       g   i     L.; i)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  Fr	  rj   s   &r3   test_daemonizedNoUmaskAUnixApplicationRunnerSetupEnvironmentTests.test_daemonizedNoUmaskl  sO     4677KK((sE4F 8E* 87r  )r  r  r  r  r  r<  N)rT   rU   rV   rW   rX   r[  r  r1  r  r  r  r  r  r  r  r  r   r  r  rZ   r[   r\   s   @r3   r  r    sT     ( HE
/70-/%&	(,)-+ +r6   r  c                   H   a  ] tR tRt o RtR tR tR tR tR t	R t
R	tV tR
# )*UnixApplicationRunnerStartApplicationTestsiw  z6
Tests for L{UnixApplicationRunner.startApplication}.
c                  a \         P                  ! 4       pVP                  . R
O4       \        P                  ! R4      p\        V4      V n        . oV3R lp\        P                  ! V P                  P                  4      P                  p\        P                  ! V4      P                  pVP                  4       pVP                  R4       V P                  WE4       V P                  \
        RV4       V P                  \
        RR 4       V P                  \        RR 4       V P                  P!                  V4       V P                  S. RO4       R	# )z
L{UnixApplicationRunner.startApplication} calls
L{UnixApplicationRunner.setupEnvironment} with the chroot, rundir,
nodaemon, umask, and pidfile parameters from the configuration it is
constructed with.
test_setupEnvironmentc                 0   < SP                  WW4V34       R # r(   )extend)rQ   rm  rn  ro  r   r  r   s   &&&&&&r3   fakeSetupEnvironment^UnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.fakeSetupEnvironment  s    KK'BCr6   rQ   rq  rv  c                      R # r(   ra   akws   *,r3   r   RUnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.<lambda>  s    Tr6   startApplicationc                      R # r(   ra   r  s   *,r3   r   r    s    Tr6   N)	
--nodaemonr   0070z--chroot/foo/chrootz--rundir/foo/rundir	--pidfile/foo/pidfile)r#  r$  T8   r&  )r   r   r   r   r0  r    r<  inspect	signaturerq  
parameterscopypopr   rD   r	   r  )rQ   rN   rc   r  setupEnvironmentParametersfakeSetupEnvironmentParametersr   s   &     @r3   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Xr6   c                ~   a  V 3R lpS P                  \        RV4       \        / 4      pVP                  ^#^^64       R# )zN
L{UnixApplicationRunner.shedPrivileges} switches the user ID
of the process.
c                 t   < SP                  V ^4       SP                  V^64       SP                  V^#4       R# )   Nr   )rF   r0   ru  rQ   s   &&&r3   switchUIDPassUUnixApplicationRunnerStartApplicationTests.test_shedPrivileges.<locals>.switchUIDPass  s3    S#&S"%T2&r6   	switchUIDN)rD   r   r    rv  )rQ   r4  r<  s   f  r3   test_shedPrivileges>UnixApplicationRunnerStartApplicationTests.test_shedPrivileges  s6    	'
 	

<m<&r*b#r*r6   c                    R p\        / 4      pV P                  \        RV4       V P                  \        VP
                  ^#^R4      pV P                  VP                  ^4       R# )z
An unexpected L{OSError} when calling
L{twisted.scripts._twistd_unix.shedPrivileges}
terminates the process via L{SystemExit}.
c                 6    \        \        P                  R 4      hr  r"  )rF   r0   ru  s   &&&r3   switchUIDFailZUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesError.<locals>.switchUIDFail  r  r6   r6  N)r    rD   r   r   r   rv  r   r   )rQ   r;  r<  excs   &   r3   test_shedPrivilegesErrorCUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesError  sU    	/ 'r*

<m<
F,A,A2sDQ1%r6   c                  a aa \        S P                  VSVS4       V VV3R lpV V3R lpV V3R lpS P                  \        RV4       S P                  \        RV4       S P                  \        RV4       \        P
                  ! 4       p	V	P                  RR\        S4      R	V.4       \        P                  ! R
4      p
\        V	4      S n        \        V	4      pVP                  V
4       R# )zR
Common code for tests which try to pass the the UID to
L{UnixApplicationRunner}.
c                 P   < SP                  V S4       SP                  VS4       R # r(   r3  )rF   r0   rQ   	wantedGid	wantedUids   &&r3   
initgroupsFUnixApplicationRunnerStartApplicationTests._setUID.<locals>.initgroups  s#    S),S),r6   c                 ,   < SP                  V S4       R # r(   r3  )rF   rQ   rC  s   &r3   r  BUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setuid      S),r6   c                 ,   < SP                  V S4       R # r(   r3  )r0   rQ   rB  s   &r3   setgidBUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setgid  rH  r6   rD  r  rJ  r!  r  r%  r  N)rI   rD   r   r:   r   r   r   r   r   r0  r    r<  r  )rQ   
wantedUserrC  wantedGrouprB  pidFilerD  r  rJ  rN   rc   r<  s   f&f&f&      r3   _setUID2UnixApplicationRunnerStartApplicationTests._setUID  s    
 	$**j)[)T	-	-	- 	

4z2

2x(

2x(&&(7C	NKI	
 ))*AB+G4&w/,r6   c                Z    V P                  RRRRV P                  4       R,           4       R# )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)rO  r  rj   s   &r3   test_setUidWithoutGid@UnixApplicationRunnerStartApplicationTests.test_setUidWithoutGid  s'     	4dkkm6R&R	
r6   c                   \         P                  ! 4       pV P                  RVRRR4       V P                  4       pRP	                  W4      pV P                  W2^ ,          R,          4       V P                  ^\        V4      V4       R# )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.messageN)r:   r;   rO  flushWarningsr   r   len)rQ   
currentUidwarningsShownexpectedWarnings   &   r3   test_setUidSameAsCurrentUidFUnixApplicationRunnerStartApplicationTests.test_setUidSameAsCurrentUid  s|    
 YY[
z9d4U	
 **,--3VJ-K 	 	*:9*EFC.>r6   r;  N)rT   rU   rV   rW   rX   r  r7  r>  rO  rR  r]  rZ   r[   r\   s   @r3   r  r  w  s/     2Yh+&-<
? ?r6   r  c                   0   a  ] tR tRt o RtR tR tRtV tR# )#UnixApplicationRunnerRemovePIDTestsi
  z/
Tests for L{UnixApplicationRunner.removePID}.
c                Z   \        / 4      pV P                  4       p\        P                  ! V4       \        P                  P                  VR4      p\        VR4      P                  4        VP                  V4       V P                  \        P                  P                  V4      4       R# )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   )rQ   r<  r   r  s   &   r3   test_removePID2UnixApplicationRunnerRemovePIDTests.test_removePID  su    
 'r*{{}
D'',,tY/Wc  "!01r6   c                   \        / 4      pVP                  R4       V P                  \        4      pV P	                  \        V4      ^4       V P	                  V^ ,          P                  P                  \        P                  4       R# )zZ
Calling L{UnixApplicationRunner.removePID} with a non-existent filename
logs an OSError.
fakepidN)	r    r~  flushLoggedErrorsr  r   rY  valuer  ENOENT)rQ   r<  errorss   &  r3   test_removePIDErrors8UnixApplicationRunnerRemovePIDTests.test_removePIDErrors  sb    
 'r*#''0Va(..=r6   ra   N)	rT   rU   rV   rW   rX   re  rm  rZ   r[   r\   s   @r3   r`  r`  
  s     2	> 	>r6   r`  c                   <   a  ] tR tRt o RtR tR tR tR tRt	V t
R# )	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                "    R V n         R V n        R# )FN)_beforeDaemonizeCalled_afterDaemonizeCalledrj   s   &r3   r{   "FakeNonDaemonizingReactor.__init__5  s    &+#%*"r6   c                    R V n         R# TN)rr  rj   s   &r3   beforeDaemonize)FakeNonDaemonizingReactor.beforeDaemonize9  s
    &*#r6   c                    R V n         R# rv  )rs  rj   s   &r3   afterDaemonize(FakeNonDaemonizingReactor.afterDaemonize<  s
    %)"r6   c                    R# )z
Skip event registration.
Nra   )rQ   r   r  s   &*,r3   addSystemEventTrigger/FakeNonDaemonizingReactor.addSystemEventTrigger?  rG  r6   )rs  rr  N)rT   rU   rV   rW   rX   r{   rw  rz  r}  rZ   r[   r\   s   @r3   rp  rp  )  s#     	++* r6   rp  c                       ] tR tRtRtRtR# )r  iE  z
A dummy reactor, providing C{beforeDaemonize} and C{afterDaemonize}
methods, announcing this, and logging whether the methods have been called.
ra   N)rT   rU   rV   rW   rX   rZ   ra   r6   r3   r  r  E  s    r6   r  c                   .   a  ] tR tRt o RtRtR tRtV tR# )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                N    V P                   '       d   \        R4      hRV n         R# )zF
A fake run method, checking that it's been called one and only time.
zAlready calledTN)r  RuntimeErrorrj   s   &r3   r_  DummyReactor.runX  s      ;;;/00r6   )r  N)	rT   rU   rV   rW   rX   r  r_  rZ   r[   r\   s   @r3   r  r  M  s      F r6   r  c                     a  ] tR tRt o Rt]! ]'       * R4      R 4       tR t]! ]'       * R4      R 4       t	R t
]! ]'       * R4      R 4       t]! ]'       * R	4      R
 4       t]! ]'       * R	4      R 4       tR tR tR tR tRtV tR# )AppProfilingTestsia  z
Tests for L{app.AppProfiler}.
zprofile module not availablec                   \         P                  ! 4       pV P                  4       VR&   RVR&   \        P                  ! V4      p\        4       pVP                  V4       V P                  VP                  4       \        VR,          4      ;_uu_ 4       pVP                  4       pRRR4       V P                  RX4       V P                  RV4       R#   + '       g   i     L6; i)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  r_  r   r  r  r  r   rQ   r   r   r   r  datas   &     r3   test_profileAppProfilingTests.test_profilef  s     %%' KKMy&z??6*.W'&#$$668D %($/&- %$   CC#	c                    \        4       pV P                  \        R V4      pV! V4      pVP                  4        VP	                  4        VP                  4       pV P                  RV4       V P                  RV4       R# )r   r  z(run)N)r   rD   sysprint_statsrestorer   r   )rQ   
statsClassr#   outr   statsr  s   &&&    r3   
_testStatsAppProfilingTests._testStatsz  sg    j C3/ 7#||~&-gt$r6   c                P   \         P                  ! 4       pV P                  4       VR&   RVR&   RVR&   \        P                  ! V4      p\        4       pVP                  V4       V P                  VP                  4       V P                  \        P                  VR,          4       R# )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  r_  r   r  r  r$   StatsrQ   r   r   r   s   &   r3   test_profileSaveStats'AppProfilingTests.test_profileSaveStats  s~     %%' KKMy&z"{??6*.W'fY&78r6   c                
   \         P                  P                  4       p\        P                  ! 4       pRVR&   \
        P                  ! V4      pR\         P                  R&    V P                  \        VP                  R4       \         P                  P                  4        \         P                  P                  V4       R#   \         P                  P                  4        \         P                  P                  T4       i ; i)zn
When the C{profile} module is not present, L{app.ProfilerRunner.run}
should raise a C{SystemExit} exception.
r#   r   Nr  modulesr+  r   r   r	   r   r   r   r_  clearupdaterQ   savedModulesr   r   s   &   r3   test_withoutProfile%AppProfilingTests.test_withoutProfile  s    
 {{'')%%'&z??6*!%I	-j(,,=KKKK|, KKKK|,   #!C ?Dc                    ! R R\         P                  4      pV P                  \         RV4       \        P                  ! 4       pV P                  4       VR&   RVR&   \        P                  ! V4      p\        4       p\        P                  pV P                  \        VP                  V4       V P                  \        P                  V4       R# )zm
When an error happens during the print of the stats, C{sys.stdout}
should be restored to its initial value.
c                   &   a  ] tR tRt o R tRtV tR# )GAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfilei  c                    \        R 4      h)Boomr  rj   s   &r3   r  SAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfile.print_stats  s    "6**r6   ra   N)rT   rU   rV   rW   r  rZ   r[   r\   s   @r3   ErroneousProfiler    s     + +r6   r  Profiler#   r   N)r#   r  rD   r   r   r  r	   r   r  r  r   r   r  r_  r   )rQ   r  r   r   r   	oldStdouts   &     r3   test_profilePrintStatsError-AppProfilingTests.test_profilePrintStatsError  s    	+w 	+ 	

7I'78%%' KKMy&z??6*.JJ	,g>cjj),r6   zcProfile module not availablec                   \         P                  ! 4       pV P                  4       VR&   RVR&   \        P                  ! V4      p\        4       pVP                  V4       V P                  VP                  4       \        VR,          4      ;_uu_ 4       pVP                  4       pRRR4       V P                  RX4       V P                  RV4       R#   + '       g   i     L6; i)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   Nr_  r  r  r  s   &     r3   test_cProfileAppProfilingTests.test_cProfile  s     %%' KKMy'z??6*.W'&#$$668D %eT"&- %$r  c                P   \         P                  ! 4       pV P                  4       VR&   RVR&   RVR&   \        P                  ! V4      p\        4       pVP                  V4       V P                  VP                  4       V P                  \        P                  VR,          4       R# )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   &   r3   test_cProfileSaveStats(AppProfilingTests.test_cProfileSaveStats  s~     %%' KKMy'z"{??6*.W'fY&78r6   c                
   \         P                  P                  4       pR\         P                  R&   \        P                  ! 4       pRVR&   \
        P                  ! V4      p V P                  \        VP                  R4       \         P                  P                  4        \         P                  P                  V4       R#   \         P                  P                  4        \         P                  P                  T4       i ; i)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   &   r3   test_withoutCProfile&AppProfilingTests.test_withoutCProfile  s     {{'')"&J%%''z??6*	-j(,,=KKKK|, KKKK|,r  c                    \         P                  ! 4       pV P                  4       VR&   RVR&   V P                  \        \
        P                  V4      pV P                  \        V4      R4       R# )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   )rQ   r   errors   &  r3   test_unknownProfiler&AppProfilingTests.test_unknownProfiler  sY    
 %%' KKMy%z!!*coovFU%HIr6   c                j    \         P                  ! / 4      pV P                  VP                  R4       R# )zE
L{app.Profiler} defaults to the cprofile profiler if not specified.
cprofileNr	   r   r   r   rQ   r   s   & r3   test_defaultProfiler&AppProfilingTests.test_defaultProfiler  s(     ??2&**J7r6   c                n    \         P                  ! RR/4      pV P                  VP                  R4       R# )zM
The case of the profiler name passed to L{app.AppProfiler} is not
relevant.
r   CprOfiler  Nr  r  s   & r3   test_profilerNameCaseInsentive0AppProfilingTests.test_profilerNameCaseInsentive  s-    
 ??J
#;<**J7r6   ra   N)rT   rU   rV   rW   rX   r   r#   r  r  r  r  r  r%   r  r  r  r  r  r  rZ   r[   r\   s   @r3   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8 8r6   r  c                X   aa . o\         P                  oVV3R lpV ! \         RV4       S# )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                 >   < SP                  V 4       S! V .VO5/ VB # r(   rl  )logFiler   kwargslogFilesoldFileLogObservers   &*,r3   observer+_patchTextFileLogObserver.<locals>.observer(  s$     !';D;F;;r6   textFileLogObserver)r   r  )rD   r  r  r  s   & @@r3   _patchTextFileLogObserverr    s/     H33< 
&'2Or6   c                T   a . o ! V3R lR4      pV P                  \        RV4       S# )zi
Make fake syslog, and return list to which prefix and then log
messages will be appended if it is used.
c                   :   <a  ] tR tRt o V3R ltV3R ltRtV tR# )(_setupSyslog.<locals>.fakesyslogobserveri7  c                *   < SP                  V4       R # r(   rl  )rQ   prefixlogMessagess   &&r3   r{   1_setupSyslog.<locals>.fakesyslogobserver.__init__8  s    v&r6   c                *   < SP                  V4       R # r(   rl  )rQ   	eventDictr  s   &&r3   emit-_setupSyslog.<locals>.fakesyslogobserver.emit;  s    y)r6   ra   N)rT   rU   rV   rW   r{   r  rZ   r[   )r]   r  s   @r3   fakesyslogobserverr  7  s     	'	* 	*r6   r  SyslogObserver)rD   syslog)testCaser  r  s   & @r3   _setupSyslogr  0  s.    
 K* * NN6+-?@r6   c                      a  ] tR tRt o RtR tR tR tR tR t	R t
/ ]P                  3R	 ltR
 tR tR tR t]! ]'       * R4      ]! ]'       * R4      R 4       4       tR tR tR tR tR tR tRtV tR# )AppLoggerTestsiB  zv
Tests for L{app.AppLogger}.

@ivar observers: list of observers installed during the tests.
@type observers: C{list}
c                P   a  . S n         V 3R lpS P                  \        RV4       R# )zp
Override L{globaLogBeginner.beginLoggingTo} so that we can trace the
observers installed in C{self.observers}.
c                 |   < V  F4  pSP                   P                  V4       \        P                  ! V4       K6  	  R # r(   )	observersr   r   addObserver)r  r  rQ   s   & r3   beginLoggingTo,AppLoggerTests.setUp.<locals>.beginLoggingToQ  s-    %%%h/"..x8 &r6   r  N)r  rD   r   )rQ   r  s   f r3   r1  AppLoggerTests.setUpJ  s%    
 	9
 	

$&6Gr6   c                X    V P                    F  p\        P                  ! V4       K  	  R# )z!
Remove all installed observers.
N)r  r   removeObserverrQ   r  s   & r3   tearDownAppLoggerTests.tearDownX  s      H--h7 'r6   c                H    \        \        4       ! R R4      4       pV! 4       # )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                   *   a  ] tR tRt o . tR tRtV tR# )2AppLoggerTests._makeObserver.<locals>.TestObserverig  c                <    V P                   P                  V4       R # r(   )_logsr   )rQ   events   &&r3   __call__;AppLoggerTests._makeObserver.<locals>.TestObserver.__call__k  s    

!!%(r6   ra   N)rT   rU   rV   rW   r  r  rZ   r[   r\   s   @r3   TestObserverr  g  s     E) )r6   r  )r   r   )rQ   r  s   & r3   _makeObserverAppLoggerTests._makeObserver_  s*     
\	"	) 	) 
#	) ~r6   c                    V P                  V P                  V.4       V P                  RVP                  ^ ,          R,          4       V P                  RVP                  ^,          R,          4       R# )zw
Ensure that initial C{twistd} logs are written to logs.

@param observer: The observer made by L{self._makeObserver).
starting up
log_formatzreactor classN)r   r  r   r  r  s   &&r3   _checkObserverAppLoggerTests._checkObserverp  sR     	(4mX^^A%6|%DEox~~a'8'FGr6   c                   a \         P                  ! / 4      pV P                  4       oV3R lVn        VP                  ! \        4       4       V P                  S4       R# )z|
L{app.AppLogger.start} calls L{globalLogBeginner.addObserver}, and then
writes some messages about twistd and the reactor.
c                     < S # r(   ra   r  s   r3   r   +AppLoggerTests.test_start.<locals>.<lambda>  s    r6   N)r	   	AppLoggerr  _getLogObserverrd   r   r  )rQ   r   r  s   & @r3   
test_startAppLoggerTests.test_startz  sE    
 r"%%'!1]_%H%r6   c                    \        4       pV P                  4       pVP                  \        V4       \        P
                  ! / 4      pVP                  ! V4       V P                  V4       R# )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  )rQ   rc   r  r   s   &   r3   $test_startUsesApplicationLogObserver3AppLoggerTests.test_startUsesApplicationLogObserver  sQ     $o%%'  x8r"[!H%r6   c                   a V P                  4       oRV3R l/pVP                  V4       V! V4      pVP                  ! V4       S# )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                     < S # r(   ra   r  s   r3   r   7AppLoggerTests._setupConfiguredLogger.<locals>.<lambda>  s    Xr6   )r  r  rd   )rQ   rc   extraLogArgs	appLoggerlogArgsr   r  s   &&&&  @r3   _setupConfiguredLogger%AppLoggerTests._setupConfiguredLogger  sE    " %%'-.|$7#[!r6   c                Z    \        4       pV P                  V P                  V4      4       R# )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   & r3   #test_startUsesConfiguredLogObserver2AppLoggerTests.test_startUsesConfiguredLogObserver  s$     $oD77DEr6   c                    V P                  4       p\        4       pVP                  \        V4       V P	                  V P                  V4      4       V P                  VP                  . 4       R# )zS
C{--logger} takes precedence over a L{ILogObserver} component set on
Application.
N)r  r   r  r   r  r  r   r  )rQ   r  rc   s   &  r3   (test_configuredLogObserverBeatsComponent7AppLoggerTests.test_configuredLogObserverBeatsComponent  sV    
 %%'#o  x8D77DE,r6   c                    . p\        4       pVP                  \        VP                  4       V P	                  V P                  V4      4       V P                  V. 4       R# )zY
C{--logger} takes precedence over a L{LegacyILogObserver} component
set on Application.
N)r   r  LegacyILogObserverr   r  r  r   )rQ   nonlogsrc   s   &  r3   .test_configuredLogObserverBeatsLegacyComponent=AppLoggerTests.test_configuredLogObserverBeatsLegacyComponent  sN    
 #o  !3W^^DD77DE"%r6   c                @   . pV P                  4       p\        4       pVP                  \        V4       VP                  \        VP
                  4       \        P                  ! / 4      pVP                  ! V4       V P                  V4       V P                  V. 4       R# )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   )rQ   r   r  rc   r   s   &    r3   .test_loggerComponentBeatsLegacyLoggerComponent=AppLoggerTests.test_loggerComponentBeatsLegacyLoggerComponent  s{    
 %%'#o  x8  !3W^^Dr"[!H%"%r6   r   zsyslog not availablec                    \        V 4      p\        4       pV P                  V P                  VRR/\        4      4       V P                  V. 4       R# )zH
C{--logger} takes precedence over a C{--syslog} command line
argument.
r  TN)r  r   r  r  r!   r   )rQ   logsrc   s   &  r3   %test_configuredLogObserverBeatsSyslog4AppLoggerTests.test_configuredLogObserverBeatsSyslog  sL     D!#o''h5E}U	
 	r"r6   c                    \        4       pV P                  4       pV P                  V P                  VRR/4      4       V P	                  \
        P                  P                  V4      4       R# )zI
C{--logger} takes precedence over a C{--logfile} command line
argument.
logfiler   N)r   r  r  r  r   r:   r   r   )rQ   rc   r   s   &  r3   &test_configuredLogObserverBeatsLogfile5AppLoggerTests.test_configuredLogObserverBeatsLogfile  sV    
 $o{{}''i5HI	
 	-.r6   c                   \         P                  ! RR/4      p\        V P                  4      pVP                  ! 4        V P                  \        V4      ^4       V P                  V^ ,          \        P                  4       \         P                  ! RR/4      pVP                  ! 4        V P                  \        V4      ^4       V P                  V^,          \        P                  4       R# )zz
When logfile is empty or set to C{-}, L{app.AppLogger._getLogObserver}
returns a log observer pointing at C{sys.stdout}.
r+  - N)
r	   r  r  rD   r	  r   rY  r   r  r   )rQ   r   r  s   &  r3   test_getLogObserverStdout(AppLoggerTests.test_getLogObserverStdout  s    
 	3/0,TZZ8 X*hqk3::.	2/ X*hqk3::.r6   c                   \        V P                  4      pV P                  4       p\        P                  ! RV/4      pVP                  4       pV P                  VP                  P                  4       V P                  \        V4      ^4       V P                  V^ ,          P                  \        P                  P                  V4      4       R# )z}
When passing the C{logfile} option, L{app.AppLogger._getLogObserver}
returns a log observer pointing at the specified path.
r+  N)r  rD   r  r	   r  r	  
addCleanup_outFilerd  r   rY  r   r:   abspath)rQ   r  filenamesutr  s   &    r3   test_getLogObserverFile&AppLoggerTests.test_getLogObserverFile  s    
 -TZZ8;;=mmY12&&())//0X*!))277??8+DEr6   c                X  a . o\        4       pV3R lpV P                  \        RV4       \        P                  ! / 4      pWn        VP                  ! 4        V P                  SV.4       VP                  ! 4        V P                  SV.4       V P                  VP
                  4       R# )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                 *   < SP                  V 4       R # r(   rl  )r  removeds   &r3   remove(AppLoggerTests.test_stop.<locals>.remove   s    NN8$r6   r  N)	r[  rD   r   r	   r  	_observerrE  r   r   )rQ   r  r>  r   r=  s   &   @r3   	test_stopAppLoggerTests.test_stop  s     8	% 	

%'7@r"#8*-8*-&**+r6   c                v  aa . o\         P                  ! / 4      p\        \        4       ! V3R lR4      4       oV3R lVn        VP
                  ! \        4       4       V P                  R\        S^ ,          4      4       V P                  V P                  .4      pV P                  \        V4      ^ V4       R# )z\
L{app.AppLogger} using a legacy logger observer still works, wrapping
it in a compat shim.
c                   2   <a  ] tR tRt o RtV3R ltRtV tR# );AppLoggerTests.test_legacyObservers.<locals>.LoggerObserveri4  z@
An observer which implements the legacy L{LegacyILogObserver}.
c                *   < SP                  V4       R# )z
Add C{x} to the logs list.
Nrl  )rQ   xr'  s   &&r3   r  DAppLoggerTests.test_legacyObservers.<locals>.LoggerObserver.__call__:  s     Ar6   ra   N)rT   rU   rV   rW   rX   r  rZ   r[   )r]   r'  s   @r3   LoggerObserverrE  4  s      r6   rI  c                     < S ! 4       # r(   ra   )rI  s   r3   r   5AppLoggerTests.test_legacyObservers.<locals>.<lambda>@  s    .*:r6   r   N)r	   r  r   r  _observerFactoryrd   r   r   r   rX  test_legacyObserversr   rY  )rQ   r   warningsrI  r'  s   &  @@r3   rM  #AppLoggerTests.test_legacyObservers,  s    
 r"	'	(		 		 
)		 #;]_%m%6tAw%?@%%t'@'@&ABX84r6   c                v  a . o\         P                  ! / 4      pV3R lVn        VP                  ! \	        4       4       V P                  R\        S^ ,          4      4       V P                  V P                  .4      pV P                  V^ ,          R,          R4       V P                  \        V4      ^V4       R# )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                     < S P                   # r(   rl  )r'  s   r3   r   AAppLoggerTests.test_unmarkedObserversDeprecated.<locals>.<lambda>O  s	    r6   r   rW  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.N)r	   r  r	  rd   r   r   r   rX   test_unmarkedObserversDeprecatedr   rY  )rQ   r   rN  r'  s   &  @r3   rS  /AppLoggerTests.test_unmarkedObserversDeprecatedG  s     r"!4]_%m%6tAw%?@%%t'L'L&MNQK	"0	
 	X84r6   )r  N)rT   rU   rV   rW   rX   r1  r  r  r  r
  r  r	   r  r  r  r  r!  r$  r   r   r  r(  r,  r1  r9  rA  rM  rS  rZ   r[   r\   s   @r3   r  r  B  s     H8"H	&& )+cmm0F	-	&&" 9:J./
# 0 ;
#
//&F,*565 5r6   r  c                   p   a  ] tR tRt o RtR tR tR tR tR t	R t
]! ]'       * R	4      R
 4       tRtV tR# )UnixAppLoggerTestsie  zg
Tests for L{UnixAppLogger}.

@ivar signals: list of signal handlers installed.
@type signals: C{list}
c                P   a  . S n         V 3R lpS P                  \        RV4       R# )z[
Fake C{signal.signal} for not installing the handlers but saving them
in C{self.signals}.
c                 @   < SP                   P                  W34       R # r(   )signalsr   )r  r  rQ   s   &&r3   
fakeSignal,UnixAppLoggerTests.setUp.<locals>.fakeSignalu  s    LL)r6   signalN)rY  rD   r\  )rQ   rZ  s   f r3   r1  UnixAppLoggerTests.setUpn  s#    
 	* 	

68Z0r6   c                   \        V P                  4      p\        RRRR/4      pVP                  ! 4        V P	                  \        V4      ^4       V P                  V^ ,          \        P                  4       \        RRRR/4      pVP                  ! 4        V P	                  \        V4      ^4       V P                  V^,          \        P                  4       R# )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+  r/  ro  Tr0  N)	r  rD   r!   r	  r   rY  r   r  r   )rQ   r  r   s   &  r3   r1  ,UnixAppLoggerTests.test_getLogObserverStdoutz  s     -TZZ8	3
DAB X*hqk3::.	2z4@A X*hqk3::.r6   c                    \        RRRR/4      pV P                  \        VP                  4      pV P	                  \        V4      R4       R# )zg
When daemonized and C{logfile} is set to C{-},
L{UnixAppLogger._getLogObserver} raises C{SystemExit}.
r+  r/  ro  Fz&Daemons cannot log to stdout, exiting!N)r!   r   r   r	  r   r   )rQ   r   r  s   &  r3   test_getLogObserverStdoutDaemon2UnixAppLoggerTests.test_getLogObserverStdoutDaemon  sD    
 	3
EBC!!*f.D.DEU%MNr6   c                  a \        V P                  4      pV P                  4       p\        RV/4      pVP	                  4       pV P                  VP                  P                  4       V P                  \        V4      ^4       V P                  V^ ,          P                  \        P                  P                  V4      4       V P                  \        V P                  4      ^4       V P                  V P                  ^ ,          ^ ,          \        P                  4       \!        4       oV3R lpWQ^ ,          n        V P                  ^ ,          ^,          pV! RR4       S# )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.
r+  c                  *   < S P                  R 4       R # r(   )callback)ds   r3   rotate:UnixAppLoggerTests.test_getLogObserverFile.<locals>.rotate  s    JJtr6   N)r  rD   r  r!   r	  r4  r5  rd  r   rY  r   r:   r6  rY  r\  SIGUSR1r   rg  )rQ   r  r7  r8  r  rg  	rotateLogrf  s   &      @r3   r9  *UnixAppLoggerTests.test_getLogObserverFile  s    -TZZ8;;=Y12&&())//0X*!))277??8+DET\\*A.a+V^^<J	 $LLOA&	$r6   c                  a  V 3R lpS P                  \        RV4       S P                  4       p\        RV/4      pVP	                  4       pS P                  VP                  P                  4       S P                  S P                  . 4       R# )za
If a signal handler is already installed,
L{UnixAppLogger._getLogObserver} doesn't override it.
c                 X   < SP                  V \        P                  4       \        4       # r(   )r   r\  ri  r[  )r  rQ   s   &r3   fakeGetSignalVUnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandler.<locals>.fakeGetSignal  s    S&..18Or6   	getsignalr+  N)
rD   r\  r  r!   r	  r4  r5  rd  r   rY  )rQ   rn  r7  r8  r  s   f    r3   ,test_getLogObserverDontOverrideSignalHandler?UnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandler  sn    	 	

6;6;;=Y12&&())//0r*r6   c                p   \        V P                  4      p\        RRRR/4      pVP                  ! 4       pV P	                  VP
                  P                  4       V P                  \        V4      ^4       V P                  V^ ,          P                  \        P                  P                  R4      4       R# )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+  r0  ro  Fz
twistd.logN)r  rD   r!   r	  r4  r5  rd  r   rY  r   r:   r6  )rQ   r  r   r  s   &   r3   test_getLogObserverDefaultFile1UnixAppLoggerTests.test_getLogObserverDefaultFile  s     -TZZ8	2z5AB))+))//0X*!))277??<+HIr6   r   c                    \        V 4      p\        RRRR/4      pVP                  ! 4       pV P                  VR.4       V! RR/4       V P                  VRRR/.4       R# )zz
If C{syslog} is set to C{True}, L{UnixAppLogger._getLogObserver} starts
a L{syslog.SyslogObserver} with given C{prefix}.
r  Tr  ztest-prefixr  bN)r  r!   r	  r   )rQ   r'  r   r  s   &   r3   test_getLogObserverSyslog,UnixAppLoggerTests.test_getLogObserverSyslog  sf     D!$-HI))+/#sSz:;r6   )rY  N)rT   rU   rV   rW   rX   r1  r1  ra  r9  rq  rt  r   r   rx  rZ   r[   r\   s   @r3   rV  rV  e  sI     
1/$O<+&J 9:
< ;
<r6   rV  z!twistd unix support not availablec                      a  ] tR tRt o RtR tR tR tR tR t	R t
R	 tR
 tR tR tR tR tR tR tR tR tRtV tR# )DaemonizeTestsi  z@
Tests for L{_twistd_unix.UnixApplicationRunner} daemonization.
c                   \        4       V n        \        P                  ! 4       V n        V P                  \        R V P                  4       \        P                  V P                  4      V n        \        P                  ! R4      V P                  n        \        P                  V P                  n        \        P                  V P                  n        R V P                  n        R# )r:   r,  c                      R # r(   ra   )r   s   *r3   r   &DaemonizeTests.setUp.<locals>.<lambda>  s    r6   N)r   mockosr   r   r   rD   r   r    r<  r   r0  rc   r  r   ry  stderrrz  r{  rj   s   &r3   r1  DaemonizeTests.setUp  s    h**,

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

 #

#5 r6   c                H   \        \        4       4      ;_uu_ 4        V P                  P                  4        RRR4       V P	                  V P
                  P                  . RO4       V P	                  V P
                  P                  RR.4       R#   + '       g   i     Lb; i)z_
When double fork succeeded in C{daemonize}, the child process writes
B{0} to the status pipe.
N)r  r  r   ?   forkTsetsidr  )r  r     0unlinkz
twistd.pid)r   r  r<  rn   r   r  actionsclosedrj   s   &r3   test_successDaemonizeTests.test_success  sq    
 4677KK'') 8KK	
 	++b"X6 87s   BB!	c                   RV P                   n        RV P                   n        \        \	        4       4      ;_uu_ 4        V P                  \        V P                  P                  4       RRR4       V P                  V P                   P                  . RO4       V P                  V P                   P                  R.4       R#   + '       g   i     La; i)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  r  d   exit    r  )r  childreadDatar   r  r   SystemErrorr<  rn   r   r  r  rj   s   &r3   test_successInParent#DaemonizeTests.test_successInParent  s    
 "#4677k4;;+F+FG 8KK
	
 	++bT2 87s   +CC	c                  a . oV3R lpWP                   n        \        \        4       4      ;_uu_ 4        V P                  P                  4        RRR4       V P                  V P                   P                  . RO4       V P                  V P                   P                  RR.4       V P                  RR.S4       R#   + '       g   i     Lv; i)zj
If the C{os.write} call to the status pipe raises an B{EINTR} error,
the process child retries to write.
c                 ~   < SP                  W34       \        S4      ^8X  d   \        \        P                  4      hR# )r  Nr   rY  r  r  EINTR)fdr  writtens   &&r3   raisingWrite6DaemonizeTests.test_successEINTR.<locals>.raisingWrite$  s1    NNB:&7|q ekk** !r6   N)r  r  r  r  r  r  r  r  )r  r  )	r  r  r   r  r<  rn   r   r  r  )rQ   r  r  s   & @r3   test_successEINTR DaemonizeTests.test_successEINTR  s    
 	+
 )4677KK'') 8KK
	
 	++b"X6*j17; 87s   B>>C	c                  a . oV3R lpWP                   n        RV P                   n        \        \	        4       4      ;_uu_ 4        V P                  \        V P                  P                  4       RRR4       V P                  V P                   P                  . RO4       V P                  V P                   P                  R.4       V P                  RR.S4       R#   + '       g   i     Lu; i)zg
If the C{os.read} call on the status pipe raises an B{EINTR} error, the
parent child retries to read.
c                 ~   < SP                  W34       \        S4      ^8X  d   \        \        P                  4      hR# )r  r  r  )r  sizer  s   &&r3   raisingRead=DaemonizeTests.test_successInParentEINTR.<locals>.raisingReadA  s.    KK
#4yA~ekk**r6   FN)r  r  r  r  r  r  )r  r  )r  r  r  r   r  r   r  r<  rn   r   r  r  )rQ   r  r  s   & @r3   test_successInParentEINTR(DaemonizeTests.test_successInParentEINTR:  s    
 	 '!4677k4;;+F+FG 8KK		
 	++bT2)Y/6 87s   +CC.	c                
  a  ! V3R lR\         P                  4      pV! 4       pVP                  V P                  P                  4       \        \        4       4      ;_uu_ 4        V P                  \        V P                  P                  4       RRR4       V P                  V P                  P                  RRRRRRR	V3R
.4       V P                  V P                  P                  RR	.4       R#   + '       g   i     Lj; i)z
Assert L{UnixApplicationRunner.postApplication} writes
C{reported} to its status pipe if the service raises an
exception whose message is C{raised}.
c                   .   <a  ] tR tRt o V3R ltRtV tR# )6DaemonizeTests.assertErrorWritten.<locals>.FakeServicei_  c                   < \        S4      hr(   r  )rQ   raiseds   &r3   r  CDaemonizeTests.assertErrorWritten.<locals>.FakeService.startService`  s    "6**r6   ra   N)rT   rU   rV   rW   r  rZ   r[   )r]   r  s   @r3   r  r  _  s     + +r6   r  Nr  r  r  r  r  r  r  r  )r   rO   r  r<  rc   r   r  r   r  rn   r   r  r  r  )rQ   r  reportedr  errorServices   &f&  r3   assertErrorWritten!DaemonizeTests.assertErrorWrittenX  s    	+'// 	+ #}%%dkk&=&=>4677lDKK,G,GH 8KK "h'(	
 	++b"X6 87s   %+C22D	c                ,    V P                  RRR7       R# )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  rj   s   &r3   
test_errorDaemonizeTests.test_errorv  s    
 	'2W 	  	
r6   c                ,    V P                  RRR7       R# )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  rj   s   &r3   test_unicodeError DaemonizeTests.test_unicodeError  s     	x:TUr6   c                &   RV P                   n        WP                   n        \        4       pV P	                  \
        RV4       \        \        4       4      ;_uu_ 4        V P                  \        V P                  P                  4       RRR4       V P                  VP                  4       V4       V P                  V P                   P                  V4       V P                  V P                   P                  R.4       R#   + '       g   i     L; i)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   rD   r  r   r  r   r  r<  rn   r   r   r  r  )rQ   r  errorMessagemockOSActionserrorIOs   &&&& r3   assertErrorInParentBehavior*DaemonizeTests.assertErrorInParentBehavior  s     "'*

3g.4677k4;;+F+FG 8))+\:,,m<++bT2	 87s   +D  D	c                2    V P                  RR. ROR7       R# )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  Nr  r  r  r  )r  r  r  r  rj   s   &r3   test_errorInParent!DaemonizeTests.test_errorInParent  s%     	((8B 	) 	
r6   c                2    V P                  RR. ROR7       R# )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  Nr  r  rj   s   &r3   test_nonASCIIErrorInParent)DaemonizeTests.test_nonASCIIErrorInParent  s%     	(()B 	) 	
r6   c                v    RpRP                  R4      pV P                  VRP                  V4      . ROR7       R# )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.
zb'RuntimeError: {}'zHAn error has occurred: {}
Please look at log file for more information.
r  Nd   1 RuntimeError: \u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022zb\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022r  )r   r  )rQ   truncatedMessagereportedMessages   &  r3   &test_errorInParentWithTruncatedUnicode5DaemonizeTests.test_errorInParentWithTruncatedUnicode  sL     A 066G((%BBH&#C 	) 	
r6   c                ,    V P                  RRR7       R# )zc
If an error occurs during daemonization and its message is too
long, it's truncated by the child.
r  Nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsd   1 RuntimeError: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr  rj   s   &r3   test_errorMessageTruncated)DaemonizeTests.test_errorMessageTruncated  s    
 	'F 	  	
r6   c                ,    V P                  RRR7       R# )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.
r  NuZ   ••••••••••••••••••••••••••••••r  r  rj   s   &r3   !test_unicodeErrorMessageTruncated0DaemonizeTests.test_unicodeErrorMessageTruncated  s     	 : 	  	
r6   c                    \        4       pV P                  P                  V4       V P                  VP                  4       V P                  VP
                  4       R# )z
C{daemonize} indeed calls L{IReactorDaemonize.beforeDaemonize} and
L{IReactorDaemonize.afterDaemonize} if the reactor implements
L{IReactorDaemonize}.
N)r  r<  r  r   rr  rs  r  s   & r3   test_hooksCalledDaemonizeTests.test_hooksCalled  sB     )*g&667556r6   c                    \        4       pV P                  P                  V4       V P                  VP                  4       V P                  VP
                  4       R# )z
C{daemonize} does NOT call L{IReactorDaemonize.beforeDaemonize} or
L{IReactorDaemonize.afterDaemonize} if the reactor does NOT implement
L{IReactorDaemonize}.
N)rp  r<  r  r   rr  rs  r  s   & r3   test_hooksNotCalled"DaemonizeTests.test_hooksNotCalled   sF     ,-g&778667r6   )r   r  r<  N)rT   rU   rV   rW   rX   r1  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rZ   r[   r\   s   @r3   r{  r{    s`     67*3,<:7<7<
V3"
,
,
:
	
	7	8 	8r6   r{  c                   X   a  ] tR tRt o Rt]R 4       t]P                  R 4       tRtV t	R# )SignalCapturingMemoryReactori  z}
MemoryReactor that implements the _ISupportsExitSignalCapturing interface,
all other operations identical to MemoryReactor.
c                    V P                   # r(   _valrj   s   &r3   r  (SignalCapturingMemoryReactor._exitSignal  s    yyr6   c                    Wn         R # r(   r  )rQ   vals   &&r3   r  r    s    	r6   r  N)
rT   rU   rV   rW   rX   propertyr  setterrZ   r[   r\   s   @r3   r  r    s8     
    r6   r  c                   F   a a ] tR tRt oRt]tV 3R ltR tR t	Rt
VtV ;t# )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                4   < \         SV `  V4       R V n        R # r(   )superr{   _signalValue)rQ   r   	__class__s   &&r3   r{   (StubApplicationRunnerWithSignal.__init__'  s      r6   c                    R# )z
Does nothing.
Nra   rj   s   &r3   rk   .StubApplicationRunnerWithSignal.preApplication+  rG  r6   c                    \        4       pV P                  Vn        V P                  V\        P
                  \        P                  4       R# )zH
Instantiate a SignalCapturingMemoryReactor and start it
in the runner.
N)r  r  r  r{  r  r   r  r  s   & r3   rn   /StubApplicationRunnerWithSignal.postApplication0  s4    
 /0"//'3::szz:r6   )r  )rT   rU   rV   rW   rX   r_   rp   r{   rk   rn   rZ   r[   __classcell__)r  r]   s   @@r3   r  r    s%      &M!
; ;r6   r  c                   a  V 3R lpV# )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                ,   < \        V 4      pSVn        V# )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   r<  signums   & r3   stubApplicationRunnerFactoryIstubApplicationRunnerFactoryCreator.<locals>.stubApplicationRunnerFactoryG  s     18$r6   ra   )r  r  s   f r3   #stubApplicationRunnerFactoryCreatorr  :  s      ('r6   c                   <   a  ] tR tRt o RtR tR tR tR tRt	V t
R# )	ExitWithSignalTestsiZ  z7
Tests for L{twisted.application.app._exitWithSignal}.
c                  a  \         P                  ! 4       S n        R\        4       /S P                  n        \        4       S P                  n        RS P                  n        RR.S n        V 3R lpS P                  \        RV4       R# )z=
Set up the server options and a fake for use by test cases.
rX  Nc                D   < V SP                   ^ &   VSP                   ^&   R# )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.
N)fakeKillArgs)r  r  rQ   s   &&r3   fakeKill+ExitWithSignalTests.setUp.<locals>.fakeKillj  s%     $'Da #&Da r6   r  )r   r   r   rK   rZ  r[  r\  r   r  rD   r:   )rQ   r  s   f r3   r1  ExitWithSignalTests.setUp`  sg     **,%35E5G$H!!'!/!4L		' 	

2vx(r6   c                  a RR.oV3R lpV P                  \        RV4       \        P                  ! \        P                  4       V P                  S^ ,          \        P                  4       V P                  S^,          \        P                  4       V P                  V P                  ^ ,          \        P                  ! 4       4       V P                  V P                  ^,          \        P                  4       R# )z
exitWithSignal replaces the existing signal handler with the default
handler and sends the replaced signal to the current process.
Nc                    < V S^ &   VS^&   R# )r  Nra   )r  handlerfakeSignalArgss   &&r3   fake_signal<ExitWithSignalTests.test_exitWithSignal.<locals>.fake_signal  s     #N1 'N1r6   r\  )
rD   r\  r	   _exitWithSignalSIGINTr  SIG_DFLr  r:   r  )rQ   r  r  s   & @r3   test_exitWithSignal'ExitWithSignalTests.test_exitWithSignalw  s     	( 	

68[1FMM*.+V]];.+V^^<$++A.		<$++A.>r6   c                   V P                  \        R\        R4      4       \        P                  ! V P                  4       V P                  V P                  ^ ,          4       V P                  V P                  ^,          4       R# )zJ
_exitWithSignal is not called if the runner does not exit with a
signal.
r  N)rD   r   r  runAppr   r   r  rj   s   &r3   test_normalExit#ExitWithSignalTests.test_normalExit  sc    
 	

,.QRV.W	
 	dkk"$++A./$++A./r6   c                p   V P                  \        R\        \        P                  4      4       \        P
                  ! V P                  4       V P                  V P                  ^ ,          \        P                  ! 4       4       V P                  V P                  ^,          \        P                  4       R# )z@
_exitWithSignal is called when the runner exits with a signal.
r  N)rD   r   r  r\  r  r  r   r  r  r:   r  rj   s   &r3   test_runnerExitsWithSignal.ExitWithSignalTests.test_runnerExitsWithSignal  st     	

$/>	

 	dkk"$++A.		<$++A.>r6   )r   r  N)rT   rU   rV   rW   rX   r1  r  r  r  rZ   r[   r\   s   @r3   r  r  Z  s#     ).?(
0? ?r6   r  )hrX   r  r(  r:   r.  r\  r  r<   _grpr9   _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%   rI   rK   r  r_   r  rh   rr   r   r)  r9  rK  rI  rV  r  r  r`  rp  r  r  r  r  r  r  rV  r{  r  r  r  r  ra   r6   r3   <module>r4     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+