ó
[³XMc           @   sÓ   d  Z  d d l Z d d l Z d d l m Z d d l m Z d d l m Z d Z
 e j ƒ  r y  d d l m Z d d l Z Wq e k
 r™ d Z
 q Xn  d e j f d	 „  ƒ  YZ d
 e j f d „  ƒ  YZ d S(   s'   
Tests for L{twisted.python.lockfile}.
iÿÿÿÿN(   t   unittest(   t   lockfile(   t   platform(   t   OpenProcesssZ   On windows, lockfile.kill is not implemented in the absence of win32api and/or pywintypes.t	   UtilTestsc           B   s   e  Z d  Z d „  Z d „  Z e j ƒ  s6 d e _ n  d „  Z d „  Z	 e j ƒ  s` d e	 _ n  d „  Z
 e e
 _ d „  Z e e _ d	 „  Z RS(
   sM   
    Tests for the helper functions used to implement L{FilesystemLock}.
    c         C   sQ   |  j  ƒ  } t j d | ƒ |  j t t j d | ƒ } |  j | j t j ƒ d S(   s    
        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.
        t   fooN(   t   mktempR   t   symlinkt   assertRaisest   OSErrort   assertEqualt   errnot   EEXIST(   t   selft   namet   exc(    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_symlinkEEXIST   s    c         C   s]   |  j  ƒ  } d „  } |  j t d | ƒ |  j t t j | d ƒ } |  j | j t j ƒ d S(   s<  
        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         S   s   t  t j d  ƒ ‚ d  S(   N(   t   IOErrorR   t   EIOt   None(   t   srct   dst(    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt
   fakeRename1   s    t   renameR   N(	   R   t   patchR   R   R   R   R
   R   R   (   R   R   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_symlinkEIOWindows'   s
    		sB   special rename EIO handling only necessary and correct on Windows.c         C   s>   |  j  ƒ  } |  j t t j | ƒ } |  j | j t j ƒ d S(   sŸ   
        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   t   readlinkR
   R   t   ENOENT(   R   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_readlinkENOENT<   s    c         C   sZ   |  j  ƒ  } d „  } |  j t d | ƒ |  j t t j | ƒ } |  j | j t j ƒ d S(   s\  
        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         S   s   t  t j d  ƒ ‚ d  S(   N(   R   R   t   EACCESR   (   t   patht   mode(    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   fakeOpenP   s    t   _openN(	   R   R   R   R   R   R   R
   R   R   (   R   R   R    R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_readlinkEACCESWindowsF   s
    		sG   special readlink EACCES handling only necessary and correct on Windows.c         C   s   t  j t j ƒ  d ƒ d S(   s}   
        L{lockfile.kill} returns without error if passed the PID of a
        process which exists and signal C{0}.
        i    N(   R   t   killt   ost   getpid(   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt	   test_kill[   s    c         C   s5   |  j  t t j d d ƒ } |  j | j t j ƒ d S(   s   
        L{lockfile.kill} raises L{OSError} with errno of L{ESRCH} if
        passed a PID which does not correspond to any process.
        i   i   i   i    Nl        l   ÿÿ (   R   R	   R   R#   R
   R   t   ESRCH(   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_killESRCHd   s    c         C   sI   |  j  t d d ƒ t j |  j ƒ  ƒ } | j ƒ  |  j | j ƒ  ƒ d S(   sµ   
        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   R   t   FilesystemLockR   t   lockt   assertFalse(   R   t   fl(    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_noKillCallo   s    
(   t   __name__t
   __module__t   __doc__R   R   R   t	   isWindowst   skipR   R"   R&   t   skipKillR(   R-   (    (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyR      s   			
					t   LockingTestCasec           B   s
  e  Z d  „  Z d „  Z d „  Z e j ƒ  r9 d e _ n  d „  Z d „  Z	 d „  Z
 d „  Z d „  Z d	 „  Z e j ƒ  s‡ d
 e _ n  d „  Z e j ƒ  s¨ d e _ n  d „  Z d „  Z d „  Z e j ƒ  rÛ d e _ n  d „  Z d „  Z d „  Z d „  Z d „  Z RS(   c            si   ‡  f d †  } |  j  t d | ƒ |  j ƒ  } t j | ƒ } |  j t | j ƒ } |  j | j ˆ  ƒ d  S(   Nc            s   t  ˆ  d  ƒ ‚ d  S(   N(   R	   R   (   t   sourcet   dest(   R   (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   fakeSymlink~   s    R   (	   R   R   R   R)   R   R	   R*   R
   R   (   R   R   R7   t   lockfR*   R   (    (   R   s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   _symlinkErrorTest}   s    c         C   s   |  j  t j ƒ d S(   s†   
        An exception raised by C{symlink} other than C{EEXIST} is passed up to
        the caller of L{FilesystemLock.lock}.
        N(   R9   R   t   ENOSYS(   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_symlinkErrorˆ   s    c         C   s$   |  j  t j ƒ |  j  t j ƒ d S(   s   
        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(   R9   R   R   R   (   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_symlinkErrorPOSIX   s    s9   POSIX-specific error propagation not expected on Windows.c         C   sR   |  j  ƒ  } t j | ƒ } |  j | j ƒ  ƒ |  j | j ƒ |  j | j ƒ d S(   s‹   
        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)   t
   assertTrueR*   t   cleant   locked(   R   R8   R*   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_cleanlyAcquireŸ   s
    c         C   sŽ   |  j  ƒ  } t j | ƒ } |  j | j ƒ  ƒ | j ƒ  |  j | j ƒ t j | ƒ } |  j | j ƒ  ƒ |  j | j ƒ |  j | j ƒ d S(   sŒ   
        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)   R=   R*   t   unlockR+   R?   R>   (   R   R8   R*   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_cleanlyRelease«   s    
c         C   sd   |  j  ƒ  } t j | ƒ } |  j | j ƒ  ƒ t j | ƒ } |  j | j ƒ  ƒ |  j | j ƒ d S(   sK   
        If a lock is currently locked, it cannot be locked again.
        N(   R   R   R)   R=   R*   R+   R?   (   R   R8   t	   firstLockt
   secondLock(    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_cannotLockLocked¼   s    c            sµ   d ‰  ‡  f d †  } |  j  ƒ  } |  j t d | ƒ t j t ˆ  ƒ | ƒ t j | ƒ } |  j | j ƒ  ƒ |  j | j	 ƒ |  j | j
 ƒ |  j t j | ƒ t t j ƒ  ƒ ƒ d S(   sÇ   
        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            sF   | d k r! t  t j d  ƒ ‚ n  |  ˆ  k rB t  t j d  ƒ ‚ n  d  S(   Ni    (   R	   R   t   EPERMR   R'   (   t   pidt   signal(   t   owner(    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   fakeKillÑ   s    R#   N(   R   R   R   R   t   strR)   R=   R*   R+   R>   R?   R
   R   R$   R%   (   R   RJ   R8   R*   (    (   RI   s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_uncleanlyAcquireÉ   s    c            s«   ‡  ‡ f d †  } |  j  t d | ƒ ‰ d „  } |  j  t d | ƒ |  j ƒ  ‰  t j ˆ  ƒ } t j t d ƒ ˆ  ƒ |  j | j ƒ  ƒ |  j | j ƒ |  j | j	 ƒ d S(   sð   
        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            s$   t  j ˆ  ƒ ˆ j ƒ  t  j |  ƒ S(   N(   R   t   rmlinkt   restoreR   (   R   (   R8   t   readlinkPatch(    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   fakeReadlinké   s    
R   c         S   sF   | d k r! t  t j d  ƒ ‚ n  |  d k rB t  t j d  ƒ ‚ n  d  S(   Ni    iu¨  (   R	   R   RF   R   R'   (   RG   RH   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyRJ   ñ   s    R#   iu¨  N(
   R   R   R   R)   R   RK   R=   R*   R>   R?   (   R   RP   RJ   R*   (    (   R8   RO   s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_lockReleasedBeforeCheckã   s    	c         C   s^   d „  } |  j  t d | ƒ |  j ƒ  } t j | ƒ } |  j | j ƒ  ƒ |  j | j ƒ d S(   s“  
        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         S   s   t  t j d  ƒ ‚ d  S(   N(   R	   R   R   R   (   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyR7   	  s    R   N(   R   R   R   R)   R+   R*   R?   (   R   R7   R8   R*   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt%   test_lockReleasedDuringAcquireSymlink   s    		sB   special rename EIO handling only necessary and correct on Windows.c         C   sv   d „  } |  j  t d | ƒ } |  j ƒ  } t j | ƒ } t j t d ƒ | ƒ |  j | j ƒ  ƒ |  j | j ƒ d S(   s»   
        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         S   s   t  t j d  ƒ ‚ d  S(   N(   R   R   R   R   (   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyRP      s    R   iu¨  N(	   R   R   R   R)   R   RK   R+   R*   R?   (   R   RP   RO   R8   R*   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt&   test_lockReleasedDuringAcquireReadlink  s    	sG   special readlink EACCES handling only necessary and correct on Windows.c            s’   ‡  ‡ f d †  } |  j  t d | ƒ |  j ƒ  } t j t d ƒ | ƒ t j | ƒ } |  j ˆ | j ƒ } |  j | j	 ˆ  ƒ |  j
 | j ƒ d  S(   Nc            s   ˆ ˆ  d  ƒ ‚ d  S(   N(   R   (   R   (   R   t   exceptionType(    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyRP   3  s    R   iu¨  (   R   R   R   R   RK   R)   R   R*   R
   R   R+   R?   (   R   RT   R   RP   R8   R*   R   (    (   R   RT   s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   _readlinkErrorTest2  s    c         C   s*   |  j  t t j ƒ |  j  t t j ƒ d S(   s‡   
        An exception raised by C{readlink} other than C{ENOENT} is passed up to
        the caller of L{FilesystemLock.lock}.
        N(   RU   R	   R   R:   R   (   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_readlinkErrorB  s    c         C   s*   |  j  t t j ƒ |  j  t t j ƒ d S(   sú   
        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   R:   R   (   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_readlinkErrorPOSIXK  s    c            s«   ‡ ‡  f d †  } |  j  t d | ƒ ‰ d „  } |  j  t d | ƒ |  j ƒ  ‰  t j ˆ  ƒ } t j t d ƒ ˆ  ƒ |  j | j ƒ  ƒ |  j | j ƒ |  j | j	 ƒ d S(   s×   
        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            s$   ˆ  j  ƒ  t j ˆ ƒ t j |  ƒ S(   N(   RN   R   RM   (   R   (   t   rmlinkPatchR8   (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt
   fakeRmlink`  s    
RM   c         S   sF   | d k r! t  t j d  ƒ ‚ n  |  d k rB t  t j d  ƒ ‚ n  d  S(   Ni    iu¨  (   R	   R   RF   R   R'   (   RG   RH   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyRJ   h  s    R#   iu¨  N(
   R   R   R   R)   R   RK   R=   R*   R>   R?   (   R   RY   RJ   R*   (    (   R8   RX   s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_lockCleanedUpConcurrentlyZ  s    	c         C   s¨   d „  } |  j  t d | ƒ d „  } |  j  t d | ƒ |  j ƒ  } t j t d ƒ | ƒ t j | ƒ } |  j t | j ƒ } |  j	 | j
 t
 j ƒ |  j | j ƒ d S(   s…   
        An exception raised by L{rmlink} other than C{ENOENT} is passed up
        to the caller of L{FilesystemLock.lock}.
        c         S   s   t  t j d  ƒ ‚ d  S(   N(   R	   R   R:   R   (   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyRY   |  s    RM   c         S   sF   | d k r! t  t j d  ƒ ‚ n  |  d k rB t  t j d  ƒ ‚ n  d  S(   Ni    iu¨  (   R	   R   RF   R   R'   (   RG   RH   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyRJ   €  s    R#   iu¨  N(   R   R   R   R   RK   R)   R   R	   R*   R
   R   R:   R+   R?   (   R   RY   RJ   R8   R*   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_rmlinkErrorw  s    		c         C   sŒ   d „  } |  j  t d | ƒ |  j ƒ  } t j t d ƒ | ƒ t j | ƒ } |  j t | j ƒ } |  j	 | j
 t
 j ƒ |  j | j ƒ d S(   s¶   
        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         S   s   t  t j d  ƒ ‚ d  S(   N(   R	   R   RF   R   (   RG   RH   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyRJ   ˜  s    R#   iu¨  N(   R   R   R   R   RK   R)   R   R	   R*   R
   R   RF   R+   R?   (   R   RJ   R8   R*   R   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_killError’  s    	c         C   sR   |  j  ƒ  } t j t t j ƒ  d ƒ | ƒ t j | ƒ } |  j t | j	 ƒ d S(   s‚   
        L{FilesystemLock.unlock} raises L{ValueError} if called for a lock
        which is held by a different process.
        i   N(
   R   R   R   RK   R$   R%   R)   R   t
   ValueErrorRA   (   R   R8   R*   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_unlockOther§  s     c         C   s~   |  j  ƒ  } |  j t j | ƒ ƒ t j | ƒ } |  j | j ƒ  ƒ |  j t j | ƒ ƒ | j ƒ  |  j t j | ƒ ƒ d S(   sp   
        L{isLocked} returns C{True} if the named lock is currently locked,
        C{False} otherwise.
        N(   R   R+   R   t   isLockedR)   R=   R*   RA   (   R   R8   R*   (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   test_isLocked²  s    
(   R.   R/   R9   R;   R<   R   R1   R2   R@   RB   RE   RL   RQ   RR   RS   RU   RV   RW   RZ   R[   R\   R^   R`   (    (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyR4   |   s4   			
											
				(   R0   R$   R   t   twisted.trialR    t   twisted.pythonR   t   twisted.python.runtimeR   R   R3   R1   t   win32apiR   t
   pywintypest   ImportErrort   TestCaseR   R4   (    (    (    s>   /usr/lib/python2.7/dist-packages/twisted/test/test_lockfile.pyt   <module>   s   d