HEX
Server: Apache
System: Linux scp1.abinfocom.com 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: confeduphaar (1010)
PHP: 8.1.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //usr/lib/python3/dist-packages/twisted/test/__pycache__/test_twistd.cpython-38.pyc
U


W[�!�@sldZddlmZmZddlZddlZddlZddlZddlZzddl	Z	ddl
Z
Wnek
rldZ	Z
YnXzddlZ
Wnek
r�ddl
Z
YnXddlmZddlmZddlmZddlmZddlmZmZmZdd	lmZmZmZdd
lmZddl m!Z!ddl"m#Z#m$Z$dd
l%m&Z&ddl'm(Z(m)Z)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0m1Z1ddl2m3Z3ddl4m5Z5ddl6m*Z7m8Z8ddl9m:Z:ddl;m<Z<ddl=m>Z>ddl?m@Z@zddl?mAZAWnek
�r�dZAYn&XddlBmCZCddlBmDZDddlBmEZEzddl4mFZFWnek
�r2dZFYnXzddlGZGWnek
�rZdZGYnXzddlHZHddlIZIWnek
�r�dZIYnXeJedd�dk�r�dZKndZKd d!�ZLGd"d#�d#eM�ZNGd$d%�d%ejO�ZPGd&d'�d'e@jQ�ZRGd(d)�d)ejS�ZTGd*d+�d+ejS�ZUGd,d-�d-ejS�ZVGd.d/�d/eM�ZWGd0d1�d1ejX�ZYGd2d3�d3ejS�ZZGd4d5�d5ejS�Z[Gd6d7�d7ejS�Z\Gd8d9�d9ejS�Z]Gd:d;�d;eM�Z^ee#�Gd<d=�d=e^��Z_Gd>d?�d?eM�Z`Gd@dA�dAejS�ZadBdC�ZbdDdE�ZcGdFdG�dGejS�ZdGdHdI�dIejS�ZeGdJdK�dKejS�Zfee$�GdLdM�dMe.��ZgGdNdO�dOe@jQ�ZhdPdQ�ZiGdRdS�dSejS�ZjeAdk�rhdTef_kdS)UzE
Tests for L{twisted.application.app} and L{twisted.scripts.twistd}.
�)�absolute_import�divisionN)�implementer)�verifyObject)�unittest)�MockOS)�plugin�logger�internet)�service�app�reactors)�
IServiceMaker)�Deferred)�IReactorDaemonize�_ISupportsExitSignalCapturing)�AlternateReactor)�globalLogBeginner�globalLogPublisher�ILogObserver)�ReactorBase)�
MemoryReactor)�NativeStringIO�_PY3)�
Componentized)�util)r�textFromEventDict)�platformType)�
UsageError)�UserDatabase)�twistd)�_twistd_unix)�checkPID)�UnixApplicationRunner)�
UnixAppLogger)�syslog�setuidz5Platform does not support --uid/--gid twistd options.c	s|t�t���}t�t����t�}|�||j	|�|j
|j|j����fdd�}|td|j
�|td|�|td|j�dS)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.
    cs<t��}�||��j�<�||��j�<t|�}�|i|S�N)�list�indexZgr_nameZgr_gid�tuple)�name�result��gidZgrent�group��:/usr/lib/python3/dist-packages/twisted/test/test_twistd.py�getgrnamys
z#patchUserDatabase.<locals>.getgrnam�getpwnamr2�getpwuidN)�pwdr4�os�getuid�grpZgetgrgid�getgidrZaddUserZ	pw_passwdZpw_gecos�pw_dirZpw_shellr3)�patch�user�uidr/r.�pwentZdatabaser2r0r-r1�patchUserDatabaseXs �r?c@seZdZdZdZdd�ZdS)�MockServiceMakerzO
    A non-implementation of L{twisted.application.service.IServiceMaker}.
    �ueoacCs||_t��|_|jS)ze
        Take a L{usage.Options} instance and return a
        L{service.IService} provider.
        )�optionsr�Service��selfrBr0r0r1�makeService�s
zMockServiceMaker.makeServiceN)�__name__�
__module__�__qualname__�__doc__�tapnamerFr0r0r0r1r@�sr@c@seZdZdZdd�ZdS)�CrippledAppLoggerz*
    @see: CrippledApplicationRunner.
    cCsdSr'r0�rE�applicationr0r0r1�start�szCrippledAppLogger.startN)rGrHrIrJrOr0r0r0r1rL�srLc@s$eZdZdZeZdd�Zdd�ZdS)�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.
    cCsdSr'r0�rEr0r0r1�preApplication�sz(CrippledApplicationRunner.preApplicationcCsdSr'r0rQr0r0r1�postApplication�sz)CrippledApplicationRunner.postApplicationN)rGrHrIrJrL�
loggerFactoryrRrSr0r0r0r1rP�srPc@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�ZedkrjdZ
e
e	_e
_e_dd�Zdd�Zdd�ZdS)�ServerOptionsTestszT
    Non-platform-specific tests for the platform-specific ServerOptions class.
    cs�Gdd�dt�}|d��|d��|d��|d�������fdd�}t��}��|jtj�||_|j}����g}t||�D]L\}}|\}}	}
}��||j	���
|	���|
�|j�f��||j�q~d	S)
zh
        subCommands is built from IServiceMaker plugins, and is sorted
        alphabetically.
        c@seZdZdd�Zdd�ZdS)z7ServerOptionsTests.test_subCommands.<locals>.FakePlugincSs||_d||_d||_dS)Nzoptions for �description of )rK�_options�description�rEr+r0r0r1�__init__�s
z@ServerOptionsTests.test_subCommands.<locals>.FakePlugin.__init__cSs|jSr')rWrQr0r0r1rB�sz?ServerOptionsTests.test_subCommands.<locals>.FakePlugin.optionsN)rGrHrIrZrBr0r0r0r1�
FakePlugin�sr[�apple�banana�coconut�donutc3s(��|t��V�V�V�VdSr')�assertEqualr)Z	interface�r\r]r^r_rEr0r1�
getPlugins�s
z7ServerOptionsTests.test_subCommands.<locals>.getPluginsN)
�objectr �
ServerOptionsr`Z_getPluginsrrb�subCommands�ziprK�assertIsNonerWrX)rEr[rb�configreZ
expectedOrder�
subCommandZexpectedCommandr+ZshortcutZparserClassZ
documentationr0rar1�test_subCommands�s"	
z#ServerOptionsTests.test_subCommandscs�Gdd�dt�}|d��|d��|d��|d������fdd�}t��}��|jtj�||_t�|_��	t
|jd	g�|j���g�����fD](}���fd
d�}||j
�||j�q����t��d�f�d
S)zP
        Reactor names are listed alphabetically by I{--help-reactors}.
        c@seZdZdd�ZdS)zGServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstallercSsd||_d||_d|_dS)Nzname of rVztwisted.internet.default)�	shortNamerXZ
moduleNamerYr0r0r1rZ�s

zPServerOptionsTests.test_sortedReactorHelp.<locals>.FakeReactorInstaller.__init__N)rGrHrIrZr0r0r0r1�FakeReactorInstaller�srlr\r]r^r_c3s�V�V�V�VdSr'r0r0)r\r]r^r_r0r1�getReactorTypes�szBServerOptionsTests.test_sortedReactorHelp.<locals>.getReactorTypesz--help-reactorscs ��|������|��dSr')�assertIn�appendr))�s)�
helpOutput�indexesrEr0r1�getIndex�sz;ServerOptionsTests.test_sortedReactorHelp.<locals>.getIndexz7reactor descriptions were not in alphabetical order: %rN)rcr rdr`Z_getReactorTypesr
rmrZ
messageOutput�assertRaises�
SystemExit�parseOptions�getvaluerkrX�sorted)rErlrmrh�reactorrsr0)r\r]r^r_rqrrrEr1�test_sortedReactorHelp�s0

��z)ServerOptionsTests.test_sortedReactorHelpcCs(t��}d|_|��|�|d�dS)zS
        postOptions should set no_save to True when a subcommand is used.
        rA�no_saveN)r rdri�postOptions�
assertTrue�rErhr0r0r1�&test_postOptionsSubCommandCausesNoSavesz9ServerOptionsTests.test_postOptionsSubCommandCausesNoSavecCs"t��}|��|�|d�dS)zR
        If no sub command is used, postOptions should not touch no_save.
        r{N)r rdr|�assertFalser~r0r0r1�(test_postOptionsNoSubCommandSavesAsUsualsz;ServerOptionsTests.test_postOptionsNoSubCommandSavesAsUsualcCs.t��}t|�}tjjD]}|�||�qdS)zq
        All the profilers that can be used in L{app.AppProfiler} are listed in
        the help output.
        N)r rd�strr�AppProfilerZ	profilersrn)rErhrq�profilerr0r0r1�test_listAllProfilerssz(ServerOptionsTests.test_listAllProfilerscCst��}|�|d�dS)zG
        The default value for the C{umask} option is L{None}.
        �umaskN)r rdrgr~r0r0r1�test_defaultUmask*sz$ServerOptionsTests.test_defaultUmaskcCsHt��}|�ddg�|�|dd�|�ddg�|�|dd�dS)zh
        The value given for the C{umask} option is parsed as an octal integer
        literal.
        �--umaskZ123r��SZ0123N)r rdrvr`r~r0r0r1�
test_umask2s
zServerOptionsTests.test_umaskcCs t��}|�t|jddg�dS)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�ZabcdefN)r rdrtrrvr~r0r0r1�test_invalidUmask>s
�z$ServerOptionsTests.test_invalidUmaskN�twistd unix not availablecCsHt��}|�t|jddg�}|�|jd�d��|�d|jd�dS)zQ
        C{--logger} with an unimportable module raises a L{UsageError}.
        �--loggerzno.such.module.I.hoperzeLogger 'no.such.module.I.hope' could not be imported: 'no.such.module.I.hope' does not name an object�
N)	r rdrtrrvr}�args�
startswith�assertNotIn�rErh�er0r0r1�&test_unimportableConfiguredLogObserverLs�
��z9ServerOptionsTests.test_unimportableConfiguredLogObservercCsjt��}|�t|jddg�}tjdkr>|�|jd�	d��n|�|jd�	d��|�
d|jd�dS)	zP
        C{--logger} with a non-existent object raises a L{UsageError}.
        r�ztwisted.test.test_twistd.FOOBAR)��rziLogger 'twisted.test.test_twistd.FOOBAR' could not be imported: 'module' object has no attribute 'FOOBAR'z{Logger 'twisted.test.test_twistd.FOOBAR' could not be imported: module 'twisted.test.test_twistd' has no attribute 'FOOBAR'r�N)r rdrtrrv�sys�version_infor}r�r�r�r�r0r0r1�*test_badAttributeWithConfiguredLogObserver[s 
�

��
��z=ServerOptionsTests.test_badAttributeWithConfiguredLogObservercCsvddlm}tdkrd}nd}d�||j|j�}t�}tj|d�}|�t	|j
dg�}|�|jd	�|�
|��|�d	S)
z2
        C{--version} prints the version.
        r)�	copyrightZwin32z(the Twisted Windows runner)z(the Twisted daemon)ztwistd {} {}
{}
)�stdoutz	--versionN)�twistedr�r�format�versionrr rdrtrurv�assertIs�coder`rw)rEr�r+ZexpectedOutputr�rhr�r0r0r1�test_versionps�zServerOptionsTests.test_version)rGrHrIrJrjrzrr�r�r�r�r�r!�msg�skipr�r�r�r0r0r0r1rU�s++
		rUc@sDeZdZdZedkrdZdd�Zdd�Zdd	�Zd
d�Z	dd
�Z
dS)�
CheckPIDTestsz 
    Tests for L{checkPID}.
    Nr�cCs |�tjddd��td�dS)z7
        Nonexistent PID file is not an error.
        �existscSsdS�NFr0)�_r0r0r1�<lambda>��z.CheckPIDTests.test_notExists.<locals>.<lambda>znon-existent PID fileN)r;r6�pathr"rQr0r0r1�test_notExists�szCheckPIDTests.test_notExistsc	CsH|��}t|d��}|�d�W5QRX|�tt|�}|�d|j�dS)zI
        Non-numeric content in a PID file causes a system exit.
        �wznon-numericznon-numeric valueN)�mktemp�open�writertrur"rnr�)rE�pidfile�fr�r0r0r1�test_nonNumeric�s
zCheckPIDTests.test_nonNumericc	Cs^|��}t|d��}|�d�W5QRXdd�}|�td|�|�tt|�}|�d|j	�dS)zE
        Another running twistd server causes a system exit.
        r�Z42cSsdSr'r0��pid�sigr0r0r1�kill�sz/CheckPIDTests.test_anotherRunning.<locals>.killr�zAnother twistd serverN)
r�r�r�r;r6rtrur"rnr��rEr�r�r�r�r0r0r1�test_anotherRunning�sz!CheckPIDTests.test_anotherRunningc	Csh|��}t|d��}|�tt��d��W5QRXdd�}|�td|�t|�|�tj	�
|��dS)zJ
        Stale PID file is removed without causing a system exit.
        r��cSsttjd��dS�NZfake)�OSError�errnoZESRCHr�r0r0r1r��sz&CheckPIDTests.test_stale.<locals>.killr�N)r�r�r�r�r6�getpidr;r"r�r�r�)rEr�r�r�r0r0r1�
test_stale�s zCheckPIDTests.test_stalec	Cst|��}t|d��}|�d�W5QRXdd�}|�td|�|�tt|�}|�|j	d�|�
|jd�d��dS)	z�
        An unexpected L{OSError} when checking the validity of a
        PID in a C{pidfile} terminates the process via L{SystemExit}.
        r�Z3581cSsttjd��dSr��r�r�ZEBADFr�r0r0r1r��sz2CheckPIDTests.test_unexpectedOSError.<locals>.killr�NrzCan't check status of PID)
r�r�r�r;r6rtrur"ZassertIsNotr�r}r�r�r�r0r0r1�test_unexpectedOSError�sz$CheckPIDTests.test_unexpectedOSError)rGrHrIrJr!r�r�r�r�r�r�r0r0r0r1r��sr�c@s eZdZdZdd�Zdd�ZdS)�TapFileTestszM
    Test twistd-related functionality that requires a tap file on disk.
    c	Cs8|��|_t|jd��}t�t�d�|�W5QRXdS)zP
        Create a trivial Application and put it in a tap file on disk.
        �wb�Hi!N)r��tapfiler��pickle�dumpr�Application)rEr�r0r0r1�setUp�s
zTapFileTests.setUpcCs<t��}|�d|jg�t|���}|�t�|�j	d�dS)z�
        Ensure that the createOrGetApplication call that 'twistd -f foo.tap'
        makes will load the Application out of foo.tap.
        z-fr�N)
r rdrvr�rPZcreateOrGetApplicationr`r�IServicer+)rErhrNr0r0r1�&test_createOrGetApplicationWithTapFile�s�z3TapFileTests.test_createOrGetApplicationWithTapFileN)rGrHrIrJr�r�r0r0r0r1r��s	r�c@s(eZdZdZdd�Zdd�Zdd�ZdS)	�TestLoggerFactoryz8
    A logger factory for L{TestApplicationRunner}.
    cCs
||_dSr')�runner)rEr�r0r0r1rZ�szTestLoggerFactory.__init__cCs"|jj�d�t|jd�|j_dS)zC
        Save the logging start on the C{runner} instance.
        �logrNN)r��orderro�hasattr�hadApplicationLogObserverrMr0r0r1rO�s�zTestLoggerFactory.startcCsdS)z%
        Don't log anything.
        Nr0rQr0r0r1�stop�szTestLoggerFactory.stopN)rGrHrIrJrZrOr�r0r0r0r1r��s	r�c@s(eZdZdZdd�Zdd�Zdd�ZdS)	�TestApplicationRunnerz`
    An ApplicationRunner which tracks the environment in which its methods are
    called.
    cCs"tj�||�g|_t|�|_dSr')r�ApplicationRunnerrZr�r�r	rDr0r0r1rZszTestApplicationRunner.__init__cCs|j�d�t|d�|_dS)N�prerN)r�ror��hadApplicationPreApplicationrQr0r0r1rRsz$TestApplicationRunner.preApplicationcCs|j�d�t|d�|_dS)N�postrN)r�ror��hadApplicationPostApplicationrQr0r0r1rSsz%TestApplicationRunner.postApplicationN)rGrHrIrJrZrRrSr0r0r0r1r�sr�c@sleZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Ze	e_
dd
�Ze	e_
dd�Zdd�Z
dd�Zdd�ZdS)�ApplicationRunnerTestszR
    Non-platform-specific tests for the platform-specific ApplicationRunner.
    cCs4t��}t�|_d|ji|_t�|_d|_||_dS)N�test_command)	r rdr@�serviceMaker�
loadedPluginsrc�
subOptionsrirhr~r0r0r1r�szApplicationRunnerTests.setUpcCsLt|j�}|��|�|jj|jjd�|�|jjt�|j	�j
dd�dS)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.rzPServiceMaker.makeService's result needs to be set as a child of the Application.N)rPrh�runr�r�rBr�rr�rN�services)rEZarunnerr0r0r1�,test_applicationRunnerGetsCorrectApplication%s
��zCApplicationRunnerTests.test_applicationRunnerGetsCorrectApplicationcCsNt|j�}|��|�|j�|�|j�|�|j�|�|j	dddg�dS)z�
        Test thet preApplication and postApplication methods are
        called by ApplicationRunner.run() when appropriate.
        r�r�r�N)
r�rhr�r�r�r}r�r�r`r�)rErpr0r0r1�test_preAndPostApplication9s
z1ApplicationRunnerTests.test_preAndPostApplicationc	s�|j�|�g�G�fdd�dtj�}ttjtj�G�fdd�dt��}|�}t	tj|�t	tj|�||j�}|�
�||_|��|�
�dddd||fd	d
g�dS)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.
        cs8eZdZ�fdd�Z�fdd�Z�fdd�Zdd�Zd	S)
z\ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunnercs��d�dS)N�environment�ro�rE�chrootZrundir�nodaemonr�r��Zeventsr0r1�setupEnvironmentTszmApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.setupEnvironmentcs��d|||f�dS)N�
privilegesr�)rE�euidr=r.r�r0r1�shedPrivilegesXszkApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.shedPrivilegescs��d�dS)Nryr�)rEry�	oldstdout�	oldstderrr�r0r1�startReactor[sziApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.startReactorcSsdSr'r0)rEr�r0r0r1�	removePID^szfApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeUnixApplicationRunner.removePIDN)rGrHrIr�r�r�r�r0r�r0r1�FakeUnixApplicationRunnerSsr�cs\eZdZdZdZdZdZdZdZdd�Z	dd�Z
dd�Z�fdd	�Z�fd
d�Z
dd
�ZdS)zNApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeServiceNcSsdSr'r0rYr0r0r1�setNamekszVApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setNamecSsdSr'r0)rE�parentr0r0r1�setServiceParentnsz_ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.setServiceParentcSsdSr'r0rQr0r0r1�disownServiceParentqszbApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.disownServiceParentcs��d�dS)N�privilegedStartServicer�rQr�r0r1r�tszeApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.privilegedStartServicecs��d�dS)N�startServicer�rQr�r0r1r�wsz[ApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.startServicecSsdSr'r0rQr0r0r1�stopServicezszZApplicationRunnerTests._applicationStartsWithConfiguredID.<locals>.FakeService.stopService)rGrHrIr��runningr+ZprocessNamer=r.r�r�r�r�r�r�r0r�r0r1�FakeServiceasr�r�r�r�Fr�ryN)rhrvr �_SomeApplicationRunnerrrr�ZIProcessrcrrRrNrSr`)rE�argvr=r.r�r�rNr�r0r�r1�"_applicationStartsWithConfiguredIDFs(	

��z9ApplicationRunnerTests._applicationStartsWithConfiguredIDcCs*d}d}|�dt|�dt|�g||�dS)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)r�r�)rEr=r.r0r0r1�.test_applicationStartsWithConfiguredNumericIDs�s�zEApplicationRunnerTests.test_applicationStartsWithConfiguredNumericIDscCs<d}d}d}d}t|j||||�|�d|d|g||�dS)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}.
        �foor��barr�r�r�N)r?r;r�)rEr<r=r/r.r0r0r1�+test_applicationStartsWithConfiguredNameIDs�s
�zBApplicationRunnerTests.test_applicationStartsWithConfiguredNameIDscCs8t�}t�dddd��}|�|dd�|�|jd�dS)z7
        L{startReactor} calls L{reactor.run}.
        F�profile�rr��debugNz'startReactor did not call reactor.run())�DummyReactorrr�r�r}�called�rEryr�r0r0r1�test_startReactorRunsTheReactor�s��z6ApplicationRunnerTests.test_startReactorRunsTheReactorcCsDt�}|�td|�t�dddd��}|�ddd�|�|j�dS)zN
        L{ApplicationRunner} chooses a reactor if none is specified.
        ryFrrN)rr;r
rr�r�r}rr	r0r0r1�*test_applicationRunnerChoosesReactorIfNone�s�zAApplicationRunnerTests.test_applicationRunnerChoosesReactorIfNonecCsHGdd�dt�}|�}t�dddd��}|�|dd�|�d|j�dS)zg
        If the reactor exits with a signal, the application runner caches
        the signal.
        c@s eZdZdZdd�Zdd�ZdS)z[ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal��
            A dummy reactor, providing a C{run} method, and setting the
            _exitSignal attribute to a nonzero value.
            cSsdS�z=
                Dummy method, does nothing.
                Nr0rQr0r0r1�installWaker�szhApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.installWakercSs
d|_dS)zZ
                A fake run method setting _exitSignal to a nonzero value
                �N��_exitSignalrQr0r0r1r��sz_ApplicationRunnerTests.test_applicationRunnerCapturesSignal.<locals>.DummyReactorWithSignal.runN�rGrHrIrJrr�r0r0r0r1�DummyReactorWithSignal�srFrrNr)rrr�r��assertEqualsr)rErryr�r0r0r1�$test_applicationRunnerCapturesSignal�s�z;ApplicationRunnerTests.test_applicationRunnerCapturesSignalcCsHGdd�dt�}|�}t�dddd��}|�|dd�|�d|j�dS)z�
        The runner sets its _exitSignal instance attribute to None if
        the reactor does not implement L{_ISupportsExitSignalCapturing}.
        c@s eZdZdZdd�Zdd�ZdS)ziApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttributercSsdSr
r0rQr0r0r1r�szvApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.installWakercSs
d|_dS)z�
                A fake run method setting _exitSignal to a nonzero value
                that should be ignored.
                rNrrQr0r0r1r��szmApplicationRunnerTests.test_applicationRunnerIgnoresNoSignal.<locals>.DummyReactorWithExitSignalAttribute.runNrr0r0r0r1�#DummyReactorWithExitSignalAttribute�srFrrN)rcrr�r�rr)rErryr�r0r0r1�%test_applicationRunnerIgnoresNoSignal�s�z<ApplicationRunnerTests.test_applicationRunnerIgnoresNoSignalN)rGrHrIrJr�r�r�r�r�
setuidSkipr�rr
rrrr0r0r0r1r�s

F r�c@s�eZdZdZedkrdZe�Zdd�Zdd�Z	dd	�Z
d
d�Zdd
�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�ZdS)�*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}.
    Nr�cs��j�_�j�_�j�_d�_t���_��td�fdd����td�fdd����td�fdd��t	t
����_�j
�j_
dS)	NFr�cst�d|�S)N�root��setattr�r�rQr0r1r�(r�zBUnixApplicationRunnerSetupEnvironmentTests.setUp.<locals>.<lambda>�chdircst�d|�S)N�cwdrrrQr0r1r�)r�r�cst�d|�S)N�maskr)r rQr0r1r�*r�)�unsetrrr �daemonr6r�r�r;r#r rdr��	daemonizerQr0rQr1r�"s
z0UnixApplicationRunnerSetupEnvironmentTests.setUpcs d�_��td�fdd��dS)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�cs
�jdS�Nr�)r�r0rQr0r1r�5r�zFUnixApplicationRunnerSetupEnvironmentTests.daemonize.<locals>.<lambda>N)r"r;r6�rEryr0rQr1r#/sz4UnixApplicationRunnerSetupEnvironmentTests.daemonizecCs&|j�ddddd�|�|jd�dS)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�r�r`rrQr0r0r1�test_chroot8sz6UnixApplicationRunnerSetupEnvironmentTests.test_chrootcCs(|j�ddddd�|�|j|j�dS)z�
        L{UnixApplicationRunner.setupEnvironment} does not change the root of
        the filesystem if passed L{None} for the C{chroot} parameter.
        Nr'T)r�r�r�rr!rQr0r0r1�
test_noChrootAsz8UnixApplicationRunnerSetupEnvironmentTests.test_noChrootcCs&|j�ddddd�|�|jd�dS)z�
        L{UnixApplicationRunner.setupEnvironment} changes the working directory
        of the process to the path given for the C{rundir} parameter.
        Nr&T)r�r�r`rrQr0r0r1�test_changeWorkingDirectoryJszFUnixApplicationRunnerSetupEnvironmentTests.test_changeWorkingDirectoryc	Cs:tt���|j�ddddd�W5QRX|�|j�dS)z�
        L{UnixApplicationRunner.setupEnvironment} daemonizes the process if
        C{False} is passed for the C{nodaemon} parameter.
        Nr'F)r�FakeDaemonizingReactorr�r�r}r"rQr0r0r1�test_daemonizeSsz9UnixApplicationRunnerSetupEnvironmentTests.test_daemonizecCs$|j�ddddd�|�|j�dS)z�
        L{UnixApplicationRunner.setupEnvironment} does not daemonize the
        process if C{True} is passed for the C{nodaemon} parameter.
        Nr'T)r�r�r�r"rQr0r0r1�test_noDaemonize]sz;UnixApplicationRunnerSetupEnvironmentTests.test_noDaemonizec	CsP|��}|j�dddd|�t|d��}t|���}W5QRX|�||j�dS)z�
        L{UnixApplicationRunner.setupEnvironment} writes the process's PID to
        the file specified by the C{pidfile} parameter.
        Nr'T�rb)r�r�r�r��int�readr`r��rEr�r�r�r0r0r1�test_nonDaemonPIDFilefs
z@UnixApplicationRunnerSetupEnvironmentTests.test_nonDaemonPIDFilec	Csj|��}tt���|j�dddd|�W5QRXt|d��}t|���}W5QRX|�||j	d�dS)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�rr+r�r�r�r/r0r`r�r1r0r0r1�test_daemonPIDFilersz=UnixApplicationRunnerSetupEnvironmentTests.test_daemonPIDFilec	Cs<tt���|j�ddddd�W5QRX|�|jd�dS)z�
        L{UnixApplicationRunner.setupEnvironment} changes the process umask to
        the value specified by the C{umask} parameter.
        Nr'F�{�rr+r�r�r`r rQr0r0r1r��sz5UnixApplicationRunnerSetupEnvironmentTests.test_umaskcCs(|j�ddddd�|�|j|j�dS)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�r�r�r r!rQr0r0r1�test_noDaemonizeNoUmask�szBUnixApplicationRunnerSetupEnvironmentTests.test_noDaemonizeNoUmaskc	Cs<tt���|j�ddddd�W5QRX|�|jd�dS)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�?r5rQr0r0r1�test_daemonizedNoUmask�szAUnixApplicationRunnerSetupEnvironmentTests.test_daemonizedNoUmask)rGrHrIrJr!r�rcr!r�r#r(r)r*r,r-r2r3r�r6r8r0r0r0r1r	s 
				
	

rc@sLeZdZdZedkrdZdd�Zdd�Zdd	�Zd
d�Z	dd
�Z
dd�ZdS)�*UnixApplicationRunnerStartApplicationTestsz>
    Tests for L{UnixApplicationRunner.startApplication}.
    Nr�cs�t��}|�ddddddddd	g	�t�d
�}t|�|_g��fdd�}tr�t�	|jj
�j}t�	|�j}|��}|�
d
�|�||�n|�t�|jj
�t�|��|�td|�|�tddd��|�tddd��|j�|�|��ddddd	g�dS)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�Z0070z--chrootz/foo/chrootz--rundirz/foo/rundirz	--pidfilez/foo/pidfile�test_setupEnvironmentcs��|||||f�dSr')�extendr��r�r0r1�fakeSetupEnvironment�sz^UnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.fakeSetupEnvironmentrEr�r�c_sdSr'r0��a�kwr0r0r1r��r�zRUnixApplicationRunnerStartApplicationTests.test_setupEnvironment.<locals>.<lambda>�startApplicationc_sdSr'r0r?r0r0r1r��r�T�8N)r rdrvrr�r#r�r�inspectZ	signaturer�Z
parameters�copy�popr`Z
getargspecr;rrB)rErBrNr>ZsetupEnvironmentParametersZfakeSetupEnvironmentParametersr0r=r1r;�sT�

�
�
�����z@UnixApplicationRunnerStartApplicationTests.test_setupEnvironmentcs4�fdd�}��td|�ti�}|�ddd�dS)zf
        L{UnixApplicationRunner.shedPrivileges} switches the user ID
        of the process.
        cs(��|d���|d���|d�dS)N���6�#�r`�r=r.r�rQr0r1�
switchUIDPass�szUUnixApplicationRunnerStartApplicationTests.test_shedPrivileges.<locals>.switchUIDPass�	switchUIDrIrGrHN)r;r!r#r�)rErLr�r0rQr1�test_shedPrivileges�sz>UnixApplicationRunnerStartApplicationTests.test_shedPrivilegescCsDdd�}ti�}|�td|�|�t|jddd�}|�|jd�dS)z�
        An unexpected L{OSError} when calling
        L{twisted.scripts._twistd_unix.shedPrivileges}
        terminates the process via L{SystemExit}.
        cSsttjd��dSr�r�rKr0r0r1�
switchUIDFail�szZUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesError.<locals>.switchUIDFailrMrIrGNr�)r#r;r!rtrur�r`r�)rErOr��excr0r0r1�test_shedPrivilegesError�s�zCUnixApplicationRunnerStartApplicationTests.test_shedPrivilegesErrorcs�t�j|�|�����fdd�}��fdd�}��fdd�}��td|���td|���td	|�t��}|�d
dt��g�t�	d�}	t
|��_t
|�}
|
�|	�d
S)zj
        Common code for tests which try to pass the the UID to
        L{UnixApplicationRunner}.
        cs��|����|��dSr'rJ)r=r.�rE�	wantedGid�	wantedUidr0r1�
initgroupsszFUnixApplicationRunnerStartApplicationTests._setUID.<locals>.initgroupscs��|��dSr'rJ)r=)rErTr0r1r&szBUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setuidcs��|��dSr'rJ)r.)rErSr0r1�setgidszBUnixApplicationRunnerStartApplicationTests._setUID.<locals>.setgidrUr&rVr:r�r;N)
r?r;rr6r rdrvr�rr�r#r�rB)rEZ
wantedUserrTZwantedGrouprSrUr&rVrBrNr�r0rRr1�_setUID�s&��

z2UnixApplicationRunnerStartApplicationTests._setUIDcCs|�dddd�dS)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.
        riri�N)rWrQr0r0r1�test_setUidWithoutGidsz@UnixApplicationRunnerStartApplicationTests.test_setUidWithoutGidcCsTt��}|�d|dd�|��}|�dt|��d�||�}|�||dd�dS)	zz
        If the specified UID is the same as the current UID of the process,
        then a warning is displayed.
        ZmorefooZmorebari�r�z\tried to drop privileges and setuid {} but uid is already {}; should we be root? Continuing.r�messageN)r6r7rW�
flushWarningsr`�lenr�)rEZ
currentUidZ
warningsShownZexpectedWarningr0r0r1�test_setUidSameAsCurrentUid%s��zFUnixApplicationRunnerStartApplicationTests.test_setUidSameAsCurrentUid)rGrHrIrJr!r�r;rNrQrWrXr\r0r0r0r1r9�s6 	r9c@s,eZdZdZedkrdZdd�Zdd�ZdS)�#UnixApplicationRunnerRemovePIDTestsz7
    Tests for L{UnixApplicationRunner.removePID}.
    Nr�cCsVti�}|��}t�|�tj�|d�}t|d���|�|�|�	tj�
|��dS)zp
        L{UnixApplicationRunner.removePID} deletes the file the name of
        which is passed to it.
        zfoo.pidr�N)r#r�r6�makedirsr��joinr��closer�r�r�)rEr�r�r�r0r0r1�test_removePID=s

z2UnixApplicationRunnerRemovePIDTests.test_removePIDcCsFti�}|�d�|�t�}|�t|�d�|�|djjtj�dS)zr
        Calling L{UnixApplicationRunner.removePID} with a non-existent filename
        logs an OSError.
        Zfakepidr�rN)	r#r�ZflushLoggedErrorsr�r`r[�valuer�ZENOENT)rEr��errorsr0r0r1�test_removePIDErrorsKs


z8UnixApplicationRunnerRemovePIDTests.test_removePIDErrors)rGrHrIrJr!r�rardr0r0r0r1r]5s
r]c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
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}
    cCsd|_d|_dSr�)�_beforeDaemonizeCalled�_afterDaemonizeCalledrQr0r0r1rZdsz"FakeNonDaemonizingReactor.__init__cCs
d|_dS�NT)rfrQr0r0r1�beforeDaemonizeisz)FakeNonDaemonizingReactor.beforeDaemonizecCs
d|_dSrh)rgrQr0r0r1�afterDaemonizemsz(FakeNonDaemonizingReactor.afterDaemonizecOsdS)z*
        Skip event registration.
        Nr0)rEr�rAr0r0r1�addSystemEventTriggerqsz/FakeNonDaemonizingReactor.addSystemEventTriggerN)rGrHrIrJrZrirjrkr0r0r0r1reXs
rec@seZdZdZdS)r+z�
    A dummy reactor, providing C{beforeDaemonize} and C{afterDaemonize}
    methods, announcing this, and logging whether the methods have been called.
    N�rGrHrIrJr0r0r0r1r+xsr+c@seZdZdZdZdd�ZdS)rz�
    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}
    FcCs|jrtd��d|_dS)zV
        A fake run method, checking that it's been called one and only time.
        zAlready calledTN)r�RuntimeErrorrQr0r0r1r��s�DummyReactor.runN)rGrHrIrJrr�r0r0r0r1r�src@s�eZdZdZdd�Zedkr"de_dd�Zdd	�Zedkr@de_d
d�Z	dd
�Z
edkr^de
_dd�Zedkrtde_dd�Z
edkr�de
_dd�Zdd�Zdd�Zdd�ZdS)�AppProfilingTestsz'
    Tests for L{app.AppProfiler}.
    c	Cs~t��}|��|d<d|d<t�|�}t�}|�|�|�|j�t	|d��}|�
�}W5QRX|�d|�|�d|�dS)z�
        L{app.ProfileRunner.run} should call the C{run} method of the reactor
        and save profile data in the specified file.
        rr�rn�function callsN�r rdr�rr�rr�r}rr�r0rn�rErhr�ryr��datar0r0r1�test_profile�s

zAppProfilingTests.test_profileNzprofile module not availablecCsPt�}|�td|�}||�}|��|��|��}|�d|�|�d|�dS)Nr�rpz(run))rr;r��print_statsZrestorerwrn)rEZ
statsClassr�outr�Zstatsrsr0r0r1�
_testStats�szAppProfilingTests._testStatscCs`t��}|��|d<d|d<d|d<t�|�}t�}|�|�|�|j�|�	t
j|d�dS)z�
        With the C{savestats} option specified, L{app.ProfileRunner.run}
        should save the raw stats object instead of a summary output.
        rr�T�	savestatsN�r rdr�rr�rr�r}rrw�pstatsZStats�rErhr�ryr0r0r1�test_profileSaveStats�s

z'AppProfilingTests.test_profileSaveStatsc	Cs`tj��}t��}d|d<t�|�}dtjd<z|�	t
|jd�W5tj��tj�|�XdS)z�
        When the C{profile} module is not present, L{app.ProfilerRunner.run}
        should raise a C{SystemExit} exception.
        rr�N�r��modulesrEr rdrr��clear�updatertrur��rEZsavedModulesrhr�r0r0r1�test_withoutProfile�s



z%AppProfilingTests.test_withoutProfilecCstGdd�dtj�}|�td|�t��}|��|d<d|d<t�|�}t�}t	j
}|�t|j
|�|�t	j
|�dS)z�
        When an error happens during the print of the stats, C{sys.stdout}
        should be restored to its initial value.
        c@seZdZdd�ZdS)zGAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfilecSstd��dS)NZBoom�rmrQr0r0r1ru�szSAppProfilingTests.test_profilePrintStatsError.<locals>.ErroneousProfile.print_statsN)rGrHrIrur0r0r0r1�ErroneousProfile�sr��Profilerr�N)rr�r;r rdr�rr�rr�r�rtrmr�r�)rEr�rhr�ryZ	oldStdoutr0r0r1�test_profilePrintStatsError�s
z-AppProfilingTests.test_profilePrintStatsErrorc	Cs~t��}|��|d<d|d<t�|�}t�}|�|�|�|j�t	|d��}|�
�}W5QRX|�d|�|�d|�dS)z�
        L{app.CProfileRunner.run} should call the C{run} method of the
        reactor and save profile data in the specified file.
        r�cProfiler�r�rpNrqrrr0r0r1�
test_cProfiles

zAppProfilingTests.test_cProfilezcProfile module not availablecCs`t��}|��|d<d|d<d|d<t�|�}t�}|�|�|�|j�|�	t
j|d�dS)z�
        With the C{savestats} option specified,
        L{app.CProfileRunner.run} should save the raw stats object
        instead of a summary output.
        rr�r�TrxNryr{r0r0r1�test_cProfileSaveStatss

z(AppProfilingTests.test_cProfileSaveStatsc	Cs`tj��}dtjd<t��}d|d<t�|�}z|�	t
|jd�W5tj��tj�|�XdS)z�
        When the C{cProfile} module is not present,
        L{app.CProfileRunner.run} should raise a C{SystemExit}
        exception and log the C{ImportError}.
        Nr�r�r}r�r0r0r1�test_withoutCProfile0s



z&AppProfilingTests.test_withoutCProfilecCs@t��}|��|d<d|d<|�ttj|�}|�t|�d�dS)zq
        Check that L{app.AppProfiler} raises L{SystemExit} when given an
        unknown profiler name.
        rZfoobarr�z!Unsupported profiler name: foobarN)	r rdr�rtrurr�r`r�)rErh�errorr0r0r1�test_unknownProfilerCs
z&AppProfilingTests.test_unknownProfilercCst�i�}|�|jd�dS)zU
        L{app.Profiler} defaults to the cprofile profiler if not specified.
        �cprofileN�rr�r`r��rEr�r0r0r1�test_defaultProfilerPs
z&AppProfilingTests.test_defaultProfilercCs t�ddi�}|�|jd�dS)ze
        The case of the profiler name passed to L{app.AppProfiler} is not
        relevant.
        r�ZCprOfiler�Nr�r�r0r0r1�test_profilerNameCaseInsentiveXsz0AppProfilingTests.test_profilerNameCaseInsentive)rGrHrIrJrtrr�rwr|r�r�r�r�r�r�r�r�r�r0r0r0r1ro�s,
rocs(g�tj���fdd�}|td|��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{unittest.TestCase.patch}).

    @return: the list that keeps track of the log files.
    @rtype: C{list}
    cs��|��|f|�|�Sr'r�)ZlogFiler��kwargs��logFilesZoldFileLogObserverr0r1�observeros
z+_patchTextFileLogObserver.<locals>.observer�textFileLogObserver)r	r�)r;r�r0r�r1�_patchTextFileLogObserverbs

r�cs*g�G�fdd�dt�}|�td|��S)zu
    Make fake syslog, and return list to which prefix and then log
    messages will be appended if it is used.
    cs$eZdZ�fdd�Z�fdd�ZdS)z(_setupSyslog.<locals>.fakesyslogobservercs��|�dSr'r�)rE�prefix�ZlogMessagesr0r1rZ�sz1_setupSyslog.<locals>.fakesyslogobserver.__init__cs��|�dSr'r�)rEZ	eventDictr�r0r1�emit�sz-_setupSyslog.<locals>.fakesyslogobserver.emitN)rGrHrIrZr�r0r�r0r1�fakesyslogobserversr�ZSyslogObserver)rcr;r%)ZtestCaser�r0r�r1�_setupSyslogxsr�c@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	ie
jfdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zedks�edkr�de_dd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�ZdS)(�AppLoggerTestsz�
    Tests for L{app.AppLogger}.

    @ivar observers: list of observers installed during the tests.
    @type observers: C{list}
    cs$g�_�fdd�}��td|�dS)z�
        Override L{globaLogBeginner.beginLoggingTo} so that we can trace the
        observers installed in C{self.observers}.
        cs$|D]}�j�|�t�|�qdSr')�	observersrorZaddObserver)r�r�rQr0r1�beginLoggingTo�sz,AppLoggerTests.setUp.<locals>.beginLoggingTor�N)r�r;r)rEr�r0rQr1r��szAppLoggerTests.setUpcCs|jD]}t�|�qdS)z1
        Remove all installed observers.
        N)r�r�removeObserver�rEr�r0r0r1�tearDown�s
zAppLoggerTests.tearDowncCstt�Gdd�dt��}|�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@seZdZgZdd�ZdS)z2AppLoggerTests._makeObserver.<locals>.TestObservercSs|j�|�dSr')�_logsro)rEZeventr0r0r1�__call__�sz;AppLoggerTests._makeObserver.<locals>.TestObserver.__call__N)rGrHrIr�r�r0r0r0r1�TestObserver�sr�)rrrc)rEr�r0r0r1�
_makeObserver�szAppLoggerTests._makeObservercCs@|�|j|g�|�d|jdd�|�d|jdd�dS)z�
        Ensure that initial C{twistd} logs are written to logs.

        @param observer: The observer made by L{self._makeObserver).
        �starting uprZ
log_formatz
reactor classr�N)r`r�rnr�r�r0r0r1�_checkObserver�szAppLoggerTests._checkObservercs:t�i�}|����fdd�|_|�t��|���dS)z�
        L{app.AppLogger.start} calls L{globalLogBeginner.addObserver}, and then
        writes some messages about twistd and the reactor.
        cs�Sr'r0r0�r�r0r1r��r�z+AppLoggerTests.test_start.<locals>.<lambda>N)r�	AppLoggerr��_getLogObserverrOrr�)rEr	r0r�r1�
test_start�s

zAppLoggerTests.test_startcCs<t�}|��}|�t|�t�i�}|�|�|�|�dS)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)rr��setComponentrrr�rOr�)rErNr�r	r0r0r1�$test_startUsesApplicationLogObserver�s

z3AppLoggerTests.test_startUsesApplicationLogObservercs8|���d�fdd�i}|�|�||�}|�|��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	cs�Sr'r0r0r�r0r1r��r�z7AppLoggerTests._setupConfiguredLogger.<locals>.<lambda>)r�r�rO)rErNZextraLogArgsZ	appLoggerZlogArgsr	r0r�r1�_setupConfiguredLogger�s

z%AppLoggerTests._setupConfiguredLoggercCst�}|�|�|��dS)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)rr�r�rMr0r0r1�#test_startUsesConfiguredLogObserver�sz2AppLoggerTests.test_startUsesConfiguredLogObservercCs<|��}t�}|�t|�|�|�|��|�|jg�dS)zk
        C{--logger} takes precedence over a L{ILogObserver} component set on
        Application.
        N)r�rr�rr�r�r`r�)rEr�rNr0r0r1�(test_configuredLogObserverBeatsComponents
z7AppLoggerTests.test_configuredLogObserverBeatsComponentcCs8g}t�}|�t|j�|�|�|��|�|g�dS)zq
        C{--logger} takes precedence over a L{LegacyILogObserver} component
        set on Application.
        N)rr��LegacyILogObserverror�r�r`)rE�nonlogsrNr0r0r1�.test_configuredLogObserverBeatsLegacyComponents
z=AppLoggerTests.test_configuredLogObserverBeatsLegacyComponentcCsZg}|��}t�}|�t|�|�t|j�t�i�}|�|�|�	|�|�
|g�dS)zw
        A L{ILogObserver} takes precedence over a L{LegacyILogObserver}
        component set on Application.
        N)r�rr�rr�rorr�rOr�r`)rEr�r�rNr	r0r0r1�.test_loggerComponentBeatsLegacyLoggerComponents


z=AppLoggerTests.test_loggerComponentBeatsLegacyLoggerComponentcCs6t|�}t�}|�|�|ddit��|�|g�dS)z`
        C{--logger} takes precedence over a C{--syslog} command line
        argument.
        r%TN)r�rr�r�r$r`)rE�logsrNr0r0r1�%test_configuredLogObserverBeatsSyslog-s
�z4AppLoggerTests.test_configuredLogObserverBeatsSyslogNz&Not on POSIX, or syslog not available.cCs:t�}|��}|�|�|ddi��|�tj�|��dS)za
        C{--logger} takes precedence over a C{--logfile} command line
        argument.
        �logfiler�N)rr�r�r�r�r6r�r�)rErNr�r0r0r1�&test_configuredLogObserverBeatsLogfile?s
�z5AppLoggerTests.test_configuredLogObserverBeatsLogfilecCs~t�ddi�}t|j�}|��|�t|�d�|�|dtj	�t�ddi�}|��|�t|�d�|�|dtj	�dS)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�rN)
rr�r�r;r�r`r[r�r�r�)rEr	r�r0r0r1�test_getLogObserverStdoutKs
z(AppLoggerTests.test_getLogObserverStdoutcCsVt|j�}|��}t�d|i�}|��|�t|�d�|�|djt	j�
|��dS)z�
        When passing the C{logfile} option, L{app.AppLogger._getLogObserver}
        returns a log observer pointing at the specified path.
        r�r�rN)r�r;r�rr�r�r`r[r�r6�abspath)rEr��filenamer	r0r0r1�test_getLogObserverFile_s

�z&AppLoggerTests.test_getLogObserverFilecspg�t�}�fdd�}|�td|�t�i�}||_|��|��|g�|��|��|g�|�|j�dS)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.
        cs��|�dSr'r�r��Zremovedr0r1�removexsz(AppLoggerTests.test_stop.<locals>.remover�N)	rcr;rrr�Z	_observerr�r`rg)rEr�r�r	r0r�r1�	test_stopos
zAppLoggerTests.test_stopcszg�t�i�}tt�G�fdd�dt����fdd�|_|�t��|�dt	�d��|�
|jg�}|�t
|�d�dS)zt
        L{app.AppLogger} using a legacy logger observer still works, wrapping
        it in a compat shim.
        cseZdZdZ�fdd�ZdS)z;AppLoggerTests.test_legacyObservers.<locals>.LoggerObserverzX
            An observer which implements the legacy L{LegacyILogObserver}.
            cs��|�dS)z<
                Add C{x} to the logs list.
                Nr�)rE�x�r�r0r1r��szDAppLoggerTests.test_legacyObservers.<locals>.LoggerObserver.__call__N)rGrHrIrJr�r0r�r0r1�LoggerObserver�sr�cs��Sr'r0r0)r�r0r1r��r�z5AppLoggerTests.test_legacyObservers.<locals>.<lambda>r�rN)rr�rr�rcZ_observerFactoryrOrrnrrZ�test_legacyObserversr`r[�rEr	�warningsr0)r�r�r1r��s

�z#AppLoggerTests.test_legacyObserverscsrg�t�i�}�fdd�|_|�t��|�dt�d��|�|jg�}|�	t
|�d�|�	|ddd�dS)	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}.
        cs�jSr'r�r0r�r0r1r��r�zAAppLoggerTests.test_unmarkedObserversDeprecated.<locals>.<lambda>r�rr�rYaZPassing 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�rOrrnrrZ� test_unmarkedObserversDeprecatedr`r[r�r0r�r1r��s
��z/AppLoggerTests.test_unmarkedObserversDeprecated)rGrHrIrJr�r�r�r�r�r�rr�r�r�r�r�r�r�r!r%r�r�r�r�r�r�r�r0r0r0r1r��s0�
�r�c@sbeZdZdZedkrdZdd�Zdd�Zdd	�Zd
d�Z	dd
�Z
dd�Zdd�Ze
dkr^de_dS)�UnixAppLoggerTestszw
    Tests for L{UnixAppLogger}.

    @ivar signals: list of signal handlers installed.
    @type signals: C{list}
    Nr�cs$g�_�fdd�}��td|�dS)zs
        Fake C{signal.signal} for not installing the handlers but saving them
        in C{self.signals}.
        cs�j�||f�dSr')�signalsro)r�r�rQr0r1�
fakeSignal�sz,UnixAppLoggerTests.setUp.<locals>.fakeSignal�signalN)r�r;r�)rEr�r0rQr1r��szUnixAppLoggerTests.setUpcCs~t|j�}tddd��}|��|�t|�d�|�|dtj�tddd��}|��|�t|�d�|�|dtj�dS)	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�r�r�rr�rN)	r�r;r$r�r`r[r�r�r��rEr�r	r0r0r1r��s
z,UnixAppLoggerTests.test_getLogObserverStdoutcCs0tddd��}|�t|j�}|�t|�d�dS)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$rtrur�r`r�)rEr	r�r0r0r1�test_getLogObserverStdoutDaemon�sz2UnixAppLoggerTests.test_getLogObserverStdoutDaemoncs�t|j�}|��}td|i�}|��|�t|�d�|�|djtj�	|��|�t|j
�d�|�|j
ddtj�t
���fdd�}||d_|j
dd}|dd��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�rcs��d�dSr')�callbackr0��dr0r1�rotatesz:UnixAppLoggerTests.test_getLogObserverFile.<locals>.rotateN)r�r;r�r$r�r`r[r�r6r�r�r��SIGUSR1rr�)rEr�r�r	r�Z	rotateLogr0r�r1r��s


z*UnixAppLoggerTests.test_getLogObserverFilecsH�fdd�}��td|����}td|i�}|�����jg�dS)zy
        If a signal handler is already installed,
        L{UnixAppLogger._getLogObserver} doesn't override it.
        cs��|tj�t�Sr')r`r�r�rc)r�rQr0r1�
fakeGetSignalszVUnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandler.<locals>.fakeGetSignal�	getsignalr�N)r;r�r�r$r�r`r�)rEr�r�r	r0rQr1�,test_getLogObserverDontOverrideSignalHandlersz?UnixAppLoggerTests.test_getLogObserverDontOverrideSignalHandlercCsNt|j�}tddd��}|��|�t|�d�|�|djtj�d��dS)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�rz
twistd.logN)	r�r;r$r�r`r[r�r6r�r�r0r0r1�test_getLogObserverDefaultFiles

z1UnixAppLoggerTests.test_getLogObserverDefaultFilecCsPt|�}tddd��}|��}|�|dg�|ddi�|�|dddig�dS)z�
        If C{syslog} is set to C{True}, L{UnixAppLogger._getLogObserver} starts
        a L{syslog.SyslogObserver} with given C{prefix}.
        Tztest-prefix)r%r�r@�bN)r�r$r�r`)rEr�r	r�r0r0r1�test_getLogObserverSyslog-sz,UnixAppLoggerTests.test_getLogObserverSyslogzSyslog not available)rGrHrIrJr!r�r�r�r�r�r�r�r�r%r0r0r0r1r��s

r�c@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"S)#�DaemonizeTestszH
    Tests for L{_twistd_unix.UnixApplicationRunner} daemonization.
    cCsbt�|_t��|_|�td|j�t�|j�|_t	�
d�|j_tj
|j_tj|j_dd�|j_dS)Nr6r�cWsdSr'r0r=r0r0r1r�Kr�z&DaemonizeTests.setUp.<locals>.<lambda>)r�mockosr rdrhr;r!r#r�rr�rNr�r�r��stderrr�r�rQr0r0r1r�Cs


zDaemonizeTests.setUpc
CsVtt���|j��W5QRX|�|jjdddddddg�|�|jjddg�d	S)
zw
        When double fork succeeded in C{daemonize}, the child process writes
        B{0} to the status pipe.
        �rr'�r�r7��forkT�setsid)r�����0��unlinkz
twistd.pid���r�N)rr+r�rSr`r��actions�closedrQr0r0r1�test_successNs��zDaemonizeTests.test_successc	Cshd|j_d|j_tt���|�t|jj�W5QRX|�	|jj
ddddddg�|�	|jjd	g�d
S)z�
        The parent process initiating the C{daemonize} call reads data from the
        status pipe and then exit the process.
        Fr�r�r�r��r0����d��exitrr�r�N)r��child�readDatarr+rt�SystemErrorr�rSr`r�r�rQr0r0r1�test_successInParent\s��z#DaemonizeTests.test_successInParentc	s|g��fdd�}||j_tt���|j��W5QRX|�|jjddddddg�|�|jjdd	g�|�d
d
g��dS)z�
        If the C{os.write} call to the status pipe raises an B{EINTR} error,
        the process child retries to write.
        cs(��||f�t��dkr$ttj��dSr$�ror[�IOErrorr�ZEINTR)�fdrs�Zwrittenr0r1�raisingWritessz6DaemonizeTests.test_successEINTR.<locals>.raisingWriter�r�r�r�r�r�r�)r�r�N)	r�r�rr+r�rSr`r�r�)rEr�r0r�r1�test_successEINTRls��z DaemonizeTests.test_successEINTRc	s�g��fdd�}||j_d|j_tt���|�t|jj�W5QRX|�	|jj
dddddg�|�	|jjd	g�|�	d
d
g��dS)z
        If the C{os.read} call on the status pipe raises an B{EINTR} error, the
        parent child retries to read.
        cs(��||f�t��dkr$ttj��dS)Nr�r�r�)r��size�r0r0r1�raisingRead�s
z=DaemonizeTests.test_successInParentEINTR.<locals>.raisingReadFr�r�r�r�r�r�)r�r�N)r�r0r�rr+rtr�r�rSr`r�r�)rEr�r0r�r1�test_successInParentEINTR�s��z(DaemonizeTests.test_successInParentEINTRcs�G�fdd�dtj�}|�}|�|jj�tt���|�t|jj	�W5QRX|�
|jjddddddd|fd	g�|�
|jj
d
dg�dS)z�
        Assert L{UnixApplicationRunner.postApplication} writes
        C{reported} to its status pipe if the service raises an
        exception whose message is C{raised}.
        cseZdZ�fdd�ZdS)z6DaemonizeTests.assertErrorWritten.<locals>.FakeServicecst���dSr'r�rQ��raisedr0r1r��szCDaemonizeTests.assertErrorWritten.<locals>.FakeService.startServiceN)rGrHrIr�r0r�r0r1r��sr�r�r�r�r�r�r�r�r�N)rrCr�r�rNrr+rtrmrSr`r�r�r�)rEr�reportedr�ZerrorServicer0r�r1�assertErrorWritten�s��z!DaemonizeTests.assertErrorWrittencCs|jddd�dS)z�
        If an error happens during daemonization, the child process writes the
        exception error to the status pipe.
        zSomething is wrongs"1 RuntimeError: Something is wrong�rrN�rrQr0r0r1�
test_error�s�zDaemonizeTests.test_errorcCs|jddd�dS)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•s1 RuntimeError: \u2022rNrrQr0r0r1�test_unicodeError�s�z DaemonizeTests.test_unicodeErrorc	Cs�d|j_||j_t�}|�td|�tt���|�t	|j
j�W5QRX|�|�
�|�|�|jj|�|�|jjdg�dS)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__r�N)r�r�r�rr;r�rr+rtr�r�rSr`rwr�r�)rEr��errorMessage�
mockOSActionsZerrorIOr0r0r1�assertErrorInParentBehavior�sz*DaemonizeTests.assertErrorInParentBehaviorc	Cs |jddddddddgd	�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�rr	N�r
rQr0r0r1�test_errorInParent�s��z!DaemonizeTests.test_errorInParentc	Cs |jddddddddgd	�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.
        s1 Exception: �zXAn error has occurred: b'Exception: \xff'
Please look at log file for more information.
r�r�r�r�rr�rNr
rQr0r0r1�test_nonASCIIErrorInParent�s��z)DaemonizeTests.test_nonASCIIErrorInParentc	Cs4d}d�d�}|j|d�|�ddddd	d
gd�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.
        �d1 RuntimeError: \u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022zb'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�r�r�rr�rN)r�r
)rEZtruncatedMessageZreportedMessager0r0r1�&test_errorInParentWithTruncatedUnicodes
���z5DaemonizeTests.test_errorInParentWithTruncatedUnicodecCs|jddd�dS)z{
        If an error occurs during daemonization and its message is too
        long, it's truncated by the child.
        Z�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxsd1 RuntimeError: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrNrrQr0r0r1�test_errorMessageTruncateds�z)DaemonizeTests.test_errorMessageTruncatedcCs|jddd�dS)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••••••••••••••••••••••••••••••rrNrrQr0r0r1�!test_unicodeErrorMessageTruncated%s�z0DaemonizeTests.test_unicodeErrorMessageTruncatedcCs.t�}|j�|�|�|j�|�|j�dS)z�
        C{daemonize} indeed calls L{IReactorDaemonize.beforeDaemonize} and
        L{IReactorDaemonize.afterDaemonize} if the reactor implements
        L{IReactorDaemonize}.
        N)r+r�r#r}rfrgr%r0r0r1�test_hooksCalled1szDaemonizeTests.test_hooksCalledcCs.t�}|j�|�|�|j�|�|j�dS)z�
        C{daemonize} does NOT call L{IReactorDaemonize.beforeDaemonize} or
        L{IReactorDaemonize.afterDaemonize} if the reactor does NOT implement
        L{IReactorDaemonize}.
        N)rer�r#r�rfrgr%r0r0r1�test_hooksNotCalled=sz"DaemonizeTests.test_hooksNotCalledN)rGrHrIrJr�r�r�r�r�rrrr
rrrrrrrr0r0r0r1r�>s"

r�c@seZdZdZdS)�SignalCapturingMemoryReactorz�
    MemoryReactor that implements the _ISupportsExitSignalCapturing interface,
    all other operations identical to MemoryReactor.
    Nrlr0r0r0r1rJsrcs4eZdZdZeZ�fdd�Zdd�Zdd�Z�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.
    cstt|��|�d|_dSr')�superrrZ�_signalValuer~��	__class__r0r1rZ]sz(StubApplicationRunnerWithSignal.__init__cCsdS)z
        Does nothing.
        Nr0rQr0r0r1rRbsz.StubApplicationRunnerWithSignal.preApplicationcCs$t�}|j|_|�|tjtj�dS)z`
        Instantiate a SignalCapturingMemoryReactor and start it
        in the runner.
        N)rrrr�r�r�r�r%r0r0r1rSgsz/StubApplicationRunnerWithSignal.postApplication)
rGrHrIrJrLrTrZrRrS�
__classcell__r0r0rr1rSs
rcs�fdd�}|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
    cst|�}�|_|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
        )rr)rhr���signumr0r1�stubApplicationRunnerFactoryszIstubApplicationRunnerFactoryCreator.<locals>.stubApplicationRunnerFactoryr0)rrr0rr1�#stubApplicationRunnerFactoryCreatorrs
r c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�ExitWithSignalTestsz?
    Tests for L{twisted.application.app._exitWithSignal}.
    csRt���_dt�i�j_t��j_d�j_ddg�_�fdd�}��	t
d|�dS)zM
        Set up the server options and a fake for use by test cases.
        r�Ncs|�jd<|�jd<dS)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.
            rr�N)�fakeKillArgsr�rQr0r1�fakeKill�s
z+ExitWithSignalTests.setUp.<locals>.fakeKillr�)r rdrhr@r�rcr�rir"r;r6)rEr#r0rQr1r��s


zExitWithSignalTests.setUpcs�ddg��fdd�}|�td|�t�tj�|��dtj�|��dtj�|�|jdt�	��|�|jdtj�dS)z�
        exitWithSignal replaces the existing signal handler with the default
        handler and sends the replaced signal to the current process.
        Ncs|�d<|�d<dS)Nrr�r0)r�Zhandler�ZfakeSignalArgsr0r1�fake_signal�sz<ExitWithSignalTests.test_exitWithSignal.<locals>.fake_signalr�rr�)
r;r�rZ_exitWithSignal�SIGINTr�SIG_DFLr"r6r�)rEr%r0r$r1�test_exitWithSignal�sz'ExitWithSignalTests.test_exitWithSignalcCsB|�tdtd��t�|j�|�|jd�|�|jd�dS)zb
        _exitWithSignal is not called if the runner does not exit with a
        signal.
        r�Nrr�)r;r r �runApprhrgr"rQr0r0r1�test_normalExit�s�z#ExitWithSignalTests.test_normalExitcCsN|�tdttj��t�|j�|�|jdt	�
��|�|jdtj�dS)zP
        _exitWithSignal is called when the runner exits with a signal.
        r�rr�N)r;r r r�r&r)rhrr"r6r�rQr0r0r1�test_runnerExitsWithSignal�s�z.ExitWithSignalTests.test_runnerExitsWithSignalN)rGrHrIrJr�r(r*r+r0r0r0r1r!�s
r!z!twistd unix support not available)lrJZ
__future__rrr�rDr�r6r�r5r8�ImportErrorZcPickler�Zzope.interfacerZzope.interface.verifyrZ
twisted.trialrZtwisted.test.test_processrr�rr	r
Ztwisted.applicationrrr
Ztwisted.application.servicerZtwisted.internet.deferrZtwisted.internet.interfacesrrZ#twisted.internet.test.modulehelpersrZtwisted.loggerrrrZtwisted.internet.baserZtwisted.test.proto_helpersrZtwisted.python.compatrrZtwisted.python.componentsrZtwisted.pythonrZtwisted.python.logr�rZtwisted.python.runtimerZtwisted.python.usagerZtwisted.python.fakepwdrZtwisted.scriptsr r!Ztwisted.scripts._twistd_unixr"r#r$r%rrzr��getattrrr?rcr@r�rLr�rPZTestCaserUr�r�r�r�r�r�rr9r]rer+rror�r�r�r�r�rrr r!r�r0r0r0r1�<module>s�



.
TGs# N4!Q