o
    ¯b"(  ã                   @   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yG   dZY nw 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y¦   dZ-dZ.Y nw 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#   úB/usr/lib/python3/dist-packages/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 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 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def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…   ó   z'StartStopProcessProtocol.connectionMadec                 C   ó   |  j |7  _ d S r   )rG   ©r!   Údatar#   r#   r$   ÚoutReceivedˆ   rL   z$StartStopProcessProtocol.outReceivedc                 C   rM   r   )rH   rN   r#   r#   r$   ÚerrReceived‹   rL   z$StartStopProcessProtocol.errReceivedc                 C   s6   |  t¡r| j | j¡ d S | j t| j| jƒ¡ d S r   )Úcheckr   rF   rI   rG   Úerrbackr8   rH   )r!   Úreasonr#   r#   r$   ÚprocessEndedŽ   s   
z%StartStopProcessProtocol.processEndedN)	r1   r2   r3   r4   r%   rK   rP   rQ   rU   r#   r#   r#   r$   rD   o   s    rD   c                 C   s‚   t tjƒ ¡ j}ttjƒ}t t 	tj¡ƒ ¡ j|d< t
ƒ }tj|||t tƒ | d ¡ ¡ jd|f g|dddddd||i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   %dr   r6   é   r5   é   )ÚenvÚchildFDs)r   ÚsysÚ
executableÚ
asTextModeÚpathÚdictÚosÚenvironr   r<   rD   r   ÚspawnProcessÚ__file__Úsibling)ÚscriptÚoutputFDÚpyExerY   Ússppr#   r#   r$   Ú_spawn•   s   

ý÷ri   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)rk   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©	rk   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.
        rn   )r   r   s   0123r   Nro   rt   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)	rq   Úlenr   rk   r   rG   rO   ÚflagsÚ	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)rk   Úsetblockingr   Ú
assertTruery   r   rG   rq   )r!   r|   ÚsentÚ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.
        rx   r   N)r   rk   r   rG   rq   r@   r#   r#   r$   Útest_roundtripEmptyAncillaryó   s   
z)SendmsgTests.test_roundtripEmptyAncillaryz7MSG_DONTWAIT is only known to work as intended on Linuxc                 C   sl   t dƒD ]*}z
t| jdtd W q ty. } z|  |jd tj¡ W Y d}~ dS d}~ww |  	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    r~   )rz   r   NzHFailed to fill up the send buffer, or maybe send1msg blocked for a while)
Úranger   rk   r   ÚOSErrorrq   r>   rr   ÚEAGAINÚ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 d  ƒ n1 s;w   Y  |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}.
        Úpullpipes   blonkr‹   Nr   s   Test fixture data: blonk.
r;   )ri   rG   r'   rE   r7   Ú
addCleanupr   r   rk   r   r   r   rF   rq   r   )r!   rh   ÚpipeOutÚpipeInr#   r#   r$   Útest_sendSubProcessFD  s    €
ýÿz"SendmsgTests.test_sendSubProcessFDN)r1   r2   r3   r4   rl   rm   rv   rw   r}   r…   r†   r   ÚdontWaitSkipr   r   r’   r#   r#   r#   r$   rj   ±   s    	

rj   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!   ÚaddressFamilyÚsr#   r#   r$   Ú_socket3  s   zGetSocketFamilyTests._socketc                 C   ó   |   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)rq   r   r   r—   r&   r#   r#   r$   Ú	test_inet=  ó   zGetSocketFamilyTests.test_inetc                 C   r˜   )zš
        When passed the file descriptor of a socket created with the
        C{AF_INET6} address family, L{getSocketFamily} returns C{AF_INET6}.
        N)rq   r   r   r—   r&   r#   r#   r$   Ú
test_inet6D  rš   zGetSocketFamilyTests.test_inet6z)Platform does not support AF_UNIX socketsc                 C   r˜   )z˜
        When passed the file descriptor of a socket created with the C{AF_UNIX}
        address family, L{getSocketFamily} returns C{AF_UNIX}.
        N)rq   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   rr   r`   r[   r(   r   r   r   r   r
   r   r   r   r	   Ústructr   r   r   ÚImportErrorr   Úunittestr   Útwisted.internetr   Útwisted.internet.deferr   r   Útwisted.internet.errorr   Útwisted.internet.protocolr   Útwisted.python.filepathr   Útwisted.python.runtimer   Útwisted.trial.unittestr   ÚisLinuxr   r“   Útwisted.python.sendmsgr   r   r   r   ÚdoImportSkipÚimportSkipReasonr   r7   Ú	Exceptionr8   rD   ri   rj   r”   r#   r#   r#   r$   Ú<module>   sV   ÿþ%&{