o
    ¯b&ˆ  ã                   @   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 dd
lmZ zddlmZ W n ey_   dZY nw eZddlmZm Z  ddl!m"Z"m#Z# ddl$m%Z% ddl&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/m0Z0 ddl1m2Z2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8m9Z9 ddl:m;Z; ddl<m=Z=m>Z>m?Z?m@Z@mAZA ddlBmCZC ddlDmEZEmFZFmGZGmHZH ddlImJZJ ddlKmLZL ddlMmNZN ddlOmPZPmQZQmRZR ddlSmTZT ddlUmVZV eTdƒZWd ZXeTdƒdu�rd!ZXG d"d#„ d#ƒZYd$d%„ ZZG d&d'„ d'e?ƒZ[G d(d)„ d)e=ƒZ\e e2ƒG d*d+„ d+e=ƒƒZ]G d,d-„ d-eYeCe>ƒZ^G d.d/„ d/eYeCƒZ_G d0d1„ d1ƒZ`G d2d3„ d3ƒZaG d4d5„ d5ƒZbG d6d7„ d7eaebeCeGƒZcG d8d9„ d9e`ebeCeGƒZdG d:d;„ d;eHeCƒZeefƒ  ge^ h¡ ¡ efƒ  ge_ h¡ ¡ efƒ  gec h¡ ¡ efƒ  ged h¡ ¡ efƒ  gee h¡ ¡ G d<d=„ d=eCe@ƒZiefƒ  gei h¡ ¡ dS )>z/
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)ÚOptionalÚSequenceÚType)ÚskipIf)ÚAF_UNIXN)Ú	InterfaceÚimplementer)ÚbaseÚ
interfaces)ÚUNIXAddress)ÚDeferredÚfailÚgatherResults)ÚUNIXClientEndpointÚUNIXServerEndpoint)ÚCannotListenErrorÚConnectionClosedÚFileDescriptorOverrun)ÚIFileDescriptorReceiverÚIReactorFDSetÚIReactorSocketÚIReactorUNIX)ÚClientFactoryÚDatagramProtocolÚServerFactory)ÚLoopingCall)ÚConnectableProtocolÚConnectionTestsMixinÚEndpointCreatorÚStreamClientTestsMixinÚrunProtocolsWithReactor)ÚReactorBuilder)ÚMyClientFactoryÚMyServerFactoryÚStreamTransportTestsMixinÚWriteSequenceTestsMixin)ÚnativeString)ÚFailure)Ú_coerceToFilesystemEncoding)ÚaddObserverÚerrÚremoveObserver)ÚrequireModule)Úplatformz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Úfactoryr?   ÚreactorÚunixPort© rK   úA/usr/lib/python3/dist-packages/twisted/internet/test/test_unix.pyÚ	_modeTestO   s
   zUNIXFamilyMixin._modeTestN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rM   rK   rK   rK   rL   r>   J   s    r>   c                 C   s   t tdƒƒ ¡ S )zI
    Return a new, unique abstract namespace path to be listened on.
    éd   )r   r   Ú	hexdigest)ÚcaserK   rK   rL   Ú_abstractPath[   s   rU   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   )rE   rI   rG   rK   rK   rL   Úserveri   ó   
zUNIXCreator.serverc                 C   s   t ||jƒS )z3
        Construct a UNIX client endpoint.
        )r   Úname)rE   rI   ÚserverAddressrK   rK   rL   Úclientq   s   zUNIXCreator.clientN)rN   rO   rP   rQ   r   r&   rW   r   r   r   r   Ú__annotations__r]   ra   rK   rK   rK   rL   rV   b   s
   
 rV   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)rE   rd   re   rK   rK   rL   Ú__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ÚsendFileDescriptorrd   re   ÚwriteÚloseConnection©rE   rK   rK   rL   ÚconnectionMadeŽ   s   z!SendFileDescriptor.connectionMadec                 C   s   t  | |¡ || _d S ©N)r+   ÚconnectionLostÚreason©rE   ro   rK   rK   rL   rn   ˜   s   
z!SendFileDescriptor.connectionLost)rN   rO   rP   rQ   ro   rf   rl   rn   rK   rK   rK   rL   rc   x   s    
rc   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u rtƒ | _| jS t| j ƒ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)ro   r   Úwaitingr   rk   rK   rK   rL   Ú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)rr   Úcallback)rE   Ú
descriptorrK   rK   rL   ÚfileDescriptorReceivedº   r^   z,ReceiveFileDescriptor.fileDescriptorReceivedc                 C   s4   | j dur| j  ttd|›d�ƒƒ¡ d| _ dS 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.)rr   Úerrbackr6   Ú	Exception©rE   re   rK   rK   rL   ÚdataReceivedÂ   s   
ÿ
üz"ReceiveFileDescriptor.dataReceivedc                 C   s2   t  | |¡ | jdur| j |¡ d| _|| _dS )zj
        Fail the waiting Deferred, initialized by C{waitForDescriptor}, if there
        is one.
        N)r+   rn   rr   rw   ro   rp   rK   rK   rL   rn   Ð   s
   

z$ReceiveFileDescriptor.connectionLost)
rN   rO   rP   rQ   ro   rr   rs   rv   rz   rn   rK   rK   rK   rL   rq   �   s    rq   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   ó   |   d|  ¡ tƒ ¡ dS )zs
        The UNIX socket created by L{IReactorUNIX.listenUNIX} is created with
        the mode specified.
        Ú
listenUNIXN)rM   r   r)   rk   rK   rK   rL   Ú	test_modeå   ó   zUNIXTestsBuilder.test_modeú8Abstract namespace UNIX sockets only supported on Linux.c                 C   ó>   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)rU   r@   r}   r)   rC   ÚgetHostr   ©rE   rG   rI   ÚportrK   rK   rL   Ú#test_listenOnLinuxAbstractNamespaceì   s   z4UNIXTestsBuilder.test_listenOnLinuxAbstractNamespacec                 C   s^   dd„ }|   tjd|¡ |  ¡ }|  t¡� | dtƒ ¡ W d  ƒ dS 1 s(w   Y  dS )z•
        L{IReactorUNIX.listenUNIX} raises L{CannotListenError} if the
        underlying port's createInternetSocket raises a socket error.
        c                 S   s   t dƒ‚)Nz FakeBasePort forced socket.error)ÚOSErrorrk   rK   rK   rL   ÚraiseSocketError  s   z=UNIXTestsBuilder.test_listenFailure.<locals>.raiseSocketErrorÚcreateInternetSocketznot-usedN)Úpatchr   ÚBasePortr@   ÚassertRaisesr    r}   r)   )rE   rˆ   rI   rK   rK   rL   Útest_listenFailureü   s   "ÿz#UNIXTestsBuilder.test_listenFailurec                 C   r�   )zc
        L{IReactorUNIX.connectUNIX} also accepts a Linux abstract namespace
        path.
        r‚   N)rU   r@   ÚconnectUNIXr'   rC   ÚgetDestinationr   )rE   rG   rI   Ú	connectorrK   rK   rL   Ú$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                   @   ó   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Ú	addressesrj   )rE   rg   rK   rK   rL   ÚmakeConnection   s   ÿzCUNIXTestsBuilder.test_addresses.<locals>.SaveAddress.makeConnectionN)rN   rO   rP   r˜   rK   rK   rK   rL   ÚSaveAddress  ó    r™   r“   r”   N)r+   r/   Ú	endpointsrC   r—   )rE   r™   r]   ra   rK   rK   rL   Ú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)r=   r   ó   junkc                    s@   ˆ | t tƒ}t| ƒ ˆ ˆ ¡ | ¡ ¡ ˆ ˆ ¡ | ¡ ¡ d S rm   )r	   r
   r   rC   ÚgetsocknameÚassertNotEqualÚfileno)ru   Úreceived)r�   ÚsrE   rK   rL   ÚcheckDescriptor=  s   zAUNIXTestsBuilder.test_sendFileDescriptor.<locals>.checkDescriptorz-Sending file descriptor encountered a problemc                    ó
   ˆ j  ¡ S rm   ©rg   rj   ©Úignored©r]   rK   rL   Ú<lambda>M  ó   
 z:UNIXTestsBuilder.test_sendFileDescriptor.<locals>.<lambda>N)r   r�   Úbindrc   r¡   rq   rs   ÚaddCallbackÚ
addErrbackr9   ÚaddBothr/   r›   )rE   ra   Údr¤   rK   )r�   r£   rE   r]   rL   Útest_sendFileDescriptor.  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                   @   r’   )zSUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.DoesNotReadc                 S   s   | j  ¡  d S rm   )rg   ÚpauseProducingrk   rK   rK   rL   rl   Y  s   zbUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.DoesNotRead.connectionMadeN©rN   rO   rP   rl   rK   rK   rK   rL   ÚDoesNotReadX  rš   r´   c                   @   ó8   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)rg   rh   r   r¡   ri   rK   rk   rK   rL   Úsenderc  s   zUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMade.<locals>.senderr   zSend loop failure)
r   rg   ÚregisterProducerr*   ÚtaskrI   ÚclockÚstartr®   r9   )rE   r·   rK   rk   rL   rl   _  s   
zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMadec                 S   ó   |   ¡  d S rm   ©Ú_disconnectrk   rK   rK   rL   ÚstopProducingk  ó   znUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.stopProducingc                 S   r¼   rm   r½   rk   rK   rK   rL   ÚresumeProducingn  rÀ   zpUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.resumeProducingc                 S   s   d| _ | j ¡  |  ¡  d S )NT)Úpausedrg   ÚunregisterProducerr¾   rk   rK   rK   rL   r²   q  s   
zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.pauseProducingc                 S   s$   | j  ¡  | j ¡  | jj ¡  d S rm   )r¹   Ústoprg   ÚabortConnectionÚotherrk   rK   rK   rL   r¾   v  s   

zlUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors._disconnectN)	rN   rO   rP   rÂ   rl   r¿   rÁ   r²   r¾   rK   rK   rK   rL   ÚSendsManyFileDescriptors\  s    rÇ   z*sendFileDescriptor producer was not pausedN)r+   rÆ   r/   r›   Ú
assertTruerÂ   )rE   r´   rÇ   r]   ra   rK   rK   rL   Ú-test_sendFileDescriptorTriggersPauseProducingQ  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                    r¥   rm   r¦   r§   r©   rK   rL   rª   ’  r«   z=UNIXTestsBuilder.test_fileDescriptorOverrun.<locals>.<lambda>r   )r   rc   r¡   rq   rs   r¯   Úappendr/   r›   ÚassertIsInstancer6   Útrapr!   ro   Úvaluer"   )rE   Úcargora   Úresultr°   rK   r©   rL   Ú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 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 rm   )r   Úst_devÚst_ino)rd   ÚfsrK   rK   rL   Ú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 rm   )ÚfdsÚdeviceInodesReceivedrk   rK   rK   rL   rf   Â  ó   
zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.__init__c                    s(   | j  |¡ | j ˆ |ƒ¡ t|ƒ d S rm   )rÚ   rÊ   rÛ   r   )rE   rd   ©rÙ   rK   rL   rv   Æ  s   zgUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.fileDescriptorReceivedN)rN   rO   rP   rf   rv   rK   rÝ   rK   rL   ÚFakeProtocolÀ  s    rÞ   c                   @   rµ   )zPUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiveré   c                 S   s   || _ || _d S rm   )r   Úprotocol)rE   ÚsktÚprotorK   rK   rL   rf   Î  rÜ   zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.__init__c                 S   ó   d S rm   rK   ry   rK   rK   rL   Ú_dataReceivedÒ  ó   z^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._dataReceivedc                 S   rã   rm   rK   rk   rK   rK   rL   rƒ   Õ  rå   zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getHostc                 S   rã   rm   rK   rk   rK   rK   rL   r–   Ø  rå   zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getPeerc                 S   rã   rm   rK   )rE   ÚorK   rK   rL   Ú_getLogPrefixÛ  rå   z^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._getLogPrefixN)	rN   rO   rP   Ú
bufferSizerf   rä   rƒ   r–   rç   rK   rK   rK   rL   ÚFakeReceiverË  s    ré   s   some data needs to be sentc                    s   g | ]}ˆ |ƒ‘qS rK   rK   ©Ú.0rd   rÝ   rK   rL   Ú
<listcomp>ú  s    zNUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.<listcomp>N)r   rÒ   Útwisted.internet.unixrÓ   Útwisted.python.sendmsgrÕ   r   r#   r+   r   r
   Ú
addCleanupr   r   r   ÚdoReadrC   ÚlenrÚ   ÚassertFalseÚsetÚintersectionrÛ   )rE   ÚancillaryPackerrÒ   rÓ   rÕ   rÞ   ré   Ú
sendSocketÚ
recvSocketrâ   ÚreceiverÚ	fileOneFDÚfileOneNameÚ	fileTwoFDÚfileTwoNameÚ
dataToSendÚ	fdsToSendÚ	ancillaryÚexpectedCountÚdeviceInodesSentrK   rÝ   rL   Ú)_sendmsgMixinFileDescriptorReceivedDriverš  s6   



þz:UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriverc                    ó&   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g| ¢R Ž fg}d}||fS )NÚiié   ©r   r   ©rþ   rÿ   r   r  rK   rL   rõ     s   z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSG.<locals>.ancillaryPackerN©rî   r  r  ©rE   rõ   rK   r  rL   Ú1test_multiFileDescriptorReceivedPerRecvmsgOneCMSGý  s   zBUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSGz=Multi control message ancillary sendmsg not supported on Mac.c                    r  )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  rK   rL   rì     s    zpUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs.<locals>.ancillaryPacker.<locals>.<listcomp>r  rK   r	  r  rK   rL   rõ     s   z\UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs.<locals>.ancillaryPackerNr
  r  rK   r  rL   Ú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   rK   r	  rK   rK   rL   rõ   0  s   z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.ancillaryPackerc                    s   d}dg}d}ˆ   |||¡S )Ns	   some data)NNó    r   )ÚReceivedMessage)rá   ÚargsÚkwargsre   rÿ   ÚflagsrÔ   rK   rL   ÚfakeRecvmsgUnsupportedAncillary5  s   zkUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.fakeRecvmsgUnsupportedAncillaryÚrecvmsgz#received unsupported ancillary datac                 3   s   � | ]	}ˆ |d  v V  qdS )ÚformatNrK   )rë   Úe)ÚexpectedMessagerK   rL   Ú	<genexpr>D  s   € zUUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.<genexpr>z+Expected message not found in logged eventsN)
Útwisted.pythonrÕ   r8   rÊ   rï   r:   rŠ   r  ÚanyrÈ   )rE   rõ   r  ÚeventsÚfoundrK   )r  rÕ   rL   Ú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rh nq[ dS qU|  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                   @   r’   )zRUNIXTestsBuilder.test_avoidLeakingFileDescriptors.<locals>.RecordEndpointAddressesc                 S   s&   | j  ¡ | _| j  ¡ | _t | ¡ d S rm   )rg   rƒ   ÚhostAddressr–   ÚpeerAddressrc   rl   rk   rK   rK   rL   rl   \  s   zaUNIXTestsBuilder.test_avoidLeakingFileDescriptors.<locals>.RecordEndpointAddresses.connectionMadeNr³   rK   rK   rK   rL   ÚRecordEndpointAddresses[  rš   r!  rž   Fr  rß   zˆ%(protocolName)s (on %(hostAddress)r) does not provide IFileDescriptorReceiver; closing file descriptor received (from %(peerAddress)r).r+   )r  r   ÚprotocolNamer  z3Expected event (%s) not found in logged events (%s)N)r   rÒ   r8   rÊ   rï   r:   rc   r¡   r+   r/   r›   r   ÚsetblockingrC   Úrecvr•   r   r  ÚitemsÚgetr   r   )rE   rÒ   ÚprobeClientÚprobeServerr  r!  r]   ra   r  ÚclsNameÚexpectedEventÚlogEventÚkÚvrK   rK   rL   Ú test_avoidLeakingFileDescriptorsG  sJ   


ÿüÿýÿþÿÿ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 rm   )r+   rl   r  rk   rK   rK   rL   rl   �  s   

zYUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.connectionMadec                    s    ˆ   t|¡ | j t|ƒ¡ d S rm   )rï   r   r  rÊ   Útype)Ú	innerSelfru   rk   rK   rL   rv   ¡  s   zaUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.fileDescriptorReceivedc                 S   s   | j  |¡ d S rm   )r  Úextendry   rK   rK   rL   rz   ¥  s   zWUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.dataReceivedN)rN   rO   rP   rl   rv   rz   rK   rk   rK   rL   ÚRecordEvents›  s    r2  rž   r   é   N)r   r#   r+   r   rc   r¡   r/   r›   rC   Úintr  Úbytes)rE   r2  rÎ   r]   ra   rK   rk   rL   Ú#test_descriptorDeliveredBeforeBytes”  s   z4UNIXTestsBuilder.test_descriptorDeliveredBeforeBytesN)rN   rO   rP   rQ   r&   rW   rV   r›   r~   r   r<   ÚisLinuxr†   r�   r‘   rœ   rÕ   ÚsendmsgSkipReasonr±   rÉ   rÐ   r  r  ÚisMacOSXr  r  r.  r6  rK   rK   rK   rL   r{   Ü   sL    þ
þ




"

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   r|   )zƒ
        The UNIX socket created by L{IReactorUNIXDatagram.listenUNIXDatagram}
        is created with the mode specified.
        ÚlistenUNIXDatagramN)rM   r   r(   rk   rK   rK   rL   Útest_listenMode¼  r   z(UNIXDatagramTestsBuilder.test_listenModer€   c                 C   r�   )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)rU   r@   r;  r(   rC   rƒ   r   r„   rK   rK   rL   r†   Ã  s   
z<UNIXDatagramTestsBuilder.test_listenOnLinuxAbstractNamespaceN)rN   rO   rP   rQ   r   ÚIReactorUNIXDatagramrW   r<  r   r<   r7  r†   rK   rK   rK   rL   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.
    rW   c                 C   s\   t tƒ}tddd�}| |¡ | d¡ | d¡ z| | ¡ |j|¡W | 	¡  S | 	¡  w )zj
        Get a UNIX port from a reactor, wrapping an already-initialized file
        descriptor.
        rX   rY   rZ   é   F)
r   r   r   r¬   Úlistenr#  ÚadoptStreamPortr¡   Úfamilyr   )rE   rI   rH   ÚportSockrG   rK   rK   rL   ÚgetListeningPortÞ  s   


z SocketUNIXMixin.getListeningPortc                 C   ó   |  |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Ž   r_   ©rE   rI   ÚaddressrH   rK   rK   rL   ÚconnectToListenerî  ó   z!SocketUNIXMixin.connectToListenerN)rN   rO   rP   rQ   r&   r%   rW   r   r   r   r   rb   rD  rJ  rK   rK   rK   rL   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
        rX   rY   rZ   )r   r}   )rE   rI   rH   rG   rK   rK   rL   rD    s   z ListenUNIXMixin.getListeningPortc                 C   rE  rF  rG  rH  rK   rK   rL   rJ    rK  z!ListenUNIXMixin.connectToListenerN)rN   rO   rP   rQ   rD  rJ  rK   rK   rK   rL   rL     s    rL  c                   @   s8   e Zd ZU efZeeee   e	d< dd„ Z
dd„ ZdS )ÚUNIXPortTestsMixinrW   c                 C   s   |› dt | ¡ jƒ›�S )zZ
        Get the message expected to be logged when a UNIX port starts listening.
        z starting on ©r5   rƒ   r_   )rE   r…   rH   rK   rK   rL   Ú#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)rN  )rE   r…   rK   rK   rL   ÚgetExpectedConnectionLostLogMsg)  s   z2UNIXPortTestsMixin.getExpectedConnectionLostLogMsgN)rN   rO   rP   r&   rW   r   r   r   r   rb   rO  rP  rK   rK   rK   rL   rM     s   
 rM  c                   @   ó   e Zd ZdZdS )ÚUNIXPortTestsBuilderz.
    Tests for L{IReactorUNIX.listenUnix}
    N©rN   rO   rP   rQ   rK   rK   rK   rL   rR  0  ó    rR  c                   @   rQ  )ÚUNIXFDPortTestsBuilderz3
    Tests for L{IReactorUNIX.adoptStreamPort}
    NrS  rK   rK   rK   rL   rU  ;  rT  rU  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                   @   r’   )zXUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNone.<locals>.NoneFactoryc                 S   rã   rm   rK   )rE   rI  rK   rK   rL   ÚbuildProtocol\  rå   zfUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNone.<locals>.NoneFactory.buildProtocolN)rN   rO   rP   rW  rK   rK   rK   rL   ÚNoneFactory[  rš   rX  FN)r@   r   rÒ   r)   r   r
   r#  rï   r   r¡   ÚadoptStreamConnectionÚassertIsNone)	rE   rI   rÒ   rX  Ús1Ús2Ús1FDrH   rÏ   rK   rK   rL   Útest_buildProtocolReturnsNoneM  s   

zCUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNonec                    s<   ‡ fdd„}ˆ   ¡ }ˆ j|ddd�}| |¡ ˆ  |¡ dS )z>
        Helper method to test UNIX server addresses.
        c                    sŠ   | \}}}z9t d| ¡ jƒ}ˆ  d|jj|f t|jƒ¡ ˆ  d|jj|f |jj¡ |jj	d }ˆ  
|t¡ W |j ¡  d S |j ¡  w )Nr=   z <AccumulatingProtocol #%s on %s>zAccumulatingProtocol,%s,%sr   )r7   rƒ   r_   rC   rg   Ú	sessionnoÚstrÚlogstrrH   ÚpeerAddressesrË   r   rj   )Ú	protocolsra   r]   r…   ÚportPathr   rk   rK   rL   Ú	connectedn  s$   

ÿý
ÿýzOUNIXAdoptStreamConnectionTestsBuilder.test_ServerAddressUNIX.<locals>.connectedN)Ú	interfaceÚaddressFamily)r@   ÚgetConnectedClientAndServerr­   Ú
runReactor)rE   re  rI   r°   rK   rk   rL   Útest_ServerAddressUNIXi  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.
        rX   rY   rZ   c                    s0   ˆ   | j¡ ˆ  | j¡ ˆ  | j ¡ tˆ¡ d S rm   )ÚremoveReaderrg   ÚremoveWriterrY  r¡   r   )râ   )rI   r]   rK   rL   ÚfirstServerConnected¡  s   z_UNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.firstServerConnectedc                    s   ˆ j rˆ  ¡  | S rm   )ÚrunningrÄ   )rÏ   )rI   rK   rL   rÄ   ¬  s   zOUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.stopc                    s   | \}}ˆ   ||ˆf¡ d S rm   )rt   )rc  ra   r]   )Údeferredr…   rK   rL   r»   º  s   zPUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.start)r2   r   ÚprotocolConnectionMadeÚprotocolConnectionLostr1   r   r}   r­   r   r¯   r®   rŽ   rƒ   r_   )rE   rI   rf  rg  ÚfirstServerra   rG   rm  ÚlostDeferredrÄ   ÚstartDeferredr»   rK   )ro  r…   rI   r]   rL   rh  ‹  s4   
ÿ


ÿ
zAUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServerN)
rN   rO   rP   r$   r%   r&   rW   r^  rj  rh  rK   rK   rK   rL   rV  F  s    ý"rV  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u r
t| ƒ| _ | j S )z‹
        Return a path usable by C{connectUNIX} and C{listenUNIX}.

        @return: A path instance, built with C{_abstractPath}.
        N)Ú_pathrU   rk   rK   rK   rL   rG   Ô  s   

zUnixClientTestsBuilder.pathc                 C   ó   |  | 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}   rG   ©rE   rI   rH   rK   rK   rL   r@  ß  ó   
zUnixClientTestsBuilder.listenc                 C   rw  )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Ž   rG   rx  rK   rK   rL   Úconnectë  ry  zUnixClientTestsBuilder.connect)rN   rO   rP   rQ   r&   rW   rv  ÚpropertyrG   r@  rz  rK   rK   rK   rL   ru  Ë  s    

ru  )jrQ   Úhashlibr   Úosr   r   r   r   r   Úpprintr   r   r	   r
   r   r   Ústructr   Útempfiler   r   Útypingr   r   r   Úunittestr   r   Ú_AF_UNIXÚImportErrorÚzope.interfacer   r   Útwisted.internetr   r   Útwisted.internet.addressr   Útwisted.internet.deferr   r   r   Útwisted.internet.endpointsr   r   Útwisted.internet.errorr    r!   r"   Útwisted.internet.interfacesr#   r$   r%   r&   Útwisted.internet.protocolr'   r(   r)   Útwisted.internet.taskr*   Ú&twisted.internet.test.connectionmixinsr+   r,   r-   r.   r/   Ú#twisted.internet.test.reactormixinsr0   Útwisted.internet.test.test_tcpr1   r2   r3   r4   Útwisted.python.compatr5   Útwisted.python.failurer6   Útwisted.python.filepathr7   Útwisted.python.logr8   r9   r:   Útwisted.python.reflectr;   Útwisted.python.runtimer<   rÕ   r8  r>   rU   rV   rc   rq   r{   r:  r>  rL  rM  rR  rU  rV  ÚglobalsÚupdateÚmakeTestCaseClassesru  rK   rK   rK   rL   Ú<module>   s’   ÿÿ%>   Y!- 
ü
ü~-