
    Ϫf,                        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 	 ddlmZ 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 ZX eTd      d!ZX G d" d#      ZYd$ ZZ G d% d&e?      Z[ G d' d(e=      Z\ e e2       G d) d*e=             Z] G d+ d,eYeCe>      Z^ G d- d.eYeC      Z_ G d/ d0      Z` G d1 d2      Za G d3 d4      Zb G d5 d6eaebeCeG      Zc G d7 d8e`ebeCeG      Zd G d9 d:eHeC      Ze ef       j                  e^j                                 ef       j                  e_j                                 ef       j                  ecj                                 ef       j                  edj                                 ef       j                  eej                                 G d; d<eCe@      Zi ef       j                  eij                                y# e$ r dZY 1w xY w)=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                       e Zd ZdZd Zy)UNIXFamilyMixinzK
    Test-helper defining mixin for things related to AF_UNIX sockets.
    c                     d}| j                         } t        ||      |||      }|j                          | j                  t	        t        |      j                        |       y)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factoryrB   reactorunixPorts          A/usr/lib/python3/dist-packages/twisted/internet/test/test_unix.py	_modeTestzUNIXFamilyMixin._modeTestO   sY    
 ##%/77J/gDI d!3!34d;    N)__name__
__module____qualname____doc__rO    rP   rN   r@   r@   J   s    	<rP   r@   c                 F    t        t        d            j                         S )zI
    Return a new, unique abstract namespace path to be listened on.
    d   )r   r   	hexdigest)cases    rN   _abstractPathrZ   [   s     ws|&&((rP   c                   T    e Zd ZU dZej
                  fZeee	e
         ed<   d Zd Zy)UNIXCreatorz(
    Create UNIX socket end points.
    requiredInterfacesc                 4    t        dd      }t        ||      S )z3
        Construct a UNIX server endpoint.
        .sock.suffixdir)r   r    )rH   rL   rJ   s      rN   serverzUNIXCreator.serveri   s    
 W#.!'400rP   c                 .    t        ||j                        S )z3
        Construct a UNIX client endpoint.
        )r   name)rH   rL   serverAddresss      rN   clientzUNIXCreator.clientq   s     "'=+=+=>>rP   N)rQ   rR   rS   rT   r   r'   r]   r   r   r   r   __annotations__rd   rh   rU   rP   rN   r\   r\   b   s7     @J?V?V>X$y/!:;X1?rP   r\   c                   &    e Zd ZdZdZd Zd Zd Zy)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                      || _         || _        y)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)rH   rm   rn   s      rN   __init__zSendFileDescriptor.__init__   s     	rP   c                     | j                   j                  | j                         | j                  r%| j                   j	                  | j                         | j                   j                          y)zn
        Send C{self.fd} and, if it is not L{None}, C{self.data}.  Then close the
        connection.
        N)	transportsendFileDescriptorrm   rn   writeloseConnectionrH   s    rN   connectionMadez!SendFileDescriptor.connectionMade   sG    
 	))$''299NN  +%%'rP   c                 >    t        j                  | |       || _        y N)r,   connectionLostreasonrH   rz   s     rN   ry   z!SendFileDescriptor.connectionLost   s    **48rP   )rQ   rR   rS   rT   rz   ro   rv   ry   rU   rP   rN   rk   rk   x   s     F	(rP   rk   c                   0    e Zd ZdZdZdZd Zd Zd Zd Z	y)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                 z    | j                   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.
        )rz   r   waitingr   ru   s    rN   waitForDescriptorz'ReceiveFileDescriptor.waitForDescriptor   s0     ;;#:DL<<$$rP   c                 H    | j                   j                  |       d| _         y)z
        Fire the waiting Deferred, initialized by C{waitForDescriptor}, with the
        file descriptor just received.
        N)r   callback)rH   
descriptors     rN   fileDescriptorReceivedz,ReceiveFileDescriptor.fileDescriptorReceived   s    
 	j)rP   c           	          | j                   9| j                   j                  t        t        d|d                   d| _         yy)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.)r   errbackr7   	ExceptionrH   rn   s     rN   dataReceivedz"ReceiveFileDescriptor.dataReceived   sF     <<#LL  	$4TH<P"QRS  DL	 $rP   c                     t        j                  | |       | j                  "| j                  j                  |       d| _        || _        y)zj
        Fail the waiting Deferred, initialized by C{waitForDescriptor}, if there
        is one.
        N)r,   ry   r   r   rz   r{   s     rN   ry   z$ReceiveFileDescriptor.connectionLost   s>    
 	**48<<#LL  (DLrP   )
rQ   rR   rS   rT   rz   r   r   r   r   ry   rU   rP   rN   r}   r}      s'    
 FG
% 	rP   r}   c                      e Zd ZdZefZ e       Zd Z e	 e
j                          d      d        Zd Z e	 e
j                          d      d        Zd Z e	e e      d        Z e	d	d
      d        Z e	e e      d        Zd Z e	e e      d        Z e	 e
j.                         d       e	e e      d               Z e	e e      d        Z e	e e      d        Z e	e e      d        Zy)UNIXTestsBuilderz=
    Builder defining tests relating to L{IReactorUNIX}.
    c                 V    | j                  d| j                         t                      y)zs
        The UNIX socket created by L{IReactorUNIX.listenUNIX} is created with
        the mode specified.
        
listenUNIXN)rO   r   r*   ru   s    rN   	test_modezUNIXTestsBuilder.test_mode   s    
 	|T[[]MODrP   8Abstract namespace UNIX sockets only supported on Linux.c                     t        |       }| j                         }|j                  d|z   t                     }| j	                  |j                         t        d|z                y)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)rZ   rC   r   r*   rF   getHostr   rH   rJ   rL   ports       rN   #test_listenOnLinuxAbstractNamespacez4UNIXTestsBuilder.test_listenOnLinuxAbstractNamespace   sS     T"##%!!$+}?TD[)ABrP   c                     d }| j                  t        j                  d|       | j                         }| j	                  t
              5  |j                  dt                      ddd       y# 1 sw Y   yxY w)z
        L{IReactorUNIX.listenUNIX} raises L{CannotListenError} if the
        underlying port's createInternetSocket raises a socket error.
        c                     t        d      )Nz FakeBasePort forced socket.error)OSErrorru   s    rN   raiseSocketErrorz=UNIXTestsBuilder.test_listenFailure.<locals>.raiseSocketError  s    <==rP   createInternetSocketznot-usedN)patchr   BasePortrC   assertRaisesr!   r   r*   )rH   r   rL   s      rN   test_listenFailurez#UNIXTestsBuilder.test_listenFailure   sc    	> 	

4=="8:JK##%01 	<z=?;	< 	< 	<s   
A..A7c                     t        |       }| j                         }|j                  d|z   t                     }| j	                  |j                         t        d|z                y)zc
        L{IReactorUNIX.connectUNIX} also accepts a Linux abstract namespace
        path.
        r   N)rZ   rC   connectUNIXr(   rF   getDestinationr   )rH   rJ   rL   	connectors       rN   $test_connectToLinuxAbstractNamespacez5UNIXTestsBuilder.test_connectToLinuxAbstractNamespace
  sV     T"##%''t]_E	113[5MNrP   c                     G d dt               } |       } |       }t        | ||| j                         | j                  |j                  d   |j                  d          | j                  |j                  d   |j                  d          y)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 Zy)4UNIXTestsBuilder.test_addresses.<locals>.SaveAddressc                     t        |j                         |j                               | _        |j	                          y )N)hostpeer)dictr   getPeer	addressesrt   )rH   rq   s     rN   makeConnectionzCUNIXTestsBuilder.test_addresses.<locals>.SaveAddress.makeConnection   s3    !%"**,93D3D3F" ((*rP   N)rQ   rR   rS   r   rU   rP   rN   SaveAddressr     s    +rP   r   r   r   N)r,   r0   	endpointsrF   r   )rH   r   rd   rh   s       rN   test_addresseszUNIXTestsBuilder.test_addresses  s}    	+- 	+ ffdnnE))&163C3CF3KL))&163C3CF3KLrP   c                 j    ddl m t               j                  d       t        j	                         d      t               }|j                         } fd}|j                  |       |j                  t        d       |j                  fd       t         | j                         y)	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                      | t         t              }t        |        j                  j	                         |j	                                j                  j                         |j                                y rx   )r
   r   r   rF   getsocknameassertNotEqualfileno)r   receivedr   srH   s     rN   checkDescriptorzAUNIXTestsBuilder.test_sendFileDescriptor.<locals>.checkDescriptor=  sY    j';?H* Q]]_h.B.B.DE
 
HOO,=>rP   z-Sending file descriptor encountered a problemc                 8    j                   j                         S rx   rq   rt   ignoredrd   s    rN   <lambda>z:UNIXTestsBuilder.test_sendFileDescriptor.<locals>.<lambda>M      &"2"2"A"A"C rP   N)r   r   bindrk   r   r}   r   addCallback
addErrbackr:   addBothr0   r   )rH   rh   dr   r   r   rd   s   `   @@@rN   test_sendFileDescriptorz(UNIXTestsBuilder.test_sendFileDescriptor.  s     	"H	w#AHHJ8&($$&	? 	
o&	SIJ			CDffdnnErP   Tzfails under LXC in Debian CIc                      G d dt               } G d dt               } |       } |       }||_        t        | ||| j                         | j	                  |j
                  d       y)z
        If a L{IUNIXTransport.sendFileDescriptor} call fills up
        the send buffer, any registered producer is paused.
        c                       e Zd Zd Zy)SUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.DoesNotReadc                 8    | j                   j                          y rx   )rq   pauseProducingru   s    rN   rv   zbUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.DoesNotRead.connectionMadeY  s    --/rP   NrQ   rR   rS   rv   rU   rP   rN   DoesNotReadr   X  s    0rP   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)`UNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptorsFc                 .    t                _          j                  j                   d        fd}t        |       _         j                  j
                   j                  _         j                  j                  d      j                  t        d       y )NTc                       j                   j                   j                  j                                 j                   j	                  d       y )N   x)rq   rr   r   r   rs   ru   s   rN   senderzUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMade.<locals>.senderc  s4    NN55dkk6H6H6JKNN((.rP   r   zSend loop failure)
r   rq   registerProducerr+   taskrL   clockstartr   r:   )rH   r   s   ` rN   rv   zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.connectionMade_  sf    $h//d;/ (/	"&.."8"8				"--c3FGrP   c                 $    | j                          y rx   _disconnectru   s    rN   stopProducingznUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.stopProducingk        "rP   c                 $    | j                          y rx   r   ru   s    rN   resumeProducingzpUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.resumeProducingn  r   rP   c                 f    d| _         | j                  j                          | j                          y )NT)pausedrq   unregisterProducerr   ru   s    rN   r   zoUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors.pauseProducingq  s%    "113  "rP   c                     | j                   j                          | j                  j                          | j                  j                  j                          y rx   )r   stoprq   abortConnectionotherru   s    rN   r   zlUNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducing.<locals>.SendsManyFileDescriptors._disconnectv  s6    		 ..0

$$446rP   N)	rQ   rR   rS   r   rv   r   r   r   r   rU   rP   rN   SendsManyFileDescriptorsr   \  s!    F
H###
7rP   r   z*sendFileDescriptor producer was not pausedN)r,   r   r0   r   
assertTruer   )rH   r   r   rd   rh   s        rN   -test_sendFileDescriptorTriggersPauseProducingz>UNIXTestsBuilder.test_sendFileDescriptorTriggersPauseProducingQ  sY    	0- 	0	7': 	7> *+ffdnnE'STrP   c                    t               }t        |j                         d      t               }g }|j	                         }|j                  |j                         |j                  fd       t        | || j                         | j                  |d   t               |d   j                  t               | j                  j                  j                  t               y)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                 8    j                   j                         S rx   r   r   s    rN   r   z=UNIXTestsBuilder.test_fileDescriptorOverrun.<locals>.<lambda>  r   rP   r   )r   rk   r   r}   r   r   appendr0   r   assertIsInstancer7   trapr"   rz   valuer#   )rH   cargorh   resultr   rd   s        @rN   test_fileDescriptorOverrunz+UNIXTestsBuilder.test_fileDescriptorOverrun  s     #ELLND9&($$&			&-- 			CDffdnnEfQi1q	'(fmm113HIrP   c                 j   ddl m} ddlm} ddlm} d t        t               G fddt                     } G d d	|      } |t        t              \  }}| j                  |j                         | j                  |j                          |       }	 |||	      }
t               \  }}t               \  }}| j                  t        |       | j                  t        |       d
}||g} ||      \  }} ||||       |
j                          | j!                  t#        |	j$                        |       | j'                  t)        |      j+                  t)        |	j$                                     |	j$                  r2|D cg c]
  } |       }}| j!                  ||	j,                         yyc c}w )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                 H    t        |       }|j                  |j                  fS rx   )r   st_devst_ino)rm   fss     rN   deviceInodeTuplezTUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.deviceInodeTuple  s    rBIIryy))rP   c                       e Zd Zd Z fdZy)PUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocolc                      g | _         g | _        y rx   )fdsdeviceInodesReceivedru   s    rN   ro   zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.__init__  s    ,.)rP   c                     | j                   j                  |       | j                  j                   |             t        |       y rx   )r  r   r  r   )rH   rm   r   s     rN   r   zgUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeProtocol.fileDescriptorReceived  s4    #))001A"1EFb	rP   N)rQ   rR   rS   ro   r   )r   s   rN   FakeProtocolr     s    /rP   r  c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)PUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver   c                      || _         || _        y rx   )r   protocol)rH   sktprotos      rN   ro   zYUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.__init__  s    ! %rP   c                      y rx   rU   r   s     rN   _dataReceivedz^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._dataReceived      rP   c                      y rx   rU   ru   s    rN   r   zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getHost  r  rP   c                      y rx   rU   ru   s    rN   r   zXUNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver.getPeer  r  rP   c                      y rx   rU   )rH   os     rN   _getLogPrefixz^UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver.<locals>.FakeReceiver._getLogPrefix  r  rP   N)	rQ   rR   rS   
bufferSizero   r  r   r   r  rU   rP   rN   FakeReceiverr    s     J&rP   r  s   some data needs to be sentN)r   r   twisted.internet.unixr   twisted.python.sendmsgr   r   r$   r,   r   r   
addCleanupr   r   r   doReadrF   lenr  assertFalsesetintersectionr  )rH   ancillaryPackerr   r   r   r  r  
sendSocket
recvSocketr  receiver	fileOneFDfileOneName	fileTwoFDfileTwoName
dataToSend	fdsToSend	ancillaryexpectedCountrm   deviceInodesSentr   s                        @rN   )_sendmsgMixinFileDescriptorReceivedDriverz:UNIXTestsBuilder._sendmsgMixinFileDescriptorReceivedDriver  sx   : 	&72	* 
,	-	. 	 
.		= 	& ",G[!A
J
(()
(()
E2 ")	;!(	;,,2
	*	#29#= 	=
J	2 	UYY7 	Y44S^DE 99?HI 0 4II-u/I/IJ Is   F0c                 >    ddl m fd}| j                  |       y)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                 8    t         t        dg|  fg}d}||fS )Nii   r   r   )r'  r(  r)  r.  s      rN   r  z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSG.<locals>.ancillaryPacker  s,    $j$t2Hi2HIJIMm++rP   Nr  r.  r+  rH   r  r.  s     @rN   1test_multiFileDescriptorReceivedPerRecvmsgOneCMSGzBUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgOneCMSG  s     	6	,
 	66GrP   z=Multi control message ancillary sendmsg not supported on Mac.c                 >    ddl m fd}| j                  |       y)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           	      Z    | D cg c]  }t         t        d|      f }}d}||fS c c}w )Nir1  r2  )r'  rm   r(  r)  r.  s       rN   r  z\UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs.<locals>.ancillaryPacker  s9    KTUR*j$sB-@UIUMm++ Vs   (Nr3  r4  s     @rN   2test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGszCUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgTwoCMSGs  s     	6	,
 	66GrP   c                 *   ddl m d }fd}g }t        |j                         | j	                  t
        |j                         | j                  d|       | j                  |       dt        fd|D              }| j                  |d       y	)
z
        _SendmsgMixin handles multiple file descriptors per recvmsg, calling
        L{IFileDescriptorReceiver.fileDescriptorReceived} once per received
        file descriptor. Scenario: unsupported CMSGs.
        r   r   c                     g }d}||fS )Nr   rU   )r'  r(  r)  s      rN   r  z[UNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.ancillaryPacker0  s    IMm++rP   c                 8    d}dg}d}j                  |||      S )Ns	   some data)NNrP   r   )ReceivedMessage)r
  argskwargsrn   r(  flagsr   s         rN   fakeRecvmsgUnsupportedAncillaryzkUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.fakeRecvmsgUnsupportedAncillary5  s*    D*+IE**4EBBrP   recvmsgz#received unsupported ancillary datac              3   ,   K   | ]  }|d    v   yw)formatNrU   ).0eexpectedMessages     rN   	<genexpr>zUUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG.<locals>.<genexpr>D  s     CqOq{2Cs   z+Expected message not found in logged eventsN)
twisted.pythonr   r9   r   r  r;   r   r+  anyr   )rH   r  rA  eventsfoundrG  r   s        @@rN   1test_multiFileDescriptorReceivedPerRecvmsgBadCMSGzBUNIXTestsBuilder.test_multiFileDescriptorReceivedPerRecvmsgBadCMSG!  s~     	+	,
	C FMM"6

7I'FG66G @CFCCLMrP   c                    ddl m}  |       \  }}g }t        |j                         | j	                  t
        |j                          G d dt              } ||j                         d      }t               }t        | ||| j                         |j                          |j                  d       | j                  d|j                  d             d	}d
}	t        |j                   |j"                  |	|      }
|D ]1  }|
j%                         D ]  \  }}||j'                  |      k7  s 0  y | j)                  d|
dt+        |      d       y)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                       e Zd Zd Zy)RUNIXTestsBuilder.test_avoidLeakingFileDescriptors.<locals>.RecordEndpointAddressesc                     | j                   j                         | _        | j                   j                         | _        t
        j                  |        y rx   )rq   r   hostAddressr   peerAddressrk   rv   ru   s    rN   rv   zaUNIXTestsBuilder.test_avoidLeakingFileDescriptors.<locals>.RecordEndpointAddresses.connectionMade\  s:    #'>>#9#9#; #'>>#9#9#; "11$7rP   Nr   rU   rP   rN   RecordEndpointAddressesrP  [  s    8rP   rT  r   FrP   r  z%(protocolName)s (on %(hostAddress)r) does not provide IFileDescriptorReceiver; closing file descriptor received (from %(peerAddress)r).r,   )rR  rS  protocolNamerD  zExpected event (z) not found in logged events ()N)r   r   r9   r   r  r;   rk   r   r,   r0   r   r   setblockingrF   recvr   rS  rR  itemsgetr   r	   )rH   r   probeClientprobeServerrK  rT  rd   rh   rD  clsNameexpectedEventlogEventkvs                 rN    test_avoidLeakingFileDescriptorsz1UNIXTestsBuilder.test_avoidLeakingFileDescriptorsG  sJ    	&#-< [FMM"6	8&8 	8 )););)=wG$&ffdnnE 	 	&k..t45: 	
 ( **** 	
  	H%++- 1Q'
 	 II "rP   c                 h    t        t               G  fddt                     }t               }t	        |j                         d      } |       }t         || j                          j                  t        |j                  d           j                  dt        |j                  dd              y)z
        L{IUNIXTransport.sendFileDescriptor} sends file descriptors before
        L{ITransport.write} sends normal bytes.
        c                   $    e Zd Zd Z fdZd Zy)JUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEventsc                 <    t        j                  |        g | _        y rx   )r,   rv   rK  ru   s    rN   rv   zYUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.connectionMade  s    #2248 rP   c                 z    j                  t        |       | j                  j                  t	        |             y rx   )r  r   rK  r   type)	innerSelfr   rH   s     rN   r   zaUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.fileDescriptorReceived  s*    z2  ''Z(89rP   c                 :    | j                   j                  |       y rx   )rK  extendr   s     rN   r   zWUNIXTestsBuilder.test_descriptorDeliveredBeforeBytes.<locals>.RecordEvents.dataReceived  s    ""4(rP   N)rQ   rR   rS   rv   r   r   ru   s   rN   RecordEventsre    s    !:)rP   rl  r   r      N)r   r$   r,   r   rk   r   r0   r   rF   intrK  bytes)rH   rl  r   rd   rh   s   `    rN   #test_descriptorDeliveredBeforeBytesz4UNIXTestsBuilder.test_descriptorDeliveredBeforeBytes  s     
,	-
	). 
	) 
.
	) #ELLNG<ffdnnEfmmA./%ab(9":;rP   N)rQ   rR   rS   rT   r'   r]   r\   r   r   r   r=   isLinuxr   r   r   r   r   sendmsgSkipReasonr   r   r   r+  r5  isMacOSXr9  rM  rb  rp  rU   rP   rN   r   r      s    'IE HE
C	
C< HEO	OM, K*+ F , FD D01.U 2.U` K*+J ,J.aKF K*+H ,H G K*+H ,	
H K*+#N ,#NJ K*+J ,JX K*+< ,<rP   r   c                   n    e Zd ZdZej
                  fZd Z e e	j                          d      d        Zy)UNIXDatagramTestsBuilderzE
    Builder defining tests relating to L{IReactorUNIXDatagram}.
    c                 V    | j                  d| j                         t                      y)z
        The UNIX socket created by L{IReactorUNIXDatagram.listenUNIXDatagram}
        is created with the mode specified.
        listenUNIXDatagramN)rO   r   r)   ru   s    rN   test_listenModez(UNIXDatagramTestsBuilder.test_listenMode  s    
 	+T[[]<L<NOrP   r   c                     t        |       }| j                         }|j                  d|z   t                     }| j	                  |j                         t        d|z                y)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)rZ   rC   rw  r)   rF   r   r   r   s       rN   r   z<UNIXDatagramTestsBuilder.test_listenOnLinuxAbstractNamespace  sU     T"##%))$+7G7IJTD[)ABrP   N)rQ   rR   rS   rT   r   IReactorUNIXDatagramr]   rx  r   r=   rq  r   rU   rP   rN   ru  ru    sM     %99;
P HE	C		CrP   ru  c                   B    e Zd ZU dZeefZeee	e
         ed<   d Zd Zy)SocketUNIXMixinzb
    Mixin which uses L{IReactorSocket.adoptStreamPort} to hand out listening
    UNIX ports.
    r]   c                 B   t        t              }t        dd      }|j                  |       |j	                  d       |j                  d       	 |j                  |j                         |j                  |      |j                          S # |j                          w xY w)zj
        Get a UNIX port from a reactor, wrapping an already-initialized file
        descriptor.
        r_   r`   ra      F)
r   r   r   r   listenrW  adoptStreamPortr   familyr   )rH   rL   rK   portSockrJ   s        rN   getListeningPortz SocketUNIXMixin.getListeningPort  sv    
 '?W#.dU#	**8??+<hoowWNNHNNs   *B Bc                 :    |j                  |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   rf   rH   rL   addressrK   s       rN   connectToListenerz!SocketUNIXMixin.connectToListener       ""7<<99rP   N)rQ   rR   rS   rT   r'   r&   r]   r   r   r   r   ri   r  r  rU   rP   rN   r|  r|    s6     	?$y/!:; 
 :rP   r|  c                       e Zd ZdZd Zd Zy)ListenUNIXMixinzZ
    Mixin which uses L{IReactorTCP.listenUNIX} to hand out listening UNIX
    ports.
    c                 @    t        dd      }|j                  ||      S )z0
        Get a UNIX port from a reactor
        r_   r`   ra   )r   r   )rH   rL   rK   rJ   s       rN   r  z ListenUNIXMixin.getListeningPort  s#    
 W#.!!$00rP   c                 :    |j                  |j                  |      S r  r  r  s       rN   r  z!ListenUNIXMixin.connectToListener  r  rP   N)rQ   rR   rS   rT   r  r  rU   rP   rN   r  r     s    
1:rP   r  c                   <    e Zd ZU efZeeee         e	d<   d Z
d Zy)UNIXPortTestsMixinr]   c                 R    | dt        |j                         j                        S )zZ
        Get the message expected to be logged when a UNIX port starts listening.
        z starting on r6   r   rf   )rH   r   rK   s      rN   #getExpectedStartListeningLogMessagez6UNIXPortTestsMixin.getExpectedStartListeningLogMessage#  s'     -T\\^5H5H(I'LMMrP   c                 P    dt        |j                         j                         dS )zJ
        Get the expected connection lost message for a UNIX port
        z(UNIX Port z Closed)r  )rH   r   s     rN   getExpectedConnectionLostLogMsgz2UNIXPortTestsMixin.getExpectedConnectionLostLogMsg)  s%     \$,,.*=*=>?xHHrP   N)rQ   rR   rS   r'   r]   r   r   r   r   ri   r  r  rU   rP   rN   r  r     s)    ?Ko$y/!:;MNIrP   r  c                       e Zd ZdZy)UNIXPortTestsBuilderz.
    Tests for L{IReactorUNIX.listenUnix}
    NrQ   rR   rS   rT   rU   rP   rN   r  r  0      rP   r  c                       e Zd ZdZy)UNIXFDPortTestsBuilderz3
    Tests for L{IReactorUNIX.adoptStreamPort}
    Nr  rU   rP   rN   r  r  ;  r  rP   r  c                   (    e Zd ZeeefZd Zd Zd Z	y)%UNIXAdoptStreamConnectionTestsBuilderc                    | j                         }ddlm}  G d dt              } |t        t
              \  }}|j                  d       | j                  |j                         | j                  |j                         |j                         } |       }|j                  |t        |      }| j                  |       y)z
        {IReactorSocket.adoptStreamConnection} returns None if the given
        factory's buildProtocol returns None.
        r   r   c                       e Zd Zd Zy)XUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNone.<locals>.NoneFactoryc                      y rx   rU   )rH   r  s     rN   buildProtocolzfUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNone.<locals>.NoneFactory.buildProtocol\  s    rP   N)rQ   rR   rS   r  rU   rP   rN   NoneFactoryr  [  s    rP   r  FN)rC   r   r   r*   r   r   rW  r  r   r   adoptStreamConnectionassertIsNone)	rH   rL   r   r  s1s2s1FDrK   r   s	            rN   test_buildProtocolReturnsNonezCUNIXAdoptStreamConnectionTestsBuilder.test_buildProtocolReturnsNoneM  s     ##%%	- 	 G[1B
u!!yy{-..tWgF&!rP   c                       fd} j                         } j                  |dd      }|j                  |        j                  |       y)z>
        Helper method to test UNIX server addresses.
        c                 ,   | \  }}}	 t        d|j                         j                        }j                  d|j                  j
                  d|dt        |j                               j                  d|j                  j
                  d||j                  j                         |j                  j                  d   }j                  |t               |j                  j                          y # |j                  j                          w xY w)Nr>   z<AccumulatingProtocol #z on >zAccumulatingProtocol,,r   )r8   r   rf   rF   rq   	sessionnostrlogstrrK   peerAddressesr   r   rt   )	protocolsrh   rd   r   portPathrS  rH   s         rN   	connectedzOUNIXAdoptStreamConnectionTestsBuilder.test_ServerAddressUNIX.<locals>.connectedn  s    #, FFD26r4<<>;N;NO  ''118=(()   ''118=$$++ %nn::1=%%k;?   //1  //1s   CC7 7DN)	interfaceaddressFamily)rC   getConnectedClientAndServerr   
runReactor)rH   r  rL   r   s   `   rN   test_ServerAddressUNIXz<UNIXAdoptStreamConnectionTestsBuilder.test_ServerAddressUNIXi  sN    
	2, ##%,,t4 - 
 	
i  rP   c                    t               }t               |_        t               t               _        t               _        t	               }t               |_        t               |_        t        dd      }j                  ||      fd}|j                  j                  |       t        |j                  j                  g      }fd}	|j                  |	       t               j                  |	       t        |j                  j                  g      }
fd}|
j                  |       j                  j                         j                  |       S )a0  
        Return a L{Deferred} firing with a L{MyClientFactory} and
        L{MyServerFactory} connected pair, and the listening C{Port}. The
        particularity is that the server protocol has been obtained after doing
        a C{adoptStreamConnection} against the original server connection.
        r_   r`   ra   c                     j                  | j                         j                  | j                         j                  | j                  j	                         t
               y rx   )removeReaderrq   removeWriterr  r   r   )r  rL   rd   s    rN   firstServerConnectedz_UNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.firstServerConnected  sF      1  1))%//*@*@*BGVTrP   c                 @    j                   rj                          | S rx   )runningr   )r   rL   s    rN   r   zOUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.stop  s    MrP   c                 8    | \  }}j                  ||f       y rx   )r   )r  rh   rd   deferredr   s      rN   r   zPUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer.<locals>.start  s!    &NFFvvt45rP   )r3   r   protocolConnectionMadeprotocolConnectionLostr2   r   r   r   r   r   r   r   r   rf   )rH   rL   r  r  firstServerrh   rJ   r  lostDeferredr   startDeferredr   r  r   rd   s    `          @@@rN   r  zAUNIXAdoptStreamConnectionTestsBuilder.getConnectedClientAndServer  s(    &'-5Z* "(0
%(0
% "(0
%(0
% W#.!!$4	U
 	**667KL$**F,I,IJ
	
 	T":D!%**F,I,IJ
	6 	!!%(DLLN//8rP   N)
rQ   rR   rS   r%   r&   r'   r]   r  r  r  rU   rP   rN   r  r  F  s#    "8 !D6rP   r  c                   6    e Zd ZdZefZdZed        Zd Z	d Z
y)UnixClientTestsBuilderz7
    Define tests for L{IReactorUNIX.connectUNIX}.
    Nc                 R    | j                   t        |       | _         | j                   S )z
        Return a path usable by C{connectUNIX} and C{listenUNIX}.

        @return: A path instance, built with C{_abstractPath}.
        )_pathrZ   ru   s    rN   rJ   zUnixClientTestsBuilder.path  s$     ::&t,DJzzrP   c                 :    |j                  | 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   rJ   rH   rL   rK   s      rN   r  zUnixClientTestsBuilder.listen  s     !!$))W55rP   c                 :    |j                  | 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   rJ   r  s      rN   connectzUnixClientTestsBuilder.connect  s     ""499g66rP   )rQ   rR   rS   rT   r'   r]   r  propertyrJ   r  r  rU   rP   rN   r  r    s2     'E 
6
7rP   r  )jrT   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/   r0   #twisted.internet.test.reactormixinsr1   twisted.internet.test.test_tcpr2   r3   r4   r5   twisted.python.compatr6   twisted.python.failurer7   twisted.python.filepathr8   twisted.python.logr9   r:   r;   twisted.python.reflectr<   twisted.python.runtimer=   r   rr  r@   rZ   r\   rk   r}   r   ru  r|  r  r  r  r  r  globalsupdatemakeTestCaseClassesr  rU   rP   rN   <module>r     s^  
  2 2  ; ;   $ + + * G 1 - 0 @ @ M 
  U T -  ?  / * ? ? ? 0 +
0
1 )*6K 
< <")?/ ?,", "J $%;/ ; &;|S<8L S<lC CB*: *:Z: :@I I 		{,C^ {| 	  !557 8 	  )==? @ 	  %99; < 	  ';;= > 	  6JJL M*7^-C *7Z 	  ';;= >G  Gs   I= =JJ