o
    ¯b;2  ã                   @   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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 de
de	f de
de	f f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)ÚFilePath)Úplatform)ÚSkipTesté   )Ú_pidfileé   )ÚAlreadyRunningErrorÚInvalidPIDFileErrorÚIPIDFileÚNonePIDFileÚ
NoPIDFoundÚPIDFileÚStalePIDFileErrorÚf.Úreturnc              	      s*   t ˆ ƒdtdtdtdtf‡ 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                    sp   t  ¡ dk}|rˆ | g|¢R i |¤ŽS | jtt| jfˆ | g|¢R i |¤Ž}t|tƒr6|  t|ƒ 	d¡¡ d S d S )NÚposixz isRunning is not implemented on )
r
   ÚgetTypeÚassertRaisesÚNotImplementedErrorr   ÚfailureExceptionÚ
isinstanceÚ
assertTrueÚstrÚ
startswith)r   r   r   Ú	supportedÚe©r   © úN/usr/lib/python3/dist-packages/twisted/application/runner/test/test_pidfile.pyÚwrapper1   s   
ýüû
ÿz$ifPlatformSupported.<locals>.wrapper)r   r   )r   r)   r'   r&   r(   ÚifPlatformSupported   s    r*   c                   @   s  e Zd ZdZd1dee defdd„Zd2dd„Zd2d	d
„Z	d2dd„Z
d2dd„Zd2dd„Zd2dd„Zd2dd„Zd2dd„Zd2dd„Zd2dd„Zd2dd„Zed2dd„ƒZed2dd „ƒZed2d!d"„ƒZed2d#d$„ƒZed2d%d&„ƒZed2d'd(„ƒZd2d)d*„Zd2d+d,„Zed2d-d.„ƒZed2d/d0„ƒZdS )3ÚPIDFileTestsz
    Tests for L{PIDFile}.
    NÚcontentr   c                 C   s"   t |  ¡ ƒ}|d ur| |¡ |S ©N)r	   ÚmktempÚ
setContent)r   r,   ÚfilePathr'   r'   r(   r0   J   s   
zPIDFileTests.filePathc                 C   s   t |  ¡ ƒ}tt|ƒ dS )z5
        L{PIDFile} conforms to L{IPIDFile}.
        N)r   r0   r   r   ©r   ÚpidFiler'   r'   r(   Útest_interfaceP   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_formatWithPIDW   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   r0   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   r0   r   r   r:   r7   r"   ©r   ÚpidValuer2   r%   r'   r'   r(   Útest_readEmptyPIDg   ó   zPIDFileTests.test_readEmptyPIDc                 C   s:   d}t |  |¡ƒ}|  t|j¡}|  t|ƒd|›¡ dS )r=   s   $foo!r?   Nr@   rA   r'   r'   r(   Útest_readWithBogusPIDr   rD   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   r0   r   r   r:   r7   r"   ©r   r2   r%   r'   r'   r(   Útest_readDoesntExist}   s   z!PIDFileTests.test_readDoesntExistc                 C   sP   ddt dtf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   ó   t tjdƒ‚)Nz	I/O error)ÚOSErrorÚerrnoÚEIO)rJ   r'   r'   r(   Úoops   ó   z>PIDFileTests.test_readOpenRaisesOSErrorNotENOENT.<locals>.oopsÚopenN)rI   )r"   r	   Úpatchr   r0   r   rL   r:   r7   rM   rN   )r   rO   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   r0   Ú_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.
        ÚburpN)r   r0   r   Ú
ValueErrorrU   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   r0   Ú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   r0   r!   ÚexistsÚremoveÚassertFalser1   r'   r'   r(   Útest_remove³   s   zPIDFileTests.test_removec                 C   óL   t |  ¡ ƒ}| d¡ dtdtddfdd„}|  td|¡ |  | ¡ ¡ dS )	zR
        L{PIDFile.isRunning} returns true for a process that does exist.
        r4   r6   Úsignalr   Nc                 S   ó   d S r-   r'   ©r6   ra   r'   r'   r(   ÚkillÅ   ó   z2PIDFileTests.test_isRunningDoesExist.<locals>.killrd   ©r   r0   rU   ÚintrR   r   r!   Ú	isRunning©r   r2   rd   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   r0   rZ   r!   rh   r1   r'   r'   r(   Útest_isRunningThisÌ   s   	zPIDFileTests.test_isRunningThisc                 C   sL   t |  ¡ ƒ}| d¡ dtdtddf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   r6   ra   r   Nc                 S   rK   ©NzNo such process©rL   rM   ÚESRCHrc   r'   r'   r(   rd   ã   rP   z5PIDFileTests.test_isRunningDoesNotExist.<locals>.killrd   )	r   r0   rU   rg   rR   r   r   r   rh   ri   r'   r'   r(   Útest_isRunningDoesNotExistÚ   ó
   
z'PIDFileTests.test_isRunningDoesNotExistc                 C   r`   )	zx
        L{PIDFile.isRunning} returns true for a process that we are not allowed
        to kill (errno=EPERM).
        r4   r6   ra   r   Nc                 S   rK   )NzOperation not permitted)rL   rM   ÚEPERMrc   r'   r'   r(   rd   ó   rP   z3PIDFileTests.test_isRunningNotAllowed.<locals>.killrd   rf   ri   r'   r'   r(   Útest_isRunningNotAllowedê   rp   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   r0   rU   r!   rh   r1   r'   r'   r(   Útest_isRunningInitú   s
   
zPIDFileTests.test_isRunningInitc                 C   sJ   t |  ¡ ƒ}| ¡  dtdtddf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.
        r6   ra   r   Nc                 S   rK   )NzFile exists)rL   rM   ÚEEXISTrc   r'   r'   r(   rd     rP   z5PIDFileTests.test_isRunningUnknownErrno.<locals>.killrd   )	r   r0   rZ   rg   rR   r   r   rL   rh   ri   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   r0   r^   rh   r1   r'   r'   r(   Útest_isRunningNoPIDFile!  s   z$PIDFileTests.test_isRunningNoPIDFilec                 C   sv   t |  ¡ ƒ}|  |j ¡ ¡ | |  |j ¡ ¡ |  | ¡ tƒ ¡ W d  ƒ n1 s,w   Y  |  |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   r0   r^   r\   r!   r7   r:   r   r1   r'   r'   r(   Útest_contextManager)  s   þz PIDFileTests.test_contextManagerc                 C   s”   t |  ¡ ƒ}| d¡ dtdtddfdd„}|  td|¡ |  t|j¡}|  	t
|ƒd	¡ | |  	| ¡ tƒ ¡ W d  ƒ dS 1 sCw   Y  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   r6   ra   r   Nc                 S   rK   rl   rm   rc   r'   r'   r(   rd   A  rP   z9PIDFileTests.test_contextManagerDoesntExist.<locals>.killrd   z'PID file refers to non-existing process)r   r0   rU   rg   rR   r   r   r   rh   r7   r"   r:   r   )r   r2   rd   r%   r'   r'   r(   Útest_contextManagerDoesntExist7  s   
"ÿz+PIDFileTests.test_contextManagerDoesntExistc                 C   sZ   t |  ¡ ƒ}| d¡ dtdtddf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   r6   ra   r   Nc                 S   rb   r-   r'   rc   r'   r'   r(   rd   V  re   z<PIDFileTests.test_contextManagerAlreadyRunning.<locals>.killrd   )r   r0   rU   rg   rR   r   r!   rh   r   r   Ú	__enter__ri   r'   r'   r(   Ú!test_contextManagerAlreadyRunningL  s   
z.PIDFileTests.test_contextManagerAlreadyRunningr-   ©r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úbytesr	   r0   r3   r9   r<   rC   rE   rH   rT   rV   rY   r[   r_   r*   rj   rk   ro   rr   ru   rw   rx   ry   rz   r|   r'   r'   r'   r(   r+   E   s@    












	


r+   c                   @   sV   e Zd ZdZddd„Zddd„Zddd	„Zdd
d„Zddd„Zddd„Z	ddd„Z
dS )ÚNonePIDFileTestsz#
    Tests for L{NonePIDFile}.
    r   Nc                 C   s   t ƒ }tt|ƒ dS )z9
        L{NonePIDFile} conforms to L{IPIDFile}.
        N)r   r   r   r1   r'   r'   r(   r3   e  s   zNonePIDFileTests.test_interfacec                 C   s(   t ƒ }|  t|j¡}|  t|ƒd¡ dS )z;
        L{NonePIDFile.read} raises L{NoPIDFound}.
        rF   N)r   r   r   r:   r7   r"   rG   r'   r'   r(   Ú	test_readl  ó   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   rL   rU   r7   rM   rq   ©r   r2   rS   r'   r'   r(   Ú
test_writeu  s   zNonePIDFileTests.test_writec                 C   ó(   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   rL   rZ   r7   rM   rq   r†   r'   r'   r(   r[   ~  s   z%NonePIDFileTests.test_writeRunningPIDc                 C   rˆ   )zZ
        L{NonePIDFile.remove} raises L{OSError} with an errno of L{errno.EPERM}.
        N)r   r   rL   r]   r7   rM   ÚENOENTr†   r'   r'   r(   r_   ˆ  r…   zNonePIDFileTests.test_removec                 C   s   t ƒ }|  | ¡ d¡ dS )z<
        L{NonePIDFile.isRunning} returns L{False}.
        FN)r   r7   rh   r1   r'   r'   r(   Útest_isRunning‘  s   zNonePIDFileTests.test_isRunningc                 C   s0   t ƒ }|	 W d  ƒ dS 1 sw   Y  dS )zo
        When used as a context manager, a L{NonePIDFile} doesn't raise, despite
        not existing.
        N)r   r1   r'   r'   r(   ry   ™  s   "ÿz$NonePIDFileTests.test_contextManagerr}   )r~   r   r€   r   r3   r„   r‡   r[   r_   rŠ   ry   r'   r'   r'   r(   rƒ   `  s    


	
	


	rƒ   )$r   rM   Ú	functoolsr   Úosr   r   rt   Útypingr   r   r   Úzope.interface.verifyr   Útwisted.trial.unittestÚtwistedÚtwisted.python.filepathr	   Útwisted.python.runtimer
   r   Úrunnerr   r   r   r   r   r   r   r   r*   ÚtrialÚunittestÚTestCaser+   rƒ   r'   r'   r'   r(   Ú<module>   s"   $"&  