U
    P|j(  ã                   @   sÔ  d Z ddlZddlZddlZddlZddlmZmZmZmZ ddl	m
Z
mZmZmZm	Z	 ddlmZ zddl	mZmZ W n ek
r�   dZY nX dZdd	lmZ dd
lmZ ddlmZmZ ddlmZ ddlmZ ddlm Z  ddl!m"Z" ddl#m$Z$ e" %¡ �rddl	m&Z& dZ'ndZ'zddl(m)Z)m*Z*m+Z+m,Z, W n ek
�rT   dZ-dZ.Y n
X dZ-dZ.G dd„ dƒZ/dd„ Z0G dd„ de1ƒZ2G dd„ deƒZ3dd„ Z4ee-e.ƒG dd „ d e$ƒƒZ5ee-e.ƒG d!d"„ d"e$ƒƒZ6dS )#z&
Tests for L{twisted.python.sendmsg}.
é    N)ÚcloseÚpathsepÚpipeÚread)ÚAF_INETÚAF_INET6Ú
SOL_SOCKETÚerrorÚsocket)Úpack)ÚAF_UNIXÚ
socketpairTF)ÚskipIf)Úreactor)ÚDeferredÚinlineCallbacks)ÚProcessDone)ÚProcessProtocol)ÚFilePath)Úplatform)ÚTestCase)ÚMSG_DONTWAIT)Ú
SCM_RIGHTSÚgetSocketFamilyÚrecvmsgÚsendmsgz!Platform doesn't support sendmsg.Ú c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )Ú	_FDHolderzP
    A wrapper around a FD that will remember if it has been closed or not.
    c                 C   s
   || _ d S ©N©Ú_fd)ÚselfÚfd© r#   úD/tmp/pip-unpacked-wheel-audpp6lv/twisted/python/test/test_sendmsg.pyÚ__init__:   s    z_FDHolder.__init__c                 C   s   | j S )z/
        Return the fileno of this FD.
        r   ©r!   r#   r#   r$   Úfileno=   s    z_FDHolder.filenoc                 C   s   | j rt| j ƒ d| _ dS )zH
        Close the FD. If it's already been closed, do nothing.
        N)r    r   r&   r#   r#   r$   r   C   s    
z_FDHolder.closec                 C   s(   | j r$t d| j › d�t¡ |  ¡  dS )z>
        If C{self._fd} is unclosed, raise a warning.
        zFD z was not closed!N)r    ÚwarningsÚwarnÚResourceWarningr   r&   r#   r#   r$   Ú__del__K   s    z_FDHolder.__del__c                 C   s   | S r   r#   r&   r#   r#   r$   Ú	__enter__S   s    z_FDHolder.__enter__c                 C   s   |   ¡  d S r   )r   )r!   Úexc_typeÚ	exc_valueÚ	tracebackr#   r#   r$   Ú__exit__V   s    z_FDHolder.__exit__N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r%   r'   r   r+   r,   r0   r#   r#   r#   r$   r   5   s   r   c                  C   s   t ƒ \} }t| ƒt|ƒfS )zI
    Create a pipe, and return the two FDs wrapped in L{_FDHolders}.
    )r   r   )ÚrÚwr#   r#   r$   Ú	_makePipeZ   s    
r7   c                   @   s   e Zd ZdZedœdd„ZdS )ÚExitedWithStderrz,
    A process exited with some stderr.
    )Úreturnc                 C   s   d  dgt| jƒ ¡}t|ƒS )zY
        Dump the errors in a pretty way in the event of a subprocess traceback.
        ó   
ó    )ÚjoinÚlistÚargsÚrepr©r!   Úresultr#   r#   r$   Ú__str__g   s    zExitedWithStderr.__str__N)r1   r2   r3   r4   ÚstrrB   r#   r#   r#   r$   r8   b   s   r8   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚStartStopProcessProtocolaø  
    An L{IProcessProtocol} with a Deferred for events where the subprocess
    starts and stops.

    @ivar started: A L{Deferred} which fires with this protocol's
        L{IProcessTransport} provider when it is connected to one.

    @ivar stopped: A L{Deferred} which fires with the process output or a
        failure if the process produces output on standard error.

    @ivar output: A C{str} used to accumulate standard output.

    @ivar errors: A C{str} used to accumulate standard error.
    c                 C   s    t ƒ | _t ƒ | _d| _d| _d S )Nr;   )r   ÚstartedÚstoppedÚoutputÚerrorsr&   r#   r#   r$   r%      s    z!StartStopProcessProtocol.__init__c                 C   s   | j  | j¡ d S r   )rE   ÚcallbackÚ	transportr&   r#   r#   r$   ÚconnectionMade…   s    z'StartStopProcessProtocol.connectionMadec                 C   s   |  j |7  _ d S r   )rG   ©r!   Údatar#   r#   r$   ÚoutReceivedˆ   s    z$StartStopProcessProtocol.outReceivedc                 C   s   |  j |7  _ d S r   )rH   rL   r#   r#   r$   ÚerrReceived‹   s    z$StartStopProcessProtocol.errReceivedc                 C   s4   |  t¡r| j | j¡ n| j t| j| jƒ¡ d S r   )Úcheckr   rF   rI   rG   Zerrbackr8   rH   )r!   Úreasonr#   r#   r$   ÚprocessEndedŽ   s    
z%StartStopProcessProtocol.processEndedN)	r1   r2   r3   r4   r%   rK   rN   rO   rR   r#   r#   r#   r$   rD   o   s   rD   c              
   C   sv   t tjƒ ¡ j}ttjƒ}t t 	tj¡ƒ ¡ j|d< t
ƒ }tj|||t tƒ | d ¡ ¡ jdg|ddd|dœd� |S )zñ
    Start a script that is a peer of this test as a subprocess.

    @param script: the module name of the script in this directory (no
        package prefix, no '.py')
    @type script: C{str}

    @rtype: L{StartStopProcessProtocol}
    Ú
PYTHONPATHz.pys   17r6   r5   )r   é   é   é   )ÚenvZchildFDs)r   ÚsysÚ
executableZ
asTextModeÚpathÚdictÚosÚenvironr   r<   rD   r   ZspawnProcessÚ__file__Zsibling)ÚscriptZoutputFDZpyExerW   Ússppr#   r#   r$   Ú_spawn•   s    

ý÷ra   c                   @   sf   e 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
eedƒdd„ ƒZedd„ ƒZdS )ÚSendmsgTestszB
    Tests for the Python2/3 compatible L{sendmsg} interface.
    c                 C   s   t tƒ\| _| _dS )z0
        Create a pair of UNIX sockets.
        N)r   r   ÚinputrG   r&   r#   r#   r$   ÚsetUp·   s    zSendmsgTests.setUpc                 C   s   | j  ¡  | j ¡  dS )z4
        Close the sockets opened by setUp.
        N)rc   r   rG   r&   r#   r#   r$   ÚtearDown½   s    
zSendmsgTests.tearDownc                 C   s4   | j  ¡  |  tt| j d¡}|  |jd tj¡ dS )z—
        If the underlying C{sendmsg} call fails, L{send1msg} raises
        L{socket.error} with its errno set to the underlying errno value.
        ó   hello, worldr   N©	rc   r   ÚassertRaisesr	   r   ÚassertEqualr>   ÚerrnoÚEBADF©r!   Úexcr#   r#   r$   Útest_syscallErrorÄ   s    
zSendmsgTests.test_syscallErrorc                 C   s:   | j  ¡  |  tt| j ddgd¡}|  |jd tj¡ dS )z�
        The behavior when the underlying C{sendmsg} call fails is the same
        whether L{sendmsg} is passed ancillary data or not.
        rf   )r   r   s   0123r   Nrg   rl   r#   r#   r$   Ú#test_syscallErrorWithControlMessageÍ   s    
     ÿz0SendmsgTests.test_syscallErrorWithControlMessagec                 C   sT   d}|   t|ƒt| j|ƒ¡ t| jƒ}|   |jd¡ |   |jd¡ |   |jg ¡ dS )zI
        L{recvmsg} will retrieve a message sent via L{sendmsg}.
        ó   hello, world!r   N)	ri   Úlenr   rc   r   rG   rM   ÚflagsZ	ancillary)r!   ÚmessagerA   r#   r#   r$   Útest_roundtripØ   s    
zSendmsgTests.test_roundtripc                 C   s^   dd d }| j  d¡ t| j |ƒ}|  |t|ƒk ¡ t| jt|ƒƒ}|  t|d ƒ|¡ dS )zS
        L{sendmsg} returns the number of bytes which it was able to send.
        ó   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxé   é   Fr   N)rc   Úsetblockingr   Ú
assertTruerq   r   rG   ri   )r!   rs   ÚsentZreceivedr#   r#   r$   Útest_shortsendä   s    zSendmsgTests.test_shortsendc                 C   s0   t | jdg dƒ t| jƒ}|  |dg df¡ dS )z™
        L{sendmsg} treats an empty ancillary data list the same way it treats
        receiving no argument for the ancillary parameter at all.
        rp   r   N)r   rc   r   rG   ri   r@   r#   r#   r$   Útest_roundtripEmptyAncillaryó   s    
z)SendmsgTests.test_roundtripEmptyAncillaryz7MSG_DONTWAIT is only known to work as intended on Linuxc                 C   sr   t dƒD ]Z}zt| jdtd� W q tk
r` } z"|  |jd tj¡ W Y ¢ qnW 5 d}~X Y qX q|  	d¡ dS )z­
        The C{flags} argument to L{sendmsg} is passed on to the underlying
        C{sendmsg} call, to affect it in whatever way is defined by those
        flags.
        i    ru   )rr   r   NzHFailed to fill up the send buffer, or maybe send1msg blocked for a while)
Úranger   rc   r   ÚOSErrorri   r>   rj   ÚEAGAINZfail)r!   ÚiÚer#   r#   r$   Ú
test_flagsý   s    
ÿzSendmsgTests.test_flagsc              
   c   s¢   t d| j ¡ ƒ}|jV  tƒ \}}|  |j¡ |  |j¡ |�& t| jdt	t
td| ¡ ƒfgƒ W 5 Q R X |jV  |  t| ¡ dƒd¡ |  t| ¡ dƒd¡ dS )zî
        Calling L{sendmsg} with SOL_SOCKET, SCM_RIGHTS, and a platform-endian
        packed file descriptor number should send that file descriptor to a
        different process, where it can be retrieved by using L{recv1msg}.
        Zpullpipes   blonkr€   rv   s   Test fixture data: blonk.
r;   N)ra   rG   r'   rE   r7   Ú
addCleanupr   r   rc   r   r   r   rF   ri   r   )r!   r`   ZpipeOutZpipeInr#   r#   r$   Útest_sendSubProcessFD  s    
ýz"SendmsgTests.test_sendSubProcessFDN)r1   r2   r3   r4   rd   re   rn   ro   rt   r{   r|   r   ÚdontWaitSkipr‚   r   r„   r#   r#   r#   r$   rb   ±   s   	

rb   c                   @   s:   e Zd ZdZdd„ Zdd„ Zdd„ Zeedƒd	d
„ ƒZ	dS )ÚGetSocketFamilyTestsz'
    Tests for L{getSocketFamily}.
    c                 C   s   t |ƒ}|  |j¡ |S )zÃ
        Create a new socket using the given address family and return that
        socket's file descriptor.  The socket will automatically be closed when
        the test is torn down.
        )r
   rƒ   r   )r!   ZaddressFamilyÚsr#   r#   r$   Ú_socket3  s    zGetSocketFamilyTests._socketc                 C   s   |   tt|  t¡ƒ¡ dS )z˜
        When passed the file descriptor of a socket created with the C{AF_INET}
        address family, L{getSocketFamily} returns C{AF_INET}.
        N)ri   r   r   rˆ   r&   r#   r#   r$   Ú	test_inet=  s    zGetSocketFamilyTests.test_inetc                 C   s   |   tt|  t¡ƒ¡ dS )zš
        When passed the file descriptor of a socket created with the
        C{AF_INET6} address family, L{getSocketFamily} returns C{AF_INET6}.
        N)ri   r   r   rˆ   r&   r#   r#   r$   Ú
test_inet6D  s    zGetSocketFamilyTests.test_inet6z)Platform does not support AF_UNIX socketsc                 C   s   |   tt|  t¡ƒ¡ dS )z˜
        When passed the file descriptor of a socket created with the C{AF_UNIX}
        address family, L{getSocketFamily} returns C{AF_UNIX}.
        N)ri   r   r   rˆ   r&   r#   r#   r$   Ú	test_unixK  s    zGetSocketFamilyTests.test_unixN)
r1   r2   r3   r4   rˆ   r‰   rŠ   r   ÚnonUNIXSkipr‹   r#   r#   r#   r$   r†   -  s   
r†   )7r4   rj   r\   rX   r(   r   r   r   r   r
   r   r   r   r	   Ústructr   r   r   ÚImportErrorrŒ   Zunittestr   Ztwisted.internetr   Ztwisted.internet.deferr   r   Ztwisted.internet.errorr   Ztwisted.internet.protocolr   Ztwisted.python.filepathr   Ztwisted.python.runtimer   Ztwisted.trial.unittestr   ZisLinuxr   r…   Ztwisted.python.sendmsgr   r   r   r   ZdoImportSkipZimportSkipReasonr   r7   Ú	Exceptionr8   rD   ra   rb   r†   r#   r#   r#   r$   Ú<module>   sP   


%&{