o
    ¼>h1>  ã                   @  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.OpenProcessÚ
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   úz/var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/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)r2   r3   r   r   r   ÚfakeOpen`   r(   z6UtilTests.test_readlinkEACCESWindows.<locals>.fakeOpenÚ_openN)r2   r    r3   r    r   r   )	r   r+   r   r   r,   r.   r   r   r5   )r   r   r6   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   r9   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}.
        r9   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-   r0   r8   r   ÚskipKillÚskipKillReasonr=   r?   rD   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   )rO   rP   ©r   r   r   ÚfakeSymlink‡   ó   
z3LockingTests._symlinkErrorTest.<locals>.fakeSymlinkr   )rO   r    rP   r    r   r   )	r+   r   r   r@   r   r   rA   r   r   )r   r   rR   ÚlockfrA   r   r   rQ   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)rU   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)rU   r   r5   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@   Ú
assertTruerA   ÚcleanÚlocked©r   rT   rA   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@   rY   rA   ÚunlockrB   r[   rZ   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@   rY   rA   rB   r[   )r   rT   Ú	firstLockÚ
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  ÚpidrN   Úsignalr   r   c                   s,   |dkr
t tjd ƒ‚| ˆ krt tjd ƒ‚d S )Nr   ©r   r   ÚEPERMr>   ©rc   rd   ©Úownerr   r   ÚfakeKillÖ   ó
   ÿz4LockingTests.test_uncleanlyAcquire.<locals>.fakeKillr9   N©rc   rN   rd   rN   r   r   )r   r+   r   r   r    r@   rY   rA   rB   rZ   r[   r   r.   r:   r;   )r   rj   rT   rA   r   rh   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   ©rT   ÚreadlinkPatchr   r   ÚfakeReadlinkî   s   

z?LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeReadlinkr.   rc   rN   rd   r   c                 S  ó,   |dkr
t tjd ƒ‚| dkrt tjd ƒ‚d S ©Nr   éu¨  re   rg   r   r   r   rj   ÷   rk   z;LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeKillr9   rv   N)r   r    r   r    rl   ©
r+   r   r   r@   r   r    rY   rA   rZ   r[   )r   rs   rj   rA   r   rq   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   rR     s   zGLockingTests.test_lockReleasedDuringAcquireSymlink.<locals>.fakeSymlinkr   Nr*   )r+   r   r   r@   rB   rA   r[   )r   rR   rT   rA   r   r   r   Ú%test_lockReleasedDuringAcquireSymlink  s   

z2LockingTests.test_lockReleasedDuringAcquireSymlinkr1   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#   r4   rp   r   r   r   rs   +  s   zILockingTests.test_lockReleasedDuringAcquireReadlink.<locals>.fakeReadlinkr.   rv   N©r   r    r   r   )	r+   r   r   r@   r   r    rB   rA   r[   )r   rs   rT   rA   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   rp   ©r   r}   r   r   rs   <  rS   z5LockingTests._readlinkErrorTest.<locals>.fakeReadlinkr.   rv   r{   )r+   r   r   r   r    r@   r   rA   r   r   rB   r[   )r   r}   r   rs   rT   rA   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   rV   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   rV   r5   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#   )ro   r   rn   rp   ©rT   ÚrmlinkPatchr   r   Ú
fakeRmlinki  s   

z?LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeRmlinkrn   rc   rN   rd   c                 S  rt   ru   re   rg   r   r   r   rj   r  rk   z=LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeKillr9   rv   N)r   r    r   r   rl   rw   )r   r…   rj   rA   r   rƒ   r   Útest_lockCleanedUpConcurrentlyb  ry   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   rV   rp   r   r   r   r…   ‡  r(   z1LockingTests.test_rmlinkError.<locals>.fakeRmlinkrn   rc   rN   rd   r   c                 S  rt   ru   re   rg   r   r   r   rj   Œ  rk   z/LockingTests.test_rmlinkError.<locals>.fakeKillr9   rv   Nr{   rl   )r+   r   r   r   r    r@   r   r   rA   r   r   rV   rB   r[   )r   r…   rj   rT   rA   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}.
        rc   rN   rd   r   r   c                 S  r"   r#   )r   r   rf   rg   r   r   r   rj   ¥  r(   z-LockingTests.test_killError.<locals>.fakeKillr9   rv   N)rc   rN   rd   rN   r   r   )r+   r   r   r   r    r@   r   r   rA   r   r   rf   rB   r[   )r   rj   rT   rA   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    r:   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   rB   r   ÚisLockedr@   rY   rA   r^   r\   r   r   r   Útest_isLocked¾  s   
zLockingTests.test_isLockedN)r   rN   r   r   rE   )r}   r~   r   rN   r   r   )rF   rG   rH   rU   rW   r   r   rJ   rX   r]   r_   rb   rm   rx   r   rz   r|   r€   r   r‚   r†   r‡   rˆ   r‹   r   r   r   r   r   rM   …   sF    

þ




þþ

þ




rM   )rI   Ú
__future__r   r   r:   Úunittestr   r   Útyping_extensionsr   Útwisted.pythonr   Útwisted.python.reflectr   Útwisted.python.runtimer   Útwisted.trial.unittestr	   rK   rL   rJ   r   rM   r   r   r   r   Ú<module>   s(   ÿb