+
    DfjH                         R t ^ RIt^ RIHtHt ^ RIHtHt ^ RIH	t	 ^ RI
Ht ]	! R4      e   ^ RIHt MRt ! R R	]P                  4      tR# )
z?
Tests for the inotify wrapper in L{twisted.internet.inotify}.
N)deferreactor)filepathruntime)requireModule)unittestztwisted.python._inotify)inotifyc                     a  ] tR t^t o Rt]P                  P                  4       '       g   RtR t	R t
R!R ltR tR tR	 tR
 tR tR tR tR tR tR tR tR tR tR tR tR tR tR tR tR tR t R t!R t"R t#R t$R t%V t&R# )"INotifyTestszQ
Define all the tests for the basic functionality exposed by
L{inotify.INotify}.
z&This platform doesn't support INotify.c                >   \         P                  ! V P                  4       4      V n        V P                  P	                  4        \
        P                  ! 4       V n        V P
                  P                  4        V P                  V P
                  P                  4       R # N)
r   FilePathmktempdirnamecreateDirectoryr   INotifystartReading
addCleanuploseConnectionselfs   &D/usr/lib/python3/dist-packages/twisted/internet/test/test_inotify.pysetUpINotifyTests.setUp   s^    ((7$$&(!!#334    c                     ! R R4      pV P                  \        P                  RV! 4       4       V P                  \        P                  \        P                  4       R# )z
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                   &   a  ] tR t^-t o R tRtV tR# );INotifyTests.test_initializationErrors.<locals>.FakeINotifyc                ,    \         P                  ! 4       hr   )r   INotifyErrorr   s   &r   init@INotifyTests.test_initializationErrors.<locals>.FakeINotify.init.   s    **,,r    N)__name__
__module____qualname____firstlineno__r    __static_attributes____classdictcell____classdict__s   @r   FakeINotifyr   -   s     - -r   r+   _inotifyN)patchr   r   assertRaisesr   )r   r+   s   & r   test_initializationErrors&INotifyTests.test_initializationErrors$   s>    	- 	- 	

7??J>'..@r   Nc                  a aaa Sf   S P                   P                  R4      o\        P                  ! 4       oVVV 3R lpSP	                  V4       S P
                  P                  S P                   SV3R l.R7       V! S4       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                    < V w  rpSP                  VP                  4       SP                  4       4       SP                  VS,          4       R # r   )assertEqualasBytesMode
assertTrue)resultwatchfilenameeventsexpectedPathmaskr   s   &   r   
cbNotified2INotifyTests._notificationTest.<locals>.cbNotifiedK   s?    (.%UfX113\5M5M5OPOOFTM*r   c                  &   < SP                  V 4      # r   callbackargsnotifieds   *r   <lambda>0INotifyTests._notificationTest.<locals>.<lambda>S   s    h>O>OPT>Ur   r;   	callbacks)r   childr   DeferredaddCallbackr   r7   )r   r;   	operationr:   r<   rC   s   ff&f @r   _notificationTestINotifyTests._notificationTest4   su    & <<--i8L>>#	+
 	Z(LLt0U/V 	 	
 	,r   c                H    R pV P                  \        P                  V4      # )zc
Reading from a file in a monitored directory sends an
C{inotify.IN_ACCESS} event to the callback.
c                 H    V P                  R 4       V P                  4        R# )   fooN)
setContent
getContentpaths   &r   rK   +INotifyTests.test_access.<locals>.operation^   s    OOF#OOr   )rL   r   	IN_ACCESSr   rK   s   & r   test_accessINotifyTests.test_accessX   s"    	 %%g&7&7CCr   c                H    R pV P                  \        P                  V4      # )za
Writing to a file in a monitored directory sends an
C{inotify.IN_MODIFY} event to the callback.
c                     V P                  R 4      ;_uu_ 4       pVP                  R4       RRR4       R#   + '       g   i     R# ; i)wrP   N)openwrite)rT   fObjs   & r   rK   +INotifyTests.test_modify.<locals>.operationj   s)    34

6"  s	   6A	)rL   r   	IN_MODIFYrW   s   & r   test_modifyINotifyTests.test_modifyd   s"    	# %%g&7&7CCr   c                H    R pV P                  \        P                  V4      # )zo
Changing the metadata of a file in a monitored directory
sends an C{inotify.IN_ATTRIB} event to the callback.
c                 F    V P                  4        V P                  4        R # r   )touchrS   s   &r   rK   +INotifyTests.test_attrib.<locals>.operationv   s    JJLJJLr   )rL   r   	IN_ATTRIBrW   s   & r   test_attribINotifyTests.test_attribp   s"    	 %%g&7&7CCr   c                H    R pV P                  \        P                  V4      # )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                 D    V P                  R 4      P                  4        R# r\   Nr]   closerS   s   &r   rK   /INotifyTests.test_closeWrite.<locals>.operation       IIcN  "r   )rL   r   IN_CLOSE_WRITErW   s   & r   test_closeWriteINotifyTests.test_closeWrite|   s"    	# %%g&<&<iHHr   c                H    R pV P                  \        P                  V4      # )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                 d    V P                  4        V P                  R 4      P                  4        R# )rN)rf   r]   ro   rS   s   &r   rK   1INotifyTests.test_closeNoWrite.<locals>.operation   s    JJLIIcN  "r   )rL   r   IN_CLOSE_NOWRITErW   s   & r   test_closeNoWriteINotifyTests.test_closeNoWrite   s"    	# %%g&>&>	JJr   c                H    R pV P                  \        P                  V4      # )z\
Opening a file in a monitored directory sends an
C{inotify.IN_OPEN} event to the callback.
c                 D    V P                  R 4      P                  4        R# rm   rn   rS   s   &r   rK   )INotifyTests.test_open.<locals>.operation   rq   r   )rL   r   IN_OPENrW   s   & r   	test_openINotifyTests.test_open   s     	# %%gooyAAr   c                P   a  V 3R lpS P                  \        P                  V4      # )ze
Moving a file out of a monitored directory sends an
C{inotify.IN_MOVED_FROM} event to the callback.
c                    < V P                  R 4      P                  4        V P                  \        P                  ! SP                  4       4      4       R# rm   )r]   ro   moveTor   r   r   rT   r   s   &r   rK   .INotifyTests.test_movedFrom.<locals>.operation   s4    IIcN  "KK))$++-89r   )rL   r   IN_MOVED_FROMrW   s   f r   test_movedFromINotifyTests.test_movedFrom   s#    	: %%g&;&;YGGr   c                P   a  V 3R lpS P                  \        P                  V4      # )za
Moving a file into a monitored directory sends an
C{inotify.IN_MOVED_TO} event to the callback.
c                    < \         P                  ! SP                  4       4      pVP                  4        VP	                  V 4       R # r   )r   r   r   rf   r   )rT   pr   s   & r   rK   ,INotifyTests.test_movedTo.<locals>.operation   s-    !!$++-0AGGIHHTNr   )rL   r   IN_MOVED_TOrW   s   f r   test_movedToINotifyTests.test_movedTo   s#    	
 %%g&9&99EEr   c                H    R pV P                  \        P                  V4      # )z_
Creating a file in a monitored directory sends an
C{inotify.IN_CREATE} event to the callback.
c                 D    V P                  R 4      P                  4        R# rm   rn   rS   s   &r   rK   +INotifyTests.test_create.<locals>.operation   rq   r   )rL   r   	IN_CREATErW   s   & r   test_createINotifyTests.test_create   s"    	# %%g&7&7CCr   c                H    R pV P                  \        P                  V4      # )z_
Deleting a file in a monitored directory sends an
C{inotify.IN_DELETE} event to the callback.
c                 F    V P                  4        V P                  4        R # r   )rf   removerS   s   &r   rK   +INotifyTests.test_delete.<locals>.operation   s    JJLKKMr   )rL   r   	IN_DELETErW   s   & r   test_deleteINotifyTests.test_delete   s"    	 %%g&7&7CCr   c                ^    R pV P                  \        P                  WP                  R7      # )zc
Deleting the monitored directory itself sends an
C{inotify.IN_DELETE_SELF} event to the callback.
c                 &    V P                  4        R # r   )r   rS   s   &r   rK   /INotifyTests.test_deleteSelf.<locals>.operation   s    KKMr   r:   )rL   r   IN_DELETE_SELFr   rW   s   & r   test_deleteSelfINotifyTests.test_deleteSelf   s0    	 %%""ILL & 
 	
r   c                   a a V 3R lpS P                   P                  S P                  ^ V3R l.R7       \        P                  ! 4       oSP                  V4       S P                  P                  4        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                    < V w  rpSP                  VP                  4       SP                  P                  4       4       SP                  V\        P
                  ,          4       R # r   )r3   r4   r   r5   r   r   )r6   r7   r8   r9   r   s   &   r   r<   6INotifyTests.test_deleteSelfForced.<locals>.cbNotified   sJ    (.%UfX113T\\5M5M5OPOOFW%;%;;<r   c                  &   < SP                  V 4      # r   r?   )rB   ds   *r   rD   4INotifyTests.test_deleteSelfForced.<locals>.<lambda>   s    QZZ=Mr   rF   )r   r7   r   r   rI   rJ   r   )r   r<   r   s   f @r   test_deleteSelfForced"INotifyTests.test_deleteSelfForced   s_    	=
 	LLs/M.N 	 	
 NN	j!r   c                h   a  V 3R lpS P                  \        P                  VS P                  R7      # )za
Renaming the monitored directory itself sends an
C{inotify.IN_MOVE_SELF} event to the callback.
c                 n   < V P                  \        P                  ! SP                  4       4      4       R # r   )r   r   r   r   r   s   &r   rK   -INotifyTests.test_moveSelf.<locals>.operation   s     KK))$++-89r   r   )rL   r   IN_MOVE_SELFr   rW   s   f r   test_moveSelfINotifyTests.test_moveSelf   s3    	: %%  )$,, & 
 	
r   c                :  a aa VV V3R lp\         P                  \         P                  ,          pS P                   P                  S P                  VRV.R7       S P                  P                  R4      o\        P                  ! 4       oSP                  4        S# )zt
L{inotify.INotify} when initialized with autoAdd==True adds
also adds the created subdirectories to the watchlist.
c                 F   < VVV3R  lp\         P                  ! ^ V4       R# )c                     <  SP                  SP                  P                  S4      4       S P                  R 4       R #   \         d    S P                  4         R # i ; ir   )r5   r   
_isWatchedr@   	Exceptionerrbackr   r   subdirs   r   _IINotifyTests.test_simpleSubdirectoryAutoAdd.<locals>._callback.<locals>._	  sG     OODLL$;$;F$CDJJt$   IIK    ;A   AANr   	callLater)wpr8   r;   r   r   r   r   s   &&& r   	_callback>INotifyTests.test_simpleSubdirectoryAutoAdd.<locals>._callback        a#r   Tr;   autoAddrG   test	r   IN_ISDIRr   r7   r   rH   r   rI   r   r   r   	checkMaskr   r   s   f  @@r   test_simpleSubdirectoryAutoAdd+INotifyTests.test_simpleSubdirectoryAutoAdd   sy    
	$ $$w'8'88	LLy$9+ 	 	
 ##F+NN r   c                B  a aaa . oVVV V3R lp\         P                  \         P                  ,          pS P                   P                  S P                  VRV.R7       S P                  P                  R4      o\        P                  ! 4       oSP                  4        S# )zb
L{inotify.INotify} removes a directory from the watchlist when
it's removed from the filesystem.
c                    < VVV3R  lpVVV3R lpS'       g+   SP                  V4       \        P                  ! ^ V4       R# \        P                  ! ^ V4       R# )c                     <  SP                  SP                  P                  S4      4       SP                  4        R #   \         d    S P                  4         R # i ; ir   )r5   r   r   r   r   r   r   s   r   r   EINotifyTests.test_simpleDeleteDirectory.<locals>._callback.<locals>._%  sD     OODLL$;$;F$CDMMO   IIK s   :? AAc                     <  SP                  SP                  P                  S4      4       S P                  R 4       R #   \         d    S P                  4         R # i ; ir   assertFalser   r   r@   r   r   r   s   r   _ebGINotifyTests.test_simpleDeleteDirectory.<locals>._callback.<locals>._eb,  sI     $$T\\%<%<V%DEJJt$   IIK r   N)appendr   r   )	r   r8   r;   r   r   callsr   r   r   s	   &&&  r   r   :INotifyTests.test_simpleDeleteDirectory.<locals>._callback"  s@       X&!!!Q' !!!S)r   Tr   r   r   )r   r   r   r   r   r   s   f  @@@r   test_simpleDeleteDirectory'INotifyTests.test_simpleDeleteDirectory  s    
 	* 	*4 $$w'8'88	LLy$9+ 	 	
 ##F+NN r   c                X  a aa VV 3R lpS P                  S P                  P                  S P                  \        P                  V3R l.R7      4       \
        P                  ! 4       oSP                  V4       S P                  P                  4        \
        P                  ! 4       oS# )z
L{inotify.INotify} closes the file descriptor after removing a
directory from the filesystem (and therefore from the watchlist).
c                 
  < VV3R  lpV w  r#pSP                  VP                  4       SP                  P                  4       4       SP                  V\        P
                  ,          4       \        P                  ! ^ V4       R# )c                  "  <  SP                  SP                  P                  SP                  4      4       SP                  SP                  P                  4       S P                  R 4       R #   \         d    S P                  4         R # i ; ir   )r   r   r   r   	connectedr@   r   r   )r   r   s   r   r   IINotifyTests.test_deleteSelfLoseConnection.<locals>.cbNotified.<locals>._L  se     $$T\\%<%<T\\%JK$$T\\%;%;<JJt$   IIK s   A*A/ /BBN)r3   r4   r   r5   r   r   r   r   )r6   r   ignoredr8   r9   r   r   s   &    r   r<   >INotifyTests.test_deleteSelfLoseConnection.<locals>.cbNotifiedK  sa      +1'WX113T\\5M5M5OPOOFW%;%;;<a#r   c                  &   < SP                  V 4      # r   r?   rA   s   *r   rD   <INotifyTests.test_deleteSelfLoseConnection.<locals>.<lambda>]  s    ):):4)@r   rF   )	r5   r   r7   r   r   r   rI   rJ   r   )r   r<   r   rC   s   f @@r   test_deleteSelfLoseConnection*INotifyTests.test_deleteSelfLoseConnectionE  s    	$ 	LL++@A  	
 >>#Z(NNr   c                n   V P                   P                  V P                  RR7       V P                  V P                   P	                  V P                  4      4       V P                   P                  V P                  4       V P                  V P                   P	                  V P                  4      4       R# )zB
L{inotify.INotify.ignore} removes a directory from the watchlist
T)r   N)r   r7   r   r5   r   ignorer   r   s   &r   test_ignoreDirectory!INotifyTests.test_ignoreDirectoryh  su     	4<<6//=>DLL)00>?r   c                h   \         P                   F2  w  rV P                  \         P                  ! V4      ^ ,          V4       K4  	  \         P                  \         P
                  ,          \         P                  ,          pV P                  \        \         P                  ! V4      4      0 Rm4       R# )za
L{inotify.humaReadableMask} translates all the possible event
masks to a human readable string.
N>   r]   accessclose_write)r   _FLAG_TO_HUMANr3   humanReadableMaskrr   rV   r   set)r   r;   valuer   s   &   r   test_humanReadableMask#INotifyTests.test_humanReadableMaskq  s{    
 #11KDW66t<Q?G 2 **W->->>P	)))45-	
r   c                   V P                   P                  R4      pVP                  R4      pVP                  R4      pVP                  4        WV.pV P                  P	                  V P                   RR7       V P                  P	                  V P                   RR7       V F-  pV P                  V P                  P                  V4      4       K/  	  R# )zv
L{inotify.INotify.watch} with recursive==True will add all the
subdirectories under the given path to the watchlist.
r   test2test3T)	recursiveN)r   rH   makedirsr   r7   r5   r   )r   r   subdir2subdir3dirsr   s   &     r   test_recursiveWatch INotifyTests.test_recursiveWatch  s    
 ##F+,,w'--()4<<484<<48AOODLL33A67 r   c                    ^ RI p\        P                  ! 4       pVP                  VP                  4       VP                  4        V P                  4        R# )z
L{inotify.INotify.connectionLost} if there's a problem while closing
the fd shouldn't raise the exception but should log the error
N)osr   r   ro   _fdr   flushLoggedErrors)r   r   in_s   &  r   test_connectionLostError%INotifyTests.test_connectionLostError  s;    
 	oo
 r   c                :  a aa VV V3R lp\         P                  \         P                  ,          pS P                   P                  S P                  VRV.R7       S P                  P                  R4      o\        P                  ! 4       oSP                  4        S# )z|
L{inotify.INotify.watch} with autoAdd==False will stop inotify
from watching subdirectories created under the watched one.
c                 F   < VVV3R  lp\         P                  ! ^ V4       R# )c                     <  SP                  SP                  P                  S4      4       S P                  R 4       R #   \         d    S P                  4         R # i ; ir   r   r   s   r   r   EINotifyTests.test_noAutoAddSubdirectory.<locals>._callback.<locals>._  sI     $$T\\%<%<V%DEJJt$   IIK r   Nr   )r   fpr;   r   r   r   r   s   &&& r   r   :INotifyTests.test_noAutoAddSubdirectory.<locals>._callback  r   r   Fr   r   r   r   s   f  @@r   test_noAutoAddSubdirectory'INotifyTests.test_noAutoAddSubdirectory  sy    
	$ $$w'8'88	LLy%I; 	 	
 ##F+NN r   c                  a aa S P                   P                  R4      oSP                  4        \        P                  ! 4       oVV 3R lpV3R lpS P                  S P                  P                  SV.R7      4       S P                  P                  S4       S P                  S P                  P                  S\        P                  V.R7      4       SP                  V4       SP                  4        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                    < V w  rpSP                  VP                  4       SP                  4       4       SP                  V\        P                  ,          4       R # r   r3   r4   r5   r   r   )r6   r   r8   r9   r:   r   s   &   r   r<   <INotifyTests.test_seriesOfWatchAndIgnore.<locals>.cbNotified  sF    *0'WX113\5M5M5OPOOFW%;%;;<r   c                  *   < SP                  V 4       R # r   r?   rA   s   *r   callIt8INotifyTests.test_seriesOfWatchAndIgnore.<locals>.callIt      d#r   rG   rF   )r   rH   rf   r   rI   r5   r   r7   r   r   rJ   r   )r   r<   r  r:   rC   s   f  @@r   test_seriesOfWatchAndIgnore(INotifyTests.test_seriesOfWatchAndIgnore  s    
 ||))*5>>#	=
	$ 	**<F8*LML)LL7#9#9fX  	
 	Z( 	r   c                  a aa S P                   P                  R4      pVP                  4        S P                   P                  R4      oSP                  4        \        P                  ! 4       oVV 3R lpV3R lpS P                  S P                  P                  V\        P                  V.R7      4       SP                  V4       S P                  S P                  P                  S\        P                  V.R7      4       S P                  P                  V4       VP                  4        SP                  4        S# )zZ
L{inotify.INotify} will ignore a filepath after it has been removed from
the watch list.
r  zfoo.bar3c                    < V w  rpSP                  VP                  4       SP                  4       4       SP                  V\        P                  ,          4       R # r   r  )r6   r   r8   r9   expectedPath2r   s   &   r   r<   4INotifyTests.test_ignoreFilePath.<locals>.cbNotified  sF    *0'WX113]5N5N5PQOOFW%;%;;<r   c                  *   < SP                  V 4       R # r   r?   rA   s   *r   r  0INotifyTests.test_ignoreFilePath.<locals>.callIt  r  r   r  )r   rH   rf   r   rI   r5   r   r7   r   rJ   r   r   )r   r:   r<   r  r  rC   s   f   @@r   test_ignoreFilePath INotifyTests.test_ignoreFilePath  s    
 ||))*5**:6>>#	=
	$ 	LL|W-C-CPVxX	
 	Z(LLw55&  	
 	L)r   c                    V P                   P                  R4      pVP                  4        V P                  \        V P
                  P                  V4       R# )zN
L{inotify.INotify} will raise KeyError if a non-watched filepath is
ignored.
zfoo.ignoredN)r   rH   rf   r.   KeyErrorr   r   )r   r:   s   & r   test_ignoreNonWatchedFile&INotifyTests.test_ignoreNonWatchedFile  s@    
 ||))-8(DLL$7$7Fr   c                  a aaaaa	a
 \        4       oVVV VVV	V
3R lp\        P                  \        P                  ,          pS P                  P	                  S P
                  VRV.R7       S P
                  P                  R4      oSP                  R4      o	S	P                  R4      o
\        P                  ! 4       oS
P                  4        SP                  R4      S	P                  R4      S
P                  R	4      .o\        S4       FB  w  r4VP                  VP                  P                  \        P                  ! 4       4      4       KD  	  S# )
a  
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P                  V4       \        S4      ^8X  d    SP                  SP                  P	                  S	4      4       SP                  SP                  P	                  S
4      4       SP                  SP                  P	                  S4      4       SS	S
S.,           pV Uu0 uF  qDP                  4       kK  	  ppSP                  \        S4      \        V4      4       SP                  SV4       SP                  R4       R# R# u upi   \         d    SP                  4         R# i ; i)   N)
addlenr5   r   r   r4   r3   r@   r   r   )r   r8   r;   createdfr   r   r   	someFilesr   r   r   s   &&&  r   r   ?INotifyTests.test_complexSubdirectoryAutoAdd.<locals>._callback  s    IIh5zQ%OODLL$;$;F$CDOODLL$;$;G$DEOODLL$;$;G$DE'67G*DDG8?@1}}G@$$SZW>$$UG4 JJt$  A !  IIK s$   BD 2D
8D D D;:D;Tr   r   r   r   z	file1.datz	file2.datz	file3.dat)r   r   r   r   r7   r   rH   r   rI   r   	enumeraterQ   rT   encodesysgetfilesystemencoding)r   r   r   ir8   r   r   r+  r   r   r   s   f    @@@@@@r   test_complexSubdirectoryAutoAdd,INotifyTests.test_complexSubdirectoryAutoAdd  s	    	% 	%  $$w'8'88	LLy$9+ 	 	
 ##F+,,w'--(NN LL%MM+&MM+&
	 %Y/KA 4 4S5N5N5P QR 0r   )r   r   r   )'r#   r$   r%   r&   __doc__r   platformsupportsINotifyskipr   r/   rL   rX   rb   ri   rs   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r
  r  r  r"  r2  r'   r(   r)   s   @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
   )r4  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   