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 gech  ef gedh  ef geeh  G d<d= d=eCe@Zief geih  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_mode8Abstract 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!- 

~-