ó
…nuMc           @   s   d  Z  d d l m Z m Z d d l m Z m Z d d l m Z y d d l m	 Z	 Wn e
 k
 ro d	 Z n Xd d l m Z d e j f d „  ƒ  YZ d	 S(
   s?   
Tests for the inotify wrapper in L{twisted.internet.inotify}.
iÿÿÿÿ(   t   defert   reactor(   t   filepatht   runtime(   t   unittest(   t   _inotify(   t   inotifyt   TestINotifyc           B   s  e  Z d  Z e j j ƒ  s$ d Z n  d „  Z d „  Z d d „ Z
 d „  Z d „  Z d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z  d „  Z! RS(   s]   
    Define all the tests for the basic functionality exposed by
    L{inotify.INotify}.
    s&   This platform doesn't support INotify.c         C   sX   t  j |  j ƒ  ƒ |  _ |  j j ƒ  t j ƒ  |  _ |  j j ƒ  |  j |  j j	 ƒ d  S(   N(
   R   t   FilePatht   mktempt   dirnamet   createDirectoryR   t   INotifyt   startReadingt
   addCleanupt   loseConnection(   t   self(    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   setUp   s
    c         C   sF   d d d „  ƒ  Y} |  j  t j d | ƒ  ƒ |  j t j t j ƒ d S(   s  
        L{inotify.INotify} emits a C{RuntimeError} when initialized
        in an environment that doesn't support inotify as we expect it.

        We just try to raise an exception for every possible case in
        the for loop in L{inotify.INotify._inotify__init__}.
        t   FakeINotifyc           B   s   e  Z d  „  Z RS(   c         S   s   t  j ƒ  ‚ d  S(   N(   R   t   INotifyError(   R   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   init.   s    (   t   __name__t
   __module__R   (    (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR   -   s   R   N(    (   t   patchR   R   t   assertRaisesR   (   R   R   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_initializationErrors%   s    c            sˆ   ˆ  d k r! ˆ j j d ƒ ‰  n  t j ƒ  ‰ ‡  ‡ ‡ f d †  } ˆ j | ƒ ˆ j j ˆ j d ˆ d ‡ f d †  g ƒ| ˆ  ƒ ˆ S(   sæ  
        Test notification from some filesystem operation.

        @param mask: The event mask to use when setting up the watch.

        @param operation: A function which will be called with the
            name of a file in the watched directory and which should
            trigger the event.

        @param expectedPath: Optionally, the name of the path which is
            expected to come back in the notification event; this will
            also be passed to C{operation} (primarily useful when the
            operation is being done to the directory itself, not a
            file in it).

        @return: A L{Deferred} which fires successfully when the
            expected event has been received or fails otherwise.
        s   foo.barc            s4   |  \ } } } ˆ j  | ˆ  ƒ ˆ j | ˆ @ƒ d  S(   N(   t   assertEqualst
   assertTrue(   t   .0t   watcht   filenamet   events(   t   expectedPatht   maskR   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt
   cbNotifiedJ   s    R!   t	   callbacksc             s   ˆ  j  |  ƒ S(   N(   t   callback(   t   args(   t   notified(    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   <lambda>Q   s    N(   t   NoneR
   t   childR    t   Deferredt   addCallbackR   R   (   R   R!   t	   operationR    R"   (    (   R    R&   R   R!   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   _notificationTest4   s    	
c         C   s   d „  } |  j  t j | ƒ S(   s{   
        Reading from a file in a monitored directory sends an
        C{inotify.IN_ACCESS} event to the callback.
        c         S   s   |  j  d ƒ |  j ƒ  d  S(   Nt   foo(   t
   setContentt
   getContent(   t   path(    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   [   s    (   R-   R   t	   IN_ACCESS(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_accessV   s    	c         C   s   d „  } |  j  t j | ƒ S(   sy   
        Writing to a file in a monitored directory sends an
        C{inotify.IN_MODIFY} event to the callback.
        c         S   s*   |  j  d ƒ } | j d ƒ | j ƒ  d  S(   Nt   wR.   (   t   opent   writet   close(   R1   t   fObj(    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   g   s    (   R-   R   t	   IN_MODIFY(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_modifyb   s    	c         C   s   d „  } |  j  t j | ƒ S(   s‰   
        Changing the metadata of a a file in a monitored directory
        sends an C{inotify.IN_ATTRIB} event to the callback.
        c         S   s   |  j  ƒ  |  j  ƒ  d  S(   N(   t   touch(   R1   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   t   s    
(   R-   R   t	   IN_ATTRIB(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_attribo   s    	c         C   s   d „  } |  j  t j | ƒ S(   sž   
        Closing a file which was open for writing in a monitored
        directory sends an C{inotify.IN_CLOSE_WRITE} event to the
        callback.
        c         S   s   |  j  d ƒ } | j ƒ  d  S(   NR4   (   R5   R7   (   R1   R8   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,      s    (   R-   R   t   IN_CLOSE_WRITE(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_closeWrite{   s    	c         C   s   d „  } |  j  t j | ƒ S(   s°   
        Closing a file which was open for reading but not writing in a
        monitored directory sends an C{inotify.IN_CLOSE_NOWRITE} event
        to the callback.
        c         S   s'   |  j  ƒ  |  j d ƒ } | j ƒ  d  S(   Nt   r(   R;   R5   R7   (   R1   R8   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   Ž   s    
(   R-   R   t   IN_CLOSE_NOWRITE(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_closeNoWriteˆ   s    	c         C   s   d „  } |  j  t j | ƒ S(   st   
        Opening a file in a monitored directory sends an
        C{inotify.IN_OPEN} event to the callback.
        c         S   s   |  j  d ƒ } | j ƒ  d  S(   NR4   (   R5   R7   (   R1   R8   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   ›   s    (   R-   R   t   IN_OPEN(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt	   test_open–   s    	c            s"   ‡  f d †  } ˆ  j  t j | ƒ S(   s}   
        Moving a file out of a monitored directory sends an
        C{inotify.IN_MOVED_FROM} event to the callback.
        c            s9   |  j  d ƒ } | j ƒ  |  j t j ˆ  j ƒ  ƒ ƒ d  S(   NR4   (   R5   R7   t   moveToR   R   R	   (   R1   R8   (   R   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   §   s    
(   R-   R   t   IN_MOVED_FROM(   R   R,   (    (   R   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_movedFrom¢   s    c            s"   ‡  f d †  } ˆ  j  t j | ƒ S(   sy   
        Moving a file into a monitored directory sends an
        C{inotify.IN_MOVED_TO} event to the callback.
        c            s0   t  j ˆ  j ƒ  ƒ } | j ƒ  | j |  ƒ d  S(   N(   R   R   R	   R;   RE   (   R1   t   p(   R   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   ´   s    
(   R-   R   t   IN_MOVED_TO(   R   R,   (    (   R   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_movedTo¯   s    c         C   s   d „  } |  j  t j | ƒ S(   sw   
        Creating a file in a monitored directory sends an
        C{inotify.IN_CREATE} event to the callback.
        c         S   s   |  j  d ƒ } | j ƒ  d  S(   NR4   (   R5   R7   (   R1   R8   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   Á   s    (   R-   R   t	   IN_CREATE(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_create¼   s    	c         C   s   d „  } |  j  t j | ƒ S(   sw   
        Deleting a file in a monitored directory sends an
        C{inotify.IN_DELETE} event to the callback.
        c         S   s   |  j  ƒ  |  j ƒ  d  S(   N(   R;   t   remove(   R1   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   Í   s    
(   R-   R   t	   IN_DELETE(   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_deleteÈ   s    	c         C   s%   d „  } |  j  t j | d |  j ƒS(   s{   
        Deleting the monitored directory itself sends an
        C{inotify.IN_DELETE_SELF} event to the callback.
        c         S   s   |  j  ƒ  d  S(   N(   RM   (   R1   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   Ù   s    R    (   R-   R   t   IN_DELETE_SELFR
   (   R   R,   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_deleteSelfÔ   s    	c            s+   ‡  f d †  } ˆ  j  t j | d ˆ  j ƒS(   sy   
        Renaming the monitored directory itself sends an
        C{inotify.IN_MOVE_SELF} event to the callback.
        c            s    |  j  t j ˆ  j ƒ  ƒ ƒ d  S(   N(   RE   R   R   R	   (   R1   (   R   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR,   å   s    R    (   R-   R   t   IN_MOVE_SELFR
   (   R   R,   (    (   R   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_moveSelfà   s    c            sy   ‡  ‡ ‡ f d †  } t  j t  j B} ˆ  j  j ˆ  j d | d t d | g ƒˆ  j j d ƒ ‰ t j ƒ  ‰ ˆ j	 ƒ  ˆ S(   sŒ   
        L{inotify.INotify} when initialized with autoAdd==True adds
        also adds the created subdirectories to the watchlist.
        c            s)   ‡  ‡ ‡ f d †  } t  j d | ƒ d  S(   Nc              sL   y* ˆ  j  ˆ  j j ˆ ƒ ƒ ˆ j d  ƒ Wn t k
 rG ˆ j ƒ  n Xd  S(   N(   R   R   t
   _isWatchedR$   R(   t	   Exceptiont   errback(    (   R   t   subdirt   d(    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   _ô   s
    i    (   R   t	   callLater(   t   wpR   R!   RY   (   R   RW   RX   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt	   _callbackñ   s    R!   t   autoAddR#   t   test(
   R   t   IN_ISDIRRK   R   R
   t   TrueR)   R    R*   R   (   R   R\   t	   checkMask(    (   R   RW   RX   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_simpleSubdirectoryAutoAddì   s    	

c            s‚   g  ‰  ‡  ‡ ‡ ‡ f d †  } t  j t  j B} ˆ j  j ˆ j d | d t d | g ƒˆ j j d ƒ ‰ t j ƒ  ‰ ˆ j	 ƒ  ˆ S(   sz   
        L{inotify.INotify} removes a directory from the watchlist when
        it's removed from the filesystem.
        c            sd   ‡ ‡ ‡ f d †  } ‡ ‡ ‡ f d †  } ˆ  sP ˆ  j  | ƒ t j d | ƒ n t j d | ƒ d  S(   Nc              sI   y' ˆ  j  ˆ  j j ˆ ƒ ƒ ˆ j ƒ  Wn t k
 rD ˆ j ƒ  n Xd  S(   N(   R   R   RT   RM   RU   RV   (    (   R   RW   RX   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyRY     s
    c              sM   y+ ˆ  j  ˆ  j j ˆ ƒ ƒ ˆ j d  ƒ Wn t k
 rH ˆ j ƒ  n Xd  S(   N(   R   R   RT   R$   R(   RU   RV   (    (   R   RW   RX   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   _eb  s
    i    (   t   appendR   RZ   (   R[   R   R!   RY   Rc   (   t   callsR   RW   RX   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR\     s    R!   R]   R#   R^   (
   R   R_   RK   R   R
   R`   R)   R    R*   R   (   R   R\   Ra   (    (   Re   R   RW   RX   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_simpleDeleteDirectory  s    	

c         C   sh   |  j  j |  j d t ƒ|  j |  j  j |  j ƒ ƒ |  j  j |  j ƒ |  j |  j  j |  j ƒ ƒ d S(   sR   
        L{inotify.INotify.ignore} removes a directory from the watchlist
        R]   N(   R   R   R
   R`   R   RT   t   ignoret   assertFalse(   R   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_ignoreDirectory/  s    c         C   s€   x4 t  j D]) \ } } |  j t  j | ƒ d | ƒ q
 Wt  j t  j Bt  j B} |  j t t  j | ƒ ƒ t d d d g ƒ ƒ d S(   sy   
        L{inotify.humaReadableMask} translates all the possible event
        masks to a human readable string.
        i    t   close_writet   accessR5   N(   R   t   _FLAG_TO_HUMANR   t   humanReadableMaskR>   R2   RC   t   set(   R   R!   t   valueRa   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_humanReadableMask9  s    !c         C   s©   |  j  j d ƒ } | j d ƒ } | j d ƒ } | j ƒ  | | | g } |  j j |  j  d t ƒ|  j j |  j  d t ƒx' | D] } |  j |  j j | ƒ ƒ q‚ Wd S(   sŽ   
        L{inotify.INotify.watch} with recursive==True will add all the
        subdirectories under the given path to the watchlist.
        R^   t   test2t   test3t	   recursiveN(   R
   R)   t   makedirsR   R   R`   R   RT   (   R   RW   t   subdir2t   subdir3t   dirsRX   (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_recursiveWatchH  s    
c         C   s@   d d l  } t j ƒ  } | j | j ƒ | j ƒ  |  j ƒ  d S(   sœ   
        L{inotify.INotify.connectionLost} if there's a problem while closing
        the fd shouldn't raise the exception but should log the error
        iÿÿÿÿN(   t   osR   R   R7   t   _fdR   t   flushLoggedErrors(   R   Ry   t   in_(    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_connectionLostErrorY  s
    
c            sy   ‡  ‡ ‡ f d †  } t  j t  j B} ˆ  j  j ˆ  j d | d t d | g ƒˆ  j j d ƒ ‰ t j ƒ  ‰ ˆ j	 ƒ  ˆ S(   s”   
        L{inotify.INotify.watch} with autoAdd==False will stop inotify
        from watching subdirectories created under the watched one.
        c            s)   ‡  ‡ ‡ f d †  } t  j d | ƒ d  S(   Nc              sO   y- ˆ  j  ˆ  j j ˆ j ƒ ƒ ˆ j d  ƒ Wn t k
 rJ ˆ j ƒ  n Xd  S(   N(   Rh   R   RT   R1   R$   R(   RU   RV   (    (   R   RW   RX   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyRY   l  s
    i    (   R   RZ   (   R[   t   fpR!   RY   (   R   RW   RX   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR\   i  s    R!   R]   R#   R^   (
   R   R_   RK   R   R
   t   FalseR)   R    R*   R   (   R   R\   Ra   (    (   R   RW   RX   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_noAutoAddSubdirectoryd  s    	

c            sÁ   ˆ j  j d ƒ ‰  ˆ  j ƒ  t j ƒ  ‰ ‡  ‡ f d †  } ‡ f d †  } ˆ j ˆ j j ˆ  d | g ƒƒ ˆ j j ˆ  ƒ ˆ j ˆ j j ˆ  d t j	 d | g ƒƒ ˆ j
 | ƒ ˆ  j ƒ  ˆ S(   sœ   
        L{inotify.INotify} will watch a filepath for events even if the same
        path is repeatedly added/removed/re-added to the watchpoints.
        s   foo.bar2c            s7   |  \ } } } ˆ j  | ˆ  ƒ ˆ j | t j @ƒ d  S(   N(   R   R   R   RP   (   R   t   ignoredR   R   (   R    R   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR"   ‡  s    c             s   ˆ  j  |  ƒ d  S(   N(   R$   (   R%   (   R&   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   callIt‹  s    R#   R!   (   R
   R)   R;   R    R*   R   R   R   Rg   RP   R+   RM   (   R   R"   R‚   (    (   R    R&   R   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_seriesOfWatchAndIgnore~  s    
"	
c            sê   ˆ j  j d ƒ } | j ƒ  ˆ j  j d ƒ ‰ ˆ j ƒ  t j ƒ  ‰  ‡ ‡ f d †  } ‡  f d †  } ˆ j ˆ j j | t j d | g ƒƒ ˆ  j	 | ƒ ˆ j ˆ j j ˆ t j d | g ƒƒ ˆ j j
 | ƒ | j ƒ  ˆ j ƒ  ˆ  S(   sr   
        L{inotify.INotify} will ignore a filepath after it has been removed from
        the watch list.
        s   foo.bar2s   foo.bar3c            s7   |  \ } } } ˆ  j  | ˆ ƒ ˆ  j | t j @ƒ d  S(   N(   R   R   R   RP   (   R   R   R   R   (   R   t   expectedPath2(    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR"   «  s    c             s   ˆ  j  |  ƒ d  S(   N(   R$   (   R%   (   R&   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR‚   ¯  s    R#   (   R
   R)   R;   R    R*   R   R   R   RP   R+   Rg   RM   (   R   R    R"   R‚   (    (   R&   R   R„   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_ignoreFilePath   s$    

		

c         C   s9   |  j  j d ƒ } | j ƒ  |  j t |  j j | ƒ d S(   sf   
        L{inotify.INotify} will raise KeyError if a non-watched filepath is
        ignored.
        s   foo.ignoredN(   R
   R)   R;   R   t   KeyErrorR   Rg   (   R   R    (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_ignoreNonWatchedFileÃ  s    
c            s  t  ƒ  ‰  ‡ ‡  ‡ ‡ ‡ ‡ ‡ f d †  } t j t j B} ˆ j j ˆ j d | d t d | g ƒˆ j j d ƒ ‰ ˆ j d ƒ ‰ ˆ j d ƒ ‰ t j	 ƒ  ‰ ˆ j
 ƒ  ˆ j d ƒ ˆ j d	 ƒ ˆ j d
 ƒ g ‰ x* t ˆ ƒ D] \ } } | j | j ƒ qß Wˆ S(   sB  
        L{inotify.INotify} with autoAdd==True for a watched path
        generates events for every file or directory already present
        in a newly created subdirectory under the watched one.

        This tests that we solve a race condition in inotify even though
        we may generate duplicate events.
        c            så   ˆ j  | ƒ t ˆ ƒ d k rá y” ˆ j ˆ j j ˆ ƒ ƒ ˆ j ˆ j j ˆ ƒ ƒ ˆ j ˆ j j ˆ ƒ ƒ ˆ ˆ ˆ ˆ g } ˆ j t ˆ ƒ t | ƒ ƒ ˆ j ˆ t | ƒ ƒ Wn t k
 rÐ ˆ  j ƒ  qá Xˆ  j	 d  ƒ n  d  S(   Ni   (   t   addt   lenR   R   RT   R   Rn   RU   RV   R$   R(   (   R[   R   R!   t   created(   RX   Re   Ru   R   Rv   t	   someFilesRW   (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR\   Ø  s    R!   R]   R#   R^   Rq   Rr   s	   file1.dats	   file2.dats	   file3.dat(   Rn   R   R_   RK   R   R
   R`   R)   R    R*   Rt   t	   enumerateR/   R1   (   R   R\   Ra   t   iR   (    (   Re   R   Ru   Rv   R‹   RW   RX   sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   test_complexSubdirectoryAutoAddÎ  s"    		!	

N("   R   R   t   __doc__R   t   platformt   supportsINotifyt   skipR   R   R(   R-   R3   R:   R=   R?   RB   RD   RG   RJ   RL   RO   RQ   RS   Rb   Rf   Ri   Rp   Rx   R}   R€   Rƒ   R…   R‡   RŽ   (    (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyR      s:   			"														)	
					"	#	N(   R   t   twisted.internetR    R   t   twisted.pythonR   R   t   twisted.trialR   R   t   ImportErrorR(   R   t   TestCaseR   (    (    (    sF   /usr/lib/python2.7/dist-packages/twisted/internet/test/test_inotify.pyt   <module>   s   
