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