
    VhH                         d Z ddlZddlmZmZ ddlmZmZ ddlm	Z	 ddl
mZ  e	d      ddlmZ ndZ G d	 d
ej                        Zy)z?
Tests for the inotify wrapper in L{twisted.internet.inotify}.
    N)deferreactor)filepathruntime)requireModule)unittestztwisted.python._inotify)inotifyc                       e Zd ZdZej
                  j                         sdZ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!d Z"d Z#y)!INotifyTestsz]
    Define all the tests for the basic functionality exposed by
    L{inotify.INotify}.
    z&This platform doesn't support INotify.c                 8   t        j                  | j                               | _        | j                  j	                          t        j                         | _        | j
                  j                          | j                  | j
                  j                         y N)
r   FilePathmktempdirnamecreateDirectoryr	   INotifystartReading
addCleanuploseConnectionselfs    R/home/dcms/DCMS/lib/python3.12/site-packages/twisted/internet/test/test_inotify.pysetUpzINotifyTests.setUp   s^    ((7$$&(!!#334    c                      G d d      }| j                  t        j                  d |              | j                  t        j                  t        j                         y)a  
        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__}.
        c                       e Zd Zd Zy);INotifyTests.test_initializationErrors.<locals>.FakeINotifyc                 *    t        j                         r   )r	   INotifyErrorr   s    r   initz@INotifyTests.test_initializationErrors.<locals>.FakeINotify.init.   s    **,,r   N)__name__
__module____qualname__r     r   r   FakeINotifyr   -   s    -r   r%   _inotifyN)patchr	   r   assertRaisesr   )r   r%   s     r   test_initializationErrorsz&INotifyTests.test_initializationErrors$   s>    	- 	- 	

7??J>'..@r   Nc                      j                   j                  d      t        j                          fd}j	                  |        j
                  j                   j                   fdg        |       S )a  
        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.
        zfoo.barc                     | \  }}}j                  |j                         j                                j                  |z         y r   )assertEqualasBytesMode
assertTrue)resultwatchfilenameeventsexpectedPathmaskr   s       r   
cbNotifiedz2INotifyTests._notificationTest.<locals>.cbNotifiedK   sA    (.%UHfX113\5M5M5OPOOFTM*r   c                  &    j                  |       S r   callbackargsnotifieds    r   <lambda>z0INotifyTests._notificationTest.<locals>.<lambda>S   s    h>O>OPT>U r   r4   	callbacks)r   childr   DeferredaddCallbackr	   r0   )r   r4   	operationr3   r5   r;   s   `` ` @r   _notificationTestzINotifyTests._notificationTest4   su    & <<--i8L>>#	+
 	Z(LLt0U/V 	 	
 	,r   c                 H    d }| j                  t        j                  |      S )z{
        Reading from a file in a monitored directory sends an
        C{inotify.IN_ACCESS} event to the callback.
        c                 F    | j                  d       | j                          y )N   foo)
setContent
getContentpaths    r   rB   z+INotifyTests.test_access.<locals>.operation^   s    OOF#OOr   )rC   r	   	IN_ACCESSr   rB   s     r   test_accesszINotifyTests.test_accessX   s"    	 %%g&7&7CCr   c                 H    d }| j                  t        j                  |      S )zy
        Writing to a file in a monitored directory sends an
        C{inotify.IN_MODIFY} event to the callback.
        c                 r    | j                  d      5 }|j                  d       d d d        y # 1 sw Y   y xY w)NwrF   )openwrite)rJ   fObjs     r   rB   z+INotifyTests.test_modify.<locals>.operationj   s0    3 #4

6"# # #s   -6)rC   r	   	IN_MODIFYrL   s     r   test_modifyzINotifyTests.test_modifyd   s"    	# %%g&7&7CCr   c                 H    d }| j                  t        j                  |      S )z
        Changing the metadata of a file in a monitored directory
        sends an C{inotify.IN_ATTRIB} event to the callback.
        c                 D    | j                          | j                          y r   )touchrI   s    r   rB   z+INotifyTests.test_attrib.<locals>.operationv   s    JJLJJLr   )rC   r	   	IN_ATTRIBrL   s     r   test_attribzINotifyTests.test_attribp   s"    	 %%g&7&7CCr   c                 H    d }| j                  t        j                  |      S )z
        Closing a file which was open for writing in a monitored
        directory sends an C{inotify.IN_CLOSE_WRITE} event to the
        callback.
        c                 B    | j                  d      j                          y NrP   rQ   closerI   s    r   rB   z/INotifyTests.test_closeWrite.<locals>.operation       IIcN  "r   )rC   r	   IN_CLOSE_WRITErL   s     r   test_closeWritezINotifyTests.test_closeWrite|   s"    	# %%g&<&<iHHr   c                 H    d }| j                  t        j                  |      S )z
        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                 b    | j                          | j                  d      j                          y )Nr)rX   rQ   r_   rI   s    r   rB   z1INotifyTests.test_closeNoWrite.<locals>.operation   s    JJLIIcN  "r   )rC   r	   IN_CLOSE_NOWRITErL   s     r   test_closeNoWritezINotifyTests.test_closeNoWrite   s"    	# %%g&>&>	JJr   c                 H    d }| j                  t        j                  |      S )zt
        Opening a file in a monitored directory sends an
        C{inotify.IN_OPEN} event to the callback.
        c                 B    | j                  d      j                          y r]   r^   rI   s    r   rB   z)INotifyTests.test_open.<locals>.operation   r`   r   )rC   r	   IN_OPENrL   s     r   	test_openzINotifyTests.test_open   s     	# %%gooyAAr   c                 N      fd} j                  t        j                  |      S )z}
        Moving a file out of a monitored directory sends an
        C{inotify.IN_MOVED_FROM} event to the callback.
        c                     | j                  d      j                          | j                  t        j                  j                                      y r]   )rQ   r_   moveTor   r   r   rJ   r   s    r   rB   z.INotifyTests.test_movedFrom.<locals>.operation   s4    IIcN  "KK))$++-89r   )rC   r	   IN_MOVED_FROMrL   s   ` r   test_movedFromzINotifyTests.test_movedFrom   s#    	: %%g&;&;YGGr   c                 N      fd} j                  t        j                  |      S )zy
        Moving a file into a monitored directory sends an
        C{inotify.IN_MOVED_TO} event to the callback.
        c                     t        j                  j                               }|j                          |j	                  |        y r   )r   r   r   rX   rn   )rJ   pr   s     r   rB   z,INotifyTests.test_movedTo.<locals>.operation   s-    !!$++-0AGGIHHTNr   )rC   r	   IN_MOVED_TOrL   s   ` r   test_movedTozINotifyTests.test_movedTo   s#    	
 %%g&9&99EEr   c                 H    d }| j                  t        j                  |      S )zw
        Creating a file in a monitored directory sends an
        C{inotify.IN_CREATE} event to the callback.
        c                 B    | j                  d      j                          y r]   r^   rI   s    r   rB   z+INotifyTests.test_create.<locals>.operation   r`   r   )rC   r	   	IN_CREATErL   s     r   test_createzINotifyTests.test_create   s"    	# %%g&7&7CCr   c                 H    d }| j                  t        j                  |      S )zw
        Deleting a file in a monitored directory sends an
        C{inotify.IN_DELETE} event to the callback.
        c                 D    | j                          | j                          y r   )rX   removerI   s    r   rB   z+INotifyTests.test_delete.<locals>.operation   s    JJLKKMr   )rC   r	   	IN_DELETErL   s     r   test_deletezINotifyTests.test_delete   s"    	 %%g&7&7CCr   c                 `    d }| j                  t        j                  || j                        S )z{
        Deleting the monitored directory itself sends an
        C{inotify.IN_DELETE_SELF} event to the callback.
        c                 $    | j                          y r   )r}   rI   s    r   rB   z/INotifyTests.test_deleteSelf.<locals>.operation   s    KKMr   r3   )rC   r	   IN_DELETE_SELFr   rL   s     r   test_deleteSelfzINotifyTests.test_deleteSelf   s2    	 %%""IDLL & 
 	
r   c                       fd} j                   j                   j                  dfdg       t        j                         j                  |        j                  j                          S )z
        Deleting the monitored directory itself sends an
        C{inotify.IN_DELETE_SELF} event to the callback
        even if the mask isn't specified by the call to watch().
        c                     | \  }}}j                  |j                         j                  j                                j                  |t        j
                  z         y r   )r,   r-   r   r.   r	   r   )r/   r0   r1   r2   r   s       r   r5   z6INotifyTests.test_deleteSelfForced.<locals>.cbNotified   sL    (.%UHfX113T\\5M5M5OPOOFW%;%;;<r   r   c                  &    j                  |       S r   r7   )r:   ds    r   r<   z4INotifyTests.test_deleteSelfForced.<locals>.<lambda>   s    QZZ=M r   r=   )r	   r0   r   r   r@   rA   r}   )r   r5   r   s   ` @r   test_deleteSelfForcedz"INotifyTests.test_deleteSelfForced   s_    	=
 	LLs/M.N 	 	
 NN	j!r   c                 f      fd} j                  t        j                  | j                        S )zy
        Renaming the monitored directory itself sends an
        C{inotify.IN_MOVE_SELF} event to the callback.
        c                 j    | j                  t        j                  j                                      y r   )rn   r   r   r   ro   s    r   rB   z-INotifyTests.test_moveSelf.<locals>.operation   s     KK))$++-89r   r   )rC   r	   IN_MOVE_SELFr   rL   s   ` r   test_moveSelfzINotifyTests.test_moveSelf   s3    	: %%  )$,, & 
 	
r   c                 .     fd}t         j                  t         j                  z  } j                   j                   j                  |d|g        j                  j                  d      t        j                         j                          S )z
        L{inotify.INotify} when initialized with autoAdd==True adds
        also adds the created subdirectories to the watchlist.
        c                 @    fd}t        j                  d|       y )Nc                      	 j                  j                  j                                j                  d        y # t        $ r  j                          Y y w xY wr   )r.   r	   
_isWatchedr8   	Exceptionerrbackr   r   subdirs   r   _zIINotifyTests.test_simpleSubdirectoryAutoAdd.<locals>._callback.<locals>._	  sG     OODLL$;$;F$CDJJt$   IIK    ;? AAr   r   	callLater)wpr1   r4   r   r   r   r   s       r   	_callbackz>INotifyTests.test_simpleSubdirectoryAutoAdd.<locals>._callback        a#r   Tr4   autoAddr>   test	r	   IN_ISDIRry   r0   r   r?   r   r@   r   r   r   	checkMaskr   r   s   `  @@r   test_simpleSubdirectoryAutoAddz+INotifyTests.test_simpleSubdirectoryAutoAdd   sy    
	$ $$w'8'88	LLy$9+ 	 	
 ##F+NN r   c                 6    g  fd}t         j                  t         j                  z  } j                   j                   j                  |d|g        j                  j                  d      t        j                         j                          S )zz
        L{inotify.INotify} removes a directory from the watchlist when
        it's removed from the filesystem.
        c                     fd}fd}s(j                  |       t        j                  d|       y t        j                  d|       y )Nc                      	 j                  j                  j                               j                          y # t        $ r  j                          Y y w xY wr   )r.   r	   r   r}   r   r   r   s   r   r   zEINotifyTests.test_simpleDeleteDirectory.<locals>._callback.<locals>._%  sD     OODLL$;$;F$CDMMO   IIK s   :> AAc                      	 j                  j                  j                                j                  d        y # t        $ r  j                          Y y w xY wr   assertFalser	   r   r8   r   r   r   s   r   _ebzGINotifyTests.test_simpleDeleteDirectory.<locals>._callback.<locals>._eb,  sI     $$T\\%<%<V%DEJJt$   IIK r   r   )appendr   r   )	r   r1   r4   r   r   callsr   r   r   s	        r   r   z:INotifyTests.test_simpleDeleteDirectory.<locals>._callback"  s@       X&!!!Q' !!!S)r   Tr   r   r   )r   r   r   r   r   r   s   `  @@@r   test_simpleDeleteDirectoryz'INotifyTests.test_simpleDeleteDirectory  s    
 	*4 $$w'8'88	LLy$9+ 	 	
 ##F+NN r   c                 P     fd} j                   j                  j                   j                  t        j                  fdg             t        j                         j                  |        j                  j                          t        j                         S )z
        L{inotify.INotify} closes the file descriptor after removing a
        directory from the filesystem (and therefore from the watchlist).
        c                     fd}| \  }}}j                  |j                         j                  j                                j                  |t        j
                  z         t        j                  d|       y )Nc                     	 j                  j                  j                  j                               j                  j                  j                          j                  d        y # t        $ r  j                          Y y w xY wr   )r   r	   r   r   	connectedr8   r   r   )r   r   s   r   r   zIINotifyTests.test_deleteSelfLoseConnection.<locals>.cbNotified.<locals>._L  se     $$T\\%<%<T\\%JK$$T\\%;%;<JJt$   IIK s   A*A. .B
	B
r   )r,   r-   r   r.   r	   r   r   r   )r/   r   ignoredr1   r2   r   r   s        r   r5   z>INotifyTests.test_deleteSelfLoseConnection.<locals>.cbNotifiedK  sc      +1'WhX113T\\5M5M5OPOOFW%;%;;<a#r   c                  &    j                  |       S r   r7   r9   s    r   r<   z<INotifyTests.test_deleteSelfLoseConnection.<locals>.<lambda>]  s    ):):4)@ r   r=   )	r.   r	   r0   r   r   r   r@   rA   r}   )r   r5   r   r;   s   ` @@r   test_deleteSelfLoseConnectionz*INotifyTests.test_deleteSelfLoseConnectionE  s    	$ 	LL++@A  	
 >>#Z(NNr   c                 l   | j                   j                  | j                  d       | j                  | j                   j	                  | j                               | j                   j                  | j                         | j                  | j                   j	                  | j                               y)zR
        L{inotify.INotify.ignore} removes a directory from the watchlist
        T)r   N)r	   r0   r   r.   r   ignorer   r   s    r   test_ignoreDirectoryz!INotifyTests.test_ignoreDirectoryh  su     	4<<6//=>DLL)00>?r   c                 H   t         j                  D ]-  \  }}| j                  t        j                  |      d   |       / t         j                  t         j
                  z  t         j                  z  }| j                  t        t        j                  |            h d       y)zy
        L{inotify.humaReadableMask} translates all the possible event
        masks to a human readable string.
        r   >   rQ   accessclose_writeN)r	   _FLAG_TO_HUMANr,   humanReadableMaskra   rK   rj   set)r   r4   valuer   s       r   test_humanReadableMaskz#INotifyTests.test_humanReadableMaskq  s    
 #11 	HKD%W66t<Q?G	H **W->->>P	)))45-	
r   c                    | j                   j                  d      }|j                  d      }|j                  d      }|j                          |||g}| j                  j	                  | j                   d       | j                  j	                  | j                   d       |D ],  }| j                  | j                  j                  |             . y)z
        L{inotify.INotify.watch} with recursive==True will add all the
        subdirectories under the given path to the watchlist.
        r   test2test3T)	recursiveN)r   r?   makedirsr	   r0   r.   r   )r   r   subdir2subdir3dirsr   s         r   test_recursiveWatchz INotifyTests.test_recursiveWatch  s    
 ##F+,,w'--()4<<484<<48 	8AOODLL33A67	8r   c                     ddl }t        j                         }|j                  |j                         |j                          | j                          y)z
        L{inotify.INotify.connectionLost} if there's a problem while closing
        the fd shouldn't raise the exception but should log the error
        r   N)osr	   r   r_   _fdr   flushLoggedErrors)r   r   in_s      r   test_connectionLostErrorz%INotifyTests.test_connectionLostError  s;    
 	oo
 r   c                 .     fd}t         j                  t         j                  z  } j                   j                   j                  |d|g        j                  j                  d      t        j                         j                          S )z
        L{inotify.INotify.watch} with autoAdd==False will stop inotify
        from watching subdirectories created under the watched one.
        c                 @    fd}t        j                  d|       y )Nc                      	 j                  j                  j                                j                  d        y # t        $ r  j                          Y y w xY wr   r   r   s   r   r   zEINotifyTests.test_noAutoAddSubdirectory.<locals>._callback.<locals>._  sI     $$T\\%<%<V%DEJJt$   IIK r   r   r   )r   fpr4   r   r   r   r   s       r   r   z:INotifyTests.test_noAutoAddSubdirectory.<locals>._callback  r   r   Fr   r   r   r   s   `  @@r   test_noAutoAddSubdirectoryz'INotifyTests.test_noAutoAddSubdirectory  sy    
	$ $$w'8'88	LLy%I; 	 	
 ##F+NN r   c                      j                   j                  d      j                          t        j                          fd}fd} j                   j                  j                  |g              j                  j                          j                   j                  j                  t        j                  |g             j                  |       j                          S )z
        L{inotify.INotify} will watch a filepath for events even if the same
        path is repeatedly added/removed/re-added to the watchpoints.
        foo.bar2c                     | \  }}}j                  |j                         j                                j                  |t        j                  z         y r   r,   r-   r.   r	   r   )r/   r   r1   r2   r3   r   s       r   r5   z<INotifyTests.test_seriesOfWatchAndIgnore.<locals>.cbNotified  sH    *0'WhX113\5M5M5OPOOFW%;%;;<r   c                  (    j                  |        y r   r7   r9   s    r   callItz8INotifyTests.test_seriesOfWatchAndIgnore.<locals>.callIt      d#r   r>   r=   )r   r?   rX   r   r@   r.   r	   r0   r   r   rA   r}   )r   r5   r   r3   r;   s   `  @@r   test_seriesOfWatchAndIgnorez(INotifyTests.test_seriesOfWatchAndIgnore  s    
 ||))*5>>#	=
	$ 	**<F8*LML)LL7#9#9fX  	
 	Z( 	r   c                 ~     j                   j                  d      }|j                           j                   j                  d      j                          t        j                          fd}fd} j                   j                  j                  |t        j                  |g             j                  |        j                   j                  j                  t        j                  |g              j                  j                  |       |j                          j                          S )zr
        L{inotify.INotify} will ignore a filepath after it has been removed from
        the watch list.
        r   zfoo.bar3c                     | \  }}}j                  |j                         j                                j                  |t        j                  z         y r   r   )r/   r   r1   r2   expectedPath2r   s       r   r5   z4INotifyTests.test_ignoreFilePath.<locals>.cbNotified  sH    *0'WhX113]5N5N5PQOOFW%;%;;<r   c                  (    j                  |        y r   r7   r9   s    r   r   z0INotifyTests.test_ignoreFilePath.<locals>.callIt  r   r   r   )r   r?   rX   r   r@   r.   r	   r0   r   rA   r   r}   )r   r3   r5   r   r   r;   s   `   @@r   test_ignoreFilePathz INotifyTests.test_ignoreFilePath  s    
 ||))*5**:6>>#	=
	$ 	LL|W-C-CPVxX	
 	Z(LLw55&  	
 	L)r   c                     | j                   j                  d      }|j                          | j                  t        | j
                  j                  |       y)zf
        L{inotify.INotify} will raise KeyError if a non-watched filepath is
        ignored.
        zfoo.ignoredN)r   r?   rX   r(   KeyErrorr	   r   )r   r3   s     r   test_ignoreNonWatchedFilez&INotifyTests.test_ignoreNonWatchedFile  s@    
 ||))-8(DLL$7$7Fr   c                    	
 t                	
fd}t        j                  t        j                  z  } j                  j	                   j
                  |d|g        j
                  j                  d      j                  d      		j                  d      
t        j                         
j                          j                  d      	j                  d      
j                  d	      gt              D ]A  \  }}|j                  |j                  j                  t        j                                      C S )
aB  
        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                 d   j                  |       t              dk(  r	 j                  j                  j	                  	             j                  j                  j	                  
             j                  j                  j	                               	
gz   }|D ch c]  }|j                          }}j                  t              t        |             j                  |       j                  d        y y c c}w # t        $ r j                          Y y w xY w)N   )
addlenr.   r	   r   r-   r,   r8   r   r   )r   r1   r4   createdfr   r   r   	someFilesr   r   r   s        r   r   z?INotifyTests.test_complexSubdirectoryAutoAdd.<locals>._callback  s    IIh5zQ%OODLL$;$;F$CDOODLL$;$;G$DEOODLL$;$;G$DE'67G*DDG8?@1q}}@G@$$SZW>$$UG4 JJt$  A !  IIK s$   B
D ,D8D D D/.D/Tr   r   r   r   z	file1.datz	file2.datz	file3.dat)r   r	   r   ry   r0   r   r?   r   r@   r   	enumeraterG   rJ   encodesysgetfilesystemencoding)r   r   r   ir1   r   r   r   r   r   r   s   `    @@@@@@r   test_complexSubdirectoryAutoAddz,INotifyTests.test_complexSubdirectoryAutoAdd  s    	% 	%  $$w'8'88	LLy$9+ 	 	
 ##F+,,w'--(NN LL%MM+&MM+&
	 %Y/ 	SKAx 4 4S5N5N5P QR	Sr   r   )$r!   r"   r#   __doc__r   platformsupportsINotifyskipr   r)   rC   rM   rU   rZ   rb   rg   rk   rq   rv   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r$   r   r   r   r      s    
 ++-75A "H
D
D
D
IK	B
HF	D
D
,
6(T!F@
8 
!6#J$LG.r   r   )r   r   twisted.internetr   r   twisted.pythonr   r   twisted.python.reflectr   twisted.trialr   r	   TestCaser   r$   r   r   <module>r      sC     + , 0 "*+7(Ge8$$ er   