U
    
W[                     @   s  d Z ddlmZmZ ddlmZ ddlmZmZmZm	Z	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 ddlmZ dd	lmZ zdd
lmZ W n ek
r   dZY nX ddl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+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 ddl2m4Z4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z?m@Z@mAZAmBZB ddl8mCZC ddl8mDZD ddl8mEZE ddl8mFZF ddlGmHZHmIZImJZJ ddlKmLZL dd lMmNZNmOZOmPZP dd!lQmRZR dd"lSmTZT dd#lUmVZV eTd$dk	r.dZWnd%ZWG d&d' d'eXZYd(d) ZZG d*d+ d+e9Z[G d,d- d-eCZ\ee.G d.d/ d/eCZ]G d0d1 d1eYe;eDZ^G d2d3 d3eYe;Z_G d4d5 d5eXZ`G d6d7 d7eXZaG d8d9 d9eXZbG d:d; d;eaebe;e=e?ZcG d<d= d=e`ebe;e=e?ZdG d>d? d?e@e;Zeef ge^h  ef ge_h  ef gech  ef gedh  ef geeh  G d@dA dAe;eEZief geih  dS )Bz/
Tests for implementations of L{IReactorUNIX}.
    )divisionabsolute_import)S_IMODE)statcloseurandomunlinkfstat)mktempmkstemp)AF_INETSOCK_STREAM
SOL_SOCKETsocketerror)pformat)md5)pack)AF_UNIXN)implementer)
interfacesbase)UNIXAddress)DeferredfailgatherResults)UNIXServerEndpointUNIXClientEndpoint)ConnectionClosedFileDescriptorOverrunCannotListenError)IFileDescriptorReceiverIReactorUNIXIReactorSocketIReactorFDSet)DatagramProtocol)ServerFactoryClientFactory)LoopingCall)EndpointCreator)ReactorBuilder)ObjectModelIntegrationMixin)StreamTransportTestsMixinWriteSequenceTestsMixinMyClientFactoryMyServerFactory)ConnectableProtocol)ConnectionTestsMixin)StreamClientTestsMixin)runProtocolsWithReactor)nativeString_PY3	iteritems)Failure)addObserverremoveObservererr)platform)requireModule)_coerceToFilesystemEncodingztwisted.python.sendmsgz>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getattrZstopListeningassertEqualr   r   st_mode)selfZ
methodNamepathfactoryr?   reactorZunixPort rH   A/usr/lib/python3/dist-packages/twisted/internet/test/test_unix.py	_modeTest@   s
    zUNIXFamilyMixin._modeTestN)__name__
__module____qualname____doc__rJ   rH   rH   rH   rI   r>   <   s   r>   c                 C   s   t td S )zI
    Return a new, unique abstract namespace path to be listened on.
    d   )r   r   Z	hexdigest)ZcaserH   rH   rI   _abstractPathL   s    rP   c                   @   s(   e Zd ZdZejfZdd Zdd ZdS )UNIXCreatorz(
    Create UNIX socket end points.
    c                 C   s   t ddd}t||S )z3
        Construct a UNIX server endpoint.
        .sock.suffixdir)r
   r   )rD   rG   rE   rH   rH   rI   serverZ   s    zUNIXCreator.serverc                 C   s   t ||jS )z3
        Construct a UNIX client endpoint.
        )r   name)rD   rG   ZserverAddressrH   rH   rI   clientc   s    zUNIXCreator.clientN)	rK   rL   rM   rN   r   r"   requiredInterfacesrW   rY   rH   rH   rH   rI   rQ   T   s   	rQ   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)rD   r\   r]   rH   rH   rI   __init__u   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sendFileDescriptorr\   r]   writeloseConnectionrD   rH   rH   rI   connectionMade   s    z!SendFileDescriptor.connectionMadec                 C   s   t | | || _d S N)r0   connectionLostreasonrD   rg   rH   rH   rI   rf      s    z!SendFileDescriptor.connectionLost)rK   rL   rM   rN   rg   r^   rd   rf   rH   rH   rH   rI   r[   k   s
   r[   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)rg   r   waitingr   rc   rH   rH   rI   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)rj   callback)rD   
descriptorrH   rH   rI   fileDescriptorReceived   s    z,ReceiveFileDescriptor.fileDescriptorReceivedc                 C   s.   | j dk	r*| j ttd|f  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 (%r) before descriptor.)rj   errbackr7   	ExceptionrD   r]   rH   rH   rI   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   rf   rj   ro   rg   rh   rH   rH   rI   rf      s
    
z$ReceiveFileDescriptor.connectionLost)
rK   rL   rM   rN   rg   rj   rk   rn   rr   rf   rH   rH   rH   rI   ri      s   	ri   c                   @   s,  e Zd ZdZefZe Zdd Zdd Z	e
 s6de	_dd Zd	d
 Ze
 sTde_dd Zdd Zedk	rree_dd Zedk	ree_dd Zedk	ree_dd Zdd Zedk	ree_dd Ze
 rde_nedk	ree_dd Zedk	ree_dd Zedk	ree_dd  Zedk	r(ee_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)rJ   r
   r&   rc   rH   rH   rI   	test_mode   s    zUNIXTestsBuilder.test_modec                 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)rP   r@   rt   r&   rB   getHostr   rD   rE   rG   portrH   rH   rI   #test_listenOnLinuxAbstractNamespace   s    z4UNIXTestsBuilder.test_listenOnLinuxAbstractNamespace8Abstract namespace UNIX sockets only supported on Linux.c              	   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)r   rc   rH   rH   rI   raiseSocketError   s    z=UNIXTestsBuilder.test_listenFailure.<locals>.raiseSocketErrorZcreateInternetSocketznot-usedN)patchr   ZBasePortr@   ZassertRaisesr    rt   r&   )rD   r|   rG   rH   rH   rI   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.
        rv   N)rP   r@   connectUNIXr'   rB   ZgetDestinationr   )rD   rE   rG   Z	connectorrH   rH   rI   $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)dictrw   getPeer	addressesrb   )rD   r_   rH   rH   rI   makeConnection  s
     zCUNIXTestsBuilder.test_addresses.<locals>.SaveAddress.makeConnectionN)rK   rL   rM   r   rH   rH   rH   rI   SaveAddress  s   r   r   r   N)r0   r3   	endpointsrB   r   )rD   r   rW   rY   rH   rH   rI   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      junkc                    s@    | t t}t|   |   |  d S re   )r   r   r   rB   ZgetsocknameZassertNotEqualfileno)rm   Zreceived)r   srD   rH   rI   checkDescriptor3  s    zAUNIXTestsBuilder.test_sendFileDescriptor.<locals>.checkDescriptorz-Sending file descriptor encountered a problemc                    s
    j  S re   r_   rb   ZignoredrW   rH   rI   <lambda>B      z:UNIXTestsBuilder.test_sendFileDescriptor.<locals>.<lambda>N)r   r   bindr[   r   ri   rk   addCallback
addErrbackr:   addBothr3   r   )rD   rY   dr   rH   )r   r   rD   rW   rI   test_sendFileDescriptor&  s    

z(UNIXTestsBuilder.test_sendFileDescriptorNc                 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 re   )r_   pauseProducingrc   rH   rH   rI   rd   O  s    zbUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.DoesNotRead.connectionMadeNrK   rL   rM   rd   rH   rH   rH   rI   DoesNotReadN  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)r_   r`   r   r   ra   rH   rc   rH   rI   senderX  s    zUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMade.<locals>.senderr   zSend loop failure)
r   r_   ZregisterProducerr(   taskrG   Zclockstartr   r:   )rD   r   rH   rc   rI   rd   U  s    
zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMadec                 S   s   |    d S re   _disconnectrc   rH   rH   rI   stopProducing_  s    znUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.stopProducingc                 S   s   |    d S re   r   rc   rH   rH   rI   resumeProducingb  s    zpUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.resumeProducingc                 S   s   d| _ | j  |   d S )NT)pausedr_   ZunregisterProducerr   rc   rH   rH   rI   r   e  s    
zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.pauseProducingc                 S   s$   | j   | j  | jj  d S re   )r   stopr_   ZabortConnectionotherrc   rH   rH   rI   r   j  s    

zlUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors._disconnectN)	rK   rL   rM   r   rd   r   r   r   r   rH   rH   rH   rI   SendsManyFileDescriptorsR  s   
r   z*sendFileDescriptor producer was not pausedN)r0   r   r3   r   
assertTruer   )rD   r   r   rW   rY   rH   rH   rI   -test_sendFileDescriptorTriggersPauseProducingI  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 re   r   r   r   rH   rI   r     r   z=UNIXTestsBuilder.test_fileDescriptorOverrun.<locals>.<lambda>r   )r   r[   r   ri   rk   r   appendr3   r   assertIsInstancer7   Ztrapr   rg   valuer   )rD   cargorY   resultr   rH   r   rI   test_fileDescriptorOverrunz  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 re   )r	   st_devst_ino)r\   ZfsrH   rH   rI   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 re   )fdsdeviceInodesReceivedrc   rH   rH   rI   r^     s    zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.__init__c                    s(   | j | | j | t| d S re   )r   r   r   r   )rD   r\   r   rH   rI   rn     s    zgUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.fileDescriptorReceivedN)rK   rL   rM   r^   rn   rH   r   rH   rI   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 re   )r   Zprotocol)rD   sktprotorH   rH   rI   r^     s    zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.__init__c                 S   s   d S re   rH   rq   rH   rH   rI   _dataReceived  s    z^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._dataReceivedc                 S   s   d S re   rH   rc   rH   rH   rI   rw     s    zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getHostc                 S   s   d S re   rH   rc   rH   rH   rI   r     s    zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getPeerc                 S   s   d S re   rH   )rD   orH   rH   rI   _getLogPrefix  s    z^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._getLogPrefixN)	rK   rL   rM   Z
bufferSizer^   r   rw   r   r   rH   rH   rH   rI   FakeReceiver  s   r   s   some data needs to be sentc                    s   g | ]} |qS rH   rH   .0r\   r   rH   rI   
<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doReadrB   lenr   ZassertFalsesetintersectionr   )rD   ancillaryPackerr   r   r   r   r   Z
sendSocketZ
recvSocketr   ZreceiverZ	fileOneFDZfileOneNameZ	fileTwoFDZfileTwoNameZ
dataToSend	fdsToSend	ancillaryexpectedCountZdeviceInodesSentrH   r   rI   )_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   rH   rI   r     s    z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSG.<locals>.ancillaryPackerNr   r   r   rD   r   rH   r   rI   1test_multiFileDescriptorReceivedPerRecvmsgOneCMSG  s    zBUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSGc                    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   rH   rI   r     s   zpUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs.<locals>.ancillaryPacker.<locals>.<listcomp>r   rH   r   r   rH   rI   r     s
    
z\UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs.<locals>.ancillaryPackerNr   r   rH   r   rI   2test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs  s    zCUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGsz=Multi control message ancillary sendmsg not supported on Mac.c                    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   rH   r   rH   rH   rI   r   )  s    z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.ancillaryPackerc                    s   d}dg}d}  |||S )Ns	   some data)NNr   r   )ZRecievedMessage)r   argskwargsr]   r   flagsr   rH   rI   fakeRecvmsgUnsupportedAncillary.  s    zkUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.fakeRecvmsgUnsupportedAncillaryZrecvmsgz#received unsupported ancillary datac                 3   s   | ]} |d  kV  qdS )formatNrH   )r   e)expectedMessagerH   rI   	<genexpr>=  s     zUUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.<genexpr>z+Expected message not found in logged eventsN)
Ztwisted.pythonr   r8   r   r   r9   r}   r   anyr   )rD   r   r   eventsfoundrH   )r   r   rI   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 ],}t|
D ]\}}|||kr qq qq| 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 re   )r_   rw   hostAddressr   peerAddressr[   rd   rc   rH   rH   rI   rd   V  s    zaUNIXTestsBuilder.test_avoidLeakingFileDescriptors.<locals>.RecordEndpointAddresses.connectionMadeNr   rH   rH   rH   rI   RecordEndpointAddressesU  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   r8   r   r   r9   r[   r   r0   r3   r   r   setblockingrB   Zrecvr   r   r   r6   getr   r   )rD   r   ZprobeClientZprobeServerr   r   rW   rY   r   ZclsNameZexpectedEventZlogEventkvrH   rH   rI    test_avoidLeakingFileDescriptorsC  s>    


 z1UNIXTestsBuilder.test_avoidLeakingFileDescriptorsc                    s   t tG  fdddt}t }t| d}| }t || j  t	|j
d  trx dt|j
dd  n dd|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 re   )r0   rd   r   rc   rH   rH   rI   rd     s    
zYUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.connectionMadec                    s      t| | jt| d S re   )r   r   r   r   type)Z	innerSelfrm   rc   rH   rI   rn     s    zaUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.fileDescriptorReceivedc                 S   s   | j | d S re   )r   extendrq   rH   rH   rI   rr     s    zWUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.dataReceivedN)rK   rL   rM   rd   rn   rr   rH   rc   rH   rI   RecordEvents  s   r   r   r      Nr   )r   r!   r0   r   r[   r   r3   r   rB   intr   r5   bytesjoin)rD   r   r   rW   rY   rH   rc   rI   #test_descriptorDeliveredBeforeBytes  s    z4UNIXTestsBuilder.test_descriptorDeliveredBeforeBytes)rK   rL   rM   rN   r"   rZ   rQ   r   ru   rz   r;   isLinuxskipr~   r   r   r   sendmsgSkipr   r   r   r   r   ZisMacOSXr   r   r   rH   rH   rH   rI   rs      sT   	-]$A

rs   c                   @   s6   e Zd ZdZejfZdd Zdd Ze	
 s2de_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)rJ   r
   r%   rc   rH   rH   rI   test_listenMode  s    z(UNIXDatagramTestsBuilder.test_listenModec                 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.
        rv   N)rP   r@   r   r%   rB   rw   r   rx   rH   rH   rI   rz     s    z<UNIXDatagramTestsBuilder.test_listenOnLinuxAbstractNamespacer{   N)rK   rL   rM   rN   r   ZIReactorUNIXDatagramrZ   r   rz   r;   r   r   rH   rH   rH   rI   r     s   
r   c                   @   s(   e Zd ZdZeefZdd Zdd ZdS )SocketUNIXMixinzb
    Mixin which uses L{IReactorSocket.adoptStreamPort} to hand out listening
    UNIX ports.
    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.
        rR   rS   rT      FN)
r   r   r
   r   listenr   r   ZadoptStreamPortr   Zfamily)rD   rG   rF   ZportSockrE   rH   rH   rI   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   rX   rD   rG   addressrF   rH   rH   rI   connectToListener  s    z!SocketUNIXMixin.connectToListenerN)	rK   rL   rM   rN   r"   r#   rZ   r  r  rH   rH   rH   rI   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
        rR   rS   rT   )r
   rt   )rD   rG   rF   rE   rH   rH   rI   r    s    z ListenUNIXMixin.getListeningPortc                 C   s   | |j|S r  r  r  rH   rH   rI   r    s    z!ListenUNIXMixin.connectToListenerN)rK   rL   rM   rN   r  r  rH   rH   rH   rI   r    s   	r  c                   @   s"   e Zd ZefZdd Zdd ZdS )UNIXPortTestsMixinc                 C   s   d|t | jf S )zZ
        Get the message expected to be logged when a UNIX port starts listening.
        z%s starting on %rr4   rw   rX   )rD   ry   rF   rH   rH   rI   #getExpectedStartListeningLogMessage  s    z6UNIXPortTestsMixin.getExpectedStartListeningLogMessagec                 C   s   dt | jf S )zJ
        Get the expected connection lost message for a UNIX port
        z(UNIX Port %s Closed)r
  )rD   ry   rH   rH   rI   getExpectedConnectionLostLogMsg$  s    z2UNIXPortTestsMixin.getExpectedConnectionLostLogMsgN)rK   rL   rM   r"   rZ   r  r  rH   rH   rH   rI   r	    s   r	  c                   @   s   e Zd ZdZdS )UNIXPortTestsBuilderz.
    Tests for L{IReactorUNIX.listenUnix}
    NrK   rL   rM   rN   rH   rH   rH   rI   r  ,  s   r  c                   @   s   e Zd ZdZdS )UNIXFDPortTestsBuilderz3
    Tests for L{IReactorUNIX.adoptStreamPort}
    Nr  rH   rH   rH   rI   r  4  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 re   rH   )rD   r  rH   rH   rI   buildProtocolN  s    zfUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNone.<locals>.NoneFactory.buildProtocolN)rK   rL   rM   r  rH   rH   rH   rI   NoneFactoryM  s   r  FN)r@   r   r   r&   r   r   r   r   r   r   adoptStreamConnectionZassertIsNone)	rD   rG   r   r  s1s2Zs1FDrF   r   rH   rH   rI   test_buildProtocolReturnsNone?  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 )Nr   z <AccumulatingProtocol #%s on %s>zAccumulatingProtocol,%s,%sr   )r_   rb   r=   rw   rX   rB   Z	sessionnostrZlogstrrF   ZpeerAddressesr   r   )	protocolsrY   rW   ry   ZportPathr   rc   rH   rI   	connecteda  s$    


zOUNIXAdoptStreamConnectionTestsBuilder.test_ServerAddressUNIX.<locals>.connectedN)	interfaceaddressFamily)r@   getConnectedClientAndServerr   Z
runReactor)rD   r  rG   r   rH   rc   rI   test_ServerAddressUNIX\  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.
        rR   rS   rT   c                    s0     | j  | j  | j t d S re   )ZremoveReaderr_   ZremoveWriterr  r   r   )r   )rG   rW   rH   rI   firstServerConnected  s      z_UNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.firstServerConnectedc                    s    j r   | S re   )runningr   )r   )rG   rH   rI   r     s    zOUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.stopc                    s   | \}}  ||f d S re   )rl   )r  rY   rW   )deferredry   rH   rI   r     s    zPUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.start)r/   r   ZprotocolConnectionMadeZprotocolConnectionLostr.   r
   rt   r   r   r   r   r   rw   rX   )rD   rG   r  r  ZfirstServerrY   rE   r  ZlostDeferredr   ZstartDeferredr   rH   )r   ry   rG   rW   rI   r  {  s4    


zAUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServerN)
rK   rL   rM   r$   r#   r"   rZ   r  r  r  rH   rH   rH   rI   r  <  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)_pathrP   rc   rH   rH   rI   rE     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.
        )rt   rE   rD   rG   rF   rH   rH   rI   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   rE   r#  rH   rH   rI   connect  s    
zUnixClientTestsBuilder.connect)rK   rL   rM   rN   r"   rZ   r"  propertyrE   r  r$  rH   rH   rH   rI   r!    s   
r!  )jrN   Z
__future__r   r   r   r   osr   r   r   r	   Ztempfiler
   r   r   r   r   r   r   Zpprintr   Zhashlibr   Zstructr   r   ImportErrorZzope.interfacer   Ztwisted.internetr   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.connectionmixinsr)   Z#twisted.internet.test.reactormixinsr*   Ztwisted.internet.test.test_corer+   Ztwisted.internet.test.test_tcpr,   r-   r.   r/   r0   r1   r2   r3   Ztwisted.python.compatr4   r5   r6   Ztwisted.python.failurer7   Ztwisted.python.logr8   r9   r:   Ztwisted.python.runtimer;   Ztwisted.python.reflectr<   Ztwisted.python.filepathr=   r   objectr>   rP   rQ   r[   ri   rs   r   r   r  r	  r  r  r  globalsupdateZmakeTestCaseClassesr!  rH   rH   rH   rI   <module>   s   
'A   Z!,!  u/