
    \d;                         d 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Zd	Z ej                    r e	d
           e	d          dZdZ G d de          Z G d de          ZdS )z'
Tests for L{twisted.python.lockfile}.
    N)skipIf
skipUnless)lockfile)requireModule)platform)TestCaseF zwin32api.OpenProcess
pywintypesTzZOn windows, lockfile.kill is not implemented in the absence of win32api and/or pywintypes.c                       e Zd ZdZd Z e ej                    d          d             Zd Z	 e ej                    d          d             Z
 eee          d             Z eee          d	             Zd
 ZdS )	UtilTestszM
    Tests for the helper functions used to implement L{FilesystemLock}.
    c                     |                                  }t          j        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excs      :lib/python3.11/site-packages/twisted/test/test_lockfile.pytest_symlinkEEXISTzUtilTests.test_symlinkEEXIST&   s`    
 {{}}%%%)95$GGEL11111    Bspecial rename EIO handling only necessary and correct on Windows.c                    |                                  }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).
        c                 6    t          t          j        d           Nr   r   EIOsrcdsts     r   
fakeRenamez4UtilTests.test_symlinkEIOWindows.<locals>.fakeRename?   s    %)T***r   renamer   N)	r   patchr   r   IOErrorr   r   r   r"   )r   r   r&   r   s       r   test_symlinkEIOWindowsz UtilTests.test_symlinkEIOWindows0   st     {{}}	+ 	+ 	+ 	

8Xz222)94GGEI.....r   c                     |                                  }|                     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   s      r   test_readlinkENOENTzUtilTests.test_readlinkENOENTF   sK    
 {{}}):DAAEL11111r   Gspecial readlink EACCES handling only necessary and correct on Windows.c                    |                                  }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).
        c                 6    t          t          j        d           r    r   r   EACCES)pathmodes     r   fakeOpenz6UtilTests.test_readlinkEACCESWindows.<locals>.fakeOpen^       %,---r   _openN)	r   r(   r   r   r)   r,   r   r   r3   )r   r   r6   r   s       r   test_readlinkEACCESWindowsz$UtilTests.test_readlinkEACCESWindowsO   sr     {{}}	. 	. 	. 	

8Wh///):DAAEL11111r   c                 R    t          j        t          j                    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   s    r   	test_killzUtilTests.test_kille   s"     	bikk1%%%%%r   c                     |                      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   r;   r   r   ESRCH)r   r   s     r   test_killESRCHzUtilTests.test_killESRCHm   s?     QGGEK00000r   c                     |                      t          dd           t          j        |                                           }|                                 |                     |                                           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}.
        r;   N)r(   r   FilesystemLockr   lockassertFalse)r   fls     r   test_noKillCallzUtilTests.test_noKillCallw   sa     	

8VT***$T[[]]33
			#####r   N)__name__
__module____qualname____doc__r   r   r   	isWindowsr*   r.   r9   r   skipKillskipKillReasonr?   rB   rH    r   r   r   r   !   s        2 2 2 ZO / /	 /$2 2 2 ZT 2 2	 2$ VHn%%& & &%& VHn%%1 1 &%1	$ 	$ 	$ 	$ 	$r   r   c                   r   e Zd Zd Zd Z e ej                    d          d             Zd Z	d Z
d Zd Zd	 Z e ej                    d
          d             Z e ej                    d          d             Zd Zd Z e ej                    d          d             Zd Zd Zd Zd Zd ZdS )LockingTestsc                    fd}|                      t          d|           |                                 }t          j        |          }|                     t
          |j                  }|                     |j                   d S )Nc                 $    t          d           r    )r   )sourcedestr   s     r   fakeSymlinkz3LockingTests._symlinkErrorTest.<locals>.fakeSymlink   s    %&&&r   r   )	r(   r   r   rD   r   r   rE   r   r   )r   r   rW   lockfrE   r   s    `    r   _symlinkErrorTestzLockingTests._symlinkErrorTest   s    	' 	' 	' 	' 	' 	

8Y444&u--33E*****r   c                 D    |                      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)rY   r   ENOSYSr>   s    r   test_symlinkErrorzLockingTests.test_symlinkError   s     
 	u|,,,,,r   z9POSIX-specific error propagation not expected on Windows.c                     |                      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)rY   r   r3   r"   r>   s    r   test_symlinkErrorPOSIXz#LockingTests.test_symlinkErrorPOSIX   s6     	u|,,,uy)))))r   c                    |                                  }t          j        |          }|                     |                                           |                     |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   rD   
assertTruerE   cleanlockedr   rX   rE   s      r   test_cleanlyAcquirez LockingTests.test_cleanlyAcquire   si    
 &u--		$$$
###$$$$$r   c                    |                                  }t          j        |          }|                     |                                           |                                 |                     |j                   t          j        |          }|                     |                                           |                     |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   rD   r`   rE   unlockrF   rb   ra   rc   s      r   test_cleanlyReleasez LockingTests.test_cleanlyRelease   s    
 &u--		$$$%%%&u--		$$$
###$$$$$r   c                 N   |                                  }t          j        |          }|                     |                                           t          j        |          }|                     |                                           |                     |j                   dS )zK
        If a lock is currently locked, it cannot be locked again.
        N)r   r   rD   r`   rE   rF   rb   )r   rX   	firstLock
secondLocks       r   test_cannotLockLockedz"LockingTests.test_cannotLockLocked   s     +E22		(())),U33
**+++*+++++r   c                 $   dfd}|                                  }|                     t          d|           t          j        t	                    |           t          j        |          }|                     |                                           |                     |j	                   |                     |j
                   |                     t          j        |          t	          t          j                                         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  c                     |dk    rt          t          j        d           | k    rt          t          j        d           d S )Nr   r   r   EPERMrA   )pidsignalowners     r   fakeKillz4LockingTests.test_uncleanlyAcquire.<locals>.fakeKill   s@    {{ek4000e||ek4000 |r   r;   N)r   r(   r   r   strrD   r`   rE   rF   ra   rb   r   r,   r<   r=   )r   rs   rX   rE   rr   s       @r   test_uncleanlyAcquirez"LockingTests.test_uncleanlyAcquire   s     	1 	1 	1 	1 	1 

8VX...UU+++&u--		$$$$$$$$$*5113ry{{3C3CDDDDDr   c                    fd}|                      t          d|          d }|                      t          d|           |                                 t          j                  }t          j        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}.
        c                 |    t          j                                                    t          j        |           S r    )r   rmlinkrestorer,   )r   rX   readlinkPatchs    r   fakeReadlinkz?LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeReadlink   s6    OE"""!!###$T***r   r,   c                     |dk    rt          t          j        d           | dk    rt          t          j        d           d S Nr   u  rn   rp   rq   s     r   rs   z;LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeKill   ?    {{ek4000e||ek4000 |r   r;   r~   N
r(   r   r   rD   r   rt   r`   rE   ra   rb   )r   r{   rs   rE   rX   rz   s       @@r   test_lockReleasedBeforeCheckz)LockingTests.test_lockReleasedBeforeCheck   s    	+ 	+ 	+ 	+ 	+ 	+ 

8ZFF	1 	1 	1 	

8VX...&u--UU+++		$$$
###$$$$$r   r   c                    d }|                      t          d|           |                                 }t          j        |          }|                     |                                           |                     |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.
        c                 6    t          t          j        d           r    r!   r#   s     r   rW   zGLockingTests.test_lockReleasedDuringAcquireSymlink.<locals>.fakeSymlink  s     %)T***r   r   N)r(   r   r   rD   rF   rE   rb   )r   rW   rX   rE   s       r   %test_lockReleasedDuringAcquireSymlinkz2LockingTests.test_lockReleasedDuringAcquireSymlink  s~    	+ 	+ 	+
 	

8Y444&u--%%%%%%%%r   r/   c                 Z   d }|                      t          d|           |                                 }t          j        |          }t          j        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}.
        c                 6    t          t          j        d           r    r2   r   s    r   r{   zILockingTests.test_lockReleasedDuringAcquireReadlink.<locals>.fakeReadlink)  s     %,---r   r,   r~   N)	r(   r   r   rD   r   rt   rF   rE   rb   )r   r{   rX   rE   s       r   &test_lockReleasedDuringAcquireReadlinkz3LockingTests.test_lockReleasedDuringAcquireReadlink  s    	. 	. 	. 	

8Z666&u--UU+++%%%%%%%%r   c                    fd}|                      t          d|           |                                 }t          j        t	          d          |           t          j        |          }|                     |j                  }|                     |j	                   | 
                    |j                   d S )Nc                      d           r    rP   )r   r   exceptionTypes    r   r{   z5LockingTests._readlinkErrorTest.<locals>.fakeReadlink8  s    -t,,,r   r,   r~   )r(   r   r   r   rt   rD   r   rE   r   r   rF   rb   )r   r   r   r{   rX   rE   r   s    ``    r   _readlinkErrorTestzLockingTests._readlinkErrorTest7  s    	- 	- 	- 	- 	- 	- 	

8Z666 	UU+++&u--ty99E***%%%%%r   c                     |                      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   r[   r)   r>   s    r   test_readlinkErrorzLockingTests.test_readlinkErrorG  s:    
 	66666666r   c                     |                      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   r[   r3   r>   s    r   test_readlinkErrorPOSIXz$LockingTests.test_readlinkErrorPOSIXO  s:     	66666666r   c                    fd}|                      t          d|          d }|                      t          d|           |                                 t          j                  }t          j        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.
        c                 |                                      t          j                   t          j        |           S r    )ry   r   rx   )r   rX   rmlinkPatchs    r   
fakeRmlinkz?LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeRmlinke  s5    !!!OE"""?4(((r   rx   c                     |dk    rt          t          j        d           | dk    rt          t          j        d           d S r}   rn   r   s     r   rs   z=LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeKilln  r   r   r;   r~   Nr   )r   r   rs   rE   rX   r   s       @@r   test_lockCleanedUpConcurrentlyz+LockingTests.test_lockCleanedUpConcurrently^  s    	) 	) 	) 	) 	) 	) jj8Z@@	1 	1 	1 	

8VX...&u--UU+++		$$$
###$$$$$r   c                    d }|                      t          d|           d }|                      t          d|           |                                 }t          j        t	          d          |           t          j        |          }|                     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}.
        c                 6    t          t          j        d           r    )r   r   r[   r   s    r   r   z1LockingTests.test_rmlinkError.<locals>.fakeRmlink  r7   r   rx   c                     |dk    rt          t          j        d           | dk    rt          t          j        d           d S r}   rn   r   s     r   rs   z/LockingTests.test_rmlinkError.<locals>.fakeKill  r   r   r;   r~   N)r(   r   r   r   rt   rD   r   r   rE   r   r   r[   rF   rb   )r   r   rs   rX   rE   r   s         r   test_rmlinkErrorzLockingTests.test_rmlinkError}  s    	. 	. 	. 	

8Xz222	1 	1 	1 	

8VX... 	UU+++&u--33EL111%%%%%r   c                    d }|                      t          d|           |                                 }t          j        t	          d          |           t          j        |          }|                     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}.
        c                 6    t          t          j        d           r    )r   r   ro   r   s     r   rs   z-LockingTests.test_killError.<locals>.fakeKill  s    %+t,,,r   r;   r~   N)r(   r   r   r   rt   rD   r   r   rE   r   r   ro   rF   rb   )r   rs   rX   rE   r   s        r   test_killErrorzLockingTests.test_killError  s    	- 	- 	- 	

8VX... 	UU+++&u--33EK000%%%%%r   c                    |                                  }t          j        t          t	          j                    dz             |           t          j        |          }|                     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   rt   r<   r=   rD   r   
ValueErrorrf   rc   s      r   test_unlockOtherzLockingTests.test_unlockOther  sd    
 RY[[1_--u555&u--*dk22222r   c                    |                                  }|                     t          j        |                     t          j        |          }|                     |                                           |                     t          j        |                     |                                 |                     t          j        |                     dS )zp
        L{isLocked} returns C{True} if the named lock is currently locked,
        C{False} otherwise.
        N)r   rF   r   isLockedrD   r`   rE   rf   rc   s      r   test_isLockedzLockingTests.test_isLocked  s    
 *511222&u--		$$$)%00111*51122222r   N)rI   rJ   rK   rY   r\   r   r   rM   r^   rd   rg   rk   ru   r   r   r   r   r   r   r   r   r   r   r   r   rP   r   r   rR   rR      s       	+ 	+ 	+- - - VC 	* 	*	 	*	% 	% 	%% % % 
, 
, 
,E E E2% % %> ZO & &	 &, ZT & &	 &*& & & 7 7 7 VC 	7 	7	 	7% % %>& & &:& & &,3 3 33 3 3 3 3r   rR   )rL   r   r<   unittestr   r   twisted.pythonr   twisted.python.reflectr   twisted.python.runtimer   twisted.trial.unittestr   rN   rO   rM   r   rR   rP   r   r   <module>r      sA  
 
  				 ' ' ' ' ' ' ' ' # # # # # # 0 0 0 0 0 0 + + + + + + + + + + + +8 	
,--5M,''/< 	_$ _$ _$ _$ _$ _$ _$ _$DB3 B3 B3 B3 B38 B3 B3 B3 B3 B3r   