ϪfHdZddlZddlmZmZddlmZmZddlm Z ddl m Z e dddlm Z ndZ Gd d e jZy) z? Tests for the inotify wrapper in L{twisted.internet.inotify}. N)deferreactor)filepathruntime) requireModule)unittestztwisted.python._inotify)inotifyceZdZdZej j sdZdZdZ d dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#y)! INotifyTestsz] Define all the tests for the basic functionality exposed by L{inotify.INotify}. z&This platform doesn't support INotify.c8tj|j|_|jj t j |_|j j|j|j jyN) rFilePathmktempdirnamecreateDirectoryr INotify startReading addCleanuploseConnectionselfs D/usr/lib/python3/dist-packages/twisted/internet/test/test_inotify.pysetUpzINotifyTests.setUps^((7  $$&(  !!#  334cGdd}|jtjd||jtjtjy)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__}. ceZdZdZy);INotifyTests.test_initializationErrors..FakeINotifyc*tjr )r INotifyErrorrs rinitz@INotifyTests.test_initializationErrors..FakeINotify.init.s**,,rN)__name__ __module__ __qualname__r rr FakeINotifyr-s -rr%_inotifyN)patchr r assertRaisesr)rr%s rtest_initializationErrorsz&INotifyTests.test_initializationErrors$s> - - 7??J > '..@rNcjjdtjfd}j |j j jfdg|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. zfoo.barc|\}}}j|jjj|zyr ) assertEqual asBytesMode assertTrue)resultwatchfilenameevents expectedPathmaskrs r cbNotifiedz2INotifyTests._notificationTest..cbNotifiedKsA(. %UHf   X113\5M5M5O P OOFTM *rc&j|Sr callbackargsnotifieds rz0INotifyTests._notificationTest..Ssh>O>OPT>Urr4 callbacks)rchildrDeferred addCallbackr r0)rr4 operationr3r5r;s`` ` @r_notificationTestzINotifyTests._notificationTest4su&  <<--i8L>># + Z(  LLt0U/V   ,rcHd}|jtj|S)z{ Reading from a file in a monitored directory sends an C{inotify.IN_ACCESS} event to the callback. cF|jd|jy)Nfoo) setContent getContentpaths rrBz+INotifyTests.test_access..operation^s OOF # OO r)rCr IN_ACCESSrrBs r test_accesszINotifyTests.test_accessXs"  %%g&7&7CCrcHd}|jtj|S)zy Writing to a file in a monitored directory sends an C{inotify.IN_MODIFY} event to the callback. cr|jd5}|jddddy#1swYyxYw)NwrF)openwrite)rJfObjs rrBz+INotifyTests.test_modify..operationjs03 #4 6" # # #s-6)rCr IN_MODIFYrLs r test_modifyzINotifyTests.test_modifyds"  #%%g&7&7CCrcHd}|jtj|S)z Changing the metadata of a file in a monitored directory sends an C{inotify.IN_ATTRIB} event to the callback. cD|j|jyr )touchrIs rrBz+INotifyTests.test_attrib..operationvs JJL JJLr)rCr IN_ATTRIBrLs r test_attribzINotifyTests.test_attribps"  %%g&7&7CCrcHd}|jtj|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. cB|jdjyNrPrQcloserIs rrBz/INotifyTests.test_closeWrite..operation IIcN "r)rCr IN_CLOSE_WRITErLs rtest_closeWritezINotifyTests.test_closeWrite|s" #%%g&<&.operations JJL IIcN "r)rCr IN_CLOSE_NOWRITErLs rtest_closeNoWritezINotifyTests.test_closeNoWrites" #%%g&>&> JJrcHd}|jtj|S)zt Opening a file in a monitored directory sends an C{inotify.IN_OPEN} event to the callback. cB|jdjyr]r^rIs rrBz)INotifyTests.test_open..operationr`r)rCr IN_OPENrLs r test_openzINotifyTests.test_opens  #%%gooyAArcNfd}jtj|S)z} Moving a file out of a monitored directory sends an C{inotify.IN_MOVED_FROM} event to the callback. c|jdj|jtjj yr])rQr_moveTorrrrJrs rrBz.INotifyTests.test_movedFrom..operations4 IIcN " KK))$++-8 9r)rCr IN_MOVED_FROMrLs` rtest_movedFromzINotifyTests.test_movedFroms#  :%%g&;&;YGGrcNfd}jtj|S)zy Moving a file into a monitored directory sends an C{inotify.IN_MOVED_TO} event to the callback. ctjj}|j|j |yr )rrrrXrn)rJprs rrBz,INotifyTests.test_movedTo..operations-!!$++-0A GGI HHTNr)rCr IN_MOVED_TOrLs` r test_movedTozINotifyTests.test_movedTos#   %%g&9&99EErcHd}|jtj|S)zw Creating a file in a monitored directory sends an C{inotify.IN_CREATE} event to the callback. cB|jdjyr]r^rIs rrBz+INotifyTests.test_create..operationr`r)rCr IN_CREATErLs r test_createzINotifyTests.test_creates"  #%%g&7&7CCrcHd}|jtj|S)zw Deleting a file in a monitored directory sends an C{inotify.IN_DELETE} event to the callback. cD|j|jyr )rXremoverIs rrBz+INotifyTests.test_delete..operations JJL KKMr)rCr IN_DELETErLs r test_deletezINotifyTests.test_deletes"  %%g&7&7CCrc`d}|jtj||jS)z{ Deleting the monitored directory itself sends an C{inotify.IN_DELETE_SELF} event to the callback. c$|jyr )r}rIs rrBz/INotifyTests.test_deleteSelf..operations KKMrr3)rCr IN_DELETE_SELFrrLs rtest_deleteSelfzINotifyTests.test_deleteSelfs2  %%  " "IDLL&  rcfd}jjjdfdgtjj |jj 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|jjjj|tj zyr )r,r-rr.r r)r/r0r1r2rs rr5z6INotifyTests.test_deleteSelfForced..cbNotifiedsL(. %UHf   X113T\\5M5M5O P OOFW%;%;; .sQZZ=Mrr=)r r0rrr@rAr})rr5rs` @rtest_deleteSelfForcedz"INotifyTests.test_deleteSelfForceds_ =  LLs/M.N   NN  j! rcffd}jtj|jS)zy Renaming the monitored directory itself sends an C{inotify.IN_MOVE_SELF} event to the callback. cj|jtjjyr )rnrrrros rrBz-INotifyTests.test_moveSelf..operations KK))$++-8 9rr)rCr IN_MOVE_SELFrrLs` r test_moveSelfzINotifyTests.test_moveSelfs3  :%%  )$,,&  rc.fd}tjtjz}jjj|d|gjj dt jjS)z L{inotify.INotify} when initialized with autoAdd==True adds also adds the created subdirectories to the watchlist. c@fd}tjd|y)Nc jjjjdy#t$rj YywxYwr )r.r _isWatchedr8 Exceptionerrbackrrsubdirsr_zIINotifyTests.test_simpleSubdirectoryAutoAdd.._callback.._ sG OODLL$;$;F$CDJJt$  IIK ;?AArr callLater)wpr1r4rrrrs r _callbackz>INotifyTests.test_simpleSubdirectoryAutoAdd.._callback    a #rTr4autoAddr>test r IN_ISDIRryr0rr?rr@rrr checkMaskrrs` @@rtest_simpleSubdirectoryAutoAddz+INotifyTests.test_simpleSubdirectoryAutoAddsy $$$w'8'88   LLy$9+  ##F+ NN  rc6gfd}tjtjz}jjj|d|gjj dt jjS)zz L{inotify.INotify} removes a directory from the watchlist when it's removed from the filesystem. cfd}fd}s(j|tjd|ytjd|y)Nc jjjjy#t$rj YywxYwr )r.r rr}rrrsrrzEINotifyTests.test_simpleDeleteDirectory.._callback.._%sD OODLL$;$;F$CDMMO  IIK s:>AAc jjjjdy#t$rj YywxYwr  assertFalser rr8rrrsr_ebzGINotifyTests.test_simpleDeleteDirectory.._callback.._eb,sI $$T\\%<%._callback"s@   X&!!!Q'!!!S)rTrrr)rrrrrrs` @@@rtest_simpleDeleteDirectoryz'INotifyTests.test_simpleDeleteDirectorys  *4$$w'8'88   LLy$9+  ##F+ NN  rcPfd}jjjjtjfdgt j j|jjt j S)z L{inotify.INotify} closes the file descriptor after removing a directory from the filesystem (and therefore from the watchlist). cfd}|\}}}j|jjjj|tj zt jd|y)Nc jjjjjjjj dy#t $rjYywxYwr )rr rr connectedr8rr)rrsrrzIINotifyTests.test_deleteSelfLoseConnection..cbNotified.._Lse $$T\\%<%INotifyTests.test_deleteSelfLoseConnection..cbNotifiedKsc +1 'Wh   X113T\\5M5M5O P OOFW%;%;; <   a #rc&j|Sr r7r9s rr<z.]s):):4)@rr=) r.r r0rrrr@rAr})rr5rr;s` @@rtest_deleteSelfLoseConnectionz*INotifyTests.test_deleteSelfLoseConnectionEs $  LL   ++@A   >>#Z(  NN rcl|jj|jd|j|jj |j|jj |j|j |jj |jy)zR L{inotify.INotify.ignore} removes a directory from the watchlist T)rN)r r0rr.rignorerrs rtest_ignoreDirectoryz!INotifyTests.test_ignoreDirectoryhsu 4<<6  // => DLL) 00>?rcHtjD]-\}}|jtj|d|/tjtj ztj z}|jttj|hdy)zy L{inotify.humaReadableMask} translates all the possible event masks to a human readable string. r>rQaccess close_writeN)r _FLAG_TO_HUMANr,humanReadableMaskrarKrjset)rr4valuers rtest_humanReadableMaskz#INotifyTests.test_humanReadableMaskqs #11 HKD%   W66t->>P   )))4 5 - rc|jjd}|jd}|jd}|j|||g}|jj |jd|jj |jd|D],}|j |jj |.y)z L{inotify.INotify.watch} with recursive==True will add all the subdirectories under the given path to the watchlist. rtest2test3T) recursiveN)rr?makedirsr r0r.r)rrsubdir2subdir3dirsrs rtest_recursiveWatchz INotifyTests.test_recursiveWatchs ##F+,,w'--() 4<<48 4<<48 8A OODLL33A6 7 8rcddl}tj}|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 rN)osr rr__fdrflushLoggedErrors)rrin_s rtest_connectionLostErrorz%INotifyTests.test_connectionLostErrors; oo    rc.fd}tjtjz}jjj|d|gjj dt jjS)z L{inotify.INotify.watch} with autoAdd==False will stop inotify from watching subdirectories created under the watched one. c@fd}tjd|y)Nc jjjjdy#t$rj YywxYwr rrsrrzEINotifyTests.test_noAutoAddSubdirectory.._callback.._sI $$T\\%<%._callbackrrFrrrrs` @@rtest_noAutoAddSubdirectoryz'INotifyTests.test_noAutoAddSubdirectorysy $$$w'8'88   LLy%I;  ##F+ NN  rcjjdjtjfd}fd}j j j|gj jj j jt j|gj|jS)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|jjj|tjzyr r,r-r.r r)r/rr1r2r3rs rr5z.cbNotifiedsH*0 'Wh   X113\5M5M5O P OOFW%;%;; .callIt   d #rr>r=) rr?rXrr@r.r r0rrrAr})rr5rr3r;s` @@rtest_seriesOfWatchAndIgnorez(INotifyTests.test_seriesOfWatchAndIgnores ||))*5 >># =  $  **.cbNotifiedsH*0 'Wh   X113]5N5N5P Q OOFW%;%;; .callItrrr) rr?rXrr@r.r r0rrArr})rr3r5rrr;s` @@rtest_ignoreFilePathz INotifyTests.test_ignoreFilePaths ||))*5  **:6 >># =  $  LL  |W-C-CPVx  X  Z(  LL  w55&   L)rc|jjd}|j|jt|j j |y)zf L{inotify.INotify} will raise KeyError if a non-watched filepath is ignored. z foo.ignoredN)rr?rXr(KeyErrorr r)rr3s rtest_ignoreNonWatchedFilez&INotifyTests.test_ignoreNonWatchedFiles@ ||))-8  (DLL$7$7Frc t fd}tjtjz}jj j |d|gj j dj d j d tj jj d j d j d gtD]A\}}|j|jjtjCS) 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. cdj|tdk(r jjj jjj jjj  gz}|Dchc]}|j }}j tt|j |jdyycc}w#t$rjYywxYw)N) addlenr.r rr-r,r8rr) rr1r4createdfrrr someFilesrrrs rrz?INotifyTests.test_complexSubdirectoryAutoAdd.._callbacks IIh 5zQ %OODLL$;$;F$CDOODLL$;$;G$DEOODLL$;$;G$DE'67G*DDG8?@1q}}@G@$$SZW>$$UG4JJt$ A! IIK s$B D,D8DDD/.D/Trrrrz file1.datz file2.datz file3.dat)rr rryr0rr?rr@r enumeraterGrJencodesysgetfilesystemencoding) rrrir1rrrrrrs ` @@@@@@rtest_complexSubdirectoryAutoAddz,INotifyTests.test_complexSubdirectoryAutoAdd s % % $$w'8'88   LLy$9+  ##F+,,w'--( NN  LL % MM+ & MM+ & %Y/ SKAx    4 4S5N5N5P Q R Srr )$r!r"r#__doc__rplatformsupportsINotifyskiprr)rCrMrUrZrbrgrkrqrvrzrrrrrrrrrrrrrrrrr$rrr r s    + + -75A "H D D D I K B H F D D  ,  6(T!F@  8 !6#J$LG.rr )rrtwisted.internetrrtwisted.pythonrrtwisted.python.reflectr twisted.trialrr TestCaser r$rrrsC +,0"*+7(Ge8$$er