U
    n5{ih2  ã                   @   s   d Z ddlZddlmZ ddl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Z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mZmZmZmZ e
de	f e
de	f dœdd„Z G dd„ dej!j"j#ƒZ$G dd„ dej!j"j#ƒZ%dS )z3
Tests for L{twisted.application.runner._pidfile}.
é    N)Úwraps)ÚgetpidÚname)ÚAnyÚCallableÚOptional)ÚverifyObject)ÚNoReturn)ÚFilePath)Úplatform)ÚSkipTesté   )Ú_pidfileé   )ÚAlreadyRunningErrorÚInvalidPIDFileErrorÚIPIDFileÚNonePIDFileÚ
NoPIDFoundÚPIDFileÚStalePIDFileError.)ÚfÚreturnc                    s$   t ˆ ƒttttdœ‡ fdd„ƒ}|S )a=  
    Decorator for tests that are not expected to work on all platforms.

    Calling L{PIDFile.isRunning} currently raises L{NotImplementedError} on
    non-POSIX platforms.

    On an unsupported platform, we expect to see any test that calls
    L{PIDFile.isRunning} to raise either L{NotImplementedError}, L{SkipTest},
    or C{self.failureException}.
    (C{self.failureException} may occur in a test that checks for a specific
    exception but it gets NotImplementedError instead.)

    @param f: The test method to decorate.

    @return: The wrapped callable.
    )ÚselfÚargsÚkwargsr   c                    s`   t  ¡ dk}|r ˆ | f|ž|ŽS | jtt| jfˆ | f|ž|Ž}t|tƒr\|  t|ƒ 	d¡¡ d S )NÚposixz isRunning is not implemented on )
r   ÚgetTypeÚassertRaisesÚNotImplementedErrorr   ZfailureExceptionÚ
isinstanceÚ
assertTrueÚstrÚ
startswith)r   r   r   Ú	supportedÚe©r   © úP/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/application/runner/test/test_pidfile.pyÚwrapper3   s    
ýüû
z$ifPlatformSupported.<locals>.wrapper)r   r   )r   r)   r'   r&   r(   ÚifPlatformSupported!   s    r*   c                   @   sp  e Zd ZdZd1ee ee dœdd„Zddœdd„Z	ddœd	d
„Z
ddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zeddœdd„ƒZeddœdd „ƒZeddœd!d"„ƒZeddœd#d$„ƒZeddœd%d&„ƒZeddœd'd(„ƒZddœd)d*„Zddœd+d,„Zeddœd-d.„ƒZeddœd/d0„ƒZdS )2ÚPIDFileTestsz
    Tests for L{PIDFile}.
    N)Úcontentr   c                 C   s"   t |  ¡ ƒ}|d k	r| |¡ |S ©N)r
   ÚmktempZ
setContent)r   r,   ÚfilePathr'   r'   r(   r/   L   s    
zPIDFileTests.filePath©r   c                 C   s   t |  ¡ ƒ}tt|ƒ dS )z5
        L{PIDFile} conforms to L{IPIDFile}.
        N)r   r/   r   r   ©r   ÚpidFiler'   r'   r(   Útest_interfaceR   s    zPIDFileTests.test_interfacec                 C   s   |   tjdd�d¡ dS )zR
        L{PIDFile._format} returns the expected format when given a PID.
        é9  ©Úpids   1337
N)ÚassertEqualr   Ú_format)r   r'   r'   r(   Útest_formatWithPIDY   s    zPIDFileTests.test_formatWithPIDc                 C   s.   d}t |  t j|d�¡ƒ}|  || ¡ ¡ dS )zK
        L{PIDFile.read} returns the PID from the given file path.
        r4   r5   N)r   r/   r8   r7   Úread©r   r6   r2   r'   r'   r(   Útest_readWithPID_   s    zPIDFileTests.test_readWithPIDc                 C   s:   d}t |  d¡ƒ}|  t|j¡}|  t|ƒd|›�¡ dS )úf
        L{PIDFile.read} raises L{InvalidPIDFileError} when given an empty file
        path.
        ó    ú#non-integer PID value in PID file: N©r   r/   r   r   r:   r7   r"   ©r   ZpidValuer2   r%   r'   r'   r(   Útest_readEmptyPIDi   s    zPIDFileTests.test_readEmptyPIDc                 C   s:   d}t |  |¡ƒ}|  t|j¡}|  t|ƒd|›�¡ dS )r=   s   $foo!r?   Nr@   rA   r'   r'   r(   Útest_readWithBogusPIDt   s    z"PIDFileTests.test_readWithBogusPIDc                 C   s.   t |  ¡ ƒ}|  t|j¡}|  t|ƒd¡ dS )zc
        L{PIDFile.read} raises L{NoPIDFound} when given a non-existing file
        path.
        úPID file does not existN)r   r/   r   r   r:   r7   r"   ©r   r2   r%   r'   r'   r(   Útest_readDoesntExist   s    z!PIDFileTests.test_readDoesntExistc                 C   sN   dt tdœdd„}|  td|¡ t|  ¡ ƒ}|  t|j¡}|  	|j
t
j¡ dS )z�
        L{PIDFile.read} re-raises L{OSError} if the associated C{errno} is
        anything other than L{errno.ENOENT}.
        Úr)Úmoder   c                 S   s   t tjdƒ‚d S )Nz	I/O error)ÚOSErrorÚerrnoÚEIO)rH   r'   r'   r(   Úoops�   s    z>PIDFileTests.test_readOpenRaisesOSErrorNotENOENT.<locals>.oopsÚopenN)rG   )r"   r	   Úpatchr
   r   r/   r   rI   r:   r7   rJ   rK   )r   rL   r2   Úerrorr'   r'   r(   Ú#test_readOpenRaisesOSErrorNotENOENT‰   s
    z0PIDFileTests.test_readOpenRaisesOSErrorNotENOENTc                 C   s.   d}t |  ¡ ƒ}| |¡ |  | ¡ |¡ dS )z9
        L{PIDFile._write} stores the given PID.
        iË  N)r   r/   Ú_writer7   r:   r;   r'   r'   r(   Útest_writePID™   s    
zPIDFileTests.test_writePIDc                 C   s    t |  ¡ ƒ}|  t|jd¡ dS )zS
        L{PIDFile._write} raises L{ValueError} when given an invalid PID.
        ZburpN)r   r/   r   Ú
ValueErrorrQ   r1   r'   r'   r(   Útest_writePIDInvalid¤   s    z!PIDFileTests.test_writePIDInvalidc                 C   s*   t |  ¡ ƒ}| ¡  |  | ¡ tƒ ¡ dS )zT
        L{PIDFile.writeRunningPID} stores the PID for the current process.
        N)r   r/   ÚwriteRunningPIDr7   r:   r   r1   r'   r'   r(   Útest_writeRunningPID¬   s    z!PIDFileTests.test_writeRunningPIDc                 C   s:   t |  d¡ƒ}|  |j ¡ ¡ | ¡  |  |j ¡ ¡ dS )z9
        L{PIDFile.remove} removes the PID file.
        r>   N)r   r/   r!   ÚexistsÚremoveÚassertFalser1   r'   r'   r(   Útest_removeµ   s    zPIDFileTests.test_removec                 C   sH   t |  ¡ ƒ}| d¡ ttddœdd„}|  td|¡ |  | ¡ ¡ dS )zR
        L{PIDFile.isRunning} returns true for a process that does exist.
        r4   N©r6   Úsignalr   c                 S   s   d S r-   r'   ©r6   r\   r'   r'   r(   ÚkillÇ   s    z2PIDFileTests.test_isRunningDoesExist.<locals>.killr^   ©r   r/   rQ   ÚintrN   r   r!   Ú	isRunning©r   r2   r^   r'   r'   r(   Útest_isRunningDoesExist¿   s
    
z$PIDFileTests.test_isRunningDoesExistc                 C   s&   t |  ¡ ƒ}| ¡  |  | ¡ ¡ dS )a@  
        L{PIDFile.isRunning} returns true for this process (which is running).

        @note: This differs from L{PIDFileTests.test_isRunningDoesExist} in
        that it actually invokes the C{kill} system call, which is useful for
        testing of our chosen method for probing the existence of a process.
        N)r   r/   rU   r!   ra   r1   r'   r'   r(   Útest_isRunningThisÎ   s    	zPIDFileTests.test_isRunningThisc                 C   sH   t |  ¡ ƒ}| d¡ ttddœdd„}|  td|¡ |  t|j¡ dS )z{
        L{PIDFile.isRunning} raises L{StalePIDFileError} for a process that
        does not exist (errno=ESRCH).
        r4   Nr[   c                 S   s   t tjdƒ‚d S ©NzNo such process©rI   rJ   ZESRCHr]   r'   r'   r(   r^   å   s    z5PIDFileTests.test_isRunningDoesNotExist.<locals>.killr^   )	r   r/   rQ   r`   rN   r   r   r   ra   rb   r'   r'   r(   Útest_isRunningDoesNotExistÜ   s
    
z'PIDFileTests.test_isRunningDoesNotExistc                 C   sH   t |  ¡ ƒ}| d¡ ttddœdd„}|  td|¡ |  | ¡ ¡ dS )zx
        L{PIDFile.isRunning} returns true for a process that we are not allowed
        to kill (errno=EPERM).
        r4   Nr[   c                 S   s   t tjdƒ‚d S )NzOperation not permitted)rI   rJ   ÚEPERMr]   r'   r'   r(   r^   õ   s    z3PIDFileTests.test_isRunningNotAllowed.<locals>.killr^   r_   rb   r'   r'   r(   Útest_isRunningNotAllowedì   s
    
z%PIDFileTests.test_isRunningNotAllowedc                 C   s8   t dkrtdƒ‚t|  ¡ ƒ}| d¡ |  | ¡ ¡ dS )ac  
        L{PIDFile.isRunning} returns true for a process that we are not allowed
        to kill (errno=EPERM).

        @note: This differs from L{PIDFileTests.test_isRunningNotAllowed} in
        that it actually invokes the C{kill} system call, which is useful for
        testing of our chosen method for probing the existence of a process
        that we are not allowed to kill.

        @note: In this case, we try killing C{init}, which is process #1 on
        POSIX systems, so this test is not portable.  C{init} should always be
        running and should not be killable by non-root users.
        r   zThis test assumes POSIXé   N)ÚSYSTEM_NAMEr   r   r/   rQ   r!   ra   r1   r'   r'   r(   Útest_isRunningInitü   s
    
zPIDFileTests.test_isRunningInitc                 C   sF   t |  ¡ ƒ}| ¡  ttddœdd„}|  td|¡ |  t|j¡ dS )zŠ
        L{PIDFile.isRunning} re-raises L{OSError} if the attached C{errno}
        value from L{os.kill} is not an expected one.
        Nr[   c                 S   s   t tjdƒ‚d S )NzFile exists)rI   rJ   ÚEEXISTr]   r'   r'   r(   r^     s    z5PIDFileTests.test_isRunningUnknownErrno.<locals>.killr^   )	r   r/   rU   r`   rN   r   r   rI   ra   rb   r'   r'   r(   Útest_isRunningUnknownErrno  s
    z'PIDFileTests.test_isRunningUnknownErrnoc                 C   s   t |  ¡ ƒ}|  | ¡ ¡ dS )zS
        L{PIDFile.isRunning} returns false if the PID file doesn't exist.
        N)r   r/   rY   ra   r1   r'   r'   r(   Útest_isRunningNoPIDFile#  s    z$PIDFileTests.test_isRunningNoPIDFilec              	   C   sb   t |  ¡ ƒ}|  |j ¡ ¡ |�( |  |j ¡ ¡ |  | ¡ tƒ ¡ W 5 Q R X |  |j ¡ ¡ dS )zŽ
        When used as a context manager, a L{PIDFile} will store the current pid
        on entry, then removes the PID file on exit.
        N)r   r/   rY   rW   r!   r7   r:   r   r1   r'   r'   r(   Útest_contextManager+  s    z PIDFileTests.test_contextManagerc              	   C   sz   t |  ¡ ƒ}| d¡ ttddœdd„}|  td|¡ |  t|j¡}|  	t
|ƒd¡ |� |  	| ¡ tƒ ¡ W 5 Q R X dS )zß
        When used as a context manager, a L{PIDFile} will replace the
        underlying PIDFile rather than raising L{AlreadyRunningError} if the
        contained PID file exists but refers to a non-running PID.
        r4   Nr[   c                 S   s   t tjdƒ‚d S re   rf   r]   r'   r'   r(   r^   C  s    z9PIDFileTests.test_contextManagerDoesntExist.<locals>.killr^   z'PID file refers to non-existing process)r   r/   rQ   r`   rN   r   r   r   ra   r7   r"   r:   r   )r   r2   r^   r%   r'   r'   r(   Útest_contextManagerDoesntExist9  s    
z+PIDFileTests.test_contextManagerDoesntExistc                 C   sV   t |  ¡ ƒ}| d¡ ttddœdd„}|  td|¡ |  | ¡ ¡ |  t	|j
¡ dS )z²
        When used as a context manager, a L{PIDFile} will raise
        L{AlreadyRunningError} if the there is already a running process with
        the contained PID.
        r4   Nr[   c                 S   s   d S r-   r'   r]   r'   r'   r(   r^   X  s    z<PIDFileTests.test_contextManagerAlreadyRunning.<locals>.killr^   )r   r/   rQ   r`   rN   r   r!   ra   r   r   Ú	__enter__rb   r'   r'   r(   Ú!test_contextManagerAlreadyRunningN  s    
z.PIDFileTests.test_contextManagerAlreadyRunning)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úbytesr
   r"   r/   r3   r9   r<   rB   rC   rF   rP   rR   rT   rV   rZ   r*   rc   rd   rg   ri   rl   rn   ro   rp   rq   rs   r'   r'   r'   r(   r+   G   s>   

	
r+   c                   @   sr   e Zd ZdZddœdd„Zddœdd„Zddœdd	„Zddœd
d„Zddœdd„Zddœdd„Z	ddœdd„Z
dS )ÚNonePIDFileTestsz#
    Tests for L{NonePIDFile}.
    Nr0   c                 C   s   t ƒ }tt|ƒ dS )z9
        L{NonePIDFile} conforms to L{IPIDFile}.
        N)r   r   r   r1   r'   r'   r(   r3   g  s    zNonePIDFileTests.test_interfacec                 C   s(   t ƒ }|  t|j¡}|  t|ƒd¡ dS )z;
        L{NonePIDFile.read} raises L{NoPIDFound}.
        rD   N)r   r   r   r:   r7   r"   rE   r'   r'   r(   Ú	test_readn  s    zNonePIDFileTests.test_readc                 C   s*   t ƒ }|  t|jd¡}|  |jtj¡ dS )zZ
        L{NonePIDFile._write} raises L{OSError} with an errno of L{errno.EPERM}.
        r   N)r   r   rI   rQ   r7   rJ   rh   ©r   r2   rO   r'   r'   r(   Ú
test_writew  s    zNonePIDFileTests.test_writec                 C   s(   t ƒ }|  t|j¡}|  |jtj¡ dS )zk
        L{NonePIDFile.writeRunningPID} raises L{OSError} with an errno of
        L{errno.EPERM}.
        N)r   r   rI   rU   r7   rJ   rh   r{   r'   r'   r(   rV   €  s    z%NonePIDFileTests.test_writeRunningPIDc                 C   s(   t ƒ }|  t|j¡}|  |jtj¡ dS )zZ
        L{NonePIDFile.remove} raises L{OSError} with an errno of L{errno.EPERM}.
        N)r   r   rI   rX   r7   rJ   ÚENOENTr{   r'   r'   r(   rZ   Š  s    zNonePIDFileTests.test_removec                 C   s   t ƒ }|  | ¡ d¡ dS )z<
        L{NonePIDFile.isRunning} returns L{False}.
        FN)r   r7   ra   r1   r'   r'   r(   Útest_isRunning“  s    zNonePIDFileTests.test_isRunningc              	   C   s   t ƒ }|� W 5 Q R X dS )zo
        When used as a context manager, a L{NonePIDFile} doesn't raise, despite
        not existing.
        N)r   r1   r'   r'   r(   rp   ›  s    z$NonePIDFileTests.test_contextManager)rt   ru   rv   rw   r3   rz   r|   rV   rZ   r~   rp   r'   r'   r'   r(   ry   b  s   		
	ry   )&rw   rJ   Ú	functoolsr   Úosr   r   rk   Útypingr   r   r   Zzope.interface.verifyr   Ztyping_extensionsr	   Ztwisted.trial.unittestZtwistedZtwisted.python.filepathr
   Ztwisted.python.runtimer   r   Úrunnerr   r   r   r   r   r   r   r   r*   ZtrialZunittestZTestCaser+   ry   r'   r'   r'   r(   Ú<module>   s"   $ &  