U
    c6{iî™  ã                   @   s´  d Z ddlmZ ddlmZmZmZmZmZ ddl	m
Z
 ddlmZmZmZmZ ddlmZ ddlmZ ddl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 W n ek
rÈ   dZY nX eZddl m!Z!m"Z" ddl#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z* ddl+m,Z,m-Z-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8m9Z9m:Z: ddl;m<Z<m=Z=m>Z> ddl?m@Z@ ddlAmBZBmCZCmDZDmEZEmFZF ddlGmHZH ddlImJZJmKZKmLZLmMZMmNZN ddlOmPZP ddlQmRZR ddlSmTZT ddlUmVZVmWZWmXZX ddlYmZZZ ddl[m\Z\m]Z] ddl^m_Z_ dd l`maZa eZd!ƒZbd"ZceZd!ƒdk	�rDd#ZcG d$d%„ d%ƒZdd&d'„ ZeG d(d)„ d)eDƒZfG d*d+„ d+eBƒZge"e7ƒG d,d-„ d-eBƒƒZhG d.d/„ d/edeHeCƒZiG d0d1„ d1edeHƒZjG d2d3„ d3ƒZkG d4d5„ d5ƒZlG d6d7„ d7ƒZmG d8d9„ d9elemeHeMƒZnG d:d;„ d;ekemeHeMƒZoG d<d=„ d=eNeHƒZpeqƒ  rei s¡ ¡ eqƒ  rej s¡ ¡ eqƒ  ren s¡ ¡ eqƒ  reo s¡ ¡ eqƒ  rep s¡ ¡ G d>d?„ d?eHeEƒZteqƒ  ret s¡ ¡ ee]d@kdAƒG dBdC„ dCeaƒƒZudS )Dz/
Tests for implementations of L{IReactorUNIX}.
é    )Úmd5)ÚcloseÚfstatÚstatÚunlinkÚurandom)Úpformat)ÚAF_INETÚSOCK_STREAMÚ
SOL_SOCKETÚsocket)ÚS_IMODE)Úpack)ÚmkstempÚmktemp)ÚAnyÚCallableÚOptionalÚSequenceÚType)ÚskipIf)ÚAF_UNIXN)Ú	InterfaceÚimplementer)ÚbaseÚerrorÚ
interfacesÚreactorÚtcp)ÚUNIXAddress)ÚDeferredÚfailÚgatherResults)ÚUNIXClientEndpointÚUNIXServerEndpoint)ÚCannotListenErrorÚConnectionClosedÚFileDescriptorOverrun)ÚIFileDescriptorReceiverÚIReactorFDSetÚIReactorSocketÚIReactorUNIX)ÚClientFactoryÚDatagramProtocolÚServerFactory)ÚLoopingCall)ÚConnectableProtocolÚConnectionTestsMixinÚEndpointCreatorÚStreamClientTestsMixinÚrunProtocolsWithReactor)ÚReactorBuilder)ÚClosingFactoryÚMyClientFactoryÚMyServerFactoryÚStreamTransportTestsMixinÚWriteSequenceTestsMixin)ÚnativeString)ÚFailure)Ú_coerceToFilesystemEncoding)ÚaddObserverÚerrÚremoveObserver)ÚrequireModule)ÚplatformÚplatformType)ÚAccumulatingProtocol)ÚTestCaseztwisted.python.sendmsgÚ z>sendmsg extension unavailable, extended UNIX features disabledc                   @   s   e Zd ZdZdd„ ZdS )ÚUNIXFamilyMixinzK
    Test-helper defining mixin for things related to AF_UNIX sockets.
    c                 C   sB   d}|   ¡ }t||ƒ|||d�}| ¡  |  tt|ƒjƒ|¡ dS )z}
        Assert that the mode of the created unix socket is set to the mode
        specified to the reactor method.
        i€  )ÚmodeN)ÚbuildReactorÚgetattrÚstopListeningÚassertEqualr   r   Úst_mode)ÚselfÚ
methodNameÚpathÚfactoryrH   r   ZunixPort© rR   úC/tmp/pip-unpacked-wheel-hfbvu0bz/twisted/internet/test/test_unix.pyÚ	_modeTestR   s
    zUNIXFamilyMixin._modeTestN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rT   rR   rR   rR   rS   rG   M   s   rG   c                 C   s   t tdƒƒ ¡ S )zI
    Return a new, unique abstract namespace path to be listened on.
    éd   )r   r   Ú	hexdigest)ZcaserR   rR   rS   Ú_abstractPath^   s    r[   c                   @   s>   e Zd ZU dZejfZeee	e
   ed< dd„ Zdd„ ZdS )ÚUNIXCreatorz(
    Create UNIX socket end points.
    ÚrequiredInterfacesc                 C   s   t ddd�}t||ƒS )z3
        Construct a UNIX server endpoint.
        ú.sockÚ.©ÚsuffixÚdir)r   r$   )rN   r   rP   rR   rR   rS   Úserverl   s    zUNIXCreator.serverc                 C   s   t ||jƒS )z3
        Construct a UNIX client endpoint.
        )r#   Úname)rN   r   ZserverAddressrR   rR   rS   Úclientt   s    zUNIXCreator.clientN)rU   rV   rW   rX   r   r+   r]   r   r   r   r   Ú__annotations__rc   re   rR   rR   rR   rS   r\   e   s   
r\   c                   @   s,   e Zd ZdZdZdd„ Zdd„ Zdd„ ZdS )	ÚSendFileDescriptorzæ
    L{SendFileDescriptorAndBytes} sends a file descriptor and optionally some
    normal bytes and then closes its connection.

    @ivar reason: The reason the connection was lost, after C{connectionLost}
        is called.
    Nc                 C   s   || _ || _dS )zà
        @param fd: A C{int} giving a file descriptor to send over the
            connection.

        @param data: A C{str} giving data to send over the connection, or
            L{None} if no data is to be sent.
        N)ÚfdÚdata)rN   rh   ri   rR   rR   rS   Ú__init__†   s    zSendFileDescriptor.__init__c                 C   s0   | j  | j¡ | jr"| j  | j¡ | j  ¡  dS )zn
        Send C{self.fd} and, if it is not L{None}, C{self.data}.  Then close the
        connection.
        N)Ú	transportÚsendFileDescriptorrh   ri   ÚwriteÚloseConnection©rN   rR   rR   rS   ÚconnectionMade‘   s    z!SendFileDescriptor.connectionMadec                 C   s   t  | |¡ || _d S ©N)r0   ÚconnectionLostÚreason©rN   rs   rR   rR   rS   rr   ›   s    z!SendFileDescriptor.connectionLost)rU   rV   rW   rX   rs   rj   rp   rr   rR   rR   rR   rS   rg   {   s
   
rg   c                   @   s8   e Zd ZdZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Z	dS )ÚReceiveFileDescriptora}  
    L{ReceiveFileDescriptor} provides an API for waiting for file descriptors to
    be received.

    @ivar reason: The reason the connection was lost, after C{connectionLost}
        is called.

    @ivar waiting: A L{Deferred} which fires with a file descriptor once one is
        received, or with a failure if the connection is lost with no descriptor
        arriving.
    Nc                 C   s&   | j dkrtƒ | _| jS t| j ƒS dS )z¯
        Return a L{Deferred} which will fire with the next file descriptor
        received, or with a failure if the connection is or has already been
        lost.
        N)rs   r    Úwaitingr!   ro   rR   rR   rS   ÚwaitForDescriptor±   s    
z'ReceiveFileDescriptor.waitForDescriptorc                 C   s   | j  |¡ d| _ dS )z�
        Fire the waiting Deferred, initialized by C{waitForDescriptor}, with the
        file descriptor just received.
        N)rv   Úcallback)rN   Ú
descriptorrR   rR   rS   ÚfileDescriptorReceived½   s    z,ReceiveFileDescriptor.fileDescriptorReceivedc                 C   s0   | j dk	r,| j  ttd|›d�ƒƒ¡ d| _ dS )a_  
        Fail the waiting Deferred, if it has not already been fired by
        C{fileDescriptorReceived}.  The bytes sent along with a file descriptor
        are guaranteed to be delivered to the protocol's C{dataReceived} method
        only after the file descriptor has been delivered to the protocol's
        C{fileDescriptorReceived}.
        NzReceived bytes (z) before descriptor.)rv   Úerrbackr<   Ú	Exception©rN   ri   rR   rR   rS   ÚdataReceivedÅ   s
    
ÿz"ReceiveFileDescriptor.dataReceivedc                 C   s2   t  | |¡ | jdk	r(| j |¡ d| _|| _dS )zj
        Fail the waiting Deferred, initialized by C{waitForDescriptor}, if there
        is one.
        N)r0   rr   rv   r{   rs   rt   rR   rR   rS   rr   Ó   s
    
z$ReceiveFileDescriptor.connectionLost)
rU   rV   rW   rX   rs   rv   rw   rz   r~   rr   rR   rR   rR   rS   ru       s   ru   c                   @   s  e Zd ZdZefZeƒ Zdd„ Ze	e
 ¡  dƒdd„ ƒZdd„ Ze	e
 ¡  dƒd	d
„ ƒZdd„ Ze	e eƒdd„ ƒZe	e eƒdd„ ƒZe	e eƒdd„ ƒZdd„ Ze	e eƒdd„ ƒZe	e
 ¡ dƒe	e eƒdd„ ƒƒZe	e eƒdd„ ƒZe	e eƒdd„ ƒZe	e eƒdd„ ƒZd S )!ÚUNIXTestsBuilderz=
    Builder defining tests relating to L{IReactorUNIX}.
    c                 C   s   |   d|  ¡ tƒ ¡ dS )zs
        The UNIX socket created by L{IReactorUNIX.listenUNIX} is created with
        the mode specified.
        Ú
listenUNIXN)rT   r   r.   ro   rR   rR   rS   Ú	test_modeè   s    zUNIXTestsBuilder.test_modeú8Abstract namespace UNIX sockets only supported on Linux.c                 C   s>   t | ƒ}|  ¡ }| d| tƒ ¡}|  | ¡ td| ƒ¡ dS )zµ
        On Linux, a UNIX socket path may begin with C{' '} to indicate
        a socket in the abstract namespace.  L{IReactorUNIX.listenUNIX}
        accepts such a path.
        ú N)r[   rI   r€   r.   rL   ÚgetHostr   ©rN   rP   r   ÚportrR   rR   rS   Ú#test_listenOnLinuxAbstractNamespaceï   s    z4UNIXTestsBuilder.test_listenOnLinuxAbstractNamespacec              	   C   sH   dd„ }|   tjd|¡ |  ¡ }|  t¡� | dtƒ ¡ W 5 Q R X dS )z•
        L{IReactorUNIX.listenUNIX} raises L{CannotListenError} if the
        underlying port's createInternetSocket raises a socket error.
        c                 S   s   t dƒ‚d S )Nz FakeBasePort forced socket.error)ÚOSErrorro   rR   rR   rS   ÚraiseSocketError  s    z=UNIXTestsBuilder.test_listenFailure.<locals>.raiseSocketErrorZcreateInternetSocketznot-usedN)Úpatchr   ZBasePortrI   ÚassertRaisesr%   r€   r.   )rN   r‰   r   rR   rR   rS   Útest_listenFailureÿ   s
    z#UNIXTestsBuilder.test_listenFailurec                 C   s>   t | ƒ}|  ¡ }| d| tƒ ¡}|  | ¡ td| ƒ¡ dS )zc
        L{IReactorUNIX.connectUNIX} also accepts a Linux abstract namespace
        path.
        rƒ   N)r[   rI   ÚconnectUNIXr,   rL   ZgetDestinationr   )rN   rP   r   Z	connectorrR   rR   rS   Ú$test_connectToLinuxAbstractNamespace  s    	z5UNIXTestsBuilder.test_connectToLinuxAbstractNamespacec                 C   s`   G dd„ dt ƒ}|ƒ }|ƒ }t| ||| jƒ |  |jd |jd ¡ |  |jd |jd ¡ dS )z¾
        A client's transport's C{getHost} and C{getPeer} return L{UNIXAddress}
        instances which have the filesystem path of the host and peer ends of
        the connection.
        c                   @   s   e Zd Zdd„ ZdS )z4UNIXTestsBuilder.test_addresses.<locals>.SaveAddressc                 S   s"   t | ¡ | ¡ d�| _| ¡  d S )N)ÚhostÚpeer)Údictr„   ÚgetPeerÚ	addressesrn   )rN   rk   rR   rR   rS   ÚmakeConnection#  s
     ÿzCUNIXTestsBuilder.test_addresses.<locals>.SaveAddress.makeConnectionN)rU   rV   rW   r”   rR   rR   rR   rS   ÚSaveAddress"  s   r•   r�   r�   N)r0   r4   Ú	endpointsrL   r“   )rN   r•   rc   re   rR   rR   rS   Útest_addresses  s    zUNIXTestsBuilder.test_addressesc                    s„   ddl m‰  t ƒ ‰ˆ d¡ tˆ ¡ dƒ‰tƒ }| ¡ }‡ ‡‡fdd„}| |¡ | t	d¡ | 
‡fdd	„¡ tˆˆ|ˆjƒ d
S )z¤
        L{IUNIXTransport.sendFileDescriptor} accepts an integer file descriptor
        and sends a copy of it to the process reading from the connection.
        r   )Úfromfd)rF   r   ó   junkc                    s@   ˆ | t tƒ}t| ƒ ˆ ˆ ¡ | ¡ ¡ ˆ ˆ ¡ | ¡ ¡ d S rq   )r	   r
   r   rL   ÚgetsocknameZassertNotEqualÚfileno)ry   Zreceived)r˜   ÚsrN   rR   rS   ÚcheckDescriptor@  s    zAUNIXTestsBuilder.test_sendFileDescriptor.<locals>.checkDescriptorz-Sending file descriptor encountered a problemc                    s
   ˆ j  ¡ S rq   ©rk   rn   ©Zignored©rc   rR   rS   Ú<lambda>P  ó    z:UNIXTestsBuilder.test_sendFileDescriptor.<locals>.<lambda>N)r   r˜   Úbindrg   r›   ru   rw   ÚaddCallbackÚ
addErrbackr?   ÚaddBothr4   r–   )rN   re   Údr�   rR   )r˜   rœ   rN   rc   rS   Útest_sendFileDescriptor1  s    

z(UNIXTestsBuilder.test_sendFileDescriptorc                 C   sT   G dd„ dt ƒ}G dd„ dt ƒ}|ƒ }|ƒ }||_t| ||| jƒ |  |jd¡ dS )z…
        If a L{IUNIXTransport.sendFileDescriptor} call fills up
        the send buffer, any registered producer is paused.
        c                   @   s   e Zd Zdd„ ZdS )zSUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.DoesNotReadc                 S   s   | j  ¡  d S rq   )rk   ÚpauseProducingro   rR   rR   rS   rp   \  s    zbUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.DoesNotRead.connectionMadeN©rU   rV   rW   rp   rR   rR   rR   rS   ÚDoesNotRead[  s   r«   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 )z`UNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptorsFc                    sP   t ƒ ˆ _ ˆ j ˆ d¡ ‡ fdd„}t|ƒˆ _ˆ jjˆ j_ˆ j d¡ t	d¡ d S )NTc                      s"   ˆ j  ˆ j ¡ ¡ ˆ j  d¡ d S )Nó   x)rk   rl   r   r›   rm   rR   ro   rR   rS   Úsenderf  s    zUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMade.<locals>.senderr   zSend loop failure)
r   rk   ZregisterProducerr/   Útaskr   ZclockÚstartr¥   r?   )rN   r­   rR   ro   rS   rp   b  s    
zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMadec                 S   s   |   ¡  d S rq   ©Ú_disconnectro   rR   rR   rS   ÚstopProducingn  s    znUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.stopProducingc                 S   s   |   ¡  d S rq   r°   ro   rR   rR   rS   ÚresumeProducingq  s    zpUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.resumeProducingc                 S   s   d| _ | j ¡  |  ¡  d S )NT)Úpausedrk   ZunregisterProducerr±   ro   rR   rR   rS   r©   t  s    
zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.pauseProducingc                 S   s$   | j  ¡  | j ¡  | jj ¡  d S rq   )r®   Ústoprk   ZabortConnectionÚotherro   rR   rR   rS   r±   y  s    

zlUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors._disconnectN)	rU   rV   rW   r´   rp   r²   r³   r©   r±   rR   rR   rR   rS   ÚSendsManyFileDescriptors_  s   r·   z*sendFileDescriptor producer was not pausedN)r0   r¶   r4   r–   Ú
assertTruer´   )rN   r«   r·   rc   re   rR   rR   rS   Ú-test_sendFileDescriptorTriggersPauseProducingT  s    z>UNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducingc                    s†   t ƒ }t| ¡ dƒ‰ tƒ }g }| ¡ }| |j¡ | ‡ fdd„¡ t| ˆ || jƒ |  	|d t
¡ |d  t¡ |  	ˆ jjt¡ dS )ag  
        If L{IUNIXTransport.sendFileDescriptor} is used to queue a greater
        number of file descriptors than the number of bytes sent using
        L{ITransport.write}, the connection is closed and the protocol connected
        to the transport has its C{connectionLost} method called with a failure
        wrapping L{FileDescriptorOverrun}.
        Nc                    s
   ˆ j  ¡ S rq   rž   rŸ   r    rR   rS   r¡   •  r¢   z=UNIXTestsBuilder.test_fileDescriptorOverrun.<locals>.<lambda>r   )r   rg   r›   ru   rw   r¦   Úappendr4   r–   ÚassertIsInstancer<   Útrapr&   rs   Úvaluer'   )rN   Úcargore   Úresultr§   rR   r    rS   Útest_fileDescriptorOverrun…  s    	z+UNIXTestsBuilder.test_fileDescriptorOverrunc                    s>  ddl m} ddlm} ddlm} dd„ ‰ ttƒG ‡ fdd„dtƒƒ}G d	d
„ d
|ƒ}|t	t
ƒ\}}|  |j¡ |  |j¡ |ƒ }	|||	ƒ}
tƒ \}}tƒ \}}|  t|¡ |  t|¡ d}||g}||ƒ\}}||||ƒ |
 ¡  |  t|	jƒ|¡ |  t|ƒ t|	jƒ¡¡ |	j�r:‡ fdd„|D ƒ}|  ||	j¡ dS )a‰  
        Drive _SendmsgMixin via sendmsg socket calls to check that
        L{IFileDescriptorReceiver.fileDescriptorReceived} is called once
        for each file descriptor received in the ancillary messages.

        @param ancillaryPacker: A callable that will be given a list of
            two file descriptors and should return a two-tuple where:
            The first item is an iterable of zero or more (cmsg_level,
            cmsg_type, cmsg_data) tuples in the same order as the given
            list for actual sending via sendmsg; the second item is an
            integer indicating the expected number of FDs to be received.
        r   ©Ú
socketpair)Ú_SendmsgMixin©Úsendmsgc                 S   s   t | ƒ}|j|jfS rq   )r   Úst_devÚst_ino)rh   ÚfsrR   rR   rS   ÚdeviceInodeTuple¿  s    zTUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.deviceInodeTuplec                       s    e Zd Zdd„ Z‡ fdd„ZdS )zPUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocolc                 S   s   g | _ g | _d S rq   )ÚfdsÚdeviceInodesReceivedro   rR   rR   rS   rj   Å  s    zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.__init__c                    s(   | j  |¡ | j ˆ |ƒ¡ t|ƒ d S rq   )rÊ   rº   rË   r   )rN   rh   ©rÉ   rR   rS   rz   É  s    zgUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.fileDescriptorReceivedN)rU   rV   rW   rj   rz   rR   rÌ   rR   rS   ÚFakeProtocolÃ  s   rÍ   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 )zPUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiveré   c                 S   s   || _ || _d S rq   )r   Úprotocol)rN   ÚsktÚprotorR   rR   rS   rj   Ñ  s    zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.__init__c                 S   s   d S rq   rR   r}   rR   rR   rS   Ú_dataReceivedÕ  s    z^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._dataReceivedc                 S   s   d S rq   rR   ro   rR   rR   rS   r„   Ø  s    zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getHostc                 S   s   d S rq   rR   ro   rR   rR   rS   r’   Û  s    zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getPeerc                 S   s   d S rq   rR   )rN   ÚorR   rR   rS   Ú_getLogPrefixÞ  s    z^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._getLogPrefixN)	rU   rV   rW   Z
bufferSizerj   rÒ   r„   r’   rÔ   rR   rR   rR   rS   ÚFakeReceiverÎ  s   rÕ   s   some data needs to be sentc                    s   g | ]}ˆ |ƒ‘qS rR   rR   ©Ú.0rh   rÌ   rR   rS   Ú
<listcomp>ý  s     zNUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.<listcomp>N)r   rÂ   Ztwisted.internet.unixrÃ   Útwisted.python.sendmsgrÅ   r   r(   r0   r   r
   Ú
addCleanupr   r   r   ZdoReadrL   ÚlenrÊ   ZassertFalseÚsetÚintersectionrË   )rN   ÚancillaryPackerrÂ   rÃ   rÅ   rÍ   rÕ   Z
sendSocketZ
recvSocketrÑ   ZreceiverZ	fileOneFDZfileOneNameZ	fileTwoFDZfileTwoNameZ
dataToSendÚ	fdsToSendÚ	ancillaryÚexpectedCountZdeviceInodesSentrR   rÌ   rS   Ú)_sendmsgMixinFileDescriptorReceivedDriver�  s4    



z:UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriverc                    s&   ddl m‰  ‡ fdd„}|  |¡ dS )zß
        _SendmsgMixin handles multiple file descriptors per recvmsg, calling
        L{IFileDescriptorReceiver.fileDescriptorReceived} once per received
        file descriptor. Scenario: single CMSG with two FDs.
        r   ©Ú
SCM_RIGHTSc                    s    t ˆ td| žŽ fg}d}||fS )NÚiié   )rå   ©r   r   ©rß   rà   rá   rã   rR   rS   rÞ   	  s    z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSG.<locals>.ancillaryPackerN©rÙ   rä   râ   ©rN   rÞ   rR   rã   rS   Ú1test_multiFileDescriptorReceivedPerRecvmsgOneCMSG   s    zBUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSGz=Multi control message ancillary sendmsg not supported on Mac.c                    s&   ddl m‰  ‡ fdd„}|  |¡ dS )zá
        _SendmsgMixin handles multiple file descriptors per recvmsg, calling
        L{IFileDescriptorReceiver.fileDescriptorReceived} once per received
        file descriptor. Scenario: two CMSGs with one FD each.
        r   rã   c                    s   ‡ fdd„| D ƒ}d}||fS )Nc                    s   g | ]}t ˆ td |ƒf‘qS )Úirç   rÖ   rã   rR   rS   rØ     s     zpUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs.<locals>.ancillaryPacker.<locals>.<listcomp>ræ   rR   rè   rã   rR   rS   rÞ     s    z\UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs.<locals>.ancillaryPackerNré   rê   rR   rã   rS   Ú2test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs  s    zCUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGsc                    s~   ddl m‰ dd„ }‡fdd„}g }t|jƒ |  t|j¡ |  ˆd|¡ |  |¡ d‰ t‡ fd	d
„|D ƒƒ}|  	|d¡ dS )zØ
        _SendmsgMixin handles multiple file descriptors per recvmsg, calling
        L{IFileDescriptorReceiver.fileDescriptorReceived} once per received
        file descriptor. Scenario: unsupported CMSGs.
        r   rÄ   c                 S   s   g }d}||fS )Nr   rR   rè   rR   rR   rS   rÞ   3  s    z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.ancillaryPackerc                    s   d}dg}d}ˆ   |||¡S )Ns	   some data)NNr¢   r   )ZReceivedMessage)rÐ   ÚargsÚkwargsri   rà   ÚflagsrÄ   rR   rS   ÚfakeRecvmsgUnsupportedAncillary8  s    zkUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.fakeRecvmsgUnsupportedAncillaryÚrecvmsgz#received unsupported ancillary datac                 3   s   | ]}ˆ |d  kV  qdS )ÚformatNrR   )r×   Úe)ÚexpectedMessagerR   rS   Ú	<genexpr>G  s     zUUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.<genexpr>z+Expected message not found in logged eventsN)
Ztwisted.pythonrÅ   r>   rº   rÚ   r@   rŠ   râ   Úanyr¸   )rN   rÞ   rñ   ÚeventsÚfoundrR   )rõ   rÅ   rS   Ú1test_multiFileDescriptorReceivedPerRecvmsgBadCMSG$  s    

zBUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSGc                 C   sò   ddl m} |ƒ \}}g }t|jƒ |  t|j¡ G dd„ dtƒ}|| ¡ dƒ}tƒ }t	| ||| j
ƒ | ¡  | d¡ |  d| d¡¡ d	}d
}	t|j|j|	|d�}
|D ],}|
 ¡ D ]\}}|| |¡kr¶ qªq¶ qîqª|  d|
t|ƒf ¡ dS )zÙ
        If associated with a protocol which does not provide
        L{IFileDescriptorReceiver}, file descriptors received by the
        L{IUNIXTransport} implementation are closed and a warning is emitted.
        r   rÁ   c                   @   s   e Zd Zdd„ ZdS )zRUNIXTestsBuilder.test_avoidLeakingFileDescriptors.<locals>.RecordEndpointAddressesc                 S   s&   | j  ¡ | _| j  ¡ | _t | ¡ d S rq   )rk   r„   ÚhostAddressr’   ÚpeerAddressrg   rp   ro   rR   rR   rS   rp   _  s    zaUNIXTestsBuilder.test_avoidLeakingFileDescriptors.<locals>.RecordEndpointAddresses.connectionMadeNrª   rR   rR   rR   rS   ÚRecordEndpointAddresses^  s   rý   r™   Fr¢   rÎ   zˆ%(protocolName)s (on %(hostAddress)r) does not provide IFileDescriptorReceiver; closing file descriptor received (from %(peerAddress)r).r0   )rû   rü   ZprotocolNameró   z3Expected event (%s) not found in logged events (%s)N)r   rÂ   r>   rº   rÚ   r@   rg   r›   r0   r4   r–   r   ÚsetblockingrL   Úrecvr‘   rü   rû   ÚitemsÚgetr!   r   )rN   rÂ   ZprobeClientZprobeServerrø   rý   rc   re   ró   ZclsNameZexpectedEventZlogEventÚkÚvrR   rR   rS   Ú test_avoidLeakingFileDescriptorsJ  sF    


ÿüÿþÿÿz1UNIXTestsBuilder.test_avoidLeakingFileDescriptorsc                    sv   t tƒG ‡ fdd„dtƒƒ}tƒ }t| ¡ dƒ}|ƒ }tˆ ||ˆ jƒ ˆ  t	|j
d ¡ ˆ  dt|j
dd… ƒ¡ dS )z„
        L{IUNIXTransport.sendFileDescriptor} sends file descriptors before
        L{ITransport.write} sends normal bytes.
        c                       s(   e Zd Zdd„ Z‡ fdd„Zdd„ ZdS )zJUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEventsc                 S   s   t  | ¡ g | _d S rq   )r0   rp   rø   ro   rR   rR   rS   rp      s    
zYUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.connectionMadec                    s    ˆ   t|¡ | j t|ƒ¡ d S rq   )rÚ   r   rø   rº   Útype)Z	innerSelfry   ro   rR   rS   rz   ¤  s    zaUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.fileDescriptorReceivedc                 S   s   | j  |¡ d S rq   )rø   Úextendr}   rR   rR   rS   r~   ¨  s    zWUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.dataReceivedN)rU   rV   rW   rp   rz   r~   rR   ro   rR   rS   ÚRecordEventsž  s   r  r™   r   é   N)r   r(   r0   r   rg   r›   r4   r–   rL   Úintrø   Úbytes)rN   r  r¾   rc   re   rR   ro   rS   Ú#test_descriptorDeliveredBeforeBytes—  s    z4UNIXTestsBuilder.test_descriptorDeliveredBeforeBytesN)rU   rV   rW   rX   r+   r]   r\   r–   r�   r   rB   ÚisLinuxr‡   rŒ   rŽ   r—   rÅ   ÚsendmsgSkipReasonr¨   r¹   rÀ   râ   rë   ZisMacOSXrí   rú   r  r  rR   rR   rR   rS   r   ß   sJ   þ
þ



"

0

c

þ


%

L
r   c                   @   s8   e Zd ZdZejfZdd„ Zee	 
¡  dƒdd„ ƒZdS )ÚUNIXDatagramTestsBuilderzE
    Builder defining tests relating to L{IReactorUNIXDatagram}.
    c                 C   s   |   d|  ¡ tƒ ¡ dS )zƒ
        The UNIX socket created by L{IReactorUNIXDatagram.listenUNIXDatagram}
        is created with the mode specified.
        ÚlistenUNIXDatagramN)rT   r   r-   ro   rR   rR   rS   Útest_listenMode¿  s    z(UNIXDatagramTestsBuilder.test_listenModer‚   c                 C   s>   t | ƒ}|  ¡ }| d| tƒ ¡}|  | ¡ td| ƒ¡ dS )z½
        On Linux, a UNIX socket path may begin with C{' '} to indicate a
        socket in the abstract namespace.  L{IReactorUNIX.listenUNIXDatagram}
        accepts such a path.
        rƒ   N)r[   rI   r  r-   rL   r„   r   r…   rR   rR   rS   r‡   Æ  s    
z<UNIXDatagramTestsBuilder.test_listenOnLinuxAbstractNamespaceN)rU   rV   rW   rX   r   ZIReactorUNIXDatagramr]   r  r   rB   r  r‡   rR   rR   rR   rS   r  µ  s   þr  c                   @   s>   e Zd ZU dZeefZeee	e
   ed< dd„ Zdd„ ZdS )ÚSocketUNIXMixinzb
    Mixin which uses L{IReactorSocket.adoptStreamPort} to hand out listening
    UNIX ports.
    r]   c                 C   sZ   t tƒ}tddd�}| |¡ | d¡ | d¡ z| | ¡ |j	|¡W ¢S | ¡  X dS )zj
        Get a UNIX port from a reactor, wrapping an already-initialized file
        descriptor.
        r^   r_   r`   é   FN)
r   r   r   r£   Úlistenrþ   r   ZadoptStreamPortr›   Úfamily)rN   r   rQ   ZportSockrP   rR   rR   rS   ÚgetListeningPortá  s    


z SocketUNIXMixin.getListeningPortc                 C   s   |  |j|¡S ©aZ  
        Connect to a listening UNIX socket.

        @param reactor: The reactor under test.
        @type reactor: L{IReactorUNIX}

        @param address: The listening's address.
        @type address: L{UNIXAddress}

        @param factory: The client factory.
        @type factory: L{ClientFactory}

        @return: The connector
        ©r�   rd   ©rN   r   ÚaddressrQ   rR   rR   rS   ÚconnectToListenerñ  s    z!SocketUNIXMixin.connectToListenerN)rU   rV   rW   rX   r+   r*   r]   r   r   r   r   rf   r  r  rR   rR   rR   rS   r  Ö  s   
þr  c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚListenUNIXMixinzZ
    Mixin which uses L{IReactorTCP.listenUNIX} to hand out listening UNIX
    ports.
    c                 C   s   t ddd�}| ||¡S )z0
        Get a UNIX port from a reactor
        r^   r_   r`   )r   r€   )rN   r   rQ   rP   rR   rR   rS   r  	  s    z ListenUNIXMixin.getListeningPortc                 C   s   |  |j|¡S r  r  r  rR   rR   rS   r    s    z!ListenUNIXMixin.connectToListenerN)rU   rV   rW   rX   r  r  rR   rR   rR   rS   r    s   r  c                   @   s8   e Zd ZU efZeeee   e	d< dd„ Z
dd„ ZdS )ÚUNIXPortTestsMixinr]   c                 C   s   |› dt | ¡ jƒ›�S )zZ
        Get the message expected to be logged when a UNIX port starts listening.
        z starting on ©r;   r„   rd   )rN   r†   rQ   rR   rR   rS   Ú#getExpectedStartListeningLogMessage&  s    z6UNIXPortTestsMixin.getExpectedStartListeningLogMessagec                 C   s   dt | ¡ jƒ› d�S )zJ
        Get the expected connection lost message for a UNIX port
        z(UNIX Port z Closed)r  )rN   r†   rR   rR   rS   ÚgetExpectedConnectionLostLogMsg,  s    z2UNIXPortTestsMixin.getExpectedConnectionLostLogMsgN)rU   rV   rW   r+   r]   r   r   r   r   rf   r  r  rR   rR   rR   rS   r  #  s   
r  c                   @   s   e Zd ZdZdS )ÚUNIXPortTestsBuilderz.
    Tests for L{IReactorUNIX.listenUnix}
    N©rU   rV   rW   rX   rR   rR   rR   rS   r   3  s   r   c                   @   s   e Zd ZdZdS )ÚUNIXFDPortTestsBuilderz3
    Tests for L{IReactorUNIX.adoptStreamPort}
    Nr!  rR   rR   rR   rS   r"  >  s   r"  c                   @   s.   e Zd ZeeefZdd„ Zdd„ Zdd„ Z	dS )Ú%UNIXAdoptStreamConnectionTestsBuilderc           	      C   s~   |   ¡ }ddlm} G dd„ dtƒ}|ttƒ\}}| d¡ |  |j¡ |  |j¡ | 	¡ }|ƒ }| 
|t|¡}|  |¡ dS )z€
        {IReactorSocket.adoptStreamConnection} returns None if the given
        factory's buildProtocol returns None.
        r   rÁ   c                   @   s   e Zd Zdd„ ZdS )zXUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNone.<locals>.NoneFactoryc                 S   s   d S rq   rR   )rN   r  rR   rR   rS   ÚbuildProtocol_  s    zfUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNone.<locals>.NoneFactory.buildProtocolN)rU   rV   rW   r$  rR   rR   rR   rS   ÚNoneFactory^  s   r%  FN)rI   r   rÂ   r.   r   r
   rþ   rÚ   r   r›   ÚadoptStreamConnectionZassertIsNone)	rN   r   rÂ   r%  Ús1Ús2Zs1FDrQ   r¿   rR   rR   rS   Útest_buildProtocolReturnsNoneP  s    

zCUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNonec                    s<   ‡ fdd„}ˆ   ¡ }ˆ j|ddd�}| |¡ ˆ  |¡ dS )z>
        Helper method to test UNIX server addresses.
        c                    s‚   | \}}}zftd| ¡ jƒ}ˆ  d|j j|f t|j ƒ¡ ˆ  d|j j|f |j j¡ |j	j
d }ˆ  |t¡ W 5 |j  ¡  X d S )NrF   z <AccumulatingProtocol #%s on %s>zAccumulatingProtocol,%s,%sr   )rk   rn   r=   r„   rd   rL   Z	sessionnoÚstrZlogstrrQ   ZpeerAddressesr»   r   )Ú	protocolsre   rc   r†   ZportPathrü   ro   rR   rS   Ú	connectedq  s$    

ÿý
ÿýzOUNIXAdoptStreamConnectionTestsBuilder.test_ServerAddressUNIX.<locals>.connectedN)Ú	interfaceÚaddressFamily)rI   ÚgetConnectedClientAndServerr¤   Z
runReactor)rN   r,  r   r§   rR   ro   rS   Útest_ServerAddressUNIXl  s      ÿ
z<UNIXAdoptStreamConnectionTestsBuilder.test_ServerAddressUNIXc                    sà   t ƒ }tƒ |_t ƒ ‰tƒ ˆ_tƒ ˆ_tƒ }tƒ |_tƒ |_tddd�}ˆ ||¡‰‡‡fdd„}|j |¡ t|jˆjgƒ}‡fdd„}	| 	|	¡ tƒ ‰ ˆ  
|	¡ t|jˆjgƒ}
‡ ‡fdd	„}|
 |¡ ˆ ˆ ¡ j|¡ ˆ S )
a0  
        Return a L{Deferred} firing with a L{MyClientFactory} and
        L{MyServerFactory} connected pair, and the listening C{Port}. The
        particularity is that the server protocol has been obtained after doing
        a C{adoptStreamConnection} against the original server connection.
        r^   r_   r`   c                    s0   ˆ   | j¡ ˆ  | j¡ ˆ  | j ¡ tˆ¡ d S rq   )ZremoveReaderrk   ZremoveWriterr&  r›   r   )rÑ   )r   rc   rR   rS   ÚfirstServerConnected¤  s    z_UNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.firstServerConnectedc                    s   ˆ j rˆ  ¡  | S rq   )Zrunningrµ   )r¿   )r   rR   rS   rµ   ¯  s    zOUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.stopc                    s   | \}}ˆ   ||ˆf¡ d S rq   )rx   )r+  re   rc   )Údeferredr†   rR   rS   r¯   ½  s    zPUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.start)r8   r    ÚprotocolConnectionMadeZprotocolConnectionLostr7   r   r€   r¤   r"   r¦   r¥   r�   r„   rd   )rN   r   r-  r.  ZfirstServerre   rP   r1  ZlostDeferredrµ   ZstartDeferredr¯   rR   )r2  r†   r   rc   rS   r/  Ž  s4    
ÿ


ÿ
zAUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServerN)
rU   rV   rW   r)   r*   r+   r]   r)  r0  r/  rR   rR   rR   rS   r#  I  s   ý"r#  c                   @   s6   e Zd ZdZefZdZedd„ ƒZdd„ Z	dd„ Z
dS )	ÚUnixClientTestsBuilderz7
    Define tests for L{IReactorUNIX.connectUNIX}.
    Nc                 C   s   | j dkrt| ƒ| _ | j S )z‹
        Return a path usable by C{connectUNIX} and C{listenUNIX}.

        @return: A path instance, built with C{_abstractPath}.
        N)Ú_pathr[   ro   rR   rR   rS   rP   ×  s    

zUnixClientTestsBuilder.pathc                 C   s   |  | j|¡S )z×
        Start an UNIX server with the given C{factory}.

        @param reactor: The reactor to create the UNIX port in.

        @param factory: The server factory.

        @return: A UNIX port instance.
        )r€   rP   ©rN   r   rQ   rR   rR   rS   r  â  s    
zUnixClientTestsBuilder.listenc                 C   s   |  | j|¡S )zÝ
        Start an UNIX client with the given C{factory}.

        @param reactor: The reactor to create the connection in.

        @param factory: The client factory.

        @return: A UNIX connector instance.
        )r�   rP   r6  rR   rR   rS   Úconnectî  s    
zUnixClientTestsBuilder.connect)rU   rV   rW   rX   r+   r]   r5  ÚpropertyrP   r  r7  rR   rR   rR   rS   r4  Î  s   

r4  Úposixz%UNIX sockets only supported on POSIX.c                   @   sP   e Zd ZdZdZdd„ Zeeegdf ddœdd„Zd	d
„ Z	dd„ Z
dd„ ZdS )ÚRealSocketTestsz,
    Test real UNIX socket connections.
    Zunixpathc                 Ã   sœ   t j t¡st‚tƒ }t | j|¡}t|t	j
ƒs4t‚||_|  |j¡ tƒ }t | j|¡ |jI dH  |jspt‚|  |jj¡ |  |j¡ |j tj¡ dS )z|
        A port created with L{IReactorTCP.listenUNIX} can be connected to with
        L{IReactorTCP.connectUNIX}.
        N)r   r+   Ú
providedByr   ÚAssertionErrorr6   r€   rP   Ú
isinstancer   ZPortr†   rÚ   ZcleanUpr7   r�   r2  ZlastProtocolr¸   ZmadeZdisconnectedZ
lostReasonr¼   r   ZConnectionDone)rN   Úfr†   ÚclientFrR   rR   rS   Útest_closePortInProtocolFactory  s    
z/RealSocketTests.test_closePortInProtocolFactoryN)rx   Úreturnc           	      Ã   s¨   t j t¡st‚tƒ }tƒ }||_t | j	|¡}|  
|j¡ tƒ }tƒ }||_t | j	|¡ t||gƒI dH \}}|||ƒ |js†t‚|js�t‚|j ¡  |j ¡  dS )z‰
        Invoke the given callback with a client protocol and a server protocol
        which have been connected to each other.
        N)r   r+   r;  r   r<  r8   r    r3  r€   rP   rÚ   rK   r7   r�   r"   rk   rn   )	rN   rx   ZserverFactoryZserverConnMader†   r?  ZclientConnMadeÚserverProtocolÚclientProtocolrR   rR   rS   Ú_connectedClientAndServerTest  s$    ÿ



z-RealSocketTests._connectedClientAndServerTestc                 ƒ   s*   t t ddœ‡ fdd„}ˆ  |¡I dH  dS )zå
        The transport of a protocol connected with L{IReactorTCP.connectUNIX} or
        L{IReactor.TCP.listenUNIX} can have L{ITCPTransport.getTcpNoDelay} or
        L{ITCPTransport.setTcpNoDelay} called without error.
        N©rB  rC  rA  c                    sn   | |fD ]`}t j |j¡st‚|j}ˆ  | ¡ d¡ | d¡ ˆ  | ¡ d¡ | d¡ ˆ  | ¡ d¡ qd S )Nr   TF)r   ÚITCPTransportr;  rk   r<  rL   ZgetTcpNoDelayZsetTcpNoDelay©rB  rC  Úprk   ro   rR   rS   ÚcheckA  s    

z.RealSocketTests.test_tcpNoDelay.<locals>.check©rD   rD  ©rN   rI  rR   ro   rS   Útest_tcpNoDelay:  s
     þzRealSocketTests.test_tcpNoDelayc                 ƒ   s*   t t ddœ‡ fdd„}ˆ  |¡I dH  dS )a  
        The transport of a protocol connected with L{IReactorTCP.connectUNIX} or
        L{IReactor.TCP.listenUNIX} can have its I{SO_KEEPALIVE} state inspected
        and manipulated with L{ITCPTransport.getTcpKeepAlive} and
        L{ITCPTransport.setTcpKeepAlive}.
        NrE  c                    sn   | |fD ]`}t j |j¡st‚|j}ˆ  | ¡ d¡ | d¡ ˆ  | ¡ d¡ | d¡ ˆ  | ¡ d¡ qd S )NFT)r   rF  r;  rk   r<  rL   ZgetTcpKeepAliveZsetTcpKeepAliverG  ro   rR   rS   rI  W  s    

z0RealSocketTests.test_tcpKeepAlive.<locals>.checkrJ  rK  rR   ro   rS   Útest_tcpKeepAliveO  s
    	 þz!RealSocketTests.test_tcpKeepAlivec                 Ã   sD   t j t¡st‚tƒ }tjd|dd� |jI dH  |j 	t
j¡ dS )zb
        Tests whether attempting to establish connection to non-existing UNIX path fails
        znon-existingé   )ÚtimeoutN)r   r+   r;  r   r<  r7   r�   ZfailDeferredrs   r¼   r   ZConnectError)rN   r?  rR   rR   rS   Útest_Failinge  s
    zRealSocketTests.test_Failing)rU   rV   rW   rX   rP   r@  r   rD   rD  rL  rM  rP  rR   rR   rR   rS   r:  þ  s   þr:  )vrX   Úhashlibr   Úosr   r   r   r   r   Úpprintr   r   r	   r
   r   r   Ústructr   Útempfiler   r   Útypingr   r   r   r   r   Zunittestr   r   Z_AF_UNIXÚImportErrorZzope.interfacer   r   Ztwisted.internetr   r   r   r   r   Ztwisted.internet.addressr   Ztwisted.internet.deferr    r!   r"   Ztwisted.internet.endpointsr#   r$   Ztwisted.internet.errorr%   r&   r'   Ztwisted.internet.interfacesr(   r)   r*   r+   Ztwisted.internet.protocolr,   r-   r.   Ztwisted.internet.taskr/   Z&twisted.internet.test.connectionmixinsr0   r1   r2   r3   r4   Z#twisted.internet.test.reactormixinsr5   Ztwisted.internet.test.test_tcpr6   r7   r8   r9   r:   Ztwisted.python.compatr;   Ztwisted.python.failurer<   Ztwisted.python.filepathr=   Ztwisted.python.logr>   r?   r@   Ztwisted.python.reflectrA   Ztwisted.python.runtimerB   rC   Ztwisted.test.test_tcprD   Ztwisted.trial.unittestrE   rÅ   r  rG   r[   r\   rg   ru   r   r  r  r  r  r   r"  r#  ÚglobalsÚupdateZmakeTestCaseClassesr4  r:  rR   rR   rR   rS   Ú<module>   s–   
ÿ%>   Y!- 
ü
ü~-