U
    .Wj1>  ã                   @  sÀ   d Z ddlmZ ddlZddlZddlmZm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 d
ZdZe ¡ rœedƒdkrœedƒdkrœdZdZG dd„ deƒZG dd„ deƒZdS )z'
Tests for L{twisted.python.lockfile}.
é    )ÚannotationsN)ÚskipIfÚ
skipUnless)ÚNoReturn)Úlockfile)ÚrequireModule)Úplatform)ÚTestCaseFÚ zwin32api.OpenProcessZ
pywintypesTzZOn windows, lockfile.kill is not implemented in the absence of win32api and/or pywintypes.c                   @  s¢   e Zd ZdZddœdd„Zee ¡ dƒddœdd„ƒZddœd	d
„Z	ee ¡ dƒddœdd„ƒZ
eeeƒddœdd„ƒZeeeƒddœdd„ƒZddœdd„ZdS )Ú	UtilTestszM
    Tests for the helper functions used to implement L{FilesystemLock}.
    ÚNone©Úreturnc                 C  s:   |   ¡ }t d|¡ |  ttjd|¡}|  |jtj¡ dS )z 
        L{lockfile.symlink} raises L{OSError} with C{errno} set to L{EEXIST}
        when an attempt is made to create a symlink which already exists.
        ÚfooN)Úmktempr   ÚsymlinkÚassertRaisesÚOSErrorÚassertEqualÚerrnoÚEEXIST©ÚselfÚnameÚexc© r   úec:\users\psant\downloads\hotstarbackend\school\venv38\Lib\site-packages\twisted/test/test_lockfile.pyÚtest_symlinkEEXIST(   s    zUtilTests.test_symlinkEEXISTúBspecial rename EIO handling only necessary and correct on Windows.c                 C  sN   |   ¡ }ddddœdd„}|  td|¡ |  ttj|d¡}|  |jtj¡ dS )	a<  
        L{lockfile.symlink} raises L{OSError} with C{errno} set to L{EIO} when
        the underlying L{rename} call fails with L{EIO}.

        Renaming a file on Windows may fail if the target of the rename is in
        the process of being deleted (directory deletion appears not to be
        atomic).
        Ústrr   ©ÚsrcÚdstr   c                 S  s   t tjd ƒ‚d S ©N©r   r   ÚEIO©r!   r"   r   r   r   Ú
fakeRenameA   s    z4UtilTests.test_symlinkEIOWindows.<locals>.fakeRenameÚrenamer   N)	r   Úpatchr   r   ÚIOErrorr   r   r   r%   )r   r   r'   r   r   r   r   Útest_symlinkEIOWindows2   s
    z UtilTests.test_symlinkEIOWindowsc                 C  s,   |   ¡ }|  ttj|¡}|  |jtj¡ dS )zŸ
        L{lockfile.readlink} raises L{OSError} with C{errno} set to L{ENOENT}
        when an attempt is made to read a symlink which does not exist.
        N)r   r   r   r   Úreadlinkr   r   ÚENOENTr   r   r   r   Útest_readlinkENOENTH   s    zUtilTests.test_readlinkENOENTúGspecial readlink EACCES handling only necessary and correct on Windows.c                 C  sL   |   ¡ }ddddœdd„}|  td|¡ |  ttj|¡}|  |jtj¡ dS )a\  
        L{lockfile.readlink} raises L{OSError} with C{errno} set to L{EACCES}
        on Windows when the underlying file open attempt fails with C{EACCES}.

        Opening a file on Windows may fail if the path is inside a directory
        which is in the process of being deleted (directory deletion appears
        not to be atomic).
        r   r   )ÚpathÚmoder   c                 S  s   t tjd ƒ‚d S r#   ©r   r   ÚEACCES)r0   r1   r   r   r   ÚfakeOpen`   s    z6UtilTests.test_readlinkEACCESWindows.<locals>.fakeOpenÚ_openN)	r   r)   r   r   r*   r,   r   r   r3   )r   r   r4   r   r   r   r   Útest_readlinkEACCESWindowsQ   s
    z$UtilTests.test_readlinkEACCESWindowsc                 C  s   t  t ¡ d¡ dS )z}
        L{lockfile.kill} returns without error if passed the PID of a
        process which exists and signal C{0}.
        r   N)r   ÚkillÚosÚgetpid©r   r   r   r   Ú	test_killg   s    zUtilTests.test_killc                 C  s&   |   ttjdd¡}|  |jtj¡ dS )z�
        L{lockfile.kill} raises L{OSError} with errno of L{ESRCH} if
        passed a PID which does not correspond to any process.
        iÿÿÿr   N)r   r   r   r7   r   r   ÚESRCH)r   r   r   r   r   Útest_killESRCHo   s    zUtilTests.test_killESRCHc                 C  s6   |   tdd¡ t |  ¡ ¡}| ¡  |  | ¡ ¡ dS )zµ
        Verify that when L{lockfile.kill} does end up as None (e.g. on Windows
        without pywin32), it doesn't end up being called and raising a
        L{TypeError}.
        r7   N)r)   r   ÚFilesystemLockr   ÚlockÚassertFalse)r   Úflr   r   r   Útest_noKillCally   s    zUtilTests.test_noKillCallN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   Ú	isWindowsr+   r.   r6   r   ÚskipKillÚskipKillReasonr;   r=   rB   r   r   r   r   r   #   s$   
þ	þ	r   c                   @  sF  e Zd Zdddœdd„Zddœdd„Zee ¡ d	ƒ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e ¡ dƒddœdd„ƒZee ¡ dƒddœdd„ƒZddddœdd„Zddœd d!„Zee ¡ d	ƒ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 )/ÚLockingTestsÚintr   )r   r   c                   sV   ddddœ‡ fdd„}|   td|¡ |  ¡ }t |¡}|  t|j¡}|  |jˆ ¡ d S )Nr   r   )ÚsourceÚdestr   c                   s   t ˆ d ƒ‚d S r#   )r   )rL   rM   ©r   r   r   ÚfakeSymlink‡   s    z3LockingTests._symlinkErrorTest.<locals>.fakeSymlinkr   )	r)   r   r   r>   r   r   r?   r   r   )r   r   rO   Úlockfr?   r   r   rN   r   Ú_symlinkErrorTest†   s    
zLockingTests._symlinkErrorTestr   c                 C  s   |   tj¡ dS )z†
        An exception raised by C{symlink} other than C{EEXIST} is passed up to
        the caller of L{FilesystemLock.lock}.
        N)rQ   r   ÚENOSYSr:   r   r   r   Útest_symlinkError‘   s    zLockingTests.test_symlinkErrorz9POSIX-specific error propagation not expected on Windows.c                 C  s   |   tj¡ |   tj¡ dS )a   
        An L{OSError} raised by C{symlink} on a POSIX platform with an errno of
        C{EACCES} or C{EIO} is passed to the caller of L{FilesystemLock.lock}.

        On POSIX, unlike on Windows, these are unexpected errors which cannot
        be handled by L{FilesystemLock}.
        N)rQ   r   r3   r%   r:   r   r   r   Útest_symlinkErrorPOSIX˜   s    z#LockingTests.test_symlinkErrorPOSIXc                 C  s<   |   ¡ }t |¡}|  | ¡ ¡ |  |j¡ |  |j¡ dS )z‹
        If the lock has never been held, it can be acquired and the C{clean}
        and C{locked} attributes are set to C{True}.
        N)r   r   r>   Ú
assertTruer?   ÚcleanÚlocked©r   rP   r?   r   r   r   Útest_cleanlyAcquire§   s
    
z LockingTests.test_cleanlyAcquirec                 C  sh   |   ¡ }t |¡}|  | ¡ ¡ | ¡  |  |j¡ t |¡}|  | ¡ ¡ |  |j¡ |  |j¡ dS )zŒ
        If a lock is released cleanly, it can be re-acquired and the C{clean}
        and C{locked} attributes are set to C{True}.
        N)	r   r   r>   rU   r?   Úunlockr@   rW   rV   rX   r   r   r   Útest_cleanlyRelease²   s    

z LockingTests.test_cleanlyReleasec                 C  sH   |   ¡ }t |¡}|  | ¡ ¡ t |¡}|  | ¡ ¡ |  |j¡ dS )zK
        If a lock is currently locked, it cannot be locked again.
        N)r   r   r>   rU   r?   r@   rW   )r   rP   Z	firstLockZ
secondLockr   r   r   Útest_cannotLockLockedÂ   s    

z"LockingTests.test_cannotLockLockedc                   sŽ   d‰ ddddœ‡ fdd„}|   ¡ }|  td|¡ t tˆ ƒ|¡ t |¡}|  | ¡ ¡ |  |j	¡ |  |j
¡ |  t |¡tt ¡ ƒ¡ dS )	zÇ
        If a lock was held by a process which no longer exists, it can be
        acquired, the C{clean} attribute is set to C{False}, and the
        C{locked} attribute is set to C{True}.
        i90  rK   r   ©ÚpidÚsignalr   c                   s,   |dkrt tjd ƒ‚| ˆ kr(t tjd ƒ‚d S )Nr   ©r   r   ÚEPERMr<   ©r^   r_   ©Úownerr   r   ÚfakeKillÖ   s    z4LockingTests.test_uncleanlyAcquire.<locals>.fakeKillr7   N)r   r)   r   r   r   r>   rU   r?   r@   rV   rW   r   r,   r8   r9   )r   re   rP   r?   r   rc   r   Útest_uncleanlyAcquireÎ   s    
z"LockingTests.test_uncleanlyAcquirec                   s�   dddœ‡ ‡fdd„}|   td|¡‰ddddœd	d
„}|   td|¡ |  ¡ ‰ t ˆ ¡}t tdƒˆ ¡ |  | ¡ ¡ |  |j¡ |  |j	¡ dS )zð
        If the lock is initially held but then released before it can be
        examined to determine if the process which held it still exists, it is
        acquired and the C{clean} and C{locked} attributes are set to C{True}.
        r   ©r   r   c                   s   t  ˆ ¡ ˆ ¡  t  | ¡S r#   )r   ÚrmlinkÚrestorer,   ©r   ©rP   ZreadlinkPatchr   r   ÚfakeReadlinkî   s    
z?LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeReadlinkr,   rK   r   r]   c                 S  s,   |dkrt tjd ƒ‚| dkr(t tjd ƒ‚d S ©Nr   éu¨  r`   rb   r   r   r   re   ÷   s    z;LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeKillr7   rn   N©
r)   r   r   r>   r   r   rU   r?   rV   rW   )r   rl   re   r?   r   rk   r   Útest_lockReleasedBeforeCheckç   s    
z)LockingTests.test_lockReleasedBeforeCheckr   c                 C  sP   ddddœdd„}|   td|¡ |  ¡ }t |¡}|  | ¡ ¡ |  |j¡ dS )a“  
        If the lock is released while an attempt is made to acquire
        it, the lock attempt fails and C{FilesystemLock.lock} returns
        C{False}.  This can happen on Windows when L{lockfile.symlink}
        fails with L{IOError} of C{EIO} because another process is in
        the middle of a call to L{os.rmdir} (implemented in terms of
        RemoveDirectory) which is not atomic.
        r   r   r    c                 S  s   t tjd ƒ‚d S r#   r$   r&   r   r   r   rO     s    zGLockingTests.test_lockReleasedDuringAcquireSymlink.<locals>.fakeSymlinkr   N)r)   r   r   r>   r@   r?   rW   )r   rO   rP   r?   r   r   r   Ú%test_lockReleasedDuringAcquireSymlink  s    
z2LockingTests.test_lockReleasedDuringAcquireSymlinkr/   c                 C  s^   dddœdd„}|   td|¡ |  ¡ }t |¡}t tdƒ|¡ |  | ¡ ¡ |  |j¡ dS )	z»
        If the lock is initially held but is released while an attempt
        is made to acquire it, the lock attempt fails and
        L{FilesystemLock.lock} returns C{False}.
        r   r   rg   c                 S  s   t tjd ƒ‚d S r#   r2   rj   r   r   r   rl   +  s    zILockingTests.test_lockReleasedDuringAcquireReadlink.<locals>.fakeReadlinkr,   rn   N)	r)   r   r   r>   r   r   r@   r?   rW   )r   rl   rP   r?   r   r   r   Ú&test_lockReleasedDuringAcquireReadlink   s    
z3LockingTests.test_lockReleasedDuringAcquireReadlinkztype[OSError] | type[IOError])ÚexceptionTyper   r   c                   sr   dddœ‡ ‡fdd„}|   td|¡ |  ¡ }t tdƒ|¡ t |¡}|  ˆ|j¡}|  |j	ˆ ¡ |  
|j¡ d S )Nr   r   rg   c                   s   ˆˆ d ƒ‚d S r#   r   rj   ©r   rs   r   r   rl   <  s    z5LockingTests._readlinkErrorTest.<locals>.fakeReadlinkr,   rn   )r)   r   r   r   r   r>   r   r?   r   r   r@   rW   )r   rs   r   rl   rP   r?   r   r   rt   r   Ú_readlinkErrorTest9  s    
zLockingTests._readlinkErrorTestc                 C  s    |   ttj¡ |   ttj¡ dS )z‡
        An exception raised by C{readlink} other than C{ENOENT} is passed up to
        the caller of L{FilesystemLock.lock}.
        N)ru   r   r   rR   r*   r:   r   r   r   Útest_readlinkErrorK  s    zLockingTests.test_readlinkErrorc                 C  s    |   ttj¡ |   ttj¡ dS )zú
        Any L{IOError} raised by C{readlink} on a POSIX platform passed to the
        caller of L{FilesystemLock.lock}.

        On POSIX, unlike on Windows, these are unexpected errors which cannot
        be handled by L{FilesystemLock}.
        N)ru   r*   r   rR   r3   r:   r   r   r   Útest_readlinkErrorPOSIXS  s    z$LockingTests.test_readlinkErrorPOSIXc                   s�   dddœ‡ ‡fdd„}|   td|¡‰ddddœd	d
„}|   td|¡ |  ¡ ‰ t ˆ ¡}t tdƒˆ ¡ |  | ¡ ¡ |  |j¡ |  |j	¡ dS )z×
        If a second process cleans up the lock after a first one checks the
        lock and finds that no process is holding it, the first process does
        not fail when it tries to clean up the lock.
        r   r   rg   c                   s   ˆ  ¡  t ˆ ¡ t | ¡S r#   )ri   r   rh   rj   ©rP   ZrmlinkPatchr   r   Ú
fakeRmlinki  s    
z?LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeRmlinkrh   rK   r]   c                 S  s,   |dkrt tjd ƒ‚| dkr(t tjd ƒ‚d S rm   r`   rb   r   r   r   re   r  s    z=LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeKillr7   rn   Nro   )r   ry   re   r?   r   rx   r   Útest_lockCleanedUpConcurrentlyb  s    
z+LockingTests.test_lockCleanedUpConcurrentlyc                 C  sŽ   dddœdd„}|   td|¡ dddd	œd
d„}|   td|¡ |  ¡ }t tdƒ|¡ t |¡}|  t|j¡}|  	|j
t
j¡ |  |j¡ dS )z…
        An exception raised by L{rmlink} other than C{ENOENT} is passed up
        to the caller of L{FilesystemLock.lock}.
        r   r   rg   c                 S  s   t tjd ƒ‚d S r#   )r   r   rR   rj   r   r   r   ry   ‡  s    z1LockingTests.test_rmlinkError.<locals>.fakeRmlinkrh   rK   r   r]   c                 S  s,   |dkrt tjd ƒ‚| dkr(t tjd ƒ‚d S rm   r`   rb   r   r   r   re   Œ  s    z/LockingTests.test_rmlinkError.<locals>.fakeKillr7   rn   N)r)   r   r   r   r   r>   r   r   r?   r   r   rR   r@   rW   )r   ry   re   rP   r?   r   r   r   r   Útest_rmlinkError�  s    
zLockingTests.test_rmlinkErrorc                 C  sp   ddddœdd„}|   td|¡ |  ¡ }t tdƒ|¡ t |¡}|  t|j¡}|  	|j
t
j¡ |  |j¡ dS )	z¶
        If L{kill} raises an exception other than L{OSError} with errno set to
        C{ESRCH}, the exception is passed up to the caller of
        L{FilesystemLock.lock}.
        rK   r   r]   c                 S  s   t tjd ƒ‚d S r#   )r   r   ra   rb   r   r   r   re   ¥  s    z-LockingTests.test_killError.<locals>.fakeKillr7   rn   N)r)   r   r   r   r   r>   r   r   r?   r   r   ra   r@   rW   )r   re   rP   r?   r   r   r   r   Útest_killErrorž  s    
zLockingTests.test_killErrorc                 C  s<   |   ¡ }t tt ¡ d ƒ|¡ t |¡}|  t|j	¡ dS )z‚
        L{FilesystemLock.unlock} raises L{ValueError} if called for a lock
        which is held by a different process.
        é   N)
r   r   r   r   r8   r9   r>   r   Ú
ValueErrorrZ   rX   r   r   r   Útest_unlockOther´  s    
zLockingTests.test_unlockOtherc                 C  s\   |   ¡ }|  t |¡¡ t |¡}|  | ¡ ¡ |  t |¡¡ | ¡  |  t |¡¡ dS )zp
        L{isLocked} returns C{True} if the named lock is currently locked,
        C{False} otherwise.
        N)r   r@   r   ZisLockedr>   rU   r?   rZ   rX   r   r   r   Útest_isLocked¾  s    
zLockingTests.test_isLockedN)rC   rD   rE   rQ   rS   r   r   rG   rT   rY   r[   r\   rf   rp   r   rq   rr   ru   rv   rw   rz   r{   r|   r   r€   r   r   r   r   rJ   …   sD   þþþþ
rJ   )rF   Ú
__future__r   r   r8   Zunittestr   r   Ztyping_extensionsr   Ztwisted.pythonr   Ztwisted.python.reflectr   Ztwisted.python.runtimer   Ztwisted.trial.unittestr	   rH   rI   rG   r   rJ   r   r   r   r   Ú<module>   s*   
ÿ
þÿb