o
    Òó·i‚H  ã                   @   sx   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ur/ddlmZ ndZG d	d
„ d
ejƒZdS )z?
Tests for the inotify wrapper in L{twisted.internet.inotify}.
é    N)ÚdeferÚreactor)ÚfilepathÚruntime)ÚrequireModule)Úunittestztwisted.python._inotify)Úinotifyc                   @   s   e Zd ZdZej ¡ sdZdd„ Zdd„ Z	d<dd	„Z
d
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Z d6d7„ Z!d8d9„ Z"d:d;„ Z#dS )=ÚINotifyTestsz]
    Define all the tests for the basic functionality exposed by
    L{inotify.INotify}.
    z&This platform doesn't support INotify.c                 C   s@   t  |  ¡ ¡| _| j ¡  t ¡ | _| j ¡  |  | jj	¡ d S ©N)
r   ÚFilePathÚmktempÚdirnameÚcreateDirectoryr   ÚINotifyZstartReadingZ
addCleanupÚloseConnection©Úself© r   úhC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/internet/test/test_inotify.pyÚsetUp   s
   


zINotifyTests.setUpc                 C   s4   G dd„ dƒ}|   tjd|ƒ ¡ |  tjtj¡ dS )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                   @   s   e Zd Zdd„ ZdS )z;INotifyTests.test_initializationErrors.<locals>.FakeINotifyc                 S   s   t  ¡ ‚r
   )r   ÚINotifyErrorr   r   r   r   Úinit.   s   z@INotifyTests.test_initializationErrors.<locals>.FakeINotify.initN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   ÚFakeINotify-   s    r   Z_inotifyN)Úpatchr   r   ÚassertRaisesr   )r   r   r   r   r   Útest_initializationErrors$   s   	z&INotifyTests.test_initializationErrorsNc                    s`   ˆ du r
ˆj  d¡‰ t ¡ ‰‡ ‡‡fdd„}ˆ |¡ ˆjjˆj ˆ‡fdd„gd� |ˆ ƒ ˆ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.
        Nzfoo.barc                    s0   | \}}}ˆ  | ¡ ˆ  ¡ ¡ ˆ |ˆ@ ¡ d S r
   )ÚassertEqualÚasBytesModeÚ
assertTrue©ÚresultÚwatchÚfilenameÚevents)ÚexpectedPathÚmaskr   r   r   Ú
cbNotifiedK   s   
z2INotifyTests._notificationTest.<locals>.cbNotifiedc                     ó
   ˆ   | ¡S r
   ©Úcallback©Úargs©Únotifiedr   r   Ú<lambda>S   ó   
 z0INotifyTests._notificationTest.<locals>.<lambda>©r(   Ú	callbacks)r   Úchildr   ÚDeferredÚaddCallbackr   r$   )r   r(   Ú	operationr'   r)   r   )r'   r(   r0   r   r   Ú_notificationTest4   s   
ÿzINotifyTests._notificationTestc                 C   ó   dd„ }|   tj|¡S )z{
        Reading from a file in a monitored directory sends an
        C{inotify.IN_ACCESS} event to the callback.
        c                 S   s   |   d¡ |  ¡  d S )Nó   foo)Ú
setContentZ
getContent©Úpathr   r   r   r8   ^   s   
z+INotifyTests.test_access.<locals>.operationN)r9   r   Ú	IN_ACCESS©r   r8   r   r   r   Útest_accessX   ó   zINotifyTests.test_accessc                 C   r:   )zy
        Writing to a file in a monitored directory sends an
        C{inotify.IN_MODIFY} event to the callback.
        c                 S   s:   |   d¡�}| d¡ W d   ƒ d S 1 sw   Y  d S )NÚwr;   )ÚopenÚwrite)r>   ZfObjr   r   r   r8   j   s   "ÿz+INotifyTests.test_modify.<locals>.operationN)r9   r   Z	IN_MODIFYr@   r   r   r   Útest_modifyd   rB   zINotifyTests.test_modifyc                 C   r:   )z‡
        Changing the metadata of a file in a monitored directory
        sends an C{inotify.IN_ATTRIB} event to the callback.
        c                 S   s   |   ¡  |   ¡  d S r
   )Útouchr=   r   r   r   r8   v   ó   z+INotifyTests.test_attrib.<locals>.operationN)r9   r   Z	IN_ATTRIBr@   r   r   r   Útest_attribp   rB   zINotifyTests.test_attribc                 C   r:   )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                 S   ó   |   d¡ ¡  d S ©NrC   ©rD   Úcloser=   r   r   r   r8   ƒ   ó   z/INotifyTests.test_closeWrite.<locals>.operationN)r9   r   ÚIN_CLOSE_WRITEr@   r   r   r   Útest_closeWrite|   s   zINotifyTests.test_closeWritec                 C   r:   )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                 S   s   |   ¡  |  d¡ ¡  d S )NÚr)rG   rD   rM   r=   r   r   r   r8   �   s   z1INotifyTests.test_closeNoWrite.<locals>.operationN)r9   r   ZIN_CLOSE_NOWRITEr@   r   r   r   Útest_closeNoWriteˆ   s   zINotifyTests.test_closeNoWritec                 C   r:   )zt
        Opening a file in a monitored directory sends an
        C{inotify.IN_OPEN} event to the callback.
        c                 S   rJ   rK   rL   r=   r   r   r   r8   ›   rN   z)INotifyTests.test_open.<locals>.operationN)r9   r   ÚIN_OPENr@   r   r   r   Ú	test_open•   ó   zINotifyTests.test_openc                    ó   ‡ fdd„}ˆ   tj|¡S )z}
        Moving a file out of a monitored directory sends an
        C{inotify.IN_MOVED_FROM} event to the callback.
        c                    s&   |   d¡ ¡  |  t ˆ  ¡ ¡¡ d S rK   )rD   rM   ÚmoveTor   r   r   r=   r   r   r   r8   ¦   s   z.INotifyTests.test_movedFrom.<locals>.operationN)r9   r   ZIN_MOVED_FROMr@   r   r   r   Útest_movedFrom    s   zINotifyTests.test_movedFromc                    rV   )zy
        Moving a file into a monitored directory sends an
        C{inotify.IN_MOVED_TO} event to the callback.
        c                    s$   t  ˆ  ¡ ¡}| ¡  | | ¡ d S r
   )r   r   r   rG   rW   )r>   Úpr   r   r   r8   ²   s   z,INotifyTests.test_movedTo.<locals>.operationN)r9   r   ZIN_MOVED_TOr@   r   r   r   Útest_movedTo¬   s   zINotifyTests.test_movedToc                 C   r:   )zw
        Creating a file in a monitored directory sends an
        C{inotify.IN_CREATE} event to the callback.
        c                 S   rJ   rK   rL   r=   r   r   r   r8   ¿   rN   z+INotifyTests.test_create.<locals>.operationN)r9   r   Ú	IN_CREATEr@   r   r   r   Útest_create¹   rU   zINotifyTests.test_createc                 C   r:   )zw
        Deleting a file in a monitored directory sends an
        C{inotify.IN_DELETE} event to the callback.
        c                 S   s   |   ¡  |  ¡  d S r
   )rG   Úremover=   r   r   r   r8   Ê   rH   z+INotifyTests.test_delete.<locals>.operationN)r9   r   Z	IN_DELETEr@   r   r   r   Útest_deleteÄ   rB   zINotifyTests.test_deletec                 C   s   dd„ }| j tj|| jd�S )z{
        Deleting the monitored directory itself sends an
        C{inotify.IN_DELETE_SELF} event to the callback.
        c                 S   s   |   ¡  d S r
   )r]   r=   r   r   r   r8   Ö   s   z/INotifyTests.test_deleteSelf.<locals>.operation©r'   N)r9   r   ÚIN_DELETE_SELFr   r@   r   r   r   Útest_deleteSelfÐ   s   
ÿzINotifyTests.test_deleteSelfc                    sJ   ‡fdd„}ˆj jˆjd‡ fdd„gd� t ¡ ‰ ˆ  |¡ ˆ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                    s4   | \}}}ˆ   | ¡ ˆ j ¡ ¡ ˆ  |tj@ ¡ d S r
   )r   r    r   r!   r   r`   r"   r   r   r   r)   ä   s   
z6INotifyTests.test_deleteSelfForced.<locals>.cbNotifiedr   c                     r*   r
   r+   r-   )Údr   r   r1   ê   r2   z4INotifyTests.test_deleteSelfForced.<locals>.<lambda>r3   N)r   r$   r   r   r6   r7   r]   ©r   r)   r   ©rb   r   r   Útest_deleteSelfForcedÝ   s   ÿ

z"INotifyTests.test_deleteSelfForcedc                    s    ‡ fdd„}ˆ j tj|ˆ jd�S )zy
        Renaming the monitored directory itself sends an
        C{inotify.IN_MOVE_SELF} event to the callback.
        c                    s   |   t ˆ  ¡ ¡¡ d S r
   )rW   r   r   r   r=   r   r   r   r8   ù   s   z-INotifyTests.test_moveSelf.<locals>.operationr_   N)r9   r   ZIN_MOVE_SELFr   r@   r   r   r   Útest_moveSelfó   s   
ÿzINotifyTests.test_moveSelfc                    óT   ‡ ‡‡fdd„}t jt jB }ˆj jˆj|d|gd� ˆj d¡‰t ¡ ‰ ˆ ¡  ˆ S )zŒ
        L{inotify.INotify} when initialized with autoAdd==True adds
        also adds the created subdirectories to the watchlist.
        c                    ó    ‡ ‡‡fdd„}t  d|¡ d S )Nc                      ó@   zˆ  ˆj ˆ¡¡ ˆ  d ¡ W d S  ty   ˆ  ¡  Y d S w r
   )r!   r   Ú
_isWatchedr,   Ú	ExceptionÚerrbackr   ©rb   r   Úsubdirr   r   Ú_	  ó   ÿzIINotifyTests.test_simpleSubdirectoryAutoAdd.<locals>._callback.<locals>._r   ©r   Ú	callLater)Úwpr%   r(   ro   rm   r   r   Ú	_callback  ó   z>INotifyTests.test_simpleSubdirectoryAutoAdd.<locals>._callbackT©r(   ÚautoAddr4   ÚtestN©	r   ÚIN_ISDIRr[   r$   r   r5   r   r6   r   ©r   rt   Ú	checkMaskr   rm   r   Útest_simpleSubdirectoryAutoAdd   ó   ÿz+INotifyTests.test_simpleSubdirectoryAutoAddc                    sZ   g ‰ ‡ ‡‡‡fdd„}t jt jB }ˆj jˆj|d|gd� ˆj d¡‰t ¡ ‰ˆ ¡  ˆS )zz
        L{inotify.INotify} removes a directory from the watchlist when
        it's removed from the filesystem.
        c                    sN   ‡‡‡fdd„}‡‡‡fdd„}ˆ sˆ   |¡ t d|¡ d S t d|¡ d S )Nc                      s>   zˆ  ˆj ˆ¡¡ ˆ ¡  W d S  ty   ˆ  ¡  Y d S w r
   )r!   r   rj   r]   rk   rl   r   rm   r   r   ro   %  s   ÿzEINotifyTests.test_simpleDeleteDirectory.<locals>._callback.<locals>._c                      ri   r
   ©ÚassertFalser   rj   r,   rk   rl   r   rm   r   r   Ú_eb,  s   ÿzGINotifyTests.test_simpleDeleteDirectory.<locals>._callback.<locals>._ebr   )Úappendr   rr   )rs   r%   r(   ro   r�   ©Úcallsrb   r   rn   r   r   rt   "  s   
z:INotifyTests.test_simpleDeleteDirectory.<locals>._callbackTrv   rx   Nry   r{   r   rƒ   r   Útest_simpleDeleteDirectory  s   ÿz'INotifyTests.test_simpleDeleteDirectoryc                    s\   ‡ ‡fdd„}ˆ  ˆjjˆjtj‡fdd„gd�¡ t ¡ ‰ˆ |¡ ˆj ¡  t ¡ ‰ ˆ S )zš
        L{inotify.INotify} closes the file descriptor after removing a
        directory from the filesystem (and therefore from the watchlist).
        c                    sN   ‡ ‡fdd„}| \}}}ˆ  | ¡ ˆj ¡ ¡ ˆ |tj@ ¡ t d|¡ d S )Nc                      sP   zˆ  ˆj ˆj¡¡ ˆ  ˆjj¡ ˆ  d ¡ W d S  ty'   ˆ  ¡  Y d S w r
   )r€   r   rj   r   Ú	connectedr,   rk   rl   r   rd   r   r   ro   L  s   ÿzIINotifyTests.test_deleteSelfLoseConnection.<locals>.cbNotified.<locals>._r   )r   r    r   r!   r   r`   r   rr   )r#   ro   Úignoredr%   r&   rd   r   r   r)   K  s
   
z>INotifyTests.test_deleteSelfLoseConnection.<locals>.cbNotifiedc                     r*   r
   r+   r-   r/   r   r   r1   ]  r2   z<INotifyTests.test_deleteSelfLoseConnection.<locals>.<lambda>r3   N)	r!   r   r$   r   r`   r   r6   r7   r]   rc   r   )rb   r0   r   r   Útest_deleteSelfLoseConnectionE  s   ýÿ

z*INotifyTests.test_deleteSelfLoseConnectionc                 C   sL   | j j| jdd� |  | j  | j¡¡ | j  | j¡ |  | j  | j¡¡ dS )zR
        L{inotify.INotify.ignore} removes a directory from the watchlist
        T)rw   N)r   r$   r   r!   rj   Úignorer€   r   r   r   r   Útest_ignoreDirectoryh  s   z!INotifyTests.test_ignoreDirectoryc                 C   sV   t jD ]\}}|  t  |¡d |¡ qt jt jB t jB }|  tt  |¡ƒh d£¡ dS )zy
        L{inotify.humaReadableMask} translates all the possible event
        masks to a human readable string.
        r   >   rD   ÚaccessZclose_writeN)r   Z_FLAG_TO_HUMANr   ZhumanReadableMaskrO   r?   rS   Úset)r   r(   Úvaluer|   r   r   r   Útest_humanReadableMaskq  s   þz#INotifyTests.test_humanReadableMaskc                 C   sv   | j  d¡}| d¡}| d¡}| ¡  |||g}| jj| j dd� | jj| j dd� |D ]}|  | j |¡¡ q-dS )zŽ
        L{inotify.INotify.watch} with recursive==True will add all the
        subdirectories under the given path to the watchlist.
        rx   Útest2Útest3T)Ú	recursiveN)r   r5   Úmakedirsr   r$   r!   rj   )r   rn   Úsubdir2Úsubdir3Údirsrb   r   r   r   Útest_recursiveWatch  s   


ÿz INotifyTests.test_recursiveWatchc                 C   s0   ddl }t ¡ }| |j¡ | ¡  |  ¡  dS )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   rM   Z_fdr   ZflushLoggedErrors)r   r—   Zin_r   r   r   Útest_connectionLostError�  s
   z%INotifyTests.test_connectionLostErrorc                    rg   )z”
        L{inotify.INotify.watch} with autoAdd==False will stop inotify
        from watching subdirectories created under the watched one.
        c                    rh   )Nc                      ri   r
   r   r   rm   r   r   ro   ¤  rp   zEINotifyTests.test_noAutoAddSubdirectory.<locals>._callback.<locals>._r   rq   )rs   Úfpr(   ro   rm   r   r   rt   ¡  ru   z:INotifyTests.test_noAutoAddSubdirectory.<locals>._callbackFrv   rx   Nry   r{   r   rm   r   Útest_noAutoAddSubdirectory›  r~   z'INotifyTests.test_noAutoAddSubdirectoryc                    sŒ   ˆj  d¡‰ ˆ  ¡  t ¡ ‰‡ ‡fdd„}‡fdd„}ˆ ˆjjˆ |gd�¡ ˆj ˆ ¡ ˆ ˆjjˆ tj	|gd�¡ ˆ 
|¡ ˆ  ¡  ˆ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                    ó2   | \}}}ˆ  | ¡ ˆ  ¡ ¡ ˆ |tj@ ¡ d S r
   ©r   r    r!   r   r`   ©r#   r‡   r%   r&   )r'   r   r   r   r)   À  ó   
z<INotifyTests.test_seriesOfWatchAndIgnore.<locals>.cbNotifiedc                     ó   ˆ   | ¡ d S r
   r+   r-   r/   r   r   ÚcallItÅ  ó   z8INotifyTests.test_seriesOfWatchAndIgnore.<locals>.callIt©r4   r3   N)r   r5   rG   r   r6   r!   r   r$   r‰   r`   r7   r]   )r   r)   r¡   r   )r'   r0   r   r   Útest_seriesOfWatchAndIgnore¶  s   
ÿÿ
z(INotifyTests.test_seriesOfWatchAndIgnorec                    s¬   ˆj  d¡}| ¡  ˆj  d¡‰ ˆ  ¡  t ¡ ‰‡ ‡fdd„}‡fdd„}ˆ ˆjj|tj|gd�¡ ˆ 	|¡ ˆ ˆjjˆ tj|gd�¡ ˆj 
|¡ | ¡  ˆ  ¡  ˆS )	zr
        L{inotify.INotify} will ignore a filepath after it has been removed from
        the watch list.
        r›   zfoo.bar3c                    rœ   r
   r�   rž   )ÚexpectedPath2r   r   r   r)   ç  rŸ   z4INotifyTests.test_ignoreFilePath.<locals>.cbNotifiedc                     r    r
   r+   r-   r/   r   r   r¡   ì  r¢   z0INotifyTests.test_ignoreFilePath.<locals>.callItr£   N)r   r5   rG   r   r6   r!   r   r$   r`   r7   r‰   r]   )r   r'   r)   r¡   r   )r¥   r0   r   r   Útest_ignoreFilePathÛ  s(   ÿ

ÿÿz INotifyTests.test_ignoreFilePathc                 C   s*   | j  d¡}| ¡  |  t| jj|¡ dS )zf
        L{inotify.INotify} will raise KeyError if a non-watched filepath is
        ignored.
        zfoo.ignoredN)r   r5   rG   r   ÚKeyErrorr   r‰   )r   r'   r   r   r   Útest_ignoreNonWatchedFile  s   z&INotifyTests.test_ignoreNonWatchedFilec                    sº   t ƒ ‰ ‡ ‡‡‡‡‡‡fdd„}tjtjB }ˆjjˆj|d|gd� ˆj d¡‰ˆ d¡‰ˆ d¡‰t ¡ ‰ˆ 	¡  ˆ d¡ˆ d	¡ˆ d
¡g‰t
ˆƒD ]\}}| |j t ¡ ¡¡ qKˆ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                    s¼   ˆ   |¡ tˆ ƒdkr\z;ˆ ˆj ˆ¡¡ ˆ ˆj ˆ¡¡ ˆ ˆj ˆ¡¡ ˆˆˆˆg }dd„ |D ƒ}ˆ tˆ ƒt|ƒ¡ ˆ ˆ |¡ W n tyT   ˆ ¡  Y d S w ˆ d ¡ d S d S )Né   c                 S   s   h | ]}|  ¡ ’qS r   )r    )Ú.0Úfr   r   r   Ú	<setcomp>  s    zRINotifyTests.test_complexSubdirectoryAutoAdd.<locals>._callback.<locals>.<setcomp>)	ÚaddÚlenr!   r   rj   r   rk   rl   r,   )rs   r%   r(   Úcreated©r„   rb   r   Z	someFilesrn   r“   r”   r   r   rt     s   
ÿôz?INotifyTests.test_complexSubdirectoryAutoAdd.<locals>._callbackTrv   rx   r�   r�   z	file1.datz	file2.datz	file3.datN)rŒ   r   rz   r[   r$   r   r5   r   r6   r’   Ú	enumerater<   r>   ÚencodeÚsysÚgetfilesystemencoding)r   rt   r|   Úir%   r   r°   r   Útest_complexSubdirectoryAutoAdd  s$   	ÿ

ýz,INotifyTests.test_complexSubdirectoryAutoAddr
   )$r   r   r   Ú__doc__r   ÚplatformZsupportsINotifyÚskipr   r   r9   rA   rF   rI   rP   rR   rT   rX   rZ   r\   r^   ra   re   rf   r}   r…   rˆ   rŠ   rŽ   r–   r˜   rš   r¤   r¦   r¨   r¶   r   r   r   r   r	      s@    

$*#	%&
r	   )r·   r³   Ztwisted.internetr   r   Ztwisted.pythonr   r   Ztwisted.python.reflectr   Ztwisted.trialr   r   ZTestCaser	   r   r   r   r   Ú<module>   s   