+
    Dfj&>                       R t ^ RIHt ^ RIt^ RIt^ RIHtHt ^ RIH	t	 ^ RI
Ht ^ RIHt ^ RIHt ^ RIHt R	tR
t]P(                  ! 4       '       d   ]! R4      f   ]! R4      f   RtRt ! R R]4      t ! R R]4      tR# )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                  
   ] tR t^#tRtR R lt]! ]P                  ! 4       R4      R R l4       t	R R lt
]! ]P                  ! 4       R	4      R
 R l4       t]! ]]4      R R l4       t]! ]]4      R R l4       tR R ltRtR# )	UtilTestszE
Tests for the helper functions used to implement L{FilesystemLock}.
c                   V ^8  d   QhRR/#    returnNone )formats   "</usr/lib/python3/dist-packages/twisted/test/test_lockfile.py__annotate__UtilTests.__annotate__(   s     2 2D 2    c                    V P                  4       p\        P                  ! RV4       V P                  \        \        P                  RV4      pV P                  VP                  \        P                  4       R# )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   &  r   test_symlinkEEXISTUtilTests.test_symlinkEEXIST(   sS    
 {{}%)9)95$GELL1r   Bspecial rename EIO handling only necessary and correct on Windows.c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r   6   s     / / /r   c                    V P                  4       pR R lpV P                  \        RV4       V P                  \        \        P
                  VR4      pV P                  VP                  \        P                  4       R# )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               $    V ^8  d   QhRRRRRR/# r   srcstrdstr   r   r   )r   s   "r   r   6UtilTests.test_symlinkEIOWindows.<locals>.__annotate__A   s!     	+ 	+C 	+c 	+h 	+r   c                6    \        \        P                  R 4      hNr   r    EIOr-   r/   s   &&r   
fakeRename4UtilTests.test_symlinkEIOWindows.<locals>.fakeRenameA   s    %))T**r   renamer   N)	r   patchr   r   IOErrorr   r   r    r4   )r#   r$   r6   r%   s   &   r   test_symlinkEIOWindows UtilTests.test_symlinkEIOWindows2   sZ     {{}	+ 	

8Xz2)9)94GEII.r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r   H   s     2 2T 2r   c                    V P                  4       pV P                  \        \        P                  V4      pV P                  VP                  \        P                  4       R# )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_readlinkENOENTUtilTests.test_readlinkENOENTH   sA    
 {{}):):DAELL1r   Gspecial readlink EACCES handling only necessary and correct on Windows.c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r   U   s     2 2D 2r   c                    V P                  4       pR R lpV P                  \        RV4       V P                  \        \        P
                  V4      pV P                  VP                  \        P                  4       R# )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               $    V ^8  d   QhRRRRRR/# )r   pathr.   moder   r   r   )r   s   "r   r   :UtilTests.test_readlinkEACCESWindows.<locals>.__annotate__`   s!     	. 	.3 	.c 	.h 	.r   c                6    \        \        P                  R 4      hr2   r   r    EACCES)rG   rH   s   &&r   fakeOpen6UtilTests.test_readlinkEACCESWindows.<locals>.fakeOpen`       %,,--r   _openN)	r   r9   r   r   r:   r?   r   r    rL   )r#   r$   rM   r%   s   &   r   test_readlinkEACCESWindows$UtilTests.test_readlinkEACCESWindowsQ   sX     {{}	. 	

8Wh/):):DAELL1r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r   h   s     & &4 &r   c                Z    \         P                  ! \        P                  ! 4       ^ 4       R# )ze
L{lockfile.kill} returns without error if passed the PID of a
process which exists and signal C{0}.
N)r   killosgetpidr#   s   &r   	test_killUtilTests.test_killg   s     	biik1%r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r   p   s     1 1 1r   c                    V P                  \        \        P                  R^ 4      pV P	                  VP
                  \
        P                  4       R# )zu
L{lockfile.kill} raises L{OSError} with errno of L{ESRCH} if
passed a PID which does not correspond to any process.
Ni)r   r   r   rU   r   r    ESRCH)r#   r%   s   & r   test_killESRCHUtilTests.test_killESRCHo   s6     	1EEKK0r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r   y   s     	$ 	$ 	$r   c                    V P                  \        RR4       \        P                  ! V P                  4       4      pVP	                  4        V P                  VP	                  4       4       R# )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}.
rU   N)r9   r   FilesystemLockr   lockassertFalse)r#   fls   & r   test_noKillCallUtilTests.test_noKillCally   sG     	

8VT*$$T[[]3
	#r   r   N)__name__
__module____qualname____firstlineno____doc__r&   r   r   	isWindowsr;   rA   rQ   r   skipKillskipKillReasonrY   r^   rf   __static_attributes__r   r   r   r   r   #   s    2 O/	/$2 T2	2$ Hn%& && Hn%1 &1	$ 	$r   r   c                     ] tR t^tR R ltR R lt]! ]P                  ! 4       R4      R R l4       t	R R	 lt
R
 R ltR R ltR R ltR R lt]! ]P                  ! 4       R4      R R l4       t]! ]P                  ! 4       R4      R R l4       tR R ltR R lt]! ]P                  ! 4       R4      R R l4       tR R ltR  R! ltR" R# ltR$ R% ltR& R' ltR(tR)# )*LockingTestsc                    V ^8  d   QhRRRR/# )r   r    intr   r   r   )r   s   "r   r   LockingTests.__annotate__   s     	+ 	+s 	+t 	+r   c                	  a R  V3R llpV P                  \        RV4       V P                  4       p\        P                  ! V4      pV P	                  \
        VP                  4      pV P                  VP                  S4       R# )c               $    V ^8  d   QhRRRRRR/# )r   sourcer.   destr   r   r   )r   s   "r   r   4LockingTests._symlinkErrorTest.<locals>.__annotate__   s!     	' 	' 	'3 	'8 	'r   c                   < \        SR 4      hr2   )r   )rx   ry   r    s   &&r   fakeSymlink3LockingTests._symlinkErrorTest.<locals>.fakeSymlink   s    %&&r   r   N)	r9   r   r   rb   r   r   rc   r   r    )r#   r    r|   lockfrc   r%   s   &f    r   _symlinkErrorTestLockingTests._symlinkErrorTest   sd    	' 	' 	

8Y4&&u-3E*r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru      s     - -4 -r   c                D    V P                  \        P                  4       R# )zn
An exception raised by C{symlink} other than C{EEXIST} is passed up to
the caller of L{FilesystemLock.lock}.
N)r   r    ENOSYSrX   s   &r   test_symlinkErrorLockingTests.test_symlinkError   s    
 	u||,r   z9POSIX-specific error propagation not expected on Windows.c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru      s     	* 	* 	*r   c                    V P                  \        P                  4       V P                  \        P                  4       R# )z
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)r   r    rL   r4   rX   s   &r   test_symlinkErrorPOSIX#LockingTests.test_symlinkErrorPOSIX   s(     	u||,uyy)r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru      s     	% 	%T 	%r   c                    V P                  4       p\        P                  ! V4      pV P                  VP	                  4       4       V P                  VP
                  4       V P                  VP                  4       R# )zs
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   rb   
assertTruerc   cleanlockedr#   r~   rc   s   &  r   test_cleanlyAcquire LockingTests.test_cleanlyAcquire   sQ    
 &&u-		$

#$r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru      s     % %T %r   c                   V P                  4       p\        P                  ! V4      pV P                  VP	                  4       4       VP                  4        V P                  VP                  4       \        P                  ! V4      pV P                  VP	                  4       4       V P                  VP                  4       V P                  VP                  4       R# )zt
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   rb   r   rc   unlockrd   r   r   r   s   &  r   test_cleanlyRelease LockingTests.test_cleanlyRelease   s    
 &&u-		$%&&u-		$

#$r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru      s     
, 
,t 
,r   c                0   V P                  4       p\        P                  ! V4      pV P                  VP	                  4       4       \        P                  ! V4      pV P                  VP	                  4       4       V P                  VP                  4       R# )z;
If a lock is currently locked, it cannot be locked again.
N)r   r   rb   r   rc   rd   r   )r#   r~   	firstLock
secondLocks   &   r   test_cannotLockLocked"LockingTests.test_cannotLockLocked   sk     ++E2		(),,U3
*+**+r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru      s     E Et Er   c                  a RoR V3R llpV P                  4       pV P                  \        RV4       \        P                  ! \	        S4      V4       \        P
                  ! V4      pV P                  VP                  4       4       V P                  VP                  4       V P                  VP                  4       V P                  \        P                  ! V4      \	        \        P                  ! 4       4      4       R# )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               $    V ^8  d   QhRRRRRR/# r   pidrt   signalr   r   r   )r   s   "r   r   8LockingTests.test_uncleanlyAcquire.<locals>.__annotate__   !     	1 	1# 	1s 	1t 	1r   c                   < V^ 8w  d   \        \        P                  R4      hV S8X  d   \        \        P                  R4      hR# )    Nr   r    EPERMr]   )r   r   owners   &&r   fakeKill4LockingTests.test_uncleanlyAcquire.<locals>.fakeKill   s8    {ekk400e|ekk400 r   rU   N)r   r9   r   r   r.   rb   r   rc   rd   r   r   r   r?   rV   rW   )r#   r   r~   rc   r   s   &   @r   test_uncleanlyAcquire"LockingTests.test_uncleanlyAcquire   s     	1 	1 

8VX.UU+&&u-		$$$**513ryy{3CDr   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru      s     % %d %r   c                  aa R VV3R llpV P                  \        RV4      oR R lpV P                  \        RV4       V P                  4       o\        P                  ! S4      p\        P                  ! \        R4      S4       V P                  VP                  4       4       V P                  VP                  4       V P                  VP                  4       R# )	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                    V ^8  d   QhRRRR/# )r   r$   r.   r   r   )r   s   "r   r   ?LockingTests.test_lockReleasedBeforeCheck.<locals>.__annotate__   s     	+ 	+s 	+s 	+r   c                |   < \         P                  ! S4       SP                  4        \         P                  ! V 4      # r2   )r   rmlinkrestorer?   )r$   r~   readlinkPatchs   &r   fakeReadlink?LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeReadlink   s,    OOE"!!#$$T**r   r?   c               $    V ^8  d   QhRRRRRR/# r   r   )r   s   "r   r   r      r   r   c                    V^ 8w  d   \        \        P                  R4      hV R8X  d   \        \        P                  R4      hR# r   Nu  r   r   r   s   &&r   r   ;LockingTests.test_lockReleasedBeforeCheck.<locals>.fakeKill   7    {ekk400e|ekk400 r   rU   r   N
r9   r   r   rb   r   r.   r   rc   r   r   )r#   r   r   rc   r~   r   s   &   @@r   test_lockReleasedBeforeCheck)LockingTests.test_lockReleasedBeforeCheck   s    	+ 	+ 

8ZF	1 	

8VX.&&u-UU+		$

#$r   r(   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru   
  s     & &t &r   c                    R R lpV P                  \        RV4       V P                  4       p\        P                  ! V4      pV P	                  VP                  4       4       V P	                  VP                  4       R# )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               $    V ^8  d   QhRRRRRR/# r,   r   )r   s   "r   r   HLockingTests.test_lockReleasedDuringAcquireSymlink.<locals>.__annotate__  s!     	+ 	+S 	+s 	+x 	+r   c                6    \        \        P                  R 4      hr2   r3   r5   s   &&r   r|   GLockingTests.test_lockReleasedDuringAcquireSymlink.<locals>.fakeSymlink  s     %))T**r   r   N)r9   r   r   rb   rd   rc   r   )r#   r|   r~   rc   s   &   r   %test_lockReleasedDuringAcquireSymlink2LockingTests.test_lockReleasedDuringAcquireSymlink  sZ    	+
 	

8Y4&&u-%%r   rC   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru   $  s     & & &r   c                @   R R lpV P                  \        RV4       V P                  4       p\        P                  ! V4      p\        P                  ! \        R4      V4       V P                  VP                  4       4       V P                  VP                  4       R# )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                    V ^8  d   QhRRRR/# r   r$   r.   r   r   r   )r   s   "r   r   ILockingTests.test_lockReleasedDuringAcquireReadlink.<locals>.__annotate__+  s     	. 	.s 	.x 	.r   c                6    \        \        P                  R 4      hr2   rK   r$   s   &r   r   ILockingTests.test_lockReleasedDuringAcquireReadlink.<locals>.fakeReadlink+  s     %,,--r   r?   r   N)	r9   r   r   rb   r   r.   rd   rc   r   )r#   r   r~   rc   s   &   r   &test_lockReleasedDuringAcquireReadlink3LockingTests.test_lockReleasedDuringAcquireReadlink   sn    	. 	

8Z6&&u-UU+%%r   c               $    V ^8  d   QhRRRRRR/# )r   exceptionTypeztype[OSError] | type[IOError]r    rt   r   r   r   )r   s   "r   r   ru   9  s$     & &:&CF&	&r   c                	~  aa R  VV3R llpV P                  \        RV4       V P                  4       p\        P                  ! \	        R4      V4       \        P
                  ! V4      pV P                  SVP                  4      pV P                  VP                  S4       V P                  VP                  4       R# )c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   5LockingTests._readlinkErrorTest.<locals>.__annotate__<  s     	- 	-s 	-x 	-r   c                   < S! SR 4      hr2   r   )r$   r    r   s   &r   r   5LockingTests._readlinkErrorTest.<locals>.fakeReadlink<  s    t,,r   r?   r   N)r9   r   r   r   r.   rb   r   rc   r   r    rd   r   )r#   r   r    r   r~   rc   r%   s   &ff    r   _readlinkErrorTestLockingTests._readlinkErrorTest9  s    	- 	- 	

8Z6 	UU+&&u-tyy9E*%r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru   K  s     7 7D 7r   c                    V P                  \        \        P                  4       V P                  \        \        P                  4       R# )zo
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:   rX   s   &r   test_readlinkErrorLockingTests.test_readlinkErrorK  s,    
 	66r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru   W  s     	7 	7 	7r   c                    V P                  \        \        P                  4       V P                  \        \        P                  4       R# )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   rL   rX   s   &r   test_readlinkErrorPOSIX$LockingTests.test_readlinkErrorPOSIXS  s,     	66r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru   b  s     % % %r   c                  aa R VV3R llpV P                  \        RV4      oR R lpV P                  \        RV4       V P                  4       o\        P                  ! S4      p\        P                  ! \        R4      S4       V P                  VP                  4       4       V P                  VP                  4       V P                  VP                  4       R# )	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                    V ^8  d   QhRRRR/# )r   r$   r.   r   r   r   )r   s   "r   r   ALockingTests.test_lockCleanedUpConcurrently.<locals>.__annotate__i  s     	) 	)S 	)T 	)r   c                |   < SP                  4        \        P                  ! S4       \        P                  ! V 4      # r2   )r   r   r   )r$   r~   rmlinkPatchs   &r   
fakeRmlink?LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeRmlinki  s*    !OOE"??4((r   r   c               $    V ^8  d   QhRRRRRR/# r   r   )r   s   "r   r   r   r  r   r   c                    V^ 8w  d   \        \        P                  R4      hV R8X  d   \        \        P                  R4      hR# r   r   r   s   &&r   r   =LockingTests.test_lockCleanedUpConcurrently.<locals>.fakeKillr  r   r   rU   r   Nr   )r#   r   r   rc   r~   r   s   &   @@r   test_lockCleanedUpConcurrently+LockingTests.test_lockCleanedUpConcurrentlyb  s    	) 	) jj8Z@	1 	

8VX.&&u-UU+		$

#$r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru     s     & &$ &r   c                   R R lpV P                  \        RV4       R R lpV P                  \        RV4       V P                  4       p\        P                  ! \	        R4      V4       \        P
                  ! V4      pV P                  \        VP                  4      pV P                  VP                  \        P                  4       V P                  VP                  4       R# )	zm
An exception raised by L{rmlink} other than C{ENOENT} is passed up
to the caller of L{FilesystemLock.lock}.
c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   3LockingTests.test_rmlinkError.<locals>.__annotate__  s     	. 	.S 	.X 	.r   c                6    \        \        P                  R 4      hr2   )r   r    r   r   s   &r   r   1LockingTests.test_rmlinkError.<locals>.fakeRmlink  rO   r   r   c               $    V ^8  d   QhRRRRRR/# r   r   )r   s   "r   r   r     r   r   c                    V^ 8w  d   \        \        P                  R4      hV R8X  d   \        \        P                  R4      hR# r   r   r   s   &&r   r   /LockingTests.test_rmlinkError.<locals>.fakeKill  r   r   rU   r   N)r9   r   r   r   r.   rb   r   r   rc   r   r    r   rd   r   )r#   r   r   r~   rc   r%   s   &     r   test_rmlinkErrorLockingTests.test_rmlinkError  s    	. 	

8Xz2	1 	

8VX. 	UU+&&u-3ELL1%r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru     s     & & &r   c                   R R lpV P                  \        RV4       V P                  4       p\        P                  ! \	        R4      V4       \        P
                  ! V4      pV P                  \        VP                  4      pV P                  VP                  \        P                  4       V P                  VP                  4       R# )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               $    V ^8  d   QhRRRRRR/# )r   r   rt   r   r   r   r   )r   s   "r   r   1LockingTests.test_killError.<locals>.__annotate__  s!     	- 	-# 	-s 	-x 	-r   c                6    \        \        P                  R 4      hr2   )r   r    r   r   s   &&r   r   -LockingTests.test_killError.<locals>.fakeKill  s    %++t,,r   rU   r   N)r9   r   r   r   r.   rb   r   r   rc   r   r    r   rd   r   )r#   r   r~   rc   r%   s   &    r   test_killErrorLockingTests.test_killError  s    	- 	

8VX. 	UU+&&u-3EKK0%r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru     s     3 3$ 3r   c                   V P                  4       p\        P                  ! \        \        P
                  ! 4       ^,           4      V4       \        P                  ! V4      pV P                  \        VP                  4       R# )zj
L{FilesystemLock.unlock} raises L{ValueError} if called for a lock
which is held by a different process.
N)
r   r   r   r.   rV   rW   rb   r   
ValueErrorr   r   s   &  r   test_unlockOtherLockingTests.test_unlockOther  sR    
 RYY[1_-u5&&u-*dkk2r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   ru     s     3 3t 3r   c                   V P                  4       pV P                  \        P                  ! V4      4       \        P                  ! V4      pV P                  VP                  4       4       V P                  \        P                  ! V4      4       VP                  4        V P                  \        P                  ! V4      4       R# )zX
L{isLocked} returns C{True} if the named lock is currently locked,
C{False} otherwise.
N)r   rd   r   isLockedrb   r   rc   r   r   s   &  r   test_isLockedLockingTests.test_isLocked  s    
 **512&&u-		$))%01**512r   r   N)rh   ri   rj   rk   r   r   r   r   rm   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  rp   r   r   r   rr   rr      s    	+- C	*		*	%% 
,E2%> O&	&, T&	&*&$7 C	7		7%>&:&,33 3r   rr   )rl   
__future__r   r    rV   unittestr   r   typingr   twisted.pythonr   twisted.python.reflectr   twisted.python.runtimer   twisted.trial.unittestr	   rn   ro   rm   r   rr   r   r   r   <module>r     s   
 #  	 '  # 0 + +,-5,'/< 	_$ _$DD38 D3r   