o
    ¯bÃ+  ã                   @   s¶   U d Z ddlZddlZddlZddlmZ ee ed< zddlZW n e	y,   dZ
Y n	w ddlmZ dZ
ddlmZ G dd	„ d	ƒZG d
d„ dƒZG dd„ deƒZG dd„ deƒZdS )z;
Tests for POSIX-based L{IReactorProcess} implementations.
é    N)ÚOptionalÚplatformSkipznon-POSIX platform)Úprocess)ÚTestCasec                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚFakeFilez>
    A dummy file object which records when it is closed.
    c                 C   s   || _ || _d S ©N)ÚtestcaseÚfd)Úselfr   r	   © r   úI/usr/lib/python3/dist-packages/twisted/internet/test/test_posixprocess.pyÚ__init__    s   
zFakeFile.__init__c                 C   s   | j j | j¡ d S r   )r   Ú_filesÚremover	   ©r
   r   r   r   Úclose$   s   zFakeFile.closec                 C   s   | S r   r   r   r   r   r   Ú	__enter__'   s   zFakeFile.__enter__c                 C   s   |   ¡  d S r   )r   )r
   Úexc_typeÚ	exc_valueÚ	tracebackr   r   r   Ú__exit__*   s   zFakeFile.__exit__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r   r      s    r   c                   @   s$   e Zd ZdZdZdd„ Zdd„ ZdS )ÚFakeResourceModulez¹
    Fake version of L{resource} which hard-codes a particular rlimit for maximum
    open files.

    @ivar _limit: The value to return for the hard limit of number of open files.
    é   c                 C   s
   || _ d S r   )Ú_limit©r
   Úlimitr   r   r   r   8   s   
zFakeResourceModule.__init__c                 C   s   || j kr
d| jgS ddgS )zX
        A fake of L{resource.getrlimit} which returns a pre-determined result.
        r   é{   iÈ  )ÚRLIMIT_NOFILEr   )r
   Únor   r   r   Ú	getrlimit;   s   

zFakeResourceModule.getrlimitN)r   r   r   r   r!   r   r#   r   r   r   r   r   .   s
    r   c                   @   s�   e Zd ZdZeZdZdZ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S ) ÚFDDetectorTestsaë  
    Tests for _FDDetector class in twisted.internet.process, which detects
    which function to drop in place for the _listOpenFDs method.

    @ivar devfs: A flag indicating whether the filesystem fake will indicate
        that /dev/fd exists.

    @ivar accurateDevFDResults: A flag indicating whether the /dev/fd fake
        returns accurate open file information.

    @ivar procfs: A flag indicating whether the filesystem fake will indicate
        that /proc/<pid>/fd exists.
    Fc                 C   s   dS )z>
        Fake os.getpid, always return the same thing
        r    r   r   r   r   r   ÚgetpidZ   s   zFDDetectorTests.getpidc                 C   sN   t t| jƒ}| jr|d|  ¡ f kr|S | jr$|dkr$| jr |S g d¢S tƒ ‚)z„
        Fake os.listdir, depending on what mode we're in to simulate behaviour.

        @param arg: the directory to list
        z/proc/%d/fdz/dev/fd)Ú0Ú1Ú2)ÚmapÚstrr   Úprocfsr%   ÚdevfsÚaccurateDevFDResultsÚOSError)r
   ÚargÚaccurater   r   r   Úlistdir`   s   zFDDetectorTests.listdirc                 C   s2   t | tttdƒƒt| jƒ ƒƒ}| j |j¡ |S )aO  
        This is a mock for L{open}.  It keeps track of opened files so extra
        descriptors can be returned from the mock for L{os.listdir} when used on
        one of the list-of-filedescriptors directories.

        A L{FakeFile} is returned which can be closed to remove the new
        descriptor from the open list.
        é   )r   ÚminÚsetÚranger   Úappendr	   )r
   ÚfnameÚmodeÚfr   r   r   Úopenfileo   s    
zFDDetectorTests.openfilec                 C   s   dt jd< dS )zp
        Make the L{resource} module unimportable for the remainder of the
        current test method.
        NÚresource)ÚsysÚmodulesr   r   r   r   ÚhideResourceModule}   s   z"FDDetectorTests.hideResourceModulec                 C   s   t |ƒtjd< dS )a  
        Make a L{FakeResourceModule} instance importable at the L{resource}
        name.

        @param limit: The value which will be returned for the hard limit of
            number of open files by the fake resource module's C{getrlimit}
            function.
        r;   N)r   r<   r=   r   r   r   r   ÚrevealResourceModule„   s   	z$FDDetectorTests.revealResourceModulec                 C   s:   |du rzt jd= W dS  ty   Y dS w |t jd< dS )zI
        Restore the original resource module to L{sys.modules}.
        Nr;   )r<   r=   ÚKeyError)r
   Úvaluer   r   r   ÚreplaceResourceModule�   s   ÿz%FDDetectorTests.replaceResourceModulec                 C   sL   t  ¡ | _| j| j_| j| j_| j| j_g d¢| _|  | jt	j
 d¡¡ dS )zž
        Set up the tests, giving ourselves a detector object to play with and
        setting up its testable knobs to refer to our mocked versions.
        ©r   r   é   r;   N)r   Ú_FDDetectorÚdetectorr1   r%   r:   r   Ú
addCleanuprB   r<   r=   Úgetr   r   r   r   ÚsetUp›   s   




zFDDetectorTests.setUpc                    s@   dd„ }dd„ }‡ fdd„}|||gˆ j _ˆ  |ˆ j  ¡ ¡ dS )zÁ
        L{FDDetector._getImplementation} returns the first method from its
        C{_implementations} list which returns results which reflect a newly
        opened file descriptor.
        c                   S   s   t dƒ‚)NzThis does not work)Ú
ValueErrorr   r   r   r   ÚfailWithException®   ó   zBFDDetectorTests.test_selectFirstWorking.<locals>.failWithExceptionc                   S   ó   g d¢S ©NrC   r   r   r   r   r   ÚfailWithWrongResults±   rL   zEFDDetectorTests.test_selectFirstWorking.<locals>.failWithWrongResultsc                      s   ˆ j d d … S r   )r   r   r   r   r   Úcorrect´   s   z8FDDetectorTests.test_selectFirstWorking.<locals>.correctN©rF   Ú_implementationsÚassertIsÚ_getImplementation)r
   rK   rO   rP   r   r   r   Útest_selectFirstWorking§   s   ýz'FDDetectorTests.test_selectFirstWorkingc                 C   s2   dd„ }dd„ }||g| j _|  || j  ¡ ¡ dS )zâ
        L{FDDetector._getImplementation} returns the last method from its
        C{_implementations} list if none of the implementations manage to return
        results which reflect a newly opened file descriptor.
        c                   S   rM   )N)é   é   é	   r   r   r   r   r   rO   Æ   rL   z=FDDetectorTests.test_selectLast.<locals>.failWithWrongResultsc                   S   rM   rN   r   r   r   r   r   ÚfailWithOtherWrongResultsÉ   rL   zBFDDetectorTests.test_selectLast.<locals>.failWithOtherWrongResultsNrQ   )r
   rO   rY   r   r   r   Útest_selectLast¿   s   þzFDDetectorTests.test_selectLastc                 C   sL   t  ¡ }|jj}| ¡  |jj}| ¡  |jj}|  ||¡ |  ||¡ dS )zä
        Check that the identity of _listOpenFDs changes after running
        _listOpenFDs the first time, but not after the second time it's run.

        In other words, check that the monkey patching actually works.
        N)r   rE   Ú_listOpenFDsr   ÚassertNotEqualÚassertEqual)r
   rF   ÚfirstÚsecondÚthirdr   r   r   Ú!test_identityOfListOpenFDsChangesÓ   s   z1FDDetectorTests.test_identityOfListOpenFDsChangesc                 C   s<   d| _ |  t| jj¡ d| _ d| _|  g d¢| j ¡ ¡ dS )zÈ
        L{_FDDetector._devFDImplementation} raises L{OSError} if there is no
        I{/dev/fd} directory, otherwise it returns the basenames of its children
        interpreted as integers.
        FTrC   N)r,   ÚassertRaisesr.   rF   Ú_devFDImplementationr-   r]   r   r   r   r   Útest_devFDImplementationæ   s
   z(FDDetectorTests.test_devFDImplementationc                 C   s6   d| _ |  t| jj¡ d| _ |  g d¢| j ¡ ¡ dS )zÐ
        L{_FDDetector._procFDImplementation} raises L{OSError} if there is no
        I{/proc/<pid>/fd} directory, otherwise it returns the basenames of its
        children interpreted as integers.
        FTrC   N)r+   rb   r.   rF   Ú_procFDImplementationr]   r   r   r   r   Útest_procFDImplementationò   s   z)FDDetectorTests.test_procFDImplementationc                 C   sT   |   d¡ |  ttdƒƒt| j ¡ ƒ¡ |   d¡ |  ttdƒƒt| j ¡ ƒ¡ dS )z×
        L{_FDDetector._fallbackFDImplementation} uses the L{resource} module if
        it is available, returning a range of integers from 0 to the
        minimum of C{1024} and the hard I{NOFILE} limit.
        i   i   r2   N)r?   r]   Úlistr5   rF   Ú_fallbackFDImplementationr   r   r   r   Útest_resourceFDImplementationý   s   
ÿ
ÿz-FDDetectorTests.test_resourceFDImplementationc                 C   s*   |   ¡  |  ttdƒƒt| j ¡ ƒ¡ dS )zÔ
        L{_FDDetector._fallbackFDImplementation}, the implementation of last
        resort, succeeds with a fixed range of integers from 0 to 1024 when the
        L{resource} module is not importable.
        r2   N)r>   r]   rg   r5   rF   rh   r   r   r   r   Útest_fallbackFDImplementation  s   ÿz-FDDetectorTests.test_fallbackFDImplementationN)r   r   r   r   r   Úskipr,   r-   r+   r%   r1   r:   r>   r?   rB   rI   rU   rZ   ra   rd   rf   ri   rj   r   r   r   r   r$   D   s(    r$   c                   @   s$   e Zd ZdZeZdd„ Zdd„ ZdS )ÚFileDescriptorTestsz<
    Tests for L{twisted.internet.process._listOpenFDs}
    c                 C   sd   t  ¡ D ]+}z	t |tj¡ W q ty/ } z|  tj|jd||jf ¡ W Y d}~qd}~ww dS )zµ
        File descriptors returned by L{_listOpenFDs} are mostly open.

        This test assumes that zero-legth writes fail with EBADF on closed
        file descriptors.
        z2fcntl(%d, F_GETFL) failed with unexpected errno %dN)r   r[   ÚfcntlÚF_GETFLr.   r]   ÚerrnoÚEBADF)r
   r	   Úerrr   r   r   Útest_openFDs"  s   ÿý€ÿýz FileDescriptorTests.test_openFDsc              	   C   sŒ   t tjƒ}t ¡ }|  | ¡ |¡ t | ¡ ¡}|  || ¡ kd¡ z| 	¡  |  |t ¡ ¡ W t 	|¡ nt 	|¡ w |  
|t ¡ ¡ dS )zB
        L{_listOpenFDs} lists expected file descriptors.
        z>Expected duplicate file descriptor to be greater than originalN)ÚopenÚosÚdevnullr   r[   ÚassertInÚfilenoÚdupÚ
assertTruer   ÚassertNotIn)r
   r9   Úopenfdsr	   r   r   r   Útest_expectedFDs4  s   

þz$FileDescriptorTests.test_expectedFDsN)r   r   r   r   r   rk   rr   r|   r   r   r   r   rl     s
    rl   )r   ro   rt   r<   Útypingr   r*   Ú__annotations__rm   ÚImportErrorr   Útwisted.internetr   Útwisted.trial.unittestr   r   r   r$   rl   r   r   r   r   Ú<module>   s&   ÿ X