
    \d*                        d Z ddlZddlZddlZddlZddlZddlZ	 ddlZddl	Z
e
Z	eZn# e$ r dZ	dZY nw xY wddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZ ddlmZmZmZ dd	lmZ dd
lmZ ddl m!Z! ddl"m#Z#m$Z$ ddl%m&Z& ddl'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0 ddl1m(Z2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z? ddl@mAZA  e5d          ZBeBr
ddlCmDZDmEZEmFZF  e5d          ZG e5d          ZH e5d          ZI e5d          ZJd  ZK G d! d"          ZL G d# d$ejM                  ZN G d% d&e;jO                  ZP G d' d(eA          ZQ eeB d)           G d* d+eA                      ZR G d, d-eA          ZS G d. d/          ZT G d0 d1ejU                  ZV G d2 d3eA          ZW eeB d)           G d4 d5eA                      ZX eeB d)           G d6 d7eA                      ZY eeB d)           G d8 d9eA                      ZZ G d: d;          Z[ ee#           G d< d=e[                      Z\ G d> d?          Z] G d@ dAeA          Z^dB Z_dC Z` G dD dEeA          Za eeB d)           G dF dGeA                      Zb eeB dH           G dI dJeA                      Zc ee$           G dK dLe=                      Zd G dM dNe;jO                  ZedO Zf G dP dQeA          ZgdS )RzE
Tests for L{twisted.application.app} and L{twisted.scripts.twistd}.
    N)StringIO)skipIf)implementer)verifyObject)internetloggerplugin)appreactorsservice)IServiceMaker)ReactorBase)Deferred)IReactorDaemonize_ISupportsExitSignalCapturing)AlternateReactor)ILogObserverglobalLogBeginnerglobalLogPublisher)util)Componentized)UserDatabase)r   textFromEventDict)requireModule)platformType)
UsageError)twistd)MemoryReactor)MockOS)TestCaseztwisted.scripts._twistd_unix)UnixApplicationRunnerUnixAppLoggercheckPIDztwisted.python.syslogprofilepstatscProfilec           	         t                               t          j                              }t                              t          j                              t                      }|                    ||j	        ||j
        |j        |j                   fd} | t           d|j                    | t          d|            | t           d|j                   dS )au  
    Patch L{pwd.getpwnam} so that it behaves as though only one user exists
    and patch L{grp.getgrnam} so that it behaves as though only one group
    exists.

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

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

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

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

    @type gid: C{int}
    @param gid: The GID of the single group which will exist.
    c                     t                    }||                    j                  <   ||                    j                  <   t	          |          }|i|          S N)listindexgr_namegr_gidtuple)nameresultgidgrentgroups     8lib/python3.11/site-packages/twisted/test/test_twistd.pygetgrnamz#patchUserDatabase.<locals>.getgrnamd   sX    e.3v||EM**+-0v||EL))*vvt$$    getpwnamr5   getpwuidN)pwdr8   osgetuidgrpgetgrgidgetgidr   addUser	pw_passwdpw_gecospw_dirpw_shellr7   )	patchuseruidr3   r1   pwentdatabaser5   r2   s	      ``   @r4   patchUserDatabaserI   C   s    2 LL%%ELL%%E~~HeosCu~  % % % % % % % 
E#z8,---	E#z8$$$	E#z8,-----r6   c                       e Zd ZdZdZd ZdS )MockServiceMakerzO
    A non-implementation of L{twisted.application.service.IServiceMaker}.
    ueoac                 N    || _         t          j                    | _        | j        S )ze
        Take a L{usage.Options} instance and return a
        L{service.IService} provider.
        )optionsr   ServiceselfrN   s     r4   makeServicezMockServiceMaker.makeServicew   s"    
 ((|r6   N)__name__
__module____qualname____doc__tapnamerR    r6   r4   rK   rK   p   s4          G    r6   rK   c                       e Zd ZdZd ZdS )CrippledAppLoggerz*
    @see: CrippledApplicationRunner.
    c                     d S r)   rX   rQ   applications     r4   startzCrippledAppLogger.start       r6   N)rS   rT   rU   rV   r^   rX   r6   r4   rZ   rZ      s-             r6   rZ   c                   "    e Zd ZdZeZd Zd ZdS )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                     d S r)   rX   rQ   s    r4   preApplicationz(CrippledApplicationRunner.preApplication   r_   r6   c                     d S r)   rX   rc   s    r4   postApplicationz)CrippledApplicationRunner.postApplication   r_   r6   N)rS   rT   rU   rV   rZ   loggerFactoryrd   rf   rX   r6   r4   ra   ra      sC          &M      r6   ra   c                       e Zd ZdZd Zd Zd Zd Zd Z e	e
 d          d             Z e	e
 d          d	             Z e	e
 d          d
             Zd Zd Zd Zd ZdS )ServerOptionsTestszT
    Non-platform-specific tests for the platform-specific ServerOptions class.
    c                 D     G d d          } |d           |d           |d           |d           fd}t          j                    }                     |j        t          j                   ||_        |j        }g}t          ||          D ]{\  }}|\  }}	}
}                     ||j                    	                    |	                                 |
            |j
                  f                      ||j                   |dS )	zh
        subCommands is built from IServiceMaker plugins, and is sorted
        alphabetically.
        c                       e Zd Zd Zd ZdS )7ServerOptionsTests.test_subCommands.<locals>.FakePluginc                 <    || _         d|z   | _        d|z   | _        d S )Nzoptions for description of )rW   _optionsdescriptionrQ   r/   s     r4   __init__z@ServerOptionsTests.test_subCommands.<locals>.FakePlugin.__init__   s(    # . 5#4t#;   r6   c                     | j         S r)   )ro   rc   s    r4   rN   z?ServerOptionsTests.test_subCommands.<locals>.FakePlugin.options   s
    }$r6   N)rS   rT   rU   rr   rN   rX   r6   r4   
FakePluginrl      s2        < < <
% % % % %r6   rt   applebananacoconutdonutc              3   b   K                        | t                     V  V  V  V  d S r)   )assertEqualr   )	interfaceru   rv   rw   rx   rQ   s    r4   
getPluginsz7ServerOptionsTests.test_subCommands.<locals>.getPlugins   sE      Y666MMMLLLKKKKKKKKr6   N)r   ServerOptionsrz   _getPluginsr	   r|   subCommandsziprW   assertIsNonero   rp   )rQ   rt   r|   configr   expectedOrder
subCommandexpectedCommandr/   shortcutparserClassdocumentationru   rv   rw   rx   s   `           @@@@r4   test_subCommandsz#ServerOptionsTests.test_subCommands   s   	% 	% 	% 	% 	% 	% 	% 	% 
7##H%%*Y''
7##	 	 	 	 	 	 	 	 	 %''+V->???' (7+.{M+J+J 	I 	I'J9C6D(KT?#:;;;h'''[[]]O,DEEFF]O,GHHHH	I 	Ir6   c                    	
  G d d          } |d           |d           |d           |d          		fd}t          j                    }                     |j        t          j                   ||_        t                      |_                             t          |j
        dg           |j                                        
g 	fD ])}
 fd	} ||j                    ||j                   *                     t                    d
                    
                     dS )zP
        Reactor names are listed alphabetically by I{--help-reactors}.
        c                       e Zd Zd ZdS )GServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstallerc                 <    d|z   | _         d|z   | _        d| _        d S )Nzname of rn   ztwisted.internet.default)	shortNamerp   
moduleNamerq   s     r4   rr   zPServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstaller.__init__   s&    !+d!2#4t#; "<r6   N)rS   rT   rU   rr   rX   r6   r4   FakeReactorInstallerr      s#        = = = = =r6   r   ru   rv   rw   rx   c               3   ,   K   V  V  V   V  d S r)   rX   )ru   rv   rw   rx   s   r4   getReactorTypeszBServerOptionsTests.test_sortedReactorHelp.<locals>.getReactorTypes   s/      MMMLLLKKKKKKKKr6   z--help-reactorsc                                          |                                                    |                      d S r)   )assertInappendr+   )s
helpOutputindexesrQ   s    r4   getIndexz;ServerOptionsTests.test_sortedReactorHelp.<locals>.getIndex   s=    a,,,z//2233333r6   z9reactor descriptions were not in alphabetical order: {!r}N)r   r}   rz   _getReactorTypesr   r   r   messageOutputassertRaises
SystemExitparseOptionsgetvaluer   rp   sortedformat)rQ   r   r   r   reactorr   ru   rv   rw   rx   r   r   s   `     @@@@@@r4   test_sortedReactorHelpz)ServerOptionsTests.test_sortedReactorHelp   s   
	= 	= 	= 	= 	= 	= 	= 	= %$W--%%h//&&y11$$W--	 	 	 	 	 	 	 	 %''0(2JKKK"1'zz*f&9<M;NOOO)2244
fgu4 	* 	*G4 4 4 4 4 4 4 HW&'''HW())))7OOGNN 	
 	
 	
 	
 	
r6   c                     t          j                    }d|_        |                                 |                     |d                    dS )zS
        postOptions should set no_save to True when a subcommand is used.
        rL   no_saveN)r   r}   r   postOptions
assertTruerQ   r   s     r4   &test_postOptionsSubCommandCausesNoSavez9ServerOptionsTests.test_postOptionsSubCommandCausesNoSave   sI     %''"y)*****r6   c                     t          j                    }|                                 |                     |d                    dS )zR
        If no sub command is used, postOptions should not touch no_save.
        r   N)r   r}   r   assertFalser   s     r4   (test_postOptionsNoSubCommandSavesAsUsualz;ServerOptionsTests.test_postOptionsNoSubCommandSavesAsUsual  sC     %''	*+++++r6   c                     t          j                    }t          |          }t          j        j        D ]}|                     ||           dS )zq
        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       r4   test_listAllProfilersz(ServerOptionsTests.test_listAllProfilers
  sR    
 %''[[
1 	0 	0HMM(J////	0 	0r6   twistd unix not availablec                 b    t          j                    }|                     |d                    dS )zG
        The default value for the C{umask} option is L{None}.
        umaskN)r   r}   r   r   s     r4   test_defaultUmaskz$ServerOptionsTests.test_defaultUmask  s0    
 %''&/*****r6   c                     t          j                    }|                    ddg           |                     |d         d           |                    ddg           |                     |d         d           dS )zh
        The value given for the C{umask} option is parsed as an octal integer
        literal.
        --umask123r   S   0123N)r   r}   r   rz   r   s     r4   
test_umaskzServerOptionsTests.test_umask  s~     %''Y.///"---Y/000"-----r6   c                 r    t          j                    }|                     t          |j        ddg           dS )z
        If a value is given for the C{umask} option which cannot be parsed as
        an integer, L{UsageError} is raised by L{ServerOptions.parseOptions}.
        r   abcdefN)r   r}   r   r   r   r   s     r4   test_invalidUmaskz$ServerOptionsTests.test_invalidUmask(  s8     %''*f&9Ix;PQQQQQr6   c                    t          j                    }|                     t          |j        ddg          }|                     |j        d                             d                     |                     d|j        d                    dS )zQ
        C{--logger} with an unimportable module raises a L{UsageError}.
        --loggerzno.such.module.I.hoper   zeLogger 'no.such.module.I.hope' could not be imported: 'no.such.module.I.hope' does not name an object
N	r   r}   r   r   r   r   args
startswithassertNotInrQ   r   es      r4   &test_unimportableConfiguredLogObserverz9ServerOptionsTests.test_unimportableConfiguredLogObserver1  s     %''+j:Q-R
 
 	F1I  B 	
 	
 	
 	qvay)))))r6   c                    t          j                    }|                     t          |j        ddg          }|                     |j        d                             d                     |                     d|j        d                    dS )zP
        C{--logger} with a non-existent object raises a L{UsageError}.
        r   ztwisted.test.test_twistd.FOOBARr   z{Logger 'twisted.test.test_twistd.FOOBAR' could not be imported: module 'twisted.test.test_twistd' has no attribute 'FOOBAR'r   Nr   r   s      r4   *test_badAttributeWithConfiguredLogObserverz=ServerOptionsTests.test_badAttributeWithConfiguredLogObserverA  s     %'':;
 

 	F1I  , 	
 	
 	
 	qvay)))))r6   c                    ddl m} t          dk    rd}nd}d                    ||j        |j                  }t                      }t          j        |          }|                     t          |j
        dg          }|                     |j        d	           |                     |                                |           d	S )
z2
        C{--version} prints the version.
        r   )	copyrightwin32z(the Twisted Windows runner)z(the Twisted daemon)ztwistd {} {}
{}
stdoutz	--versionN)twistedr   r   r   versionr   r   r}   r   r   r   assertIscoderz   r   )rQ   r   r/   expectedOutputr   r   r   s          r4   test_versionzServerOptionsTests.test_versionT  s     	&%%%%%7""1DD)D-44)#Y%8
 
 %V444j&*=}MMafd###**N;;;;;r6   c                     t                      }t          j        |          }|                     t          |j        dg           dS )zI
        Command is printed when an invalid option is requested.
        r   z	web --fooN)r   r   r}   r   r   r   )rQ   r   r   s      r4   !test_printSubCommandForUsageErrorz4ServerOptionsTests.test_printSubCommandForUsageErrorh  sC     %V444*f&9K=IIIIIr6   N)rS   rT   rU   rV   r   r   r   r   r   r   _twistd_unixr   r   r   r   r   r   r   rX   r6   r4   ri   ri      s6        )I )I )IV-
 -
 -
^+ + +, , ,0 0 0 V9::+ + ;:+ V9::	. 	. ;:	. V9::R R ;:R* * * * * *&< < <(J J J J Jr6   ri   r   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )CheckPIDTestsz 
    Tests for L{checkPID}.
    c                 h    |                      t          j        dd            t          d           dS )z7
        Nonexistent PID file is not an error.
        existsc                     dS NFrX   )_s    r4   <lambda>z.CheckPIDTests.test_notExists.<locals>.<lambda>|  s     r6   znon-existent PID fileN)rD   r:   pathr#   rc   s    r4   test_notExistszCheckPIDTests.test_notExistsx  s3     	

27Hoo666()))))r6   c                     |                                  }t          |d          5 }|                    d           ddd           n# 1 swxY w Y   |                     t          t
          |          }|                     d|j                   dS )zI
        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       r4   test_nonNumericzCheckPIDTests.test_nonNumeric  s     ++--'3 	#1GGM"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#j(G<<)1622222   AAAc                 ^   |                                  }t          |d          5 }|                    d           ddd           n# 1 swxY w Y   d }|                     t          d|           |                     t          t          |          }|                     d|j	                   dS )zE
        Another running twistd server causes a system exit.
        r   42Nc                     d S r)   rX   pidsigs     r4   killz/CheckPIDTests.test_anotherRunning.<locals>.kill  s    Dr6   r   zAnother twistd server)
r   r   r   rD   r:   r   r   r#   r   r   rQ   r   r   r   r   s        r4   test_anotherRunningz!CheckPIDTests.test_anotherRunning  s     ++--'3 	1GGDMMM	 	 	 	 	 	 	 	 	 	 	 	 	 	 		 	 	 	

2vt$$$j(G<<-qv66666r   c                    |                                  }t          |d          5 }|                    t          t	          j                    dz                        ddd           n# 1 swxY w Y   d }|                     t          d|           t          |           |                     t          j	        
                    |                     dS )zJ
        Stale PID file is removed without causing a system exit.
        r      Nc                 6    t          t          j        d          Nfake)OSErrorerrnoESRCHr   s     r4   r   z&CheckPIDTests.test_stale.<locals>.kill      %+v...r6   r   )r   r   r   r   r:   getpidrD   r#   r   r   r   )rQ   r   r   r   s       r4   
test_stalezCheckPIDTests.test_stale  s     ++--'3 	*1GGC	a(()))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*	/ 	/ 	/ 	

2vt$$$0011111s   7A((A,/A,c                    |                                  }t          |d          5 }|                    d           ddd           n# 1 swxY w Y   d }|                     t          d|           |                     t          t          |          }|                     |j	        d           | 
                    |j        d                             d                     dS )z
        An unexpected L{OSError} when checking the validity of a
        PID in a C{pidfile} terminates the process via L{SystemExit}.
        r   3581Nc                 6    t          t          j        d          r   r   r   EBADFr   s     r4   r   z2CheckPIDTests.test_unexpectedOSError.<locals>.kill  r   r6   r   r   zCan't check status of PID)r   r   r   rD   r:   r   r   r#   assertIsNotr   r   r   r   r   s        r4   test_unexpectedOSErrorz$CheckPIDTests.test_unexpectedOSError  s   
 ++--'3 	1GGFOOO	 	 	 	 	 	 	 	 	 	 	 	 	 	 		/ 	/ 	/ 	

2vt$$$j(G<<&&&q	,,-HIIJJJJJr   N)	rS   rT   rU   rV   r   r   r   r   r  rX   r6   r4   r   r   r  sn         * * *3 3 37 7 72 2 2K K K K Kr6   r   c                       e Zd ZdZd Zd ZdS )TapFileTestszM
    Test twistd-related functionality that requires a tap file on disk.
    c                     |                                  | _        t          | j        d          5 }t          j        t          j        d          |           ddd           dS # 1 swxY w Y   dS )zP
        Create a trivial Application and put it in a tap file on disk.
        wbHi!N)r   tapfiler   pickledumpr   Application)rQ   r   s     r4   setUpzTapFileTests.setUp  s     {{}}$,%% 	7K+E22A666	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7s   (A$$A(+A(c                     t          j                    }|                    d| j        g           t	          |                                          }|                     t          j        |          j	        d           dS )z
        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  ra   createOrGetApplicationrz   r   IServicer/   )rQ   r   r]   s      r4   &test_createOrGetApplicationWithTapFilez3TapFileTests.test_createOrGetApplicationWithTapFile  sp    
 %''T4<0111/77NNPP)+66;UCCCCCr6   N)rS   rT   rU   rV   r  r  rX   r6   r4   r	  r	    sA         7 7 7D D D D Dr6   r	  c                   $    e Zd ZdZd Zd Zd ZdS )TestLoggerFactoryz8
    A logger factory for L{TestApplicationRunner}.
    c                     || _         d S r)   )runner)rQ   r  s     r4   rr   zTestLoggerFactory.__init__  s    r6   c                     | j         j                            d           t          | j         d          | j         _        dS )zC
        Save the logging start on the C{runner} instance.
        logr]   N)r  orderr   hasattrhadApplicationLogObserverr\   s     r4   r^   zTestLoggerFactory.start  s9     	  '''07]0S0S---r6   c                     dS )z%
        Don't log anything.
        NrX   rc   s    r4   stopzTestLoggerFactory.stop        r6   N)rS   rT   rU   rV   rr   r^   r   rX   r6   r4   r  r    sN           T T T    r6   r  c                   $    e Zd ZdZd Zd Zd ZdS )TestApplicationRunnerz`
    An ApplicationRunner which tracks the environment in which its methods are
    called.
    c                 |    t           j                            | |           g | _        t	          |           | _        d S r)   )r
   ApplicationRunnerrr   r  r  r   rP   s     r4   rr   zTestApplicationRunner.__init__  s5    &&tW555
'--r6   c                 d    | j                             d           t          | d          | _        d S )Nprer]   )r  r   r  hadApplicationPreApplicationrc   s    r4   rd   z$TestApplicationRunner.preApplication  s0    
%   ,3D-,H,H)))r6   c                 d    | j                             d           t          | d          | _        d S )Npostr]   )r  r   r  hadApplicationPostApplicationrc   s    r4   rf   z%TestApplicationRunner.postApplication  s0    
&!!!-4T=-I-I***r6   N)rS   rT   rU   rV   rr   rd   rf   rX   r6   r4   r#  r#    sS         
. . .
I I IJ J J J Jr6   r#  c                       e Zd ZdZd Zd Zd Zd Z e e	e
dd           d          d	             Z e e	e
dd           d          d
             Zd Zd Zd Zd ZdS )ApplicationRunnerTestszR
    Non-platform-specific tests for the platform-specific ApplicationRunner.
    c                     t          j                    }t                      | _        d| j        i|_        t                      |_        d|_        || _        d S )Ntest_command)	r   r}   rK   serviceMakerloadedPluginsobject
subOptionsr   r   r   s     r4   r  zApplicationRunnerTests.setUp  sM    %'',.. .0AB"HH*r6   c                 2   t          | j                  }|                                 |                     | j        j        | j        j        d           |                     | j        j        t          j        |j	                  j
        d         d           dS )z
        Ensure that a twistd plugin gets used in appropriate ways: it
        is passed its Options instance, and the service it returns is
        added to the application.
        zKServiceMaker.makeService needs to be passed the correct sub Command object.r   zPServiceMaker.makeService's result needs to be set as a child of the Application.N)ra   r   runr   r0  rN   r3  r   r  r]   services)rQ   arunners     r4   ,test_applicationRunnerGetsCorrectApplicationzCApplicationRunnerTests.test_applicationRunnerGetsCorrectApplication  s     ,DK88%K""	
 	
 	
 	%W011:1="	
 	
 	
 	
 	
r6   c                 ,   t          | j                  }|                                 |                     |j                   |                     |j                   |                     |j                   |                     |j	        g d           dS )z
        Test thet preApplication and postApplication methods are
        called by ApplicationRunner.run() when appropriate.
        )r'  r  r*  N)
r#  r   r5  r   r(  r   r+  r  rz   r  )rQ   r   s     r4   test_preAndPostApplicationz1ApplicationRunnerTests.test_preAndPostApplication  s    
 "$+..	788878883444"8"8"899999r6   c           	         | j                             |           g  G fddt          j                  }t	          t
          j        t
          j                   G fdd                      } |            }t          t
          j        |           t          t
          j        |            || j                   }|	                                 ||_
        |                                 |                     dddd||fd	d
g           dS )a.  
        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                   4    e Zd Z fdZ fdZ fdZd ZdS )\ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunnerc                 2                         d           d S )Nenvironmentr   )rQ   chrootrundirnodaemonr   r   eventss         r4   setupEnvironmentzmApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.setupEnvironment8  s    m,,,,,r6   c                 :                         d|||f           d S )N
privilegesr@  )rQ   euidrF   r1   rD  s       r4   shedPrivilegeszkApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.shedPrivileges;  s$    |T3<=====r6   c                 2                         d           d S )Nr   r@  )rQ   r   	oldstdout	oldstderrrD  s       r4   startReactorziApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.startReactor>  s    i(((((r6   c                     d S r)   rX   )rQ   r   s     r4   	removePIDzfApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.removePIDA      r6   N)rS   rT   rU   rE  rI  rM  rO  rD  s   r4   FakeUnixApplicationRunnerr=  7  so        - - - - -> > > > >) ) ) ) )    r6   rR  c                   T    e Zd ZdZdZdZdZdZdZd Z	d Z
d Z fdZ fdZd ZdS )NApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeServiceNc                     d S r)   rX   rq   s     r4   setNamezVApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setNameN  rP  r6   c                     d S r)   rX   )rQ   parents     r4   setServiceParentz_ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setServiceParentQ  rP  r6   c                     d S r)   rX   rc   s    r4   disownServiceParentzbApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.disownServiceParentT  rP  r6   c                 2                         d           d S )NprivilegedStartServicer@  rQ   rD  s    r4   r]  zeApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.privilegedStartServiceW  s    677777r6   c                 2                         d           d S )NstartServicer@  r^  s    r4   r`  z[ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.startServiceZ  s    n-----r6   c                     d S r)   rX   rc   s    r4   stopServicezZApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.stopService]  rP  r6   )rS   rT   rU   rX  runningr/   processNamerF   r1   rV  rY  r[  r]  r`  rb  rQ  s   r4   FakeServicerT  D  s         FGDKCC      8 8 8 8 8. . . . .    r6   re  r?  r]  rG  Fr`  r   N)r   r   r   _SomeApplicationRunnerr   r   r  IProcessr   rd   r]   rf   rz   )	rQ   argvrF   r1   rR  re  r]   r  rD  s	           @r4   "_applicationStartsWithConfiguredIDz9ApplicationRunnerTests._applicationStartsWithConfiguredID*  sY    	  &&&	 	 	 	 	 	 	(E 	 	 	 
W%w'7	8	8	 	 	 	 	 	 	 	 	 
9	8	6 "kmmW%{333W%{333**4;77(   (uc3/		
 		
 		
 		
 		
r6   setuidNz5Platform does not support --uid/--gid twistd options.c                 x    d}d}|                      dt          |          dt          |          g||           dS )a  
        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)ri  r   )rQ   rF   r1   s      r4   .test_applicationStartsWithConfiguredNumericIDszEApplicationRunnerTests.test_applicationStartsWithConfiguredNumericIDst  sL     //c#hhS2C	
 	
 	
 	
 	
r6   c                 |    d}d}d}d}t          | j        ||||           |                     d|d|g||           dS )a  
        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}.
        foorl  barrm  rn  ro  N)rI   rD   ri  )rQ   rE   rF   r3   r1   s        r4   +test_applicationStartsWithConfiguredNameIDszBApplicationRunnerTests.test_applicationStartsWithConfiguredNameIDs  sb     $*dC<<<//dGU+S#	
 	
 	
 	
 	
r6   c                     t                      }t          j        dddd          }|                    |dd           |                     |j        d           dS )z7
        L{startReactor} calls L{reactor.run}.
        Fr$   r$   r   debugNz'startReactor did not call reactor.run())DummyReactorr
   r%  rM  r   calledrQ   r   r  s      r4   test_startReactorRunsTheReactorz6ApplicationRunnerTests.test_startReactorRunsTheReactor  sc     ..&9uEE
 
 	GT4000(QRRRRRr6   c                     t                      }|                     t          d|           t          j        dddd          }|                    ddd           |                     |j                   dS )zN
        L{ApplicationRunner} chooses a reactor if none is specified.
        r   Fr$   rv  N)rx  rD   r   r
   r%  rM  r   ry  rz  s      r4   *test_applicationRunnerChoosesReactorIfNonezAApplicationRunnerTests.test_applicationRunnerChoosesReactorIfNone  sv     ..

8Y000&9uEE
 
 	D$---'''''r6   c                      G d dt                     } |            }t          j        dddd          }|                    |dd           |                     d|j                   dS )zg
        If the reactor exits with a signal, the application runner caches
        the signal.
        c                       e Zd ZdZd Zd ZdS )[ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal
            A dummy reactor, providing a C{run} method, and setting the
            _exitSignal attribute to a nonzero value.
            c                     dS z=
                Dummy method, does nothing.
                NrX   rc   s    r4   installWakerzhApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.installWaker  r!  r6   c                     d| _         dS )zZ
                A fake run method setting _exitSignal to a nonzero value
                   N_exitSignalrc   s    r4   r5  z_ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.run  s     $%   r6   NrS   rT   rU   rV   r  r5  rX   r6   r4   DummyReactorWithSignalr    s<         
  
% % % % %r6   r  Fr$   rv  Nr  )r   r
   r%  rM  assertEqualsr  )rQ   r  r   r  s       r4   $test_applicationRunnerCapturesSignalz;ApplicationRunnerTests.test_applicationRunnerCapturesSignal  s    	% 	% 	% 	% 	%[ 	% 	% 	%" )(**&9uEE
 
 	GT4000!V/00000r6   c                      G d d          } |            }t          j        dddd          }|                    |dd           |                     d|j                   dS )z
        The runner sets its _exitSignal instance attribute to None if
        the reactor does not implement L{_ISupportsExitSignalCapturing}.
        c                       e Zd ZdZd Zd ZdS )iApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttributer  c                     dS r  rX   rc   s    r4   r  zvApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.installWaker  r!  r6   c                     d| _         dS )z
                A fake run method setting _exitSignal to a nonzero value
                that should be ignored.
                r  Nr  rc   s    r4   r5  zmApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.run  s    
 $%   r6   Nr  rX   r6   r4   #DummyReactorWithExitSignalAttributer    s<         
  
% % % % %r6   r  Fr$   rv  N)r
   r%  rM  r  r  )rQ   r  r   r  s       r4   %test_applicationRunnerIgnoresNoSignalz<ApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal  s    	% 	% 	% 	% 	% 	% 	% 	%$ 6577&9uEE
 
 	GT4000$ 233333r6   )rS   rT   rU   rV   r  r8  r:  ri  r   getattrr:   rp  rt  r{  r}  r  r  rX   r6   r4   r-  r-    s          
 
 
,
: 
: 
:H
 H
 H
T VGB$'''? 
 
	 
 VGB$'''? 
 
	 
 	S 	S 	S
( 
( 
(1 1 1<4 4 4 4 4r6   r-  c                   n    e Zd ZdZ e            Zd Zd Zd Zd Z	d Z
d Zd Zd	 Zd
 Zd Zd Zd ZdS )*UnixApplicationRunnerSetupEnvironmentTestsa  
    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                      j          _         j          _         j          _        d _        t          j                     _                             t
          d fd                                t
          d fd                                t
          d fd           t          t          j                               _         j         j        _        d S )NFrA  c                 &    t          d|           S )Nrootsetattrr   rQ   s    r4   r   zBUnixApplicationRunnerSetupEnvironmentTests.setUp.<locals>.<lambda>  s    gdFD.I.I r6   chdirc                 &    t          d|           S )Ncwdr  r  s    r4   r   zBUnixApplicationRunnerSetupEnvironmentTests.setUp.<locals>.<lambda>  s    WT5$-G-G r6   r   c                 &    t          d|           S )Nmaskr  )r  rQ   s    r4   r   zBUnixApplicationRunnerSetupEnvironmentTests.setUp.<locals>.<lambda>  s    WT64-H-H r6   )unsetr  r  r  daemonr:   r   r   rD   r!   r   r}   r  	daemonizerc   s   `r4   r  z0UnixApplicationRunnerSetupEnvironmentTests.setUp  s    J	:J	9;;

2x!I!I!I!IJJJ

2w G G G GHHH

2w H H H HIII+F,@,B,BCC $r6   c                 T     d _                              t          d fd           dS )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                       j         dz   S Nr   )r   rc   s   r4   r   zFUnixApplicationRunnerSetupEnvironmentTests.daemonize.<locals>.<lambda>  s    A r6   N)r  rD   r:   rQ   r   s   ` r4   r  z4UnixApplicationRunnerSetupEnvironmentTests.daemonize  s2    
 

2x!5!5!5!566666r6   c                 x    | j                             ddddd           |                     | j        d           dS )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  rE  rz   r  rc   s    r4   test_chrootz6UnixApplicationRunnerSetupEnvironmentTests.test_chroot  s@    
 	$$ZdD$GGGJ/////r6   c                     | j                             ddddd           |                     | j        | j                   dS )z
        L{UnixApplicationRunner.setupEnvironment} does not change the root of
        the filesystem if passed L{None} for the C{chroot} parameter.
        Nr  T)r  rE  r   r  r  rc   s    r4   test_noChrootz8UnixApplicationRunnerSetupEnvironmentTests.test_noChroot"  s@    
 	$$T3dDAAAdi,,,,,r6   c                 x    | j                             ddddd           |                     | j        d           dS )z
        L{UnixApplicationRunner.setupEnvironment} changes the working directory
        of the process to the path given for the C{rundir} parameter.
        Nr  T)r  rE  rz   r  rc   s    r4   test_changeWorkingDirectoryzFUnixApplicationRunnerSetupEnvironmentTests.test_changeWorkingDirectory*  s@    
 	$$T:tT4HHH:.....r6   c                     t          t                                5  | j                            ddddd           ddd           n# 1 swxY w Y   |                     | j                   dS )z
        L{UnixApplicationRunner.setupEnvironment} daemonizes the process if
        C{False} is passed for the C{nodaemon} parameter.
        Nr  F)r   FakeDaemonizingReactorr  rE  r   r  rc   s    r4   test_daemonizez9UnixApplicationRunnerSetupEnvironmentTests.test_daemonize2  s    
 46677 	G 	GK((sE4FFF	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G$$$$$   AAAc                 v    | j                             ddddd           |                     | j                   dS )z
        L{UnixApplicationRunner.setupEnvironment} does not daemonize the
        process if C{True} is passed for the C{nodaemon} parameter.
        Nr  T)r  rE  r   r  rc   s    r4   test_noDaemonizez;UnixApplicationRunnerSetupEnvironmentTests.test_noDaemonize;  s>    
 	$$T3dDAAA%%%%%r6   c                 2   |                                  }| j                            dddd|           t          |d          5 }t	          |                                          }ddd           n# 1 swxY w Y   |                     || j                   dS )z
        L{UnixApplicationRunner.setupEnvironment} writes the process's PID to
        the file specified by the C{pidfile} parameter.
        Nr  Trb)r   r  rE  r   intreadrz   r   rQ   r   r   r   s       r4   test_nonDaemonPIDFilez@UnixApplicationRunnerSetupEnvironmentTests.test_nonDaemonPIDFileC  s    
 ++--$$T3dGDDD'4   	 Aaffhh--C	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 dh'''''s   "A11A58A5c                    |                                  }t          t                                5  | j                            dddd|           ddd           n# 1 swxY w Y   t          |d          5 }t          |                                          }ddd           n# 1 swxY w Y   |                     || j	        dz              dS )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  r  rE  r   r  r  rz   r   r  s       r4   test_daemonPIDFilez=UnixApplicationRunnerSetupEnvironmentTests.test_daemonPIDFileN  sA    ++--46677 	J 	JK((sE4III	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J'4   	 Aaffhh--C	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 dhl+++++s#   AA"A6"B$$B(+B(c                     t          t                                5  | j                            ddddd           ddd           n# 1 swxY w Y   |                     | j        d           dS )z
        L{UnixApplicationRunner.setupEnvironment} changes the process umask to
        the value specified by the C{umask} parameter.
        Nr  F{   r   r  r  rE  rz   r  rc   s    r4   r   z5UnixApplicationRunnerSetupEnvironmentTests.test_umask[  s    
 46677 	F 	FK((sE3EEE	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	FC(((((r  c                     | j                             ddddd           |                     | j        | j                   dS )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  rE  r   r  r  rc   s    r4   test_noDaemonizeNoUmaskzBUnixApplicationRunnerSetupEnvironmentTests.test_noDaemonizeNoUmaskd  s@     	$$T3dDAAAdi,,,,,r6   c                     t          t                                5  | j                            ddddd           ddd           n# 1 swxY w Y   |                     | j        d           dS )z
        L{UnixApplicationRunner.setupEnvironment} changes the process umask to
        C{0077} if L{None} is passed for the C{umask} parameter and C{False} is
        passed for the C{nodaemon} parameter.
        Nr  F?   r  rc   s    r4   test_daemonizedNoUmaskzAUnixApplicationRunnerSetupEnvironmentTests.test_daemonizedNoUmaskm  s     46677 	G 	GK((sE4FFF	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	GE*****r  N)rS   rT   rU   rV   r2  r  r  r  r  r  r  r  r  r  r  r   r  r  rX   r6   r4   r  r    s         ( FHHE
/ 
/ 
/7 7 70 0 0- - -/ / /% % %& & &	( 	( 	(, , ,) ) )- - -+ + + + +r6   r  c                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	*UnixApplicationRunnerStartApplicationTestsz>
    Tests for L{UnixApplicationRunner.startApplication}.
    c                    t          j                    }|                    g d           t          j        d          }t          |          | _        g fd}t          j        | j        j	                  j
        }t          j        |          j
        }|                                }|                    d           |                     ||           |                     t
          d|           |                     t
          dd            |                     t          dd	            | j                            |           |                     g d
           dS )z
        L{UnixApplicationRunner.startApplication} calls
        L{UnixApplicationRunner.setupEnvironment} with the chroot, rundir,
        nodaemon, umask, and pidfile parameters from the configuration it is
        constructed with.
        )	
--nodaemonr   0070z--chroot/foo/chrootz--rundir/foo/rundirz	--pidfile/foo/pidfiletest_setupEnvironmentc                 <                         |||||f           d S r)   )extend)rQ   rA  rB  rC  r   r   r   s         r4   fakeSetupEnvironmentz^UnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.fakeSetupEnvironment  s&    KK5'BCCCCCr6   rQ   rE  rI  c                      d S r)   rX   akws     r4   r   zRUnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.<lambda>  s    T r6   startApplicationc                      d S r)   rX   r  s     r4   r   zRUnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.<lambda>  s    T r6   )r  r  T8   r  N)r   r}   r   r   r  r!   r  inspect	signaturerE  
parameterscopypoprz   rD   r
   r  )rQ   rN   r]   r  setupEnvironmentParametersfakeSetupEnvironmentParametersr   s         @r4   r  z@UnixApplicationRunnerStartApplicationTests.test_setupEnvironment~  s    &((
 
 
	
 	
 	
 )*ABB+G44	D 	D 	D 	D 	D &-%6K(&
 &

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

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

(*<>RSSS

(*:<Q<QRRR

3*,A,ABBB$$[111WWWXXXXXr6   c                       fd}                      t          d|           t          i           }|                    ddd           dS )zf
        L{UnixApplicationRunner.shedPrivileges} switches the user ID
        of the process.
        c                                          | d                                |d                                |d           d S )N   6   #   rz   )rF   r1   rH  rQ   s      r4   switchUIDPasszUUnixApplicationRunnerStartApplicationTests.test_shedPrivileges.<locals>.switchUIDPass  sK    S#&&&S"%%%T2&&&&&r6   	switchUIDr  r  r  N)rD   r   r!   rI  )rQ   r  r  s   `  r4   test_shedPrivilegesz>UnixApplicationRunnerStartApplicationTests.test_shedPrivileges  s_    	' 	' 	' 	' 	'
 	

<m<<<&r**b#r*****r6   c                     d }t          i           }|                     t          d|           |                     t          |j        ddd          }|                     |j        d           dS )z
        An unexpected L{OSError} when calling
        L{twisted.scripts._twistd_unix.shedPrivileges}
        terminates the process via L{SystemExit}.
        c                 6    t          t          j        d          r   r  )rF   r1   rH  s      r4   switchUIDFailzZUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesError.<locals>.switchUIDFail  r   r6   r  r  r  Nr   )r!   rD   r   r   r   rI  rz   r   )rQ   r  r  excs       r4   test_shedPrivilegesErrorzCUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesError  sr    	/ 	/ 	/ 'r**

<m<<<
F,A2sDQQ1%%%%%r6   c                     t           j        ||            fd} fd} fd}                     t          d|                                t          d|                                t          d|           t	          j                    }|                    ddt                    g           t          j	        d	          }	t          |           _        t          |          }
|
                    |	           d
S )zj
        Common code for tests which try to pass the the UID to
        L{UnixApplicationRunner}.
        c                 `                         |                                 |           d S r)   r  )rF   r1   rQ   	wantedGid	wantedUids     r4   
initgroupszFUnixApplicationRunnerStartApplicationTests._setUID.<locals>.initgroups  s5    S),,,S),,,,,r6   c                 4                         |            d S r)   r  )rF   rQ   r  s    r4   rj  zBUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setuid      S),,,,,r6   c                 4                         |            d S r)   r  )r1   rQ   r  s    r4   setgidzBUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setgid  r  r6   r  rj  r  r  rn  r  N)rI   rD   r   r:   r   r}   r   r   r   r  r!   r  r  )rQ   
wantedUserr  wantedGroupr  r  rj  r  rN   r]   r  s   ` ` `      r4   _setUIDz2UnixApplicationRunnerStartApplicationTests._setUID  s8   
 	$*j)[)TTT	- 	- 	- 	- 	- 	- 	-	- 	- 	- 	- 	- 	-	- 	- 	- 	- 	- 	- 	

4z222

2x(((

2x(((&((lGS^^DEEE)*ABB+G44&w//,,,,,r6   c                 6    |                      dddd           dS )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.
        rr  i  rs  i  N)r  rc   s    r4   test_setUidWithoutGidz@UnixApplicationRunnerStartApplicationTests.test_setUidWithoutGid  s"     	UD%.....r6   c                 :   t          j                    }|                     d|dd           |                                 }|                     dt          |                     d                    ||          }|                     ||d         d                    dS )	zz
        If the specified UID is the same as the current UID of the process,
        then a warning is displayed.
        morefoomorebari  r   z\tried to drop privileges and setuid {} but uid is already {}; should we be root? Continuing.r   messageN)r:   r;   r  flushWarningsrz   lenr   )rQ   
currentUidwarningsShownexpectedWarnings       r4   test_setUidSameAsCurrentUidzFUnixApplicationRunnerStartApplicationTests.test_setUidSameAsCurrentUid  s    
 Y[[
Y
It<<<**,,C..///--3VJ
-K-K 	 	-*:9*EFFFFFr6   N)
rS   rT   rU   rV   r  r  r  r  r  r  rX   r6   r4   r  r  x  s         2Y 2Y 2Yh+ + +& & &- - -8/ / /G G G G Gr6   r  c                       e Zd ZdZd Zd ZdS )#UnixApplicationRunnerRemovePIDTestsz7
    Tests for L{UnixApplicationRunner.removePID}.
    c                    t          i           }|                                 }t          j        |           t          j                            |d          }t          |d                                           |                    |           | 	                    t          j        
                    |                     dS )zp
        L{UnixApplicationRunner.removePID} deletes the file the name of
        which is passed to it.
        zfoo.pidr   N)r!   r   r:   makedirsr   joinr   closerO  r   r   )rQ   r  r   r   s       r4   test_removePIDz2UnixApplicationRunnerRemovePIDTests.test_removePID  s    
 'r**{{}}
D',,tY//Wc  """!!!0011111r6   c                 (   t          i           }|                    d           |                     t                    }|                     t          |          d           |                     |d         j        j        t          j                   dS )zr
        Calling L{UnixApplicationRunner.removePID} with a non-existent filename
        logs an OSError.
        fakepidr   r   N)	r!   rO  flushLoggedErrorsr   rz   r  valuer   ENOENT)rQ   r  errorss      r4   test_removePIDErrorsz8UnixApplicationRunnerRemovePIDTests.test_removePIDErrors  s{    
 'r**###''00Va(((.=====r6   N)rS   rT   rU   rV   r  r  rX   r6   r4   r  r    s<         2 2 2	> 	> 	> 	> 	>r6   r  c                   *    e Zd ZdZd Zd Zd Zd ZdS )FakeNonDaemonizingReactora  
    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                 "    d| _         d| _        d S r   )_beforeDaemonizeCalled_afterDaemonizeCalledrc   s    r4   rr   z"FakeNonDaemonizingReactor.__init__0  s    &+#%*"""r6   c                     d| _         d S NT)r  rc   s    r4   beforeDaemonizez)FakeNonDaemonizingReactor.beforeDaemonize4  s    &*###r6   c                     d| _         d S r  )r  rc   s    r4   afterDaemonizez(FakeNonDaemonizingReactor.afterDaemonize7  s    %)"""r6   c                     dS )z*
        Skip event registration.
        NrX   )rQ   r   r  s      r4   addSystemEventTriggerz/FakeNonDaemonizingReactor.addSystemEventTrigger:  r!  r6   N)rS   rT   rU   rV   rr   r  r  r   rX   r6   r4   r  r  $  sZ        	 	+ + ++ + +* * *    r6   r  c                       e Zd ZdZdS )r  z
    A dummy reactor, providing C{beforeDaemonize} and C{afterDaemonize}
    methods, announcing this, and logging whether the methods have been called.
    N)rS   rT   rU   rV   rX   r6   r4   r  r  @  s           r6   r  c                       e Zd ZdZdZd ZdS )rx  z
    A dummy reactor, only providing a C{run} method and checking that it
    has been called.

    @ivar called: if C{run} has been called or not.
    @type called: C{bool}
    Fc                 @    | j         rt          d          d| _         dS )zV
        A fake run method, checking that it's been called one and only time.
        zAlready calledTN)ry  RuntimeErrorrc   s    r4   r5  zDummyReactor.runS  s(     ; 	1/000r6   N)rS   rT   rU   rV   ry  r5  rX   r6   r4   rx  rx  H  s4          F    r6   rx  c                      e Zd ZdZ ee d          d             Zd Z ee d          d             Zd Z	 ee d          d             Z
 ee d          d	             Z ee d          d
             Zd Zd Zd Zd ZdS )AppProfilingTestsz'
    Tests for L{app.AppProfiler}.
    zprofile module not availablec                    t          j                    }|                                 |d<   d|d<   t          j        |          }t                      }|                    |           |                     |j                   t          |d                   5 }|
                                }ddd           n# 1 swxY w Y   |                     d|           |                     d|           dS )z
        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   rx  r5  r   ry  r   r  r   rQ   r   r   r   r   datas         r4   test_profilezAppProfilingTests.test_profilea  s    %'' KKMMy&z?6**..W'''&#$$ 	6688D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	($///&-----   B77B;>B;c                 @   t                      }|                     t          d|          } ||          }|                                 |                                 |                                }|                     d|           |                     d|           d S )Nr   r(  z(run))r   rD   sysprint_statsrestorer   r   )rQ   
statsClassr$   outr   statsr+  s          r4   
_testStatszAppProfilingTests._testStatsu  s    jj C3// 
7##||~~&---gt$$$$$r6   c                 \   t          j                    }|                                 |d<   d|d<   d|d<   t          j        |          }t                      }|                    |           |                     |j                   | 	                    t          j        |d                    dS )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   rx  r5  r   ry  r5  r%   StatsrQ   r   r   r   s       r4   test_profileSaveStatsz'AppProfilingTests.test_profileSaveStats  s     %'' KKMMy&z"{?6**..W'''fY&788888r6   c                    t           j                                        }t          j                    }d|d<   t          j        |          }dt           j        d<   	 |                     t          |j	        d           t           j        
                                 t           j                            |           dS # t           j        
                                 t           j                            |           w xY w)z
        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   r5  clearupdaterQ   savedModulesr   r   s       r4   test_withoutProfilez%AppProfilingTests.test_withoutProfile  s    
 {''))%''&z?6**!%I	-j(,===KK|,,,,, KK|,,,,   !B; ;?C:c                     G d dt           j                  }|                     t           d|           t          j                    }|                                 |d<   d|d<   t          j        |          }t                      }t          j
        }|                     t          |j        |           |                     t          j
        |           dS )z
        When an error happens during the print of the stats, C{sys.stdout}
        should be restored to its initial value.
        c                       e Zd Zd ZdS )GAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfilec                      t          d          )NBoomr$  rc   s    r4   r0  zSAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfile.print_stats  s    "6***r6   N)rS   rT   rU   r0  rX   r6   r4   ErroneousProfilerG    s#        + + + + +r6   rK  Profiler$   r   N)r$   rL  rD   r   r}   r   r
   r   rx  r/  r   r   r$  r5  r   )rQ   rK  r   r   r   	oldStdouts         r4   test_profilePrintStatsErrorz-AppProfilingTests.test_profilePrintStatsError  s    	+ 	+ 	+ 	+ 	+w 	+ 	+ 	+ 	

7I'7888%'' KKMMy&z?6**..J	,g>>>cj),,,,,r6   zcProfile module not availablec                    t          j                    }|                                 |d<   d|d<   t          j        |          }t                      }|                    |           |                     |j                   t          |d                   5 }|
                                }ddd           n# 1 swxY w Y   |                     d|           |                     d|           dS )z
        L{app.CProfileRunner.run} should call the C{run} method of the
        reactor and save profile data in the specified file.
        r$   r&   r   Nr5  r(  r)  r*  s         r4   test_cProfilezAppProfilingTests.test_cProfile  s    %'' KKMMy'z?6**..W'''&#$$ 	6688D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	eT"""&-----r-  c                 \   t          j                    }|                                 |d<   d|d<   d|d<   t          j        |          }t                      }|                    |           |                     |j                   | 	                    t          j        |d                    dS )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   Tr7  Nr8  r:  s       r4   test_cProfileSaveStatsz(AppProfilingTests.test_cProfileSaveStats  s     %'' KKMMy'z"{?6**..W'''fY&788888r6   c                    t           j                                        }dt           j        d<   t          j                    }d|d<   t          j        |          }	 |                     t          |j	        d           t           j        
                                 t           j                            |           dS # t           j        
                                 t           j                            |           w xY w)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=  rA  s       r4   test_withoutCProfilez&AppProfilingTests.test_withoutCProfile  s     {''))"&J%'''z?6**	-j(,===KK|,,,,, KK|,,,,rD  c                     t          j                    }|                                 |d<   d|d<   |                     t          t
          j        |          }|                     t          |          d           dS )zq
        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   rz   r   )rQ   r   errors      r4   test_unknownProfilerz&AppProfilingTests.test_unknownProfiler  sj    
 %'' KKMMy%z!!*covFFU%HIIIIIr6   c                 d    t          j        i           }|                     |j        d           dS )zU
        L{app.Profiler} defaults to the cprofile profiler if not specified.
        cprofileNr
   r   rz   r   rQ   r   s     r4   test_defaultProfilerz&AppProfilingTests.test_defaultProfiler  s2     ?2&&*J77777r6   c                 h    t          j        ddi          }|                     |j        d           dS )ze
        The case of the profiler name passed to L{app.AppProfiler} is not
        relevant.
        r   CprOfilerZ  Nr[  r\  s     r4   test_profilerNameCaseInsentivez0AppProfilingTests.test_profilerNameCaseInsentive  s7    
 ?J
#;<<*J77777r6   N)rS   rT   rU   rV   r   r$   r,  r5  r;  rC  rN  r&   rP  rR  rT  rX  r]  r`  rX   r6   r4   r&  r&  \  sR         VK788. . 98.&% % %" VK7889 9 989"- - -$ VK788- - 98-, VL9::. . ;:.& VL9::9 9 ;:9$- - -$
J 
J 
J8 8 88 8 8 8 8r6   r&  c                 V    g t           j        fd} | t           d|           S )a  
    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                 F                         |             | g|R i |S r)   r@  )logFiler   kwargslogFilesoldFileLogObservers      r4   observerz+_patchTextFileLogObserver.<locals>.observer#  s6       !!';D;;;F;;;r6   textFileLogObserver)r   rh  )rD   rg  re  rf  s     @@r4   _patchTextFileLogObserverri    sN     H3< < < < < < 
E&'222Or6   c                 b    g  G fdd          }|                      t          d|           S )zu
    Make fake syslog, and return list to which prefix and then log
    messages will be appended if it is used.
    c                   $    e Zd Z fdZ fdZdS )(_setupSyslog.<locals>.fakesyslogobserverc                 2                         |           d S r)   r@  )rQ   prefixlogMessagess     r4   rr   z1_setupSyslog.<locals>.fakesyslogobserver.__init__3  s    v&&&&&r6   c                 2                         |           d S r)   r@  )rQ   	eventDictro  s     r4   emitz-_setupSyslog.<locals>.fakesyslogobserver.emit6  s    y)))))r6   N)rS   rT   rU   rr   rr  )ro  s   r4   fakesyslogobserverrl  2  sG        	' 	' 	' 	' 	'	* 	* 	* 	* 	* 	* 	*r6   rs  SyslogObserver)rD   syslog)testCasers  ro  s     @r4   _setupSyslogrw  +  s\    
 K* * * * * * * * * * NN6+-?@@@r6   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	i e
j        fdZd	 Zd
 Zd Zd Z ee d           ee d          d                         Zd Zd Zd Zd Zd Zd ZdS )AppLoggerTestsz
    Tests for L{app.AppLogger}.

    @ivar observers: list of observers installed during the tests.
    @type observers: C{list}
    c                 X     g  _          fd}                     t          d|           dS )z
        Override L{globaLogBeginner.beginLoggingTo} so that we can trace the
        observers installed in C{self.observers}.
        c                 n    | D ]0}j                             |           t          j        |           1d S r)   )	observersr   r   addObserver)r|  rg  rQ   s     r4   beginLoggingToz,AppLoggerTests.setUp.<locals>.beginLoggingToL  sF    % 9 9%%h///".x88889 9r6   r~  N)r|  rD   r   )rQ   r~  s   ` r4   r  zAppLoggerTests.setUpE  sE    
 	9 	9 	9 	9 	9
 	

$&6GGGGGr6   c                 B    | j         D ]}t          j        |           dS )z1
        Remove all installed observers.
        N)r|  r   removeObserverrQ   rg  s     r4   tearDownzAppLoggerTests.tearDownS  s3      	8 	8H-h7777	8 	8r6   c                 d    t          t                     G d d                      } |            S )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                       e Zd Zg Zd ZdS )2AppLoggerTests._makeObserver.<locals>.TestObserverc                 :    | j                             |           d S r)   )_logsr   )rQ   events     r4   __call__z;AppLoggerTests._makeObserver.<locals>.TestObserver.__call__f  s    
!!%(((((r6   N)rS   rT   rU   r  r  rX   r6   r4   TestObserverr  b  s(        E) ) ) ) )r6   r  )r   r   )rQ   r  s     r4   _makeObserverzAppLoggerTests._makeObserverZ  sM     
\	"	"	) 	) 	) 	) 	) 	) 	) 
#	"	) |~~r6   c                     |                      | j        |g           |                     d|j        d         d                    |                     d|j        d         d                    dS )z
        Ensure that initial C{twistd} logs are written to logs.

        @param observer: The observer made by L{self._makeObserver).
        starting upr   
log_formatzreactor classr   N)rz   r|  r   r  r  s     r4   _checkObserverzAppLoggerTests._checkObserverk  sd     	(444mX^A%6|%DEEEox~a'8'FGGGGGr6   c                     t          j        i           }|                                 fd|_         |j        t                                 |                                dS )z
        L{app.AppLogger.start} calls L{globalLogBeginner.addObserver}, and then
        writes some messages about twistd and the reactor.
        c                       S r)   rX   rg  s   r4   r   z+AppLoggerTests.test_start.<locals>.<lambda>|  s     r6   N)r
   	AppLoggerr  _getLogObserverr^   r   r  )rQ   r   rg  s     @r4   
test_startzAppLoggerTests.test_startu  sf    
 r""%%''!1!1!1!1]__%%%H%%%%%r6   c                     t                      }|                                 }|                    t          |           t	          j        i           } |j        |           |                     |           dS )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  r^   r  )rQ   r]   rg  r   s       r4   $test_startUsesApplicationLogObserverz3AppLoggerTests.test_startUsesApplicationLogObserver  so     $oo%%''  x888r""[!!!H%%%%%r6   c                     |                                  dfdi}|                    |            ||          } |j        |           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)   rX   r  s   r4   r   z7AppLoggerTests._setupConfiguredLogger.<locals>.<lambda>  s    X r6   )r  r@  r^   )rQ   r]   extraLogArgs	appLoggerlogArgsr   rg  s         @r4   _setupConfiguredLoggerz%AppLoggerTests._setupConfiguredLogger  sb    " %%''----.|$$$7##[!!!r6   c                 r    t                      }|                     |                     |                     dS )a  
        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  r\   s     r4   #test_startUsesConfiguredLogObserverz2AppLoggerTests.test_startUsesConfiguredLogObserver  s5     $ooD77DDEEEEEr6   c                    |                                  }t                      }|                    t          |           |                     |                     |                     |                     |j        g            dS )zk
        C{--logger} takes precedence over a L{ILogObserver} component set on
        Application.
        N)r  r   r  r   r  r  rz   r  )rQ   rg  r]   s      r4   (test_configuredLogObserverBeatsComponentz7AppLoggerTests.test_configuredLogObserverBeatsComponent  st    
 %%''#oo  x888D77DDEEE,,,,,r6   c                     g }t                      }|                    t          |j                   |                     |                     |                     |                     |g            dS )zq
        C{--logger} takes precedence over a L{LegacyILogObserver} component
        set on Application.
        N)r   r  LegacyILogObserverr   r  r  rz   )rQ   nonlogsr]   s      r4   .test_configuredLogObserverBeatsLegacyComponentz=AppLoggerTests.test_configuredLogObserverBeatsLegacyComponent  si    
 #oo  !3W^DDDD77DDEEE"%%%%%r6   c                 b   g }|                                  }t                      }|                    t          |           |                    t          |j                   t          j        i           } |j        |           | 	                    |           | 
                    |g            dS )zw
        A L{ILogObserver} takes precedence over a L{LegacyILogObserver}
        component set on Application.
        N)r  r   r  r   r  r   r
   r  r^   r  rz   )rQ   r  rg  r]   r   s        r4   .test_loggerComponentBeatsLegacyLoggerComponentz=AppLoggerTests.test_loggerComponentBeatsLegacyLoggerComponent  s    
 %%''#oo  x888  !3W^DDDr""[!!!H%%%"%%%%%r6   r   zsyslog not availablec                     t          |           }t                      }|                     |                     |ddit                               |                     |g            dS )z`
        C{--logger} takes precedence over a C{--syslog} command line
        argument.
        ru  TN)rw  r   r  r  r"   rz   )rQ   logsr]   s      r4   %test_configuredLogObserverBeatsSyslogz4AppLoggerTests.test_configuredLogObserverBeatsSyslog  sj     D!!#oo''h5E}UU	
 	
 	
 	r"""""r6   c                    t                      }|                                 }|                     |                     |ddi                     |                     t
          j                            |                     dS )za
        C{--logger} takes precedence over a C{--logfile} command line
        argument.
        logfiler   N)r   r   r  r  r   r:   r   r   )rQ   r]   r   s      r4   &test_configuredLogObserverBeatsLogfilez5AppLoggerTests.test_configuredLogObserverBeatsLogfile  st    
 $oo{{}}''i5HII	
 	
 	
 	--.....r6   c                    t          j        ddi          }t          | j                  } |j                     |                     t          |          d           |                     |d         t          j	                   t          j        ddi          } |j                     |                     t          |          d           |                     |d         t          j	                   dS )z
        When logfile is empty or set to C{-}, L{app.AppLogger._getLogObserver}
        returns a log observer pointing at C{sys.stdout}.
        r  -r   r    r  N)
r
   r  ri  rD   r  rz   r  r   r/  r   )rQ   r   re  s      r4   test_getLogObserverStdoutz(AppLoggerTests.test_getLogObserverStdout  s    
 	3/00,TZ88   X***hqk3:...	2//   X***hqk3:.....r6   c                    t          | j                  }|                                 }t          j        d|i          }|                                }|                     |j        j                   | 	                    t          |          d           | 	                    |d         j        t          j                            |                     dS )z
        When passing the C{logfile} option, L{app.AppLogger._getLogObserver}
        returns a log observer pointing at the specified path.
        r  r   r   N)ri  rD   r   r
   r  r  
addCleanup_outFiler  rz   r  r   r:   abspath)rQ   re  filenamesutrg  s        r4   test_getLogObserverFilez&AppLoggerTests.test_getLogObserverFile  s    
 -TZ88;;==mY122&&(()/000X***!)27??8+D+DEEEEEr6   c                 l   g t                      }fd}|                     t          d|           t          j        i           }||_         |j                     |                     |g            |j                     |                     |g           |                     |j                   dS )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                 2                         |            d S r)   r@  )rg  removeds    r4   removez(AppLoggerTests.test_stop.<locals>.remove  s    NN8$$$$$r6   r  N)	r2  rD   r   r
   r  	_observerr   rz   r   )rQ   rg  r  r   r  s       @r4   	test_stopzAppLoggerTests.test_stop  s     88	% 	% 	% 	% 	% 	

%'7@@@r""#8*---8*---&*+++++r6   c                    g t          j        i           }t          t                     G fdd                      fd|_         |j        t                                 |                     dt          d                              | 	                    | j
        g          }|                     t          |          d|           dS )zt
        L{app.AppLogger} using a legacy logger observer still works, wrapping
        it in a compat shim.
        c                       e Zd ZdZ fdZdS );AppLoggerTests.test_legacyObservers.<locals>.LoggerObserverzX
            An observer which implements the legacy L{LegacyILogObserver}.
            c                 2                         |           dS )z<
                Add C{x} to the logs list.
                Nr@  )rQ   xr  s     r4   r  zDAppLoggerTests.test_legacyObservers.<locals>.LoggerObserver.__call__5  s     Ar6   N)rS   rT   rU   rV   r  r  s   r4   LoggerObserverr  /  s8               r6   r  c                                    S r)   rX   )r  s   r4   r   z5AppLoggerTests.test_legacyObservers.<locals>.<lambda>;  s    ..*:*: r6   r  r   N)r
   r  r   r  _observerFactoryr^   r   r   r   r  test_legacyObserversrz   r  )rQ   r   warningsr  r  s      @@r4   r  z#AppLoggerTests.test_legacyObservers'  s    
 r""	'	(	(		 		 		 		 		 		 		 		 		 
)	(		 #;":":":]__%%%m%6tAw%?%?@@@%%t'@&ABBX844444r6   c                    g t          j        i           }fd|_         |j        t	                                 |                     dt          d                              |                     | j        g          }| 	                    t          |          d|           | 	                    |d         d         d           dS )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                       j         S r)   r@  r  s   r4   r   zAAppLoggerTests.test_unmarkedObserversDeprecated.<locals>.<lambda>J  s	     r6   r  r   r   r   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  r^   r   r   r   r   test_unmarkedObserversDeprecatedrz   r  )rQ   r   r  r  s      @r4   r  z/AppLoggerTests.test_unmarkedObserversDeprecatedB  s     r""!4!4!4!4]__%%%m%6tAw%?%?@@@%%t'L&MNNX8444QK	"0	
 	
 	
 	
 	
r6   N)rS   rT   rU   rV   r  r  r  r  r  r  r
   r  r  r  r  r  r  r   r   ru  r  r  r  r  r  r  r  rX   r6   r4   ry  ry  =  s}        H H H8 8 8  "H H H	& 	& 	&& & & )+cm   0F F F	- 	- 	-	& 	& 	&& & &" V9::VJ.//
# 
# 0/ ;:
#
/ 
/ 
// / /&F F F, , ,*5 5 56
 
 
 
 
r6   ry  c                   b    e Zd ZdZd Zd Zd Zd Zd Zd Z	 e
e d          d	             Zd
S )UnixAppLoggerTestszw
    Tests for L{UnixAppLogger}.

    @ivar signals: list of signal handlers installed.
    @type signals: C{list}
    c                 X     g  _          fd}                     t          d|           dS )zs
        Fake C{signal.signal} for not installing the handlers but saving them
        in C{self.signals}.
        c                 @    j                             | |f           d S r)   )signalsr   )r   r   rQ   s     r4   
fakeSignalz,UnixAppLoggerTests.setUp.<locals>.fakeSignalp  s#    La)))))r6   signalN)r  rD   r  )rQ   r  s   ` r4   r  zUnixAppLoggerTests.setUpi  sC    
 	* 	* 	* 	* 	* 	

68Z00000r6   c                    t          | j                  }t          ddd          } |j                     |                     t          |          d           |                     |d         t          j                   t          ddd          } |j                     |                     t          |          d           |                     |d         t          j                   dS )	z
        When non-daemonized and C{logfile} is empty or set to C{-},
        L{UnixAppLogger._getLogObserver} returns a log observer pointing at
        C{sys.stdout}.
        r  Tr  rC  r   r   r  r  N)	ri  rD   r"   r  rz   r  r   r/  r   rQ   re  r   s      r4   r  z,UnixAppLoggerTests.test_getLogObserverStdoutu  s     -TZ883DAABB   X***hqk3:...24@@AA   X***hqk3:.....r6   c                     t          ddd          }|                     t          |j                  }|                     t          |          d           dS )z
        When daemonized and C{logfile} is set to C{-},
        L{UnixAppLogger._getLogObserver} raises C{SystemExit}.
        r  Fr  z&Daemons cannot log to stdout, exiting!N)r"   r   r   r  rz   r   )rQ   r   rW  s      r4   test_getLogObserverStdoutDaemonz2UnixAppLoggerTests.test_getLogObserverStdoutDaemon  sT    
 3EBBCC!!*f.DEEU%MNNNNNr6   c                    t          | j                  }|                                 }t          d|i          }|                                }|                     |j        j                   |                     t          |          d           |                     |d         j
        t          j
                            |                     |                     t          | j                  d           |                     | j        d         d         t          j                   t!                      fd}||d         _        | j        d         d         } |dd           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  r   r   c                  2                          d            d S r)   )callback)ds   r4   rotatez:UnixAppLoggerTests.test_getLogObserverFile.<locals>.rotate  s    JJtr6   N)ri  rD   r   r"   r  r  r  r  rz   r  r   r:   r  r  r  SIGUSR1r   r  )rQ   re  r  r  rg  r  	rotateLogr  s          @r4   r  z*UnixAppLoggerTests.test_getLogObserverFile  s=    -TZ88;;==Y122&&(()/000X***!)27??8+D+DEEET\**A...a+V^<<<JJ	 	 	 	 	 $LOA&		$r6   c                 0     fd}                      t          d|                                            }t          d|i          }|                                }                     |j        j                                         j	        g            dS )zy
        If a signal handler is already installed,
        L{UnixAppLogger._getLogObserver} doesn't override it.
        c                 `                         | t          j                   t                      S r)   )rz   r  r  r2  )r   rQ   s    r4   fakeGetSignalzVUnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandler.<locals>.fakeGetSignal  s$    S&.11188Or6   	getsignalr  N)
rD   r  r   r"   r  r  r  r  rz   r  )rQ   r  r  r  rg  s   `    r4   ,test_getLogObserverDontOverrideSignalHandlerz?UnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandler  s    	 	 	 	 	 	

6;666;;==Y122&&(()/000r*****r6   c                 2   t          | j                  }t          ddd          } |j                     |                     t          |          d           |                     |d         j        t          j                            d                     dS )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  Fr  r   r   z
twistd.logN)	ri  rD   r"   r  rz   r  r   r:   r  r  s      r4   test_getLogObserverDefaultFilez1UnixAppLoggerTests.test_getLogObserverDefaultFile  s     -TZ8825AABB   X***!)27??<+H+HIIIIIr6   r   c                     t          |           }t          ddd          } |j                    }|                     |dg            |ddi           |                     |dddig           dS )z
        If C{syslog} is set to C{True}, L{UnixAppLogger._getLogObserver} starts
        a L{syslog.SyslogObserver} with given C{prefix}.
        Tztest-prefix)ru  rn  r  bN)rw  r"   r  rz   )rQ   r  r   rg  s       r4   test_getLogObserverSyslogz,UnixAppLoggerTests.test_getLogObserverSyslog  s     D!!$-HHII)6)++///#sSz:;;;;;r6   N)rS   rT   rU   rV   r  r  r  r  r  r  r   r   r  rX   r6   r4   r  r  `  s         
1 
1 
1/ / /$O O O  <+ + +&J J J V9::
< 
< ;:
< 
< 
<r6   r  z!twistd unix support not availablec                   r    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd ZdS )DaemonizeTestszH
    Tests for L{_twistd_unix.UnixApplicationRunner} daemonization.
    c                    t                      | _        t          j                    | _        |                     t          d| j                   t                              | j                  | _        t          j
        d          | j        _        t          j        | j        _        t          j        | j        _        d | j        _        d S )Nr:   r  c                      d S r)   rX   )r   s    r4   r   z&DaemonizeTests.setUp.<locals>.<lambda>  s     r6   )r   mockosr   r}   r   rD   r   r!   r  r   r  r]   r/  r   rK  stderrrL  rM  rc   s    r4   r  zDaemonizeTests.setUp  s    hh*,,

<t{333"88EE")"5e"<"< #
 #
#5#5   r6   c                 &   t          t                                5  | j                                         ddd           n# 1 swxY w Y   |                     | j        j        g d           |                     | j        j        ddg           dS )zw
        When double fork succeeded in C{daemonize}, the child process writes
        B{0} to the status pipe.
        N)r  r  r   r  forkTsetsidr  )r      0unlinkz
twistd.pidr  )r   r  r  rf   rz   r  actionsclosedrc   s    r4   test_successzDaemonizeTests.test_success  s    
 46677 	* 	*K'')))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*K  	
 	
 	
 	+b"X66666s   AA	Ac                 l   d| j         _        d| j         _        t          t	                                5  |                     t          | j        j                   ddd           n# 1 swxY w Y   | 	                    | j         j
        g d           | 	                    | j         j        dg           dS )z
        The parent process initiating the C{daemonize} call reads data from the
        status pipe and then exit the process.
        Fr  N)r  r  r  r  d   exitr   r  r  )r  childreadDatar   r  r   SystemErrorr  rf   rz   r  r  rc   s    r4   test_successInParentz#DaemonizeTests.test_successInParent  s   
 "#46677 	H 	Hk4;+FGGG	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	HK  
	
 
	
 
	
 	+bT22222s   &A&&A*-A*c                 ~   g fd}|| j         _        t          t                                5  | j                                         ddd           n# 1 swxY w Y   |                     | j         j        g d           |                     | j         j        ddg           |                     ddg           dS )z
        If the C{os.write} call to the status pipe raises an B{EINTR} error,
        the process child retries to write.
        c                                          | |f           t                    dk    rt          t          j                  d S r  r   r  r   r   EINTR)fdr+  writtens     r4   raisingWritez6DaemonizeTests.test_successEINTR.<locals>.raisingWrite  sB    NNB:&&&7||q  ek*** ! r6   N)r  r  r  r  r  r  r  r  )r  r  )	r  r   r   r  r  rf   rz   r  r  )rQ   r  r  s     @r4   test_successEINTRz DaemonizeTests.test_successEINTR  s   
 	+ 	+ 	+ 	+ 	+
 )46677 	* 	*K'')))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*K  
	
 
	
 
	
 	+b"X666*j17;;;;;s   AAAc                    g fd}|| j         _        d| j         _        t          t	                                5  |                     t          | j        j                   ddd           n# 1 swxY w Y   | 	                    | j         j
        g d           | 	                    | j         j        dg           | 	                    ddg           dS )z
        If the C{os.read} call on the status pipe raises an B{EINTR} error, the
        parent child retries to read.
        c                                          | |f           t                    dk    rt          t          j                  dS )Nr   r  r  )r  sizer  s     r4   raisingReadz=DaemonizeTests.test_successInParentEINTR.<locals>.raisingRead;  s=    KKT
###4yyA~~ek***4r6   FN)r  r  r  r  r  r  )r  r  )r  r  r  r   r  r   r  r  rf   rz   r  r  )rQ   r  r  s     @r4   test_successInParentEINTRz(DaemonizeTests.test_successInParentEINTR4  s>   
 	 	 	 	 	 '!46677 	H 	Hk4;+FGGG	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	HK  		
 		
 		
 	+bT222)Y/66666s   &A..A25A2c                     G fddt           j                  } |            }|                    | j        j                   t          t                                5  |                     t          | j        j	                   ddd           n# 1 swxY w Y   | 
                    | j        j        ddddddd	|fd
g           | 
                    | j        j        dd	g           dS )z
        Assert L{UnixApplicationRunner.postApplication} writes
        C{reported} to its status pipe if the service raises an
        exception whose message is C{raised}.
        c                       e Zd Z fdZdS )6DaemonizeTests.assertErrorWritten.<locals>.FakeServicec                 "    t                    r)   rJ  )rQ   raiseds    r4   r`  zCDaemonizeTests.assertErrorWritten.<locals>.FakeService.startServiceZ  s    "6***r6   N)rS   rT   rU   r`  )r  s   r4   re  r  Y  s.        + + + + + + +r6   re  Nr  r  r  r  r   r  r  r  )r   rO   rY  r  r]   r   r  r   r$  rf   rz   r  r  r  )rQ   r  reportedre  errorServices    `   r4   assertErrorWrittenz!DaemonizeTests.assertErrorWrittenR  s]   	+ 	+ 	+ 	+ 	+ 	+ 	+'/ 	+ 	+ 	+ #{}}%%dk&=>>>46677 	I 	IlDK,GHHH	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	IK "h'(	
 	
 	
 	+b"X66666s    &BBBc                 4    |                      dd           dS )z
        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  rc   s    r4   
test_errorzDaemonizeTests.test_errorp  s1    
 	'2W 	  	
 	
 	
 	
 	
r6   c                 4    |                      dd           dS )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   rc   s    r4   test_unicodeErrorz DaemonizeTests.test_unicodeErrory  s$     	x:TUUUUUr6   c                    d| j         _        || j         _        t                      }|                     t
          d|           t          t                                5  |                     t          | j
        j                   ddd           n# 1 swxY w Y   |                     |                                |           |                     | j         j        |           |                     | j         j        dg           dS )a  
        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  rf   rz   r   r  r  )rQ   r  errorMessagemockOSActionserrorIOs        r4   assertErrorInParentBehaviorz*DaemonizeTests.assertErrorInParentBehavior  s-    "'**

3g...46677 	H 	Hk4;+FGGG	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H 	H))++\:::,m<<<+bT22222s   &BBBc                 :    |                      ddg d           dS )z
        When the child writes an error message to the status pipe
        during daemonization, the parent writes the repr of the
        message to C{stderr} and exits with non-zero status code.
        s    1 Exception: An identified errorzgAn error has occurred: b'Exception: An identified error'
Please look at log file for more information.
r  r  r  r   )r  r   r  r  r&  r'  Nr)  rc   s    r4   test_errorInParentz!DaemonizeTests.test_errorInParent  sC     	((8B   	) 	
 	
 	
 	
 	
r6   c                 :    |                      ddg d           dS )z
        When the child writes a non-ASCII error message to the status
        pipe during daemonization, the parent writes the repr of the
        message to C{stderr} and exits with a non-zero status code.
        s   1 Exception: zXAn error has occurred: b'Exception: \xff'
Please look at log file for more information.
r+  r,  Nr-  rc   s    r4   test_nonASCIIErrorInParentz)DaemonizeTests.test_nonASCIIErrorInParent  sC     	(()B   	) 	
 	
 	
 	
 	
r6   c                     d}d                     d          }|                     |d                     |          g d           dS )a
  
        When the child writes a non-ASCII error message to the status
        pipe during daemonization, and that message is too longer, the
        parent writes the repr of the truncated message to C{stderr}
        and exits with a non-zero status code.
        d   1 RuntimeError: \u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022zb'RuntimeError: {}'zb\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022zHAn error has occurred: {}
Please look at log file for more information.
r+  r,  N)r   r)  )rQ   truncatedMessagereportedMessages      r4   &test_errorInParentWithTruncatedUnicodez5DaemonizeTests.test_errorInParentWithTruncatedUnicode  ss     A 066GG((%BBH&#C C   	) 	
 	
 	
 	
 	
r6   c                 4    |                      dd           dS )z{
        If an error occurs during daemonization and its message is too
        long, it's truncated by the child.
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsd   1 RuntimeError: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr  Nr   rc   s    r4   test_errorMessageTruncatedz)DaemonizeTests.test_errorMessageTruncated  s1    
 	'F 	  	
 	
 	
 	
 	
r6   c                 4    |                      dd           dS )z
        If an error occurs during daemonization and its message is
        unicode and too long, it's truncated by the child, even if
        this splits a unicode escape sequence.
        uZ   ••••••••••••••••••••••••••••••r2  r  Nr   rc   s    r4   !test_unicodeErrorMessageTruncatedz0DaemonizeTests.test_unicodeErrorMessageTruncated  s1     	 : 	  	
 	
 	
 	
 	
r6   c                     t                      }| j                            |           |                     |j                   |                     |j                   dS )z
        C{daemonize} indeed calls L{IReactorDaemonize.beforeDaemonize} and
        L{IReactorDaemonize.afterDaemonize} if the reactor implements
        L{IReactorDaemonize}.
        N)r  r  r  r   r  r  r  s     r4   test_hooksCalledzDaemonizeTests.test_hooksCalled  sU     )**g&&&6777566666r6   c                     t                      }| j                            |           |                     |j                   |                     |j                   dS )z
        C{daemonize} does NOT call L{IReactorDaemonize.beforeDaemonize} or
        L{IReactorDaemonize.afterDaemonize} if the reactor does NOT implement
        L{IReactorDaemonize}.
        N)r  r  r  r   r  r  r  s     r4   test_hooksNotCalledz"DaemonizeTests.test_hooksNotCalled  sY     ,--g&&&7888677777r6   N)rS   rT   rU   rV   r  r  r  r  r  r  r!  r#  r)  r.  r0  r5  r8  r:  r<  r>  rX   r6   r4   r  r    s        6 6 67 7 7*3 3 3,< < <:7 7 7<7 7 7<
 
 
V V V3 3 3"
 
 
,
 
 
,
 
 
:
 
 
	
 	
 	
	7 	7 	7	8 	8 	8 	8 	8r6   r  c                   H    e Zd ZdZed             Zej        d             ZdS )SignalCapturingMemoryReactorz
    MemoryReactor that implements the _ISupportsExitSignalCapturing interface,
    all other operations identical to MemoryReactor.
    c                     | j         S r)   _valrc   s    r4   r  z(SignalCapturingMemoryReactor._exitSignal  s
    yr6   c                     || _         d S r)   rB  )rQ   vals     r4   r  z(SignalCapturingMemoryReactor._exitSignal  s    			r6   N)rS   rT   rU   rV   propertyr  setterrX   r6   r4   r@  r@    sX         
   X     r6   r@  c                   2     e Zd ZdZeZ fdZd Zd Z xZ	S )StubApplicationRunnerWithSignalz
    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                 X    t                                          |           d | _        d S r)   )superrr   _signalValue)rQ   r   	__class__s     r4   rr   z(StubApplicationRunnerWithSignal.__init__!  s)        r6   c                     dS )z
        Does nothing.
        NrX   rc   s    r4   rd   z.StubApplicationRunnerWithSignal.preApplication%  r!  r6   c                     t                      }| j        |_        |                     |t          j        t          j                   dS )z`
        Instantiate a SignalCapturingMemoryReactor and start it
        in the runner.
        N)r@  rL  r  rM  r/  r   r  r  s     r4   rf   z/StubApplicationRunnerWithSignal.postApplication*  s<    
 /00"/'3:sz:::::r6   )
rS   rT   rU   rV   rZ   rg   rr   rd   rf   __classcell__)rM  s   @r4   rI  rI    sg          &M! ! ! ! !  
; ; ; ; ; ; ;r6   rI  c                       fd}|S )aI  
    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                 4    t          |           }|_        |S )a  
        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
        )rI  rL  )r   r  signums     r4   stubApplicationRunnerFactoryzIstubApplicationRunnerFactoryCreator.<locals>.stubApplicationRunnerFactoryA  s     188$r6   rX   )rS  rT  s   ` r4   #stubApplicationRunnerFactoryCreatorrU  4  s$          ('r6   c                   *    e Zd ZdZd Zd Zd Zd ZdS )ExitWithSignalTestsz?
    Tests for L{twisted.application.app._exitWithSignal}.
    c                     t          j                     _        dt                      i j        _        t                       j        _        d j        _        ddg _         fd} 	                    t          d|           dS )zM
        Set up the server options and a fake for use by test cases.
        r/  Nc                 0    | j         d<   |j         d<   dS )z
            Fake method to capture arguments passed to os.kill.

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

            @param sig: The signal sent to the process.
            r   r   N)fakeKillArgs)r   r   rQ   s     r4   fakeKillz+ExitWithSignalTests.setUp.<locals>.fakeKilld  s%     $'Da #&Da   r6   r   )r   r}   r   rK   r1  r2  r3  r   rZ  rD   r:   )rQ   r[  s   ` r4   r  zExitWithSignalTests.setUpZ  s     *,,%35E5G5G$H!!'!/!4L		' 		' 		' 		' 		' 	

2vx(((((r6   c                    ddgfd}|                      t          d|           t          j        t          j                   |                     d         t          j                   |                     d         t          j                   |                     | j        d         t          j	                               |                     | j        d         t          j                   dS )z
        exitWithSignal replaces the existing signal handler with the default
        handler and sends the replaced signal to the current process.
        Nc                     | d<   |d<   d S )Nr   r   rX   )r   handlerfakeSignalArgss     r4   fake_signalz<ExitWithSignalTests.test_exitWithSignal.<locals>.fake_signaly  s     #N1 'N1r6   r  r   r   )
rD   r  r
   _exitWithSignalSIGINTr  SIG_DFLrZ  r:   r   )rQ   r`  r_  s     @r4   test_exitWithSignalz'ExitWithSignalTests.test_exitWithSignalq  s     	( 	( 	( 	( 	( 	

68[111FM***.+V];;;.+V^<<<$+A.	<<<$+A.>>>>>r6   c                 
   |                      t          dt          d                     t          j        | j                   |                     | j        d                    |                     | j        d                    dS )zb
        _exitWithSignal is not called if the runner does not exit with a
        signal.
        rf  Nr   r   )rD   r   rU  runAppr   r   rZ  rc   s    r4   test_normalExitz#ExitWithSignalTests.test_normalExit  s~    
 	

,.QRV.W.W	
 	
 	
 	dk"""$+A.///$+A./////r6   c                 X   |                      t          dt          t          j                             t          j        | j                   |                     | j        d         t          j
                               |                     | j        d         t          j                   dS )zP
        _exitWithSignal is called when the runner exits with a signal.
        rf  r   r   N)rD   r   rU  r  rb  rf  r   r  rZ  r:   r   rc   s    r4   test_runnerExitsWithSignalz.ExitWithSignalTests.test_runnerExitsWithSignal  s     	

$/>>	
 	
 	

 	dk"""$+A.	<<<$+A.>>>>>r6   N)rS   rT   rU   rV   r  rd  rg  ri  rX   r6   r4   rW  rW  T  sZ         ) ) ).? ? ?(
0 
0 
0? ? ? ? ?r6   rW  )hrV   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.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.proto_helpersr   twisted.test.test_processr   twisted.trial.unittestr    r   twisted.scripts._twistd_unixr!   r"   r#   ru  r$   r%   r&   rI   rK   r  rZ   rf  ra   ri   r   r	  r  r%  r#  r-  r  r  r  r  r  rx  r&  ri  rw  ry  r  r  r@  rI  rU  rW  rX   r6   r4   <module>r     s?   
   				   




 C
CC    
C
CCC             & & & & & & . . . . . . , , , , , , , , , , 6 6 6 6 6 6 6 6 6 6 5 5 5 5 5 5 - - - - - - + + + + + + X X X X X X X X @ @ @ @ @ @ N N N N N N N N N N       3 3 3 3 3 3 / / / / / / T T T T T T T T 0 0 0 0 0 0 / / / / / / + + + + + + " " " " " " 4 4 4 4 4 4 , , , , , , + + + + + +};<<           
.	/	/
-	
"
"	x	 	 =$$*. *. *.Z       "            =    UJ UJ UJ UJ UJ UJ UJ UJp L566CK CK CK CK CKH CK CK 76CKLD D D D D8 D D D0       *J J J J JC1 J J J(q4 q4 q4 q4 q4X q4 q4 q4h L566F+ F+ F+ F+ F+ F+ F+ 76F+R L566IG IG IG IG IG IG IG 76IGX L566> > > > >( > > 76><       8     6           (w8 w8 w8 w8 w8 w8 w8 w8t  *  $`
 `
 `
 `
 `
X `
 `
 `
F	 L566x< x< x< x< x< x< x< 76x<v L=>>f8 f8 f8 f8 f8X f8 f8 ?>f8R	 *++    =   ,+; ; ; ; ;f&C ; ; ;<( ( (@H? H? H? H? H?( H? H? H? H? H?s   ) 	55