o
    Óó·i1>  ã                   @  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 ¡ rNedƒdu rNedƒdu rNd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„Zee ¡ dƒddd„ƒZdd	d
„Z	ee ¡ dƒddd„ƒZ
eeeƒddd„ƒZeeeƒddd„ƒZddd„ZdS )Ú	UtilTestszM
    Tests for the helper functions used to implement L{FilesystemLock}.
    ÚreturnÚNonec                 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   ú`C:\Users\psant\Downloads\PAF backend\school\venv\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  sF   |   ¡ }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).
        ÚsrcÚstrÚdstr   r   c                 S  ó   t tjd ƒ‚©N©r   r   ÚEIO©r   r    r   r   r   Ú
fakeRenameA   ó   z4UtilTests.test_symlinkEIOWindows.<locals>.fakeRenameÚrenamer   N©r   r   r    r   r   r   )	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  sD   |   ¡ }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).
        Úpathr   Úmoder   r   c                 S  r!   r"   ©r   r   ÚEACCES)r1   r2   r   r   r   ÚfakeOpen`   r'   z6UtilTests.test_readlinkEACCESWindows.<locals>.fakeOpenÚ_openN)r1   r   r2   r   r   r   )	r   r*   r   r   r+   r-   r   r   r4   )r   r   r5   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   r8   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}.
        r8   N)r*   r   ÚFilesystemLockr   ÚlockÚassertFalse)r   Úflr   r   r   Útest_noKillCally   s   zUtilTests.test_noKillCallN©r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   Ú	isWindowsr,   r/   r7   r   ÚskipKillÚskipKillReasonr<   r>   rC   r   r   r   r   r   #   s&    

þ
	þ	r   c                   @  sø   e Zd Zd/dd„Zd0dd„Zee ¡ d	ƒd0d
d„ƒZd0dd„Z	d0dd„Z
d0dd„Zd0dd„Zd0dd„Zee ¡ dƒd0dd„ƒZee ¡ dƒd0dd„ƒZd1dd„Zd0d d!„Zee ¡ d	ƒd0d"d#„ƒZd0d$d%„Zd0d&d'„Zd0d(d)„Zd0d*d+„Zd0d,d-„Zd.S )2ÚLockingTestsr   Úintr   r   c                   sN   d	‡ fdd„}|   td|¡ |  ¡ }t |¡}|  t|j¡}|  |jˆ ¡ d S )
NÚsourcer   Údestr   r   c                   s
   t ˆ d ƒ‚r"   )r   )rN   rO   ©r   r   r   ÚfakeSymlink‡   ó   
z3LockingTests._symlinkErrorTest.<locals>.fakeSymlinkr   )rN   r   rO   r   r   r   )	r*   r   r   r?   r   r   r@   r   r   )r   r   rQ   Úlockfr@   r   r   rP   r   Ú_symlinkErrorTest†   s   
zLockingTests._symlinkErrorTestc                 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)rT   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)rT   r   r4   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   rS   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?   rX   r@   ÚunlockrA   rZ   rY   r[   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?   rX   r@   rA   rZ   )r   rS   Z	firstLockZ
secondLockr   r   r   Útest_cannotLockLockedÂ   s   

z"LockingTests.test_cannotLockLockedc                   s†   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  ÚpidrM   Úsignalr   r   c                   s,   |dkr
t tjd ƒ‚| ˆ krt tjd ƒ‚d S )Nr   ©r   r   ÚEPERMr=   ©r`   ra   ©Úownerr   r   ÚfakeKillÖ   ó
   ÿz4LockingTests.test_uncleanlyAcquire.<locals>.fakeKillr8   N©r`   rM   ra   rM   r   r   )r   r*   r   r   r   r?   rX   r@   rA   rY   rZ   r   r-   r9   r:   )r   rg   rS   r@   r   re   r   Útest_uncleanlyAcquireÎ   s   
z"LockingTests.test_uncleanlyAcquirec                   s‚   d‡ ‡fdd„}|   t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   ©rS   ZreadlinkPatchr   r   ÚfakeReadlinkî   s   

z?LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeReadlinkr-   r`   rM   ra   r   c                 S  ó,   |dkr
t tjd ƒ‚| dkrt tjd ƒ‚d S ©Nr   éu¨  rb   rd   r   r   r   rg   ÷   rh   z;LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeKillr8   rr   N)r   r   r   r   ri   ©
r*   r   r   r?   r   r   rX   r@   rY   rZ   )r   ro   rg   r@   r   rn   r   Útest_lockReleasedBeforeCheckç   ó   

z)LockingTests.test_lockReleasedBeforeCheckr   c                 C  sH   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    r   r   c                 S  r!   r"   r#   r%   r   r   r   rQ     s   zGLockingTests.test_lockReleasedDuringAcquireSymlink.<locals>.fakeSymlinkr   Nr)   )r*   r   r   r?   rA   r@   rZ   )r   rQ   rS   r@   r   r   r   Ú%test_lockReleasedDuringAcquireSymlink  s   

z2LockingTests.test_lockReleasedDuringAcquireSymlinkr0   c                 C  sX   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   r   r   c                 S  r!   r"   r3   rm   r   r   r   ro   +  s   zILockingTests.test_lockReleasedDuringAcquireReadlink.<locals>.fakeReadlinkr-   rr   N©r   r   r   r   )	r*   r   r   r?   r   r   rA   r@   rZ   )r   ro   rS   r@   r   r   r   Ú&test_lockReleasedDuringAcquireReadlink   s   

z3LockingTests.test_lockReleasedDuringAcquireReadlinkÚexceptionTypeútype[OSError] | type[IOError]c                   sl   d	‡ ‡fdd„}|   td|¡ |  ¡ }t tdƒ|¡ t |¡}|  ˆ|j¡}|  |j	ˆ ¡ |  
|j¡ d S )
Nr   r   r   r   c                   s
   ˆˆ d ƒ‚r"   r   rm   ©r   ry   r   r   ro   <  rR   z5LockingTests._readlinkErrorTest.<locals>.fakeReadlinkr-   rr   rw   )r*   r   r   r   r   r?   r   r@   r   r   rA   rZ   )r   ry   r   ro   rS   r@   r   r   r{   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)r|   r   r   rU   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)r|   r+   r   rU   r4   r;   r   r   r   Útest_readlinkErrorPOSIXS  s   z$LockingTests.test_readlinkErrorPOSIXc                   s‚   d‡ ‡fdd„}|   t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   r   r   c                   s   ˆ  ¡  t ˆ ¡ t | ¡S r"   )rl   r   rk   rm   ©rS   ZrmlinkPatchr   r   Ú
fakeRmlinki  s   

z?LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeRmlinkrk   r`   rM   ra   c                 S  rp   rq   rb   rd   r   r   r   rg   r  rh   z=LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeKillr8   rr   N)r   r   r   r   ri   rs   )r   r€   rg   r@   r   r   r   Útest_lockCleanedUpConcurrentlyb  ru   z+LockingTests.test_lockCleanedUpConcurrentlyc                 C  s€   ddd„}|   t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   r   r   c                 S  r!   r"   )r   r   rU   rm   r   r   r   r€   ‡  r'   z1LockingTests.test_rmlinkError.<locals>.fakeRmlinkrk   r`   rM   ra   r   c                 S  rp   rq   rb   rd   r   r   r   rg   Œ  rh   z/LockingTests.test_rmlinkError.<locals>.fakeKillr8   rr   Nrw   ri   )r*   r   r   r   r   r?   r   r   r@   r   r   rU   rA   rZ   )r   r€   rg   rS   r@   r   r   r   r   Útest_rmlinkError�  s   


zLockingTests.test_rmlinkErrorc                 C  sh   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}.
        r`   rM   ra   r   r   c                 S  r!   r"   )r   r   rc   rd   r   r   r   rg   ¥  r'   z-LockingTests.test_killError.<locals>.fakeKillr8   rr   N)r`   rM   ra   rM   r   r   )r*   r   r   r   r   r?   r   r   r@   r   r   rc   rA   rZ   )r   rg   rS   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   r9   r:   r?   r   Ú
ValueErrorr]   r[   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   rA   r   ZisLockedr?   rX   r@   r]   r[   r   r   r   Útest_isLocked¾  s   
zLockingTests.test_isLockedN)r   rM   r   r   rD   )ry   rz   r   rM   r   r   )rE   rF   rG   rT   rV   r   r   rI   rW   r\   r^   r_   rj   rt   r   rv   rx   r|   r}   r~   r�   r‚   rƒ   r†   r‡   r   r   r   r   rL   …   sF    

þ




þþ

þ




rL   )rH   Ú
__future__r   r   r9   Zunittestr   r   Ztyping_extensionsr   Ztwisted.pythonr   Ztwisted.python.reflectr   Ztwisted.python.runtimer   Ztwisted.trial.unittestr	   rJ   rK   rI   r   rL   r   r   r   r   Ú<module>   s,   
ÿ
þÿb