o
    bD                 
   @   sR  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 ddlmZ ddlmZmZmZ 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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)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z?m@Z@mAZAmBZB ddlCmDZDmEZE ddlFmGZG ddlHmIZImJZJ ddlKmLZL ddlMmNZN ddlOmPZP ddlQmRZR ddlSmTZT ddlUmVZV ddlWmXZX ddlYmZZZm[Z[ dd l\mZ eVd!j]^d"Z_eVd!j]^d#Z`eVd!j]^d$ZaeVebj]^d%Zcecdd&Zeefe_jgZhefe`jgZiefeajgZjefecjgZkefeejgZlz:dd'lmmnZompZpmqZqmrZr dd(lsmtZtmuZumvZvmwZwmxZx dd)lymzZz dd*l{m|Z| et}e_~ Zex}e_~ Zd+Zd,ZW n ey Z zd-ZeeZW Y d.Z[nd.Z[ww G d/d0 d0e8ZeejG d1d2 d2eZeejG d3d4 d4eZeejG d5d6 d6eZG d7d8 d8e6ZG d9d: d:e6ZG d;d< d<ejZG d=d> d>ZG d?d@ d@ZG dAdB dBeeZG dCdD dDe7ZG dEdF dFZG dGdH dHejZG dIdJ dJej8ZeejG dKdL dLeBZeej0e eej2e eeje eejG dMdN dNZG dOdP dPejZG dQdR dRejZG dSdT dTejZG dUdV dVeejZG dWdX dXeejZG dYdZ dZeejZG d[d\ d\e@e<Zdd^d_ZG d`da daejZG dbdc dcejZG ddde deeZG dfdg dgeejZG dhdi dieejZG djdk dkeejZG dldm dmeejZG dndo doejZG dpdq dqejZG drds dsejZG dtdu duejZeeeG dvdw dweejZG dxdy dyeejZG dzd{ d{ejZG d|d} d}ejZdddZG dd dejZeeeG dd dejZG dd deejZG dd dejZG dd dejZG dd dejZG dd dejZG dd deJjZG dd deJjZG dd deIjZG dd deZG dd dejZdd ZeeeG dd dejZdd ZG dd dejZd.S )z
Test the C{I...Endpoint} implementations that wrap the L{IReactorTCP},
L{IReactorSSL}, and L{IReactorUNIX} interfaces found in
L{twisted.internet.endpoints}.
    )EPERM)AF_INETAF_INET6IPPROTO_TCPSOCK_STREAMgaierror)FunctionType)	normalize)skipIf)implementer
providedByprovider)InterfaceClass)verifyClassverifyObject)plugins)defer	endpointserror
interfacesprotocolreactorstdiothreads)isIPv6Address)HostnameAddressIPv4AddressIPv6AddressUNIXAddress_ProcessAddress)StandardErrorBehavior)ConnectingCancelledError)	IConsumerIHostnameResolverIPushProducerIReactorPluggableNameResolver
ITransport)ClientFactoryFactoryProtocol)PipeAddress)Clock)MemoryReactorClockRaisingMemoryReactorStringTransport StringTransportWithDisconnection)ILogObserverglobalLogPublisher)
getPlugins)basicpolicies)log)nativeString)proxyForInterface)Failure)FilePath)	getModule)	ListenFDs)connectableEndpointconnectedServerAndClient)unittestztwisted.testz
server.pemzkey.pem.no_trailing_newlinezcert.pem.no_trailing_newlinefake_CAsz	chain.pem)ContextOP_NO_SSLv3SSLv23_METHODTLSv1_METHOD)CertificateCertificateOptionsDiffieHellmanParametersKeyPairPrivateCertificateTLSMemoryBIOFactory)makeCertificateF TNc                   @   8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )TestProtocolzx
    Protocol whose only function is to callback deferreds on the
    factory when it is connected or disconnected.
    c                 C   s   g | _ g | _d| _d S Nr   )dataconnectionsLostconnectionMadeCallsself rU   F/usr/lib/python3/dist-packages/twisted/internet/test/test_endpoints.py__init__|   s   
zTestProtocol.__init__c                 C   s   dS )NA Test ProtocolrU   rS   rU   rU   rV   	logPrefix      zTestProtocol.logPrefixc                 C   s   |  j d7  _ d S N   )rR   rS   rU   rU   rV   connectionMade      zTestProtocol.connectionMadec                 C      | j | d S N)rP   appendrT   rP   rU   rU   rV   dataReceived      zTestProtocol.dataReceivedc                 C   r_   r`   )rQ   ra   rT   reasonrU   rU   rV   connectionLost   rd   zTestProtocol.connectionLostN)	__name__
__module____qualname____doc__rW   rY   r]   rc   rg   rU   rU   rU   rV   rN   v   s    rN   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	TestHalfCloseableProtocolab  
    A Protocol that implements L{IHalfCloseableProtocol} and records whether
    its C{readConnectionLost} and {writeConnectionLost} methods are called.

    @ivar readLost: A C{bool} indicating whether C{readConnectionLost} has been
        called.

    @ivar writeLost: A C{bool} indicating whether C{writeConnectionLost} has
        been called.
    c                 C   s   t |  d| _d| _d S )NF)rN   rW   readLost	writeLostrS   rU   rU   rV   rW      s   

z"TestHalfCloseableProtocol.__init__c                 C   
   d| _ d S NT)rn   rS   rU   rU   rV   readConnectionLost      
z,TestHalfCloseableProtocol.readConnectionLostc                 C   rp   rq   )ro   rS   rU   rU   rV   writeConnectionLost   rs   z-TestHalfCloseableProtocol.writeConnectionLostN)rh   ri   rj   rk   rW   rr   rt   rU   rU   rU   rV   rm      s
    rm   c                   @       e Zd ZdZdd Zdd ZdS )"TestFileDescriptorReceiverProtocola  
    A Protocol that implements L{IFileDescriptorReceiver} and records how its
    C{fileDescriptorReceived} method is called.

    @ivar receivedDescriptors: A C{list} containing all of the file descriptors
        passed to C{fileDescriptorReceived} calls made on this instance.
    c                 C   s   t |  g | _d S r`   )rN   r]   receivedDescriptorsrS   rU   rU   rV   r]         

z1TestFileDescriptorReceiverProtocol.connectionMadec                 C   r_   r`   )rw   ra   )rT   
descriptorrU   rU   rV   fileDescriptorReceived   rd   z9TestFileDescriptorReceiverProtocol.fileDescriptorReceivedN)rh   ri   rj   rk   r]   rz   rU   rU   rU   rV   rv      s    rv   c                   @   ru   )TestHandshakeListenera  
    A Protocol that implements L{IHandshakeListener} and records the
    number of times its C{handshakeCompleted} method has been called.

    @ivar handshakeCompletedCalls: The number of times
        C{handshakeCompleted}
    @type handshakeCompletedCalls: L{int}
    c                 C   s   t |  d| _d S rO   )rN   rW   handshakeCompletedCallsrS   rU   rU   rV   rW      rx   zTestHandshakeListener.__init__c                 C   s   |  j d7  _ dS )zk
        Called when a TLS handshake has completed.  Implemented per
        L{IHandshakeListener}
        r\   N)r|   rS   rU   rU   rV   handshakeCompleted      z(TestHandshakeListener.handshakeCompletedN)rh   ri   rj   rk   rW   r}   rU   rU   rU   rV   r{      s    	r{   c                   @      e Zd ZdZeZdS )TestFactoryz
    Simple factory to be used both when connecting and listening. It contains
    two deferreds which are called back when my protocol connects and
    disconnects.
    N)rh   ri   rj   rk   rN   r   rU   rU   rU   rV   r      s    r   c                   @      e Zd ZdZdd ZdS )NoneFactoryzC
    A one off factory whose C{buildProtocol} returns L{None}.
    c                 C      d S r`   rU   rT   addrrU   rU   rV   buildProtocol   rZ   zNoneFactory.buildProtocolNrh   ri   rj   rk   r   rU   rU   rU   rV   r          r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,S )-WrappingFactoryTestszS
    Test the behaviour of our ugly implementation detail C{_WrappingFactory}.
    c                 C   s*   t  }t|}|  | d|j dS )z
        L{_WrappingFactory.doStart} passes through to the wrapped factory's
        C{doStart} method, allowing application-specific setup and logging.
        r\   N)r'   r   _WrappingFactorydoStartassertEqualnumPortsrT   factorywfrU   rU   rV   test_doStart   s   
z!WrappingFactoryTests.test_doStartc                 C   s0   t  }d|_t|}|  | d|j dS )z
        L{_WrappingFactory.doStop} passes through to the wrapped factory's
        C{doStop} method, allowing application-specific cleanup and logging.
              N)r'   r   r   r   doStopr   r   rU   rU   rV   test_doStop   s
   
z WrappingFactoryTests.test_doStopc                    sJ   G dd dt }t| }|d  |jt}| fdd |S )z
        An exception raised in C{buildProtocol} of our wrappedFactory
        results in our C{onConnection} errback being fired.
        c                   @   r   )zCWrappingFactoryTests.test_failedBuildProtocol.<locals>.BogusFactoryzZ
            A one off factory whose C{buildProtocol} raises an C{Exception}.
            c                 S   s   t d)NMy protocol is poorly defined.)
ValueErrorr   rU   rU   rV   r     s   zQWrappingFactoryTests.test_failedBuildProtocol.<locals>.BogusFactory.buildProtocolNr   rU   rU   rU   rV   BogusFactory  r   r   Nc                    s     | jdS )N)r   )r   args)erS   rU   rV   <lambda>  s    z?WrappingFactoryTests.test_failedBuildProtocol.<locals>.<lambda>)r'   r   r   r   assertFailure_onConnectionr   addCallback)rT   r   r   drU   rS   rV   test_failedBuildProtocol   s   

z-WrappingFactoryTests.test_failedBuildProtocolc                 C   s*   t t }|d | |jtj dS )z
        If the wrapped factory's C{buildProtocol} returns L{None} the
        C{onConnection} errback fires with L{error.NoProtocol}.
        N)r   r   r   r   failureResultOfr   r   
NoProtocolrT   wrappingFactoryrU   rU   rV   test_buildNoneProtocol  s   
z+WrappingFactoryTests.test_buildNoneProtocolc                 C   s0   t t }|jdd  | |d dS )z
        If the wrapped factory's C{buildProtocol} returns L{None} then
        L{endpoints._WrappingFactory.buildProtocol} returns L{None}.
        c                 S   r   r`   rU   rf   rU   rU   rV   r   &      zDWrappingFactoryTests.test_buildProtocolReturnsNone.<locals>.<lambda>N)r   r   r   r   
addErrbackassertIsNoner   r   rU   rU   rV   test_buildProtocolReturnsNone  s   z2WrappingFactoryTests.test_buildProtocolReturnsNonec                 C   s*   t t }|d}| | d dS )z
        If the wrapped protocol provides L{ILoggingContext}, whatever is
        returned from the wrapped C{logPrefix} method is returned from
        L{_WrappingProtocol.logPrefix}.
        NrX   )r   r   r   r   r   rY   )rT   r   wprU   rU   rV   test_logPrefixPassthrough*  s   
z.WrappingFactoryTests.test_logPrefixPassthroughc                 C   sB   G dd d}t  }||_t|}|d}| | d dS )z
        If the wrapped protocol does not provide L{ILoggingContext}, the
        wrapped protocol's class name is returned from
        L{_WrappingProtocol.logPrefix}.
        c                   @      e Zd ZdS )z>WrappingFactoryTests.test_logPrefixDefault.<locals>.NoProtocolNrh   ri   rj   rU   rU   rU   rV   r   ;  s    r   N)r   r   r   r   r   r   rY   )rT   r   r   r   r   rU   rU   rV   test_logPrefixDefault4  s   

z*WrappingFactoryTests.test_logPrefixDefaultc                 C   s^   t t }|d}|d |d | |jjdg |d | |jjddg dS )z
        The wrapped C{Protocol}'s C{dataReceived} will get called when our
        C{_WrappingProtocol}'s C{dataReceived} gets called.
        Ns   foos   bar)	r   r   r   r   makeConnectionrc   r   _wrappedProtocolrP   )rT   r   prU   rU   rV    test_wrappedProtocolDataReceivedD  s   



z5WrappingFactoryTests.test_wrappedProtocolDataReceivedc                 C   sH   t t }|d}t }|| | |j| | |jj| dS )zo
        Our transport is properly hooked up to the wrappedProtocol when a
        connection is made.
        N)	r   r   r   r   objectr   r   	transportr   )rT   r   r   dummyTransportrU   rU   rV   test_wrappedProtocolTransportS  s   

z2WrappingFactoryTests.test_wrappedProtocolTransportc                 C   s:   t  }t|}|d}|d | |jjdg dS )z
        Our wrappedProtocol's connectionLost method is called when
        L{_WrappingProtocol.connectionLost} is called.
        Nfail)r   r   r   r   rg   r   r   rQ   )rT   tfr   r   rU   rU   rV   "test_wrappedProtocolConnectionLostc  s
   


z7WrappingFactoryTests.test_wrappedProtocolConnectionLostc                    sV   t t }ttjdd}|d| g   fdd}|j| | 	 |g dS )z
        Calls to L{_WrappingFactory.clientConnectionLost} should errback the
        L{_WrappingFactory._onConnection} L{Deferred}
        r   stringNc                         |  d S r`   ra   ferrorsrU   rV   gotError|     zBWrappingFactoryTests.test_clientConnectionFailed.<locals>.gotError)
r   r   r   r8   r   ConnectErrorclientConnectionFailedr   r   r   )rT   r   expectedFailurer   rU   r   rV   test_clientConnectionFailedp  s   z0WrappingFactoryTests.test_clientConnectionFailedc                 C   s>   d}t  }t||}| tj| | ttj| dS )zv
        Our L{_WrappingProtocol} should be an L{IFileDescriptorReceiver} if the
        wrapped protocol is.
        N)rv   r   _WrappingProtocol
assertTruer   IFileDescriptorReceiverr   r   )rT   connectedDeferredapplicationProtocolwrapperrU   rU   rV   +test_wrappingProtocolFileDescriptorReceiver  s
   z@WrappingFactoryTests.test_wrappingProtocolFileDescriptorReceiverc                 C   (   t  }td|}| tj| dS )z~
        Our L{_WrappingProtocol} does not provide L{IHalfCloseableProtocol} if
        the wrapped protocol doesn't.
        N)rN   r   r   assertFalser   r   r   rT   tpr   rU   rU   rV   .test_wrappingProtocolNotFileDescriptorReceiver     zCWrappingFactoryTests.test_wrappingProtocolNotFileDescriptorReceiverc                 C   s@   t  }tt |}|t  |d | |j	dg dS )z
        L{_WrappingProtocol.fileDescriptorReceived} calls the wrapped
        protocol's C{fileDescriptorReceived} method.
        *   N)
rv   r   r   r   Deferredr   r.   rz   r   rw   )rT   wrappedProtocolr   rU   rU   rV   *test_wrappedProtocolFileDescriptorReceived  s
   
z?WrappingFactoryTests.test_wrappedProtocolFileDescriptorReceivedc                 C   s0   t  }t }t||}| tj|d dS )zw
        Our L{_WrappingProtocol} should be an L{IHalfCloseableProtocol} if the
        C{wrappedProtocol} is.
        TN)r   rm   r   r   r   r   IHalfCloseableProtocolr   )rT   cdhcpr   rU   rU   rV   "test_wrappingProtocolHalfCloseable  s   z7WrappingFactoryTests.test_wrappingProtocolHalfCloseablec                 C   s*   t  }td|}| tj|d dS )z
        Our L{_WrappingProtocol} should not provide L{IHalfCloseableProtocol}
        if the C{WrappedProtocol} doesn't.
        NF)rN   r   r   r   r   r   r   r   rU   rU   rV   %test_wrappingProtocolNotHalfCloseable  s   z:WrappingFactoryTests.test_wrappingProtocolNotHalfCloseablec                 C   r   )zs
        Our L{_WrappingProtocol} should be an L{IHandshakeListener} if
        the C{wrappedProtocol} is.
        N)r{   r   r   r   r   IHandshakeListenerr   )rT   handshakeListenerwrappedrU   rU   rV   &test_wrappingProtocolHandshakeListener  r   z;WrappingFactoryTests.test_wrappingProtocolHandshakeListenerc                 C   r   )z~
        Our L{_WrappingProtocol} should not provide L{IHandshakeListener}
        if the C{wrappedProtocol} doesn't.
        N)rN   r   r   r   r   r   r   r   rU   rU   rV   )test_wrappingProtocolNotHandshakeListener  r   z>WrappingFactoryTests.test_wrappingProtocolNotHandshakeListenerc                 C   *   t  }td|}|  | |j dS )z~
        L{_WrappingProtocol.readConnectionLost} should proxy to the wrapped
        protocol's C{readConnectionLost}
        N)rm   r   r   rr   r   rn   rT   r   r   rU   rU   rV   &test_wrappedProtocolReadConnectionLost     z;WrappingFactoryTests.test_wrappedProtocolReadConnectionLostc                 C   r   )z
        L{_WrappingProtocol.writeConnectionLost} should proxy to the wrapped
        protocol's C{writeConnectionLost}
        N)rm   r   r   rt   r   ro   r   rU   rU   rV   'test_wrappedProtocolWriteConnectionLost  r   z<WrappingFactoryTests.test_wrappedProtocolWriteConnectionLostc                 C   s,   t  }td|}|  | |jd dS )z~
        L{_WrappingProtocol.handshakeCompleted} should proxy to the
        wrapped protocol's C{handshakeCompleted}
        Nr\   )r{   r   r   r}   r   r|   )rT   listenerr   rU   rU   rV   &test_wrappedProtocolHandshakeCompleted  s   z;WrappingFactoryTests.test_wrappedProtocolHandshakeCompletedN)rh   ri   rj   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rU   rU   rU   rV   r      s.    
	
	
			

r   c                   @   @   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )ClientEndpointTestCaseMixinQ
    Generic test methods to be mixed into all client endpoint test classes.
    c                 C   0   t  }| t |\}}}| ttj| dS )zK
        The endpoint provides L{interfaces.IStreamClientEndpoint}
        N)r   createClientEndpointMemoryReactorr   r   r   IStreamClientEndpoint)rT   clientFactoryepignoredArgsaddressrU   rU   rV   test_interface  
   
z*ClientEndpointTestCaseMixin.test_interfacec                 C      |  |d d S )z
        Retrieve a single factory that has connected using the given reactor.
        (This behavior is valid for TCP and SSL but needs to be overridden for
        UNIX.)

        @param reactor: a L{MemoryReactor}
        r   r   expectedClientsrT   r   rU   rU   rV   retrieveConnectedFactory  s   z4ClientEndpointTestCaseMixin.retrieveConnectedFactoryc                    s   t  }t }t  }| ||\}}}||}g   fdd}|| | |}	|	j| |  |g | 	|}
| t
|
d | |
d | dS )z}
        A client endpoint can connect and returns a deferred who gets called
        back with a protocol instance.
        c                    r   r`   r   r   receivedProtosrU   rV   
checkProto  r   zKClientEndpointTestCaseMixin.test_endpointConnectSuccess.<locals>.checkProtor\   r   N)r   r   r   connectr   r   r   callbackr   r   lenassertConnectArgsrT   protomreactorr   r   expectedArgsignoredDestr   r   r   r   rU   r   rV   test_endpointConnectSuccess  s    




z7ClientEndpointTestCaseMixin.test_endpointConnectSuccessc           	         sd   t jdd}t|d}t }| ||\}}}||}g   fdd}|| |  |g dS )t
        If an endpoint tries to connect to a non-listening port it gets
        a C{ConnectError} failure.
        Connection Failedr   connectExceptionc                         | j d S r`   ra   valuer   receivedExceptionsrU   rV   checkFailure2  rd   zMClientEndpointTestCaseMixin.test_endpointConnectFailure.<locals>.checkFailureN)r   r   r-   r   r   r  r   r   )	rT   expectedErrorr  r   r   r   r	  r   r  rU   r  rV   test_endpointConnectFailure  s   



z7ClientEndpointTestCaseMixin.test_endpointConnectFailurec           
         s   t  }t }| ||\}}}||}g   fdd}|| |  | |}|dtt	
  | t d  d }	| |	jt	j | |	jj| dS )
        Calling L{Deferred.cancel} on the L{Deferred} returned from
        L{IStreamClientEndpoint.connect} is errbacked with an expected
        L{ConnectingCancelledError} exception.
        c                    r   r`   r   r   receivedFailuresrU   rV   r  I  r   zRClientEndpointTestCaseMixin.test_endpointConnectingCancelled.<locals>.checkFailureNr\   r   )r   r   r   r  r   cancelr   r   r8   r   	UserErrorr   r  assertIsInstancer  r!   r   )
rT   r  r   r   r   r   r   r  attemptFactoryfailurerU   r  rV    test_endpointConnectingCancelled9  s   


z<ClientEndpointTestCaseMixin.test_endpointConnectingCancelledc                 C   sb   t  }t }| j||fi |  \}}}|| | |}| t|d | |d | dS )zn
        The endpoint should pass it's connectArgs parameter to the reactor's
        listen methods.
        r\   r   N)	r   r   r   connectArgsr  r   r   r  r  )rT   r   r  r   r  ignoredHostr   rU   rU   rV   "test_endpointConnectNonDefaultArgs\  s   

z>ClientEndpointTestCaseMixin.test_endpointConnectNonDefaultArgsN)
rh   ri   rj   rk   r   r   r
  r  r  r"  rU   rU   rU   rV   r     s    

 #r   c                   @   0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ServerEndpointTestCaseMixinr   c                 C   r   )zL
        The endpoint provides L{interfaces.IStreamServerEndpoint}.
        N)r   createServerEndpointr   r   r   r   IStreamServerEndpoint)rT   r   r   r   r	  rU   rU   rV   r   v  r   z*ServerEndpointTestCaseMixin.test_interfacec                    sh   t  }t }| ||\}}}||}g   fdd}|| |  |g | | ||g dS )zs
        An endpoint can listen and returns a deferred that gets called back
        with a port instance.
        c                    s     |   d S r`   )ra   getHost)portreceivedHostsrU   rV   checkPortAndServer  r^   zRServerEndpointTestCaseMixin.test_endpointListenSuccess.<locals>.checkPortAndServerN)r   r   r%  listenr   r   expectedServers)rT   r  r   r   r  expectedHostr   r+  rU   r)  rV   test_endpointListenSuccess  s   

z6ServerEndpointTestCaseMixin.test_endpointListenSuccessc           	         sh   t  }tdd|}t|d}| ||\}}}|t  }g   fdd}|| |  |g dS )z
        When an endpoint tries to listen on an already listening port, a
        C{CannotListenError} failure is errbacked.
        rL   P   )listenExceptionc                    r  r`   r  r   r  rU   rV   r    rd   zLServerEndpointTestCaseMixin.test_endpointListenFailure.<locals>.checkFailureN)r   r   CannotListenErrorr-   r%  r,  r   r   )	rT   r   	exceptionr  r   r   r	  r   r  rU   r  rV   test_endpointListenFailure  s   

z6ServerEndpointTestCaseMixin.test_endpointListenFailurec                 C   sP   t  }t }| j||fi |  \}}}|| | |}| ||g dS )zm
        The endpoint should pass it's listenArgs parameter to the reactor's
        listen methods.
        N)r   r   r%  
listenArgsr,  r-  r   )rT   r   r  r   r  r!  r-  rU   rU   rV   !test_endpointListenNonDefaultArgs  s   

z=ServerEndpointTestCaseMixin.test_endpointListenNonDefaultArgsN)rh   ri   rj   rk   r   r/  r4  r6  rU   rU   rU   rV   r$  q  s    
r$  c                   @      e Zd ZdZdS )EndpointTestCaseMixinzJ
    Generic test methods to be mixed into all endpoint test classes.
    Nrh   ri   rj   rk   rU   rU   rU   rV   r8        r8  c                   @   ru   )SpecificFactoryz
    An L{IProtocolFactory} whose C{buildProtocol} always returns its
    C{specificProtocol} and sets C{passedAddress}.

    Raising an exception if C{specificProtocol} has already been used.
    c                 C   s
   || _ d S r`   )specificProtocol)rT   r<  rU   rU   rV   rW     rs   zSpecificFactory.__init__c                 C   s"   t | jdr
td|| j_| jS )NpassedAddresszspecificProtocol already used.)hasattrr<  r   r=  r   rU   rU   rV   r     s   zSpecificFactory.buildProtocolN)rh   ri   rj   rk   rW   r   rU   rU   rU   rV   r;    s    r;  c                   @      e Zd ZdZdddZdS )	FakeStdioz_
    A L{stdio.StandardIO} like object that simply captures its constructor
    arguments.
    Nc                 C   s   || _ || _dS )z
        @param protocolInstance: like the first argument of L{stdio.StandardIO}

        @param reactor: like the reactor keyword argument of
            L{stdio.StandardIO}
        N)protocolInstancer   )rT   rA  r   rU   rU   rV   rW     s   
zFakeStdio.__init__r`   rh   ri   rj   rk   rW   rU   rU   rU   rV   r@    s    r@  c                   @   rl   )	StandardIOEndpointsTestsz*
    Tests for Standard I/O Endpoints
    c                 C   sN   t  | _t| j}| |jtj t|_t	 | _
| |t| j
| _dS )z
        Construct a L{StandardIOEndpoint} with a dummy reactor and a fake
        L{stdio.StandardIO} like object.  Listening on it with a
        L{SpecificFactory}.
        N)r   r   r   StandardIOEndpointassertIs_stdior   
StandardIOr@  r)   r<  successResultOfr,  r;  	fakeStdiorT   endpointrU   rU   rV   setUp  s   
zStandardIOEndpointsTests.setUpc                 C   s(   |  | jj| j | | jjjt dS )z
        L{StandardIOEndpoint} returns a L{Deferred} that fires with an instance
        of a L{stdio.StandardIO} like object that was passed the result of
        L{SpecificFactory.buildProtocol} which was passed a L{PipeAddress}.
        N)rE  rI  rA  r<  r  r=  r*   rS   rU   rU   rV   test_protocolCreation   s   
z.StandardIOEndpointsTests.test_protocolCreationc                 C   s   |  | jj| j dS )z
        L{StandardIOEndpoint} passes its C{reactor} argument to the constructor
        of its L{stdio.StandardIO} like object.
        N)rE  rI  r   rS   rU   rU   rV   test_passedReactor     z+StandardIOEndpointsTests.test_passedReactorN)rh   ri   rj   rk   rL  rM  rN  rU   rU   rU   rV   rC    s
    rC  c                   @   ru   )StubApplicationProtocolz#
    An L{IProtocol} provider.
    c                 C   
   || _ dS )zY
        @param data: The data received by the protocol.
        @type data: str
        N)rP   rb   rU   rU   rV   rc        
z$StubApplicationProtocol.dataReceivedc                 C   rQ  )zA
        @type reason: L{twisted.python.failure.Failure}
        Nr   re   rU   rU   rV   rg        
z&StubApplicationProtocol.connectionLostN)rh   ri   rj   rk   rc   rg   rU   rU   rU   rV   rP    s    rP  c                       sZ   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Z  ZS )MemoryProcessTransportzC
    A fake L{IProcessTransport} provider to be used in tests.
    Nc                    s.   t  jt t d g | _t | _t | _d S )N)hostAddresspeerAddress)superrW   r   signalssetclosedChildFDsr)   r   rT   r   	__class__rU   rV   rW   ,  s   zMemoryProcessTransport.__init__c                 C   s   |dkr|  | d S d S rO   write)rT   childFDrP   rU   rU   rV   writeToChild2  s   z#MemoryProcessTransport.writeToChildc                 C      |  d d S rO   closeChildFDrS   rU   rU   rV   
closeStdin6  r   z!MemoryProcessTransport.closeStdinc                 C   rb  r[   rc  rS   rU   rU   rV   closeStdout9  r   z"MemoryProcessTransport.closeStdoutc                 C   rb  )Nr   rc  rS   rU   rU   rV   closeStderr<  r   z"MemoryProcessTransport.closeStderrc                 C   r_   r`   )rZ  add)rT   fdrU   rU   rV   rd  ?  rd   z#MemoryProcessTransport.closeChildFDc                 C   r_   r`   )rX  ra   )rT   signalrU   rU   rV   signalProcessB  rd   z$MemoryProcessTransport.signalProcessc                 C   r   r`   rU   rS   rU   rU   rV   pidE  s   zMemoryProcessTransport.pidr`   )rh   ri   rj   rk   rW   ra  re  rf  rg  rd  rk  rl  __classcell__rU   rU   r\  rV   rT  &  s    rT  c                   @   s(   e Zd ZdZdi dddddfddZdS )MemoryProcessReactorzA
    A fake L{IReactorProcess} provider to be used in tests.
    rU   Nr   c
           
      C   sR   || _ || _|| _|| _|| _|| _|| _|| _|	| _t	 | _
| j | j
 | j
S )z
        @ivar processProtocol: Stores the protocol passed to the reactor.
        @return: An L{IProcessTransport} provider.
        )processProtocol
executabler   envpathuidgidusePTYchildFDsrT  processTransportr   )
rT   ro  rp  r   rq  rr  rs  rt  ru  rv  rU   rU   rV   spawnProcessU  s   z!MemoryProcessReactor.spawnProcess)rh   ri   rj   rk   rx  rU   rU   rU   rV   rn  O  s    rn  c                   @   P   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )ProcessEndpointsTestsz,
    Tests for child process endpoints.
    c                 C   s.   t  | _t| jd| _t | _t| j_d S N   /bin/executable)	rn  r   r   ProcessEndpointr   r   r(   r   rP  rS   rU   rU   rV   rL  y  s   
zProcessEndpointsTests.setUpc                 C   s   |  | jjt | | jjd | | jjd | | jji  | | jj	 | | jj
 | | jj | | jjd | | jj | | jjtj dS )zU
        Default values are set for the optional parameters in the endpoint.
        r|  rU   r   N)r  r   _reactorrn  r   _executable_args_envr   _path_uid_gid_usePTY	_childFDs_errFlagr    LOGrS   rU   rU   rV   test_constructorDefaults  s   z.ProcessEndpointsTests.test_constructorDefaultsc                 C   s   ddi}t t ddgd|d idddddd	d	d
tj
}| |jt | |jd | |j	dg | |j
d|d i | |jd | |jd | |jd | |j | |jdd	d	d
 | |jtj dS )zI
        The parameters passed to the endpoint are stored in it.
           HOMENr|     /runProcessHere/r\   r   Twrr         )r   r}  rn  r    DROPr  r~  r   r  r  r  r  r  r  r   r  r  r  )rT   environr   rU   rU   rV   test_constructorNonDefaults  s.   

z1ProcessEndpointsTests.test_constructorNonDefaultsc                 C   s2   | j | j}| | | jj}| |tj dS )z
        The wrapper function _WrapIProtocol gives an IProcessProtocol
        implementation that wraps over an IProtocol.
        N)	r   r  r   rH  r   ro  r  r   _WrapIProtocolrT   r   wpprU   rU   rV   test_wrappedProtocol  s   
z*ProcessEndpointsTests.test_wrappedProtocolc                 C   s   ddi}t  }t|ddgd|d idddddd	d	d
	}|| j}| | | |jtj | 	|j
|j | 	|j|j | 	|j|j | 	|j|j | 	|j|j | 	|j|j | 	|j|j | 	|j|j dS )z
        The parameters for spawnProcess stored in the endpoint are passed when
        the endpoint's connect method is invoked.
        r  Nr|  r  r\   r   Tr  r  r  )rn  r   r}  r  r   rH  r  ro  r  r   rp  r  r   r  rq  r  rr  r  rs  r  rt  r  ru  r  rv  r  )rT   r  memoryReactorr   r   rU   rU   rV   test_spawnProcess  s0   


z'ProcessEndpointsTests.test_spawnProcessc                 C   s@   G dd dt j}| }| j|}| | | |jt dS )zz
        The address passed to the factory's buildProtocol in the endpoint is a
        _ProcessAddress instance.
        c                   @   s   e Zd ZeZdZdd ZdS )zBProcessEndpointsTests.test_processAddress.<locals>.TestAddrFactoryNc                 S   s   || _ |  }| |_|S r`   )r   r   r   )rT   r   r   rU   rU   rV   r     s   zPProcessEndpointsTests.test_processAddress.<locals>.TestAddrFactory.buildProtocol)rh   ri   rj   rP  r   r   r   rU   rU   rU   rV   TestAddrFactory  s    r  N)r   r(   r   r  rH  r  r   r   )rT   r  	myFactoryr   rU   rU   rV   test_processAddress  s
   

z)ProcessEndpointsTests.test_processAddressc                 C   s$   |  | j| j}| |t dS )zd
        L{ProcessEndpoint.connect} returns a Deferred with the connected
        protocol.
        N)rH  r   r  r   r  rP  )rT   r  rU   rU   rV   test_connect  s   z"ProcessEndpointsTests.test_connectc                 C   s6   dd }|| j _| j | j}| |}|t dS )zg
        In case of failure, L{ProcessEndpoint.connect} returns a Deferred that
        fails.
        c	           	      S   s   t  r`   )	Exception)	pprp  r   rq  rr  rs  rt  ru  rv  rU   rU   rV   testSpawnProcess  s   zCProcessEndpointsTests.test_connectFailure.<locals>.testSpawnProcessN)r   _spawnProcessr  r   r   trapr  )rT   r  r   r   rU   rU   rV   test_connectFailure  s
   
z)ProcessEndpointsTests.test_connectFailureN)rh   ri   rj   rk   rL  r  r  r  r  r  r  r  rU   rU   rU   rV   rz  t  s    
 rz  c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"S )#ProcessEndpointTransportTestsze
    Test the behaviour of the implementation detail
    L{endpoints._ProcessEndpointTransport}.
    c                 C   sF   t  | _t| jd| _| | jtt	}| jj
| _|j| _d S r{  )rn  r   r   r}  rK  rH  r  r(   forProtocolr)   rw  processr   endpointTransportr[  rU   rU   rV   rL  	  s   
z#ProcessEndpointTransportTests.setUpc                 C      t t| j dS )zE
        L{_ProcessEndpointTransport}s provide L{IConsumer}.
        N)r   r"   r  rS   rU   rU   rV   test_verifyConsumer     z1ProcessEndpointTransportTests.test_verifyConsumerc                 C   r  )zI
        L{_ProcessEndpointTransport}s provide L{IPushProducer}.
        N)r   r$   r  rS   rU   rU   rV   test_verifyProducer  r  z1ProcessEndpointTransportTests.test_verifyProducerc                 C   r  )zF
        L{_ProcessEndpointTransport}s provide L{ITransport}.
        N)r   r&   r  rS   rU   rU   rV   test_verifyTransport  r  z2ProcessEndpointTransportTests.test_verifyTransportc                 C   s   |  | jj| j dS )zd
        The L{_ProcessEndpointTransport} instance stores the process passed to
        it.
        N)rE  r  _processr  rS   rU   rU   rV   test_constructor$  rO  z.ProcessEndpointTransportTests.test_constructorc                 C   s>   t tG dd d}| }| j|d | | jj| dS )z
        Registering a producer with the endpoint transport registers it with
        the underlying process transport.
        c                   @   r   )zFProcessEndpointTransportTests.test_registerProducer.<locals>.AProducerNr   rU   rU   rU   rV   	AProducer1  s    r  FN)r   r$   r  registerProducerrE  r  producer)rT   r  	aProducerrU   rU   rV   test_registerProducer+  s
   z3ProcessEndpointTransportTests.test_registerProducerc                 C      | j   | | jjd dS )zY
        Pausing the endpoint transport pauses the underlying process transport.
        pausedN)r  pauseProducingr   r  producerStaterS   rU   rU   rV   test_pauseProducing9  s   
z1ProcessEndpointTransportTests.test_pauseProducingc                 C   s&   |    | j  | | jjd dS )zc
        Resuming the endpoint transport resumes the underlying process
        transport.
        	producingN)r  r  resumeProducingr   r  r  rS   rU   rU   rV   test_resumeProducing@  s   
z2ProcessEndpointTransportTests.test_resumeProducingc                 C   r  )zo
        Stopping the endpoint transport as a producer stops the underlying
        process transport.
        stoppedN)r  stopProducingr   r  r  rS   rU   rU   rV   test_stopProducingI  s   
z0ProcessEndpointTransportTests.test_stopProducingc                 C   s$   |    | j  | | jj dS )z
        Unregistring the endpoint transport's producer unregisters the
        underlying process transport's producer.
        N)r  r  unregisterProducerr   r  r  rS   rU   rU   rV   test_unregisterProducerQ  s   
z5ProcessEndpointTransportTests.test_unregisterProducerc                 C   s   g | j _| tt| jd dS )z
        L{endpoints._ProcessEndpointTransport} filters out extraneous
        attributes of its underlying transport, to present a more consistent
        cross-platform view of subprocesses and prevent accidental
        dependencies.
        pipesN)r  r  assertRaisesAttributeErrorgetattrr  rS   rU   rU   rV   test_extraneousAttributesZ  s   z7ProcessEndpointTransportTests.test_extraneousAttributesc                 C   s(   | j g d | | jj d dS )z
        The writeSequence method of L{_ProcessEndpointTransport} writes a list
        of string passed to it to the transport's stdin.
        )s   test1s   test2s   test3s   test1test2test3N)r  writeSequencer   r  iogetvaluerS   rU   rU   rV   test_writeSequenced  s   z0ProcessEndpointTransportTests.test_writeSequencec                 C   s$   | j d | | jj d dS )z
        The write method of L{_ProcessEndpointTransport} writes a string of
        data passed to it to the child process's stdin.
        s   testN)r  r_  r   r  r  r  rS   rU   rU   rV   
test_writel  s   z(ProcessEndpointTransportTests.test_writec                 C   s   | j   | | jj dS )z
        A call to the loseConnection method of a L{_ProcessEndpointTransport}
        instance returns a call to the process transport's loseConnection.
        N)r  loseConnectionr   r  	connectedrS   rU   rU   rV   test_loseConnectiont  s   
z1ProcessEndpointTransportTests.test_loseConnectionc                 C   ,   | j  }| |t | || j  dS )z
        L{_ProcessEndpointTransport.getHost} returns a L{_ProcessAddress}
        instance matching the process C{getHost}.
        N)r  r'  r  r   rE  r  )rT   hostrU   rU   rV   test_getHost|     
z*ProcessEndpointTransportTests.test_getHostc                 C   r  )z
        L{_ProcessEndpointTransport.getPeer} returns a L{_ProcessAddress}
        instance matching the process C{getPeer}.
        N)r  getPeerr  r   rE  r  )rT   peerrU   rU   rV   test_getPeer  r  z*ProcessEndpointTransportTests.test_getPeerN)rh   ri   rj   rk   rL  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rU   rU   rU   rV   r    s$    			
	r  c                   @   sX   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd ZdS )WrappedIProtocolTestszL
    Test the behaviour of the implementation detail C{_WrapIProtocol}.
    c                 C   s4   t  | _t| jd| _d | _t | _t	| j_d S r{  )
rn  r   r   r}  r   eventLogr   r(   r   rP  rS   rU   rU   rV   rL    s
   
zWrappedIProtocolTests.setUpc                 C   sD   | j | j}| | | jj}| |jt | 	|j
| j j dS )zQ
        Stores an L{IProtocol} provider and the flag to log/drop stderr
        N)r   r  r   rH  r   ro  r  r   rP  r   errFlagr  r  rU   rU   rV   r    s
   
z&WrappedIProtocolTests.test_constructorc                 C   s6   | j | j}| | | jj}| |jj|j dS )zx
        Our process transport is properly hooked up to the wrappedIProtocol
        when a connection is made.
        N)	r   r  r   rH  r   ro  r   r   r   r  rU   rU   rV   test_makeConnection  s   
z)WrappedIProtocolTests.test_makeConnectionc                 C   rQ  )z!
        A log observer.
        N)r  )rT   	eventDictrU   rU   rV   _stdLog  rS  zWrappedIProtocolTests._stdLogc                 C   s   | j | j}| | | jj}t| j | 	tj
| j |dd | | jd |j | | jd d | | jd |j | dt| j dS )z
        When the _errFlag is set to L{StandardErrorBehavior.LOG},
        L{endpoints._WrapIProtocol} logs stderr (in childDataReceived).
        r   s   stderr1rp  rP   r   zwrote stderr unhandled byN)r   r  r   rH  r   ro  r5   addObserverr  
addCleanupremoveObserverchildDataReceivedr   r  rp  r   assertIntextFromEventDictr  rU   rU   rV   test_logStderr  s   
z$WrappedIProtocolTests.test_logStderrc                 C   sb   t j| j_| j| j}| | | jj}t	
| j | t	j| j |dd | | j dS )z
        When the _errFlag is set to L{StandardErrorBehavior.DROP},
        L{endpoints._WrapIProtocol} ignores stderr.
        r   s   stderr2N)r    r  r   r  r  r   rH  r   ro  r5   r  r  r  r  r  r   r  r  rU   rU   rV   test_stderrSkip  s   

z%WrappedIProtocolTests.test_stderrSkipc                 C   s@   | j | j}| | | jj}|dd | |jj	d dS )z
        In childDataReceived of L{_WrappedIProtocol} instance, the protocol's
        dataReceived is called when stdout is generated.
        r\   s   stdoutN)
r   r  r   rH  r   ro  r  r   r   rP   r  rU   rU   rV   test_stdout  s
   
z!WrappedIProtocolTests.test_stdoutc                 C   sR   | j | j}| | | jj}|tt	d | 
|jjtjtj dS )z
        L{error.ProcessDone} with status=0 is turned into a clean disconnect
        type, i.e. L{error.ConnectionDone}.
        r   N)r   r  r   rH  r   ro  processEndedr8   r   ProcessDoner   r   rf   checkConnectionDoner  rU   rU   rV   test_processDone  s   
z&WrappedIProtocolTests.test_processDonec                 C   sP   | j | j}| | | jj}|tt	  | 
|jjtjtj dS )z{
        Exceptions other than L{error.ProcessDone} with status=0 are turned
        into L{error.ConnectionLost}.
        N)r   r  r   rH  r   ro  r  r8   r   ProcessTerminatedr   r   rf   r  ConnectionLostr  rU   rU   rV   test_processEnded  s   
z'WrappedIProtocolTests.test_processEndedN)rh   ri   rj   rk   rL  r  r  r  r  r  r  r  r  rU   rU   rU   rV   r    s    

r  c                   @   H   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )TCP4EndpointsTestsz'
    Tests for TCP IPv4 Endpoints.
    c                 C      |j S zD
        @return: List of calls to L{IReactorTCP.listenTCP}
        
tcpServersr   rU   rU   rV   r-       z"TCP4EndpointsTests.expectedServersc                 C   r  zE
        @return: List of calls to L{IReactorTCP.connectTCP}
        
tcpClientsr   rU   rU   rV   r   	  r  z"TCP4EndpointsTests.expectedClientsc                 C   P   |\}}}}}|\}}	}
}}|  || |  ||	 |  || |  || dS a]  
        Compare host, port, timeout, and bindAddress in C{receivedArgs}
        to C{expectedArgs}.  We ignore the factory because we don't
        only care what protocol comes out of the
        C{IStreamClientEndpoint.connect} call.

        @param receivedArgs: C{tuple} of (C{host}, C{port}, C{factory},
            C{timeout}, C{bindAddress}) that was passed to
            L{IReactorTCP.connectTCP}.
        @param expectedArgs: C{tuple} of (C{host}, C{port}, C{factory},
            C{timeout}, C{bindAddress}) that we expect to have been passed
            to L{IReactorTCP.connectTCP}.
        Nr   rT   receivedArgsr  r  r(  ignoredFactorytimeoutbindAddressr.  expectedPort_ignoredFactoryexpectedTimeoutexpectedBindAddressrU   rU   rV   r       z$TCP4EndpointsTests.assertConnectArgsc                 C   
   dddS K
        @return: C{dict} of keyword arguments to pass to connect.
        
   	localhosti  r  r  rU   rS   rU   rU   rV   r   +  rS  zTCP4EndpointsTests.connectArgsc                 C   r  I
        @return: C{dict} of keyword arguments to pass to listen
        d   	127.0.0.1backlog	interfacerU   rS   rU   rU   rV   r5  1  rS  zTCP4EndpointsTests.listenArgsc                 K   sB   t ddd}tj||jfi ||j||dd|ddf|fS )a  
        Create an L{TCP4ServerEndpoint} and return the values needed to verify
        its behaviour.

        @param reactor: A fake L{IReactorTCP} that L{TCP4ServerEndpoint} can
            call L{IReactorTCP.listenTCP} on.
        @param factory: The thing that we expect to be passed to our
            L{IStreamServerEndpoint.listen} implementation.
        @param listenArgs: Optional dictionary of arguments to
            L{IReactorTCP.listenTCP}.
        TCP0.0.0.0r   r  2   r  rL   )r   r   TCP4ServerEndpointr(  getrT   r   r   r5  r   rU   rU   rV   r%  7     

z'TCP4EndpointsTests.createServerEndpointc              	   K   J   t ddd}tj||j|jfi ||j|j||dd|ddf|fS )a  
        Create an L{TCP4ClientEndpoint} and return the values needed to verify
        its behavior.

        @param reactor: A fake L{IReactorTCP} that L{TCP4ClientEndpoint} can
            call L{IReactorTCP.connectTCP} on.
        @param clientFactory: The thing that we expect to be passed to our
            L{IStreamClientEndpoint.connect} implementation.
        @param connectArgs: Optional dictionary of arguments to
            L{IReactorTCP.connectTCP}
        r  r  r0  r     r  N)r   r   TCP4ClientEndpointr  r(  r  rT   r   r   r   r   rU   rU   rV   r   P     


z'TCP4EndpointsTests.createClientEndpointNrh   ri   rj   rk   r-  r   r  r   r5  r%  r   rU   rU   rU   rV   r    s    r  c                   @   r  )TCP6EndpointsTestsz'
    Tests for TCP IPv6 Endpoints.
    c                 C   r  r  r  r   rU   rU   rV   r-  r  r  z"TCP6EndpointsTests.expectedServersc                 C   r  r  r  r   rU   rU   rV   r   x  r  z"TCP6EndpointsTests.expectedClientsc                 C   r  r  r  r  rU   rU   rV   r  ~  r  z$TCP6EndpointsTests.assertConnectArgsc                 C   r  r  rU   rS   rU   rU   rV   r     rS  zTCP6EndpointsTests.connectArgsc                 C   r  )r  r  ::1r  rU   rS   rU   rU   rV   r5    rS  zTCP6EndpointsTests.listenArgsc                 K   sF   | dd}td|d}tj||jfi ||j|| dd|f|fS )a  
        Create a L{TCP6ServerEndpoint} and return the values needed to verify
        its behaviour.

        @param reactor: A fake L{IReactorTCP} that L{TCP6ServerEndpoint} can
            call L{IReactorTCP.listenTCP} on.
        @param factory: The thing that we expect to be passed to our
            L{IStreamServerEndpoint.listen} implementation.
        @param listenArgs: Optional dictionary of arguments to
            L{IReactorTCP.listenTCP}.
        r  z::r  r   r  r  )r  r   r   TCP6ServerEndpointr(  )rT   r   r   r5  r  r   rU   rU   rV   r%    s   z'TCP6EndpointsTests.createServerEndpointc              	   K   r  )  
        Create a L{TCP6ClientEndpoint} and return the values needed to verify
        its behavior.

        @param reactor: A fake L{IReactorTCP} that L{TCP6ClientEndpoint} can
            call L{IReactorTCP.connectTCP} on.
        @param clientFactory: The thing that we expect to be passed to our
            L{IStreamClientEndpoint.connect} implementation.
        @param connectArgs: Optional dictionary of arguments to
            L{IReactorTCP.connectTCP}
        r  r  r0  r  r  r  N)r   r   TCP6ClientEndpointr  r(  r  r  rU   rU   rV   r     r  z'TCP6EndpointsTests.createClientEndpointNr  rU   rU   rU   rV   r  m  s    r  c                   @   r   )TCP6EndpointNameResolutionTestszl
    Tests for a TCP IPv6 Client Endpoint pointed at a hostname instead
    of an IPv6 address literal.
    c              	      sd   t ddd}tj|d|jfi | _ fdd}| j_ j|j|j||dd|d	d
f|fS )r!  r  ::2r0  ipv6.example.comc                    s>     d|  tttddftttddftttddfg}t|S )Nr%  rL   )r$  r   r   r   )z::3r   r   r   )z::4r   r   r   )r   r   r   r   r   succeed)r  rP   rS   rU   rV   testNameResolution  s   
zPTCP6EndpointNameResolutionTests.createClientEndpoint.<locals>.testNameResolutionr  r  r  N)r   r   r"  r(  r   _nameResolutionr  r  )rT   r   r   r   r   r'  rU   rS   rV   r     s"   	

z4TCP6EndpointNameResolutionTests.createClientEndpointc                 C   r  r  rU   rS   rU   rU   rV   r     rS  z+TCP6EndpointNameResolutionTests.connectArgsc                 C   r  r  r  r   rU   rU   rV   r     r  z/TCP6EndpointNameResolutionTests.expectedClientsc                 C   r  r  r  r  rU   rU   rV   r    r  z1TCP6EndpointNameResolutionTests.assertConnectArgsc                 C   s"   t ddd}| |jtj dS )zg
        By default, L{TCP6ClientEndpoint._deferToThread} is
        L{threads.deferToThread}.
        Nzwww.example.com  )r   r"  r   _deferToThreadr   deferToThreadrT   r   rU   rU   rV   test_freeFunctionDeferToThread.  s   z>TCP6EndpointNameResolutionTests.test_freeFunctionDeferToThreadc                    sZ   g   fdd}t tdd}t }||_||_|t  | |ddt	fi fg  dS )zl
        While resolving hostnames, _nameResolution calls
        _deferToThread with _getaddrinfo.
        c                    s     | ||f t S r`   )ra   r   r   )r   r   kwargscallsrU   rV   fakeDeferToThread=  s   zNTCP6EndpointNameResolutionTests.test_nameResolution.<locals>.fakeDeferToThreadr%  r)  r   N)
r   r"  r   r   _getaddrinfor*  r  r   r   r   )rT   r1  rK  fakegetaddrinforU   r/  rV   test_nameResolution6  s   z3TCP6EndpointNameResolutionTests.test_nameResolutionN)
rh   ri   rj   rk   r   r   r   r  r-  r4  rU   rU   rU   rV   r#    s    (r#  c                   @   r?  )RaisingMemoryReactorWithClockzE
    An extension of L{RaisingMemoryReactor} with L{task.Clock}.
    Nc                 C   s   t |  t| || d S r`   )r+   rW   r-   )rT   r1  r  rU   rU   rV   rW   P  s   
z&RaisingMemoryReactorWithClock.__init__)NNrB  rU   rU   rU   rV   r5  K  s    r5  rU   c              
      sf   du ri   ttG fddd ttG  fdddttdtt| }|| S )ap  
    Create a reactor that will deterministically resolve all hostnames it is
    passed to the list of addresses given.

    @param reactor: An object that we wish to add an
        L{IReactorPluggableNameResolver} to.
    @type reactor: Any object with some formally-declared interfaces (i.e. one
        where C{list(providedBy(reactor))} is not empty); usually C{IReactor*}
        interfaces.

    @param expectedAddresses: (optional); the addresses expected to be returned
        for every address.  If these are strings, they should be IPv4 or IPv6
        literals, and they will be wrapped in L{IPv4Address} and L{IPv6Address}
        objects in the resolution result.
    @type expectedAddresses: iterable of C{object} or C{str}

    @param hostMap: (optional); the names (unicode) mapped to lists of
        addresses (str or L{IAddress}); in the same format as expectedAddress,
        which map the results for I{specific} hostnames to addresses.

    @return: A new reactor which provides all the interfaces previously
        provided by C{reactor} as well as L{IReactorPluggableNameResolver}.
        All name resolutions performed with its C{nameResolver} attribute will
        resolve reentrantly and synchronously with the given
        C{expectedAddresses}.  However, it is not a complete implementation as
        it does not have an C{installNameResolver} method.
    Nc                       s&   e Zd Ze			d fdd	ZdS )z9deterministicResolvingReactor.<locals>.SimpleNameResolverr   Nr  c                    sT   |  d  | D ]}t|trttgt| d||}| | q|   d S )Nr  )	resolutionBeganr  
isinstancestrr   r   r   addressResolvedresolutionComplete)resolutionReceiverhostName
portNumberaddressTypestransportSemanticsexpectedAddressexpectedAddresseshostMaprU   rV   resolveHostNamew  s   

zIdeterministicResolvingReactor.<locals>.SimpleNameResolver.resolveHostName)r   Nr  )rh   ri   rj   staticmethodrD  rU   rA  rU   rV   SimpleNameResolveru  s    rF  c                       s   e Zd Z  ZdS )z3deterministicResolvingReactor.<locals>.WithResolverN)rh   ri   rj   nameResolverrU   )rF  rU   rV   WithResolver  s    
rH  *)copyr   r#   r%   r7   r   tupler   )r   rB  rC  rH  rU   )rF  rB  rC  rV   deterministicResolvingReactorU  s   rL  c                   @   rM   )SimpleHostnameResolverTestsa  
    Tests for L{endpoints._SimpleHostnameResolver}.

    @ivar fakeResolverCalls: Arguments with which L{fakeResolver} was
        called.
    @type fakeResolverCalls: L{list} of C{(hostName, port)} L{tuple}s.

    @ivar fakeResolverReturns: The return value of L{fakeResolver}.
    @type fakeResolverReturns: L{Deferred}

    @ivar resolver: The instance to test.
    @type resolver: L{endpoints._SimpleHostnameResolver}

    @ivar resolutionBeganCalls: Arguments with which receiver's
        C{resolutionBegan} method was called.
    @type resolutionBeganCalls: L{list}

    @ivar addressResolved: Arguments with which C{addressResolved} was
        called.
    @type addressResolved: L{list}

    @ivar resolutionCompleteCallCount: The number of calls to the
        receiver's C{resolutionComplete} method.
    @type resolutionCompleteCallCount: L{int}

    @ivar receiver: A L{interfaces.IResolutionReceiver} provider.
    c                    sV   g  _ t  _t j _g  _g  _	d _
ttjG  fddd}| _d S )Nr   c                       s<   e Zd Ze fddZe fddZe fddZdS )z4SimpleHostnameResolverTests.setUp.<locals>._Receiverc                        j |  d S r`   )resolutionBeganCallsra   )resolutionInProgressrS   rU   rV   r6       zDSimpleHostnameResolverTests.setUp.<locals>._Receiver.resolutionBeganc                    rN  r`   )addressResolvedCallsra   )r   rS   rU   rV   r9    rQ  zDSimpleHostnameResolverTests.setUp.<locals>._Receiver.addressResolvedc                      s     j d7  _ d S r[   )resolutionCompleteCallCountrU   rS   rU   rV   r:    s   zGSimpleHostnameResolverTests.setUp.<locals>._Receiver.resolutionCompleteN)rh   ri   rj   rE  r6  r9  r:  rU   rS   rU   rV   	_Receiver  s    rT  )fakeResolverCallsr   r   fakeResolverReturnsr   _SimpleHostnameResolverfakeResolverresolverrO  rR  rS  r   r   IResolutionReceiverreceiver)rT   rT  rU   rS   rV   rL    s   

z!SimpleHostnameResolverTests.setUpc                 C   s   | j ||f | jS )z
        A fake resolver callable.

        @param hostName: The hostname to resolve.

        @param portNumber: The port number the returned address should
            include.

        @return: L{fakeResolverCalls}
        @rtype: L{Deferred}
        )rU  ra   rV  )rT   r<  r=  rU   rU   rV   rX    s   z(SimpleHostnameResolverTests.fakeResolverc                 C   s   |  ttj| j dS )zs
        A L{endpoints._SimpleHostnameResolver} instance provides
        L{interfaces.IHostnameResolver}.
        N)r   r   r   r#   rY  rS   rU   rU   rV   r        z*SimpleHostnameResolverTests.test_interfacec                    s
  g t tfdd t  |  fdd | j| jd}| || j | j	
t  | dt | dt| t \}| |d | |dd | |d	t| j | dt| j | | jd
 jd | | j | d| j dS )z
        A resolution failure is logged with the name that failed to
        resolve and the callable that tried to resolve it.  The
        resolution receiver begins, receives no addresses, and
        completes.
        c                    r   r`   r   )event)logsrU   rV   captureLogs  s   zHSimpleHostnameResolverTests.test_resolveNameFailure.<locals>.captureLogsc                      s
   t  S r`   )r1   r  rU   )r_  rU   rV   r     s   
 zESimpleHostnameResolverTests.test_resolveNameFailure.<locals>.<lambda>example.comr\   isErrornamecallabler   N)r   r0   r1   r  r  rY  rD  r[  rE  rV  errbackr  r   r  flushLoggedErrorsr   r  reprrX  rO  rb  r   rR  rS  )rT   r[  r]  rU   )r_  r^  rV   test_resolveNameFailure  s$   
z3SimpleHostnameResolverTests.test_resolveNameFailurec              	   C   s   d}d}d}| j | jd}| || j | jtttd||fft	ttd||ffg | 
dt| j | 
| jd jd | 
| jtd||td||g | 
| jd d	S )
zs
        The resolution receiver begins, and resolved hostnames are
        delivered before it completes.
        r0  1.2.3.4z
1::2::3::4r`  rL   r\   r   r  N)rY  rD  r[  rE  rV  r  r   r   r   r   r   r  rO  rb  rR  r   r   rS  )rT   r(  ipv4Hostipv6Hostr[  rU   rU   rV   test_resolveNameDelivers   s"   z4SimpleHostnameResolverTests.test_resolveNameDeliversN)	rh   ri   rj   rk   rL  rX  r   rg  rk  rU   rU   rU   rV   rM    s    #rM  c                   @   r   )+HostnameEndpointFallbackNameResolutionTestszd
    L{HostnameEndpoint._fallbackNameResolution} defers a name
    resolution call to a thread.
    c                    sJ   ddl m} tj|ddd}d\ | } fdd}||S )z
        L{_fallbackNameResolution} returns a L{Deferred} that fires
        with the resoution of the the host and request port.
        r   )r   ignored)r  r(  )rh  r\   c                    sL    t| d | \\}}}}} |t  |t  | f d S r[   )r   r  r   r   )resultfamilysocktype_sockaddrr  r(  rT   rU   rV   assertHostPortFamilySockType0  s
   zmHostnameEndpointFallbackNameResolutionTests.test_fallbackNameResolution.<locals>.assertHostPortFamilySockType)twisted.internetr   r   HostnameEndpoint_fallbackNameResolutionr   )rT   r   r   resolutionDeferredrt  rU   rs  rV   test_fallbackNameResolution#  s   
zGHostnameEndpointFallbackNameResolutionTests.test_fallbackNameResolutionN)rh   ri   rj   rk   ry  rU   rU   rU   rV   rl        rl  c                   @   r  )#_HostnameEndpointMemoryReactorMixinz
    Common methods for testing L{HostnameEndpoint} against
    L{MemoryReactor} instances that do not provide
    L{IReactorPluggableNameResolver}.
    c                 O   s8   z	||i |}W n t y   t  Y S w t|S )a  
        A synchronous version of L{deferToThread}.

        @param f: The callable to invoke.
        @type f: L{callable}

        @param args: Positional arguments to the callable.

        @param kwargs: Keyword arguments to the callable.

        @return: A L{Deferred} that fires with the result of applying
            C{f} to C{args} and C{kwargs} or the exception raised.
        )BaseExceptionr   r   r&  )rT   r   r   r.  rn  rU   rU   rV   synchronousDeferredToThreadA  s   
z?_HostnameEndpointMemoryReactorMixin.synchronousDeferredToThreadc                 C   r  )z
        Extract expected clients from the reactor.

        @param reactor: The L{MemoryReactor} under test.

        @return: List of calls to L{IReactorTCP.connectTCP}
        r  r   rU   rU   rV   r   V  s   z3_HostnameEndpointMemoryReactorMixin.expectedClientsc                 C   r  )zL

        @return: C{dict} of keyword arguments to pass to connect.
        g      $@r  r	  rU   rS   rU   rU   rV   r   `  rR  z/_HostnameEndpointMemoryReactorMixin.connectArgsc                 C   r  r  r  r  rU   rU   rV   r  g  r  z5_HostnameEndpointMemoryReactorMixin.assertConnectArgsc                 C   n   t jdd}t|d}t }| ||\}}}||}|tjj	 | 
| |j| | 
g |  dS )z
        When L{HostnameEndpoint.connect} cannot connect to its
        destination, the returned L{Deferred} will fail with
        C{ConnectError}.
        r  r   r  Nr   r   r5  r   r   r  advancer   rv  _DEFAULT_ATTEMPT_DELAYr   r   r  getDelayedCallsrT   r  r  r   r   r   r	  r   rU   rU   rV   r       


z?_HostnameEndpointMemoryReactorMixin.test_endpointConnectFailurec                 C   s`   t  }t }| || |  }| dt| | t|d d  | |d d 	d dS )z
        Instantiating L{HostnameEndpoint} with a reactor that does not
        provide L{IReactorPluggableResolver} emits a deprecation warning.
        r\   r   categorymessagezPassing HostnameEndpoint a reactor that does not provide IReactorPluggableNameResolver (twisted.internet.testing.MemoryReactorClock) was deprecated in Twisted 17.5.0; please use a reactor that provides IReactorPluggableNameResolver insteadN)
r   r   r   flushWarningsr   r  rE  DeprecationWarningr   
startswith)rT   r  r   warningsrU   rU   rV   test_deprecation  s   z4_HostnameEndpointMemoryReactorMixin.test_deprecationc                 C   sf   t  }t }| ||\}}}dd }||_||}| | |jtj	 | 
dt| t dS )z8
        Hostname resolution errors are logged.
        c                  _   s
   t dd)Nz#No address associated with hostname)r   )r   r.  rU   rU   rV   getaddrinfoThatFails  rs   zS_HostnameEndpointMemoryReactorMixin.test_errorsLogged.<locals>.getaddrinfoThatFailsr\   N)r   r   r   r2  r  r  r   r  r   DNSLookupErrorr   r  re  r   )rT   r  r   r   r   r	  r  r   rU   rU   rV   test_errorsLogged  s   

z5_HostnameEndpointMemoryReactorMixin.test_errorsLoggedN)rh   ri   rj   rk   r}  r   r   r  r  r  r  rU   rU   rU   rV   r{  :  s    
r{  c                   @   r   )&HostnameEndpointMemoryIPv4ReactorTestsz
    IPv4 resolution tests for L{HostnameEndpoint} with
    L{MemoryReactor} subclasses that do not provide
    L{IReactorPluggableNameResolver}.
    c              	      f   d t dd}tj|d|jfi |} fdd}||_| j|_| |j||dd|dd	f|fS )
a  
        Creates a L{HostnameEndpoint} instance where the hostname is
        resolved into a single IPv4 address.

        @param reactor: The L{MemoryReactor}

        @param clientFactory: The client L{IProtocolFactory}

        @param connectArgs: Additional arguments to
            L{HostnameEndpoint.connect}

        @return: A L{tuple} of the form C{(endpoint, (expectedAddress,
            expectedPort, clientFactory, timeout, localBindAddress,
            hostnameAddress))}
        rh     example.comr0  c                       t ttd dffgS NrL   r0  )r   r   r   r  r(  ro  rp  r@  rU   rV   r3       zTHostnameEndpointMemoryIPv4ReactorTests.createClientEndpoint.<locals>.fakegetaddrinfor  r  r  Nr   r   rv  r(  r2  r}  r*  r  rT   r   r   r   r   rK  r3  rU   r  rV   r     &   


z;HostnameEndpointMemoryIPv4ReactorTests.createClientEndpointNrh   ri   rj   rk   r   rU   rU   rU   rV   r        r  c                   @   r   )&HostnameEndpointMemoryIPv6ReactorTestsz
    IPv6 resolution tests for L{HostnameEndpoint} with
    L{MemoryReactor} subclasses that do not provide
    L{IReactorPluggableNameResolver}.
    c              	      r  )
a  
        Creates a L{HostnameEndpoint} instance where the hostname is
        resolved into a single IPv6 address.

        @param reactor: The L{MemoryReactor}

        @param clientFactory: The client L{IProtocolFactory}

        @param connectArgs: Additional arguments to
            L{HostnameEndpoint.connect}

        @return: A L{tuple} of the form C{(endpoint, (expectedAddress,
            expectedPort, clientFactory, timeout, localBindAddress,
            hostnameAddress))}
        1:2::3:4   ipv6.example.comr0  c                    r  r  )r   r   r   r  r  rU   rV   r3    r  zTHostnameEndpointMemoryIPv6ReactorTests.createClientEndpoint.<locals>.fakegetaddrinfor  r  r  Nr  r  rU   r  rV   r     r  z;HostnameEndpointMemoryIPv6ReactorTests.createClientEndpointNr  rU   rU   rU   rV   r    r  r  c                   @   sZ   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZdd Z	dd Z
dd Zdd Zd
S )HostnameEndpointsOneIPv4Testsz^
    Tests for the hostname based endpoints when GAI returns only one
    (IPv4) address.
    c              	   K   sT   d}t dd}tjt||gd|jfi |}|||j||dd|ddf|fS )z{
        Creates a L{HostnameEndpoint} instance where the hostname is resolved
        into a single IPv4 address.
        rh  r  r0  r  r  r  Nr   r   rv  rL  r(  r  )rT   r   r   r   r@  r   rK  rU   rU   rV   r   7  s$   



z2HostnameEndpointsOneIPv4Tests.createClientEndpointc                 C   r  r  r  r   rU   rU   rV   r   Q  r  z-HostnameEndpointsOneIPv4Tests.expectedClientsc                 C   r  r  r  r  rU   rU   rV   r  W  r  z/HostnameEndpointsOneIPv4Tests.assertConnectArgsc                 C   r  r  rU   rS   rU   rU   rV   r   s  rS  z)HostnameEndpointsOneIPv4Tests.connectArgsNc           
      C   s   t  }t }tj|_| ||\}}}||}|dur"|| |  | |}|	dt
t  | |}	| |	jtj | |	jj| | |jd d jj | g |  dS )z
        Calling L{Deferred.cancel} on the L{Deferred} returned from
        L{IStreamClientEndpoint.connect} will cause it to be errbacked with a
        L{ConnectingCancelledError} exception.
        Nr   r   )r   r   r(   r)   r   r  r  r  r   r   r8   r   r  r   r  r  r!   r   r   r   r  
_connectorstoppedConnectingr  )
rT   r  r  r   r   r   r   r   r  r  rU   rU   rV   r  y  s   



z>HostnameEndpointsOneIPv4Tests.test_endpointConnectingCancelledc                 C   s$   t jj}||d  }| j|d dS )a   
        Calling L{Deferred.cancel} on the L{Deferred} returned from
        L{IStreamClientEndpoint.connect} after enough time has passed that all
        connection attempts have been initiated will cause it to be errbacked
        with a L{ConnectingCancelledError} exception.
        g       @)r  N)r   rv  r  r  )rT   
oneBetweenr  rU   rU   rV   7test_endpointConnectingCancelledAfterAllAttemptsStarted  s   zUHostnameEndpointsOneIPv4Tests.test_endpointConnectingCancelledAfterAllAttemptsStartedc                 C   r~  )z
        If L{HostnameEndpoint.connect} is invoked and there is no server
        listening for connections, the returned L{Deferred} will fail with
        C{ConnectError}.
        r  r   r  Nr  r  rU   rU   rV   r    r  z9HostnameEndpointsOneIPv4Tests.test_endpointConnectFailurec                 C   s   t jdd}t }t }| ||\}}}||}|d |jd \}}	}
}}|
|j	d | | 
| |j| | 
g |  dS )a  
        If a connection attempt initiated by
        L{HostnameEndpoint.connect} fails only after
        L{HostnameEndpoint} has exhausted the list of possible server
        addresses, the returned L{Deferred} will fail with
        C{ConnectError}.
        r  r   333333?r   N)r   r   r   r   r   r  r  r  r   
connectorsr   r   r  r  )rT   r  r  r   r   r   r	  r   r  r(  r   r  r  rU   rU   rV   )test_endpointConnectFailureAfterIteration  s   


zGHostnameEndpointsOneIPv4Tests.test_endpointConnectFailureAfterIterationc                    s   t  }t }t  }| ||\}}}||}g   fdd}|| | |}	|d |	j| | 	 |g | 
|}
| 	t|
d | |
d | | 	g |  dS )a\  
        If a connection attempt initiated by
        L{HostnameEndpoint.connect} succeeds only after
        L{HostnameEndpoint} has exhausted the list of possible server
        addresses, the returned L{Deferred} will fire with the
        connected protocol instance and the endpoint will leave no
        delayed calls in the reactor.
        c                    r   r`   r   r   r   rU   rV   r     r   z[HostnameEndpointsOneIPv4Tests.test_endpointConnectSuccessAfterIteration.<locals>.checkProtor  r\   r   N)r   r   r   r  r   r   r  r   r  r   r   r  r  r  r  rU   r   rV   )test_endpointConnectSuccessAfterIteration  s$   	





zGHostnameEndpointsOneIPv4Tests.test_endpointConnectSuccessAfterIterationr`   )rh   ri   rj   rk   r   r   r  r   r  r  r  r  r  rU   rU   rU   rV   r  1  s    
r  c                   @   r   )HostnameEndpointsOneIPv6Testsz^
    Tests for the hostname based endpoints when GAI returns only one
    (IPv6) address.
    c              	   K   sP   t dd}tjt|dgd|jfi |}|d|j||dd|ddf|fS )z{
        Creates a L{HostnameEndpoint} instance where the hostname is resolved
        into a single IPv6 address.
        r  r0  r  r  r  r  Nr  )rT   r   r   r   r   rK  rU   rU   rV   r     s"   



z2HostnameEndpointsOneIPv6Tests.createClientEndpointc                 C   r  r  r  r   rU   rU   rV   r   	  r  z-HostnameEndpointsOneIPv6Tests.expectedClientsc                 C   r  r  r  r  rU   rU   rV   r  	  r  z/HostnameEndpointsOneIPv6Tests.assertConnectArgsc                 C   r  r  rU   rS   rU   rU   rV   r   9	  rS  z)HostnameEndpointsOneIPv6Tests.connectArgsc           	      C   s   t  }t }tj|_| t|dg|\}}}||}|  | |}|	dt
t  | |}| |jtj | |jj| | |jd d jj | g |  dS )r  r  Nr   r   )r   r   r(   r)   r   rL  r  r  r   r   r8   r   r  r   r  r  r!   r   r   r   r  r  r  r  )	rT   r  r   r   r   r   r   r  r  rU   rU   rV   r  ?	  s   



z>HostnameEndpointsOneIPv6Tests.test_endpointConnectingCancelledc                 C   sj   t jdd}t|d}t }| ||\}}}||}|d | | |j	| | g |
  dS )r  r  r   r  r  N)r   r   r5  r   r   r  r  r   r   r  r  r  rU   rU   rV   r  \	  s   



z9HostnameEndpointsOneIPv6Tests.test_endpointConnectFailureN)
rh   ri   rj   rk   r   r   r  r   r  r  rU   rU   rU   rV   r    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 )HostnameEndpointIDNATestszJ
    Tests for L{HostnameEndpoint}'s constructor's encoding behavior.
    
   bücher.chs   xn--bcher-kva.chc                 C   >   t tt dg| jd}| |j| j | |j| j dS )z
        A L{HostnameEndpoint} constructed with text will contain an
        IDNA-encoded bytes representation of that text.
        r  r0  N	r   rv  rL  r   sampleIDNATextr   
_hostBytessampleIDNABytes	_hostTextrJ  rU   rU   rV   test_idnaHostnameTextw	     z/HostnameEndpointIDNATests.test_idnaHostnameTextc                 C   r  )z
        A L{HostnameEndpoint} constructed with bytes will contain an
        IDNA-decoded textual representation of those bytes.
        r  r0  Nr  rJ  rU   rU   rV   test_idnaHostnameBytes	  r  z0HostnameEndpointIDNATests.test_idnaHostnameBytesc                 C   sD   t tt dgtd| jd}| |j| j | |j	| j dS )z
        A L{HostnameEndpoint} constructed with NFD-normalized text will store
        the NFC-normalized version of that text.
        r  NFDr0  N)
r   rv  rL  r   r	   r  r   r  r  r  rJ  rU   rU   rV   test_nonNormalizedText	  s   
z0HostnameEndpointIDNATests.test_nonNormalizedTextc                 C   s   t tt dgdd}|tt}| |t	}| 
dt| t tt dgdd}|t }| |t	}| 
dt| dS )a&  
        Since any client of L{IStreamClientEndpoint} needs to handle Deferred
        failures from C{connect}, L{HostnameEndpoint}'s constructor will not
        raise exceptions when given bad host names, instead deferring to
        returning a failing L{Deferred} from C{connect}.
        r     -garbage-r0  z\xff-garbage-\xffu   ⿰-garbage-⿰z\u2ff0-garbage-\u2ff0N)r   rv  rL  r   r  r(   r  r)   r   r   r  r8  )rT   rK  deferrederrrU   rU   rV   test_deferBadEncodingToConnect	  s    z8HostnameEndpointIDNATests.test_deferBadEncodingToConnectN)
rh   ri   rj   rk   r  r  r  r  r  r  rU   rU   rU   rV   r  o	  s    r  c                   @   r#  )HostnameEndpointReprTestsz@
    Tests for L{HostnameEndpoint}'s string representation.
    c                 C   >   t tt g dd}t|}| d| | tt| dS )z
        The string representation of L{HostnameEndpoint} includes the host and
        port passed to the constructor.
        r`  r0  z!<HostnameEndpoint example.com:80>N	r   rv  rL  r+   rf  r   rE  r8  typerT   rK  reprU   rU   rV   test_allASCII	     
z'HostnameEndpointReprTests.test_allASCIIc                 C   r  )z
        When IDN is passed to the L{HostnameEndpoint} constructor the string
        representation includes the punycode version of the host.
        r    z'<HostnameEndpoint xn--bcher-kva.ch:443>Nr  r  rU   rU   rV   test_idnaHostname	  r  z+HostnameEndpointReprTests.test_idnaHostnamec                 C   r  )z
        When the host passed to L{HostnameEndpoint} is an IPv6 address it is
        wrapped in brackets in the string representation, like in a URI. This
        prevents the colon separating the host from the port from being
        ambiguous.
        s   ::1   z<HostnameEndpoint [::1]:22>Nr  r  rU   rU   rV   test_hostIPv6Address	  s   
z.HostnameEndpointReprTests.test_hostIPv6Addressc                 C   s*   t tt g dd}| dt| dS )z
        When a bad hostname is passed to L{HostnameEndpoint}, the string
        representation displays invalid characters in backslash-escaped form.
        r  r0  z'<HostnameEndpoint \xff-garbage-\xff:80>N)r   rv  rL  r+   r   rf  rJ  rU   rU   rV   test_badEncoding	  s   z*HostnameEndpointReprTests.test_badEncodingN)rh   ri   rj   rk   r  r  r  r  rU   rU   rU   rV   r  	  s    r  c                   @   r   ) HostnameEndpointsGAIFailureTestszM
    Tests for the hostname based endpoints when GAI returns no address.
    c                 C   sH   t tt g dd}t }||}| |tj}| 	dt
| dS )z
        If no address is returned by GAI for a hostname, the connection attempt
        fails with L{error.DNSLookupError}.
        r  r0  r`  N)r   rv  rL  r+   r   r  r   r   r  r  r8  )rT   rK  r   dConnectexcrU   rU   rV   test_failure
  s   
z-HostnameEndpointsGAIFailureTests.test_failureN)rh   ri   rj   rk   r  rU   rU   rU   rV   r  	  r   r  c                   @   rM   )&HostnameEndpointsFasterConnectionTestsz
    Tests for the hostname based endpoints when gai returns an IPv4 and
    an IPv6 address, and one connection takes less time than the other.
    c                 C   s(   t  | _tt| jddgdd| _d S )Nrh  r     www.example.comr0  )r   r  r   rv  rL  rK  rS   rU   rU   rV   rL  
  s   
z,HostnameEndpointsFasterConnectionTests.setUpc                 C   s   t  | _tt| jdt dgdd| _d}| j| | jd | jj	d \}}}}}| 
t| jj	d | 
|d | 
|d dS )	z
        If an address type other than L{IPv4Address} and L{IPv6Address} is
        returned by on address resolution, the endpoint ignores that address.
        rh  r  r  r0  Nr  r\   r   )r   r  r   rv  rL  r   rK  r  r  r  r   r  )rT   r   r  r(  r   r  r  rU   rU   rV   test_ignoreUnknownAddressTypes
  s   zEHostnameEndpointsFasterConnectionTests.test_ignoreUnknownAddressTypesc                 C   s   t  }t j|_ | j|}g }||j | jjd \}}}}}| 	|d | 	|d |
||f}	t }
| 	|g  |	|
 | 	t|d | 	|d j| | 	g | j  dS )a=  
        The endpoint returns a connection to the IPv4 address.

        IPv4 ought to be the first attempt, since nameResolution (standing in
        for GAI here) returns it first. The IPv4 attempt succeeds, the
        connection is established, and a Deferred fires with the protocol
        constructed.
        r   rh  r0  r\   N)r   r(   r)   rK  r  r   ra   r  r  r   r   r   r   r  r   r  rT   r   r   resultsr  r(  r   r  r  r  fakeTransportrU   rU   rV   test_IPv4IsFaster5
  s   	
z8HostnameEndpointsFasterConnectionTests.test_IPv4IsFasterc                 C   s   t  }t j|_ | j|}g }||j | jd | jj	d \}}}}}| 
|d | 
|d |||f}	t }
| 
|g  |	|
 | 
t|d | 
|d j| | 
g | j  dS )a=  
        The endpoint returns a connection to the IPv6 address.

        IPv6 ought to be the second attempt, since nameResolution (standing in
        for GAI here) returns it second. The IPv6 attempt succeeds, a
        connection is established, and a Deferred fires with the protocol
        constructed.
        r  r\   r  r0  r   N)r   r(   r)   rK  r  r   ra   r  r  r  r   r   r   r   r  r   r  r  rU   rU   rV   test_IPv6IsFasterT
  s    	
z8HostnameEndpointsFasterConnectionTests.test_IPv6IsFasterc                 C   s   t  }t j|_ | j|}g }||j | jd | jj	d \}}}}}|
||f}	t }
|	|
 | d| jj	d d jj | g | j  dS )a   
        Once the endpoint returns a successful connection, all the other
        pending connections are cancelled.

        Here, the second connection attempt, i.e. IPv6, succeeds, and the
        pending first attempt, i.e. IPv4, is cancelled.
        r  r\   Tr   r   N)r   r(   r)   rK  r  r   ra   r  r  r  r   r   r   r   r  r  r  r  rU   rU   rV   test_otherConnectionsCancelledu
  s   
zEHostnameEndpointsFasterConnectionTests.test_otherConnectionsCancelledN)	rh   ri   rj   rk   rL  r  r  r  r  rU   rU   rU   rV   r  
  s    !r  c                   @   ry  )SSL4EndpointsTestsz"
    Tests for SSL Endpoints.
    c                 C   r  )zD
        @return: List of calls to L{IReactorSSL.listenSSL}
        )
sslServersr   rU   rU   rV   r-  
  r  z"SSL4EndpointsTests.expectedServersc                 C   r  )zE
        @return: List of calls to L{IReactorSSL.connectSSL}
        )
sslClientsr   rU   rU   rV   r   
  r  z"SSL4EndpointsTests.expectedClientsc                 C   s`   |\}}}}}}|\}	}
}}}}|  ||	 |  ||
 |  || |  || |  || dS )a  
        Compare host, port, contextFactory, timeout, and bindAddress in
        C{receivedArgs} to C{expectedArgs}.  We ignore the factory because we
        don't only care what protocol comes out of the
        C{IStreamClientEndpoint.connect} call.

        @param receivedArgs: C{tuple} of (C{host}, C{port}, C{factory},
            C{contextFactory}, C{timeout}, C{bindAddress}) that was passed to
            L{IReactorSSL.connectSSL}.
        @param expectedArgs: C{tuple} of (C{host}, C{port}, C{factory},
            C{contextFactory}, C{timeout}, C{bindAddress}) that we expect to
            have been passed to L{IReactorSSL.connectSSL}.
        Nr  )rT   r  r  r  r(  r  contextFactoryr  r  r.  r  r  expectedContextFactoryr   r  rU   rU   rV   r  
  s*   
z$SSL4EndpointsTests.assertConnectArgsc                 C   r  r  rU   rS   rU   rU   rV   r   
  rS  zSSL4EndpointsTests.connectArgsc                 C   r  r
  rU   rS   rU   rU   rV   r5  
  rS  zSSL4EndpointsTests.listenArgsc                 C   sL   t ddd\| _| _t ddd\| _| _t| j| jdd| _tdd| _d	S )
zF
        Set up client and server SSL contexts for use later.
        zServer Test Certificateserver)OCNzClient Test CertificateclientF)
privateKeycertificaterequireCertificate)r  N)rK   sKeysCertcKeycCertrE   serverSSLContextclientSSLContextrS   rU   rU   rV   rL  
  s   
zSSL4EndpointsTests.setUpc              	   K   sJ   t ddd}tj||j| jfi ||j|| j|dd|ddf|fS )a  
        Create an L{SSL4ServerEndpoint} and return the tools to verify its
        behaviour.

        @param factory: The thing that we expect to be passed to our
            L{IStreamServerEndpoint.listen} implementation.
        @param reactor: A fake L{IReactorSSL} that L{SSL4ServerEndpoint} can
            call L{IReactorSSL.listenSSL} on.
        @param listenArgs: Optional dictionary of arguments to
            L{IReactorSSL.listenSSL}.
        r  r  r   r  r  r  rL   )r   r   SSL4ServerEndpointr(  r  r  r  rU   rU   rV   r%  
  s   


z'SSL4EndpointsTests.createServerEndpointc              
   K   sR   t ddd}tj||j|j| jfi ||j|j|| j|dd|ddf|fS )a  
        Create an L{SSL4ClientEndpoint} and return the values needed to verify
        its behaviour.

        @param reactor: A fake L{IReactorSSL} that L{SSL4ClientEndpoint} can
            call L{IReactorSSL.connectSSL} on.
        @param clientFactory: The thing that we expect to be passed to our
            L{IStreamClientEndpoint.connect} implementation.
        @param connectArgs: Optional dictionary of arguments to
            L{IReactorSSL.connectSSL}
        r  r  r0  r  r  r  N)r   r   SSL4ClientEndpointr  r(  r  r  r  rU   rU   rV   r     s$   

z'SSL4EndpointsTests.createClientEndpointN)rh   ri   rj   rk   r-  r   r  r   r5  rL  r%  r   rU   rU   rU   rV   r  
  s    &r  c                   @   ry  )UNIXEndpointsTestsz)
    Tests for UnixSocket Endpoints.
    c                 C   r   )z
        Override L{EndpointTestCaseMixin.retrieveConnectedFactory} to account
        for different index of 'factory' in C{connectUNIX} args.
        r   r\   r   r   rU   rU   rV   r   (  r~   z+UNIXEndpointsTests.retrieveConnectedFactoryc                 C   r  )zF
        @return: List of calls to L{IReactorUNIX.listenUNIX}
        )unixServersr   rU   rU   rV   r-  /  r  z"UNIXEndpointsTests.expectedServersc                 C   r  )zG
        @return: List of calls to L{IReactorUNIX.connectUNIX}
        )unixClientsr   rU   rU   rV   r   5  r  z"UNIXEndpointsTests.expectedClientsc                 C   s@   |\}}}}|\}}}	}
|  || |  ||	 |  ||
 dS )a  
        Compare path, timeout, checkPID in C{receivedArgs} to C{expectedArgs}.
        We ignore the factory because we don't only care what protocol comes
        out of the C{IStreamClientEndpoint.connect} call.

        @param receivedArgs: C{tuple} of (C{path}, C{timeout}, C{checkPID})
            that was passed to L{IReactorUNIX.connectUNIX}.
        @param expectedArgs: C{tuple} of (C{path}, C{timeout}, C{checkPID})
            that we expect to have been passed to L{IReactorUNIX.connectUNIX}.
        Nr  )rT   r  r  rr  r  r  checkPIDexpectedPathr  r   expectedCheckPIDrU   rU   rV   r  ;  s   z$UNIXEndpointsTests.assertConnectArgsc                 C   r  )r  r  r\   )r  r  rU   rS   rU   rU   rV   r   T  rS  zUNIXEndpointsTests.connectArgsc                 C   s   ddddS )r  r  i  r\   )r  modewantPIDrU   rS   rU   rU   rV   r5  Z  s   zUNIXEndpointsTests.listenArgsc              	   K   sL   t |  }tj||jfi ||j||dd|dd|ddf|fS )a  
        Create an L{UNIXServerEndpoint} and return the tools to verify its
        behaviour.

        @param reactor: A fake L{IReactorUNIX} that L{UNIXServerEndpoint} can
            call L{IReactorUNIX.listenUNIX} on.
        @param factory: The thing that we expect to be passed to our
            L{IStreamServerEndpoint.listen} implementation.
        @param listenArgs: Optional dictionary of arguments to
            L{IReactorUNIX.listenUNIX}.
        r  r  r    r  r   )r   mktempr   UNIXServerEndpointrb  r  r  rU   rU   rV   r%  `  s   


z'UNIXEndpointsTests.createServerEndpointc                 K   sB   t |  }tj||jfi ||j||dd|ddf|fS )a  
        Create an L{UNIXClientEndpoint} and return the values needed to verify
        its behaviour.

        @param reactor: A fake L{IReactorUNIX} that L{UNIXClientEndpoint} can
            call L{IReactorUNIX.connectUNIX} on.
        @param clientFactory: The thing that we expect to be passed to our
            L{IStreamClientEndpoint.connect} implementation.
        @param connectArgs: Optional dictionary of arguments to
            L{IReactorUNIX.connectUNIX}
        r  r  r  r   )r   r  r   UNIXClientEndpointrb  r  r  rU   rU   rV   r   z  r  z'UNIXEndpointsTests.createClientEndpointN)rh   ri   rj   rk   r   r-  r   r  r   r5  r%  r   rU   rU   rU   rV   r  #  s    r  c                   @   sl   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )ParserTestszK
    Tests for L{endpoints._parseServer}, the low-level parsing logic.
    r(   c                 O   s   t j|i |S )zT
        Provide a hook for test_strports to substitute the deprecated API.
        )r   _parseServer)rT   akwrU   rU   rV   parse  r  zParserTests.parsec                 C   ,   |  | d| jdd| jfdddf dS )zN
        Simple strings with a 'tcp:' prefix should be parsed as TCP.
        ztcp:80r  r0  rL   r  r  r  Nr   r  r   rS   rU   rU   rV   test_simpleTCP     zParserTests.test_simpleTCPc                 C   r  )zU
        TCP port descriptions parse their 'interface' argument as a string.
        ztcp:80:interface=127.0.0.1r  r0  r  r  r  Nr  rS   rU   rU   rV   test_interfaceTCP  r  zParserTests.test_interfaceTCPc                 C   r  )zU
        TCP port descriptions parse their 'backlog' argument as an integer.
        ztcp:80:backlog=6r  r0  rL      r  Nr  rS   rU   rU   rV   test_backlogTCP  r  zParserTests.test_backlogTCPc              	   C   .   |  | d| jdd| jfddddf dS )	z
        L{endpoints._parseServer} returns a C{'UNIX'} port description with
        defaults for C{'mode'}, C{'backlog'}, and C{'wantPID'} when passed a
        string with the C{'unix:'} prefix and no other parameter values.
        zunix:/var/run/fingerUNIX/var/run/fingerr  r  Tr  r  r  Nr  rS   rU   rU   rV   test_simpleUNIX  s   
zParserTests.test_simpleUNIXc              	   C   r  )	zK
        C{mode} can be set by including C{"mode=<some integer>"}.
        zunix:/var/run/finger:mode=0660r  r  i  r  Tr  Nr  rS   rU   rU   rV   test_modeUNIX     
zParserTests.test_modeUNIXc              	   C   r  )	zM
        C{wantPID} can be set to false by included C{"lockfile=0"}.
        zunix:/var/run/finger:lockfile=0r  r  r  r  Fr  Nr  rS   rU   rU   rV   test_wantPIDUNIX  r	  zParserTests.test_wantPIDUNIXc              	   C   r  )	zf
        Backslash can be used to escape colons and backslashes in port
        descriptions.
        zunix:foo\:bar\=baz\:qux\\r  zfoo:bar=baz:qux\r  r  Tr  Nr  rS   rU   rU   rV   test_escape     
zParserTests.test_escapec                 C   s   |  tdd dS )z
        L{endpoints.quoteStringArgument} should quote backslashes and colons
        for interpolation into L{endpoints.serverFromString} and
        L{endpoints.clientFactory} arguments.
        zsome : stuff \zsome \: stuff \\N)r   r   quoteStringArgumentrS   rU   rU   rV   test_quoteStringArgument  s   z$ParserTests.test_quoteStringArgumentc              	   C   r  )	z
        In strports descriptions, '=' in a parameter value does not need to be
        quoted; it will simply be parsed as part of the value.
        zunix:address=foo=barr  zfoo=barr  r  Tr  Nr  rS   rU   rU   rV   test_impliedEscape  r  zParserTests.test_impliedEscapec                 C   s   |  t| jd| j dS )ze
        L{strports.parse} raises C{ValueError} when given an unknown endpoint
        type.
        zbogus-type:nothingN)r  r   r  r   rS   rU   rU   rV   test_unknownType  r\  zParserTests.test_unknownTypeN)rh   ri   rj   rk   r   r  r  r   r  r  r  r
  r  r  r  r  rU   rU   rU   rV   r    s    			r  c                   @   s   e Zd ZdZdd Zeeedd Zeeedd Z	dZ
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d Zdd Zdd ZdS )ServerStringTestszC
    Tests for L{twisted.internet.endpoints.serverFromString}.
    c                 C   s\   t  }t|d}| |tj | |j| | |jd | |j	d | |j
d dS )z
        When passed a TCP strports description, L{endpoints.serverFromString}
        returns a L{TCP4ServerEndpoint} instance initialized with the values
        from the string.
        z&tcp:1234:backlog=12:interface=10.0.0.1r)     10.0.0.1N)r   r   serverFromStringr  r  rE  r~  r   _port_backlog
_interface)rT   r   r  rU   rU   rV   test_tcp  s   zServerStringTests.test_tcpc                 C   s   t  }t|dttf }| |tj | |j| | |j	d | |j
d | |jd | |jjt |j }| |t dS )z
        When passed an SSL strports description, L{endpoints.serverFromString}
        returns a L{SSL4ServerEndpoint} instance initialized with the values
        from the string.
        Vssl:1234:backlog=12:privateKey=%s:certKey=%s:sslmethod=TLSv1_METHOD:interface=10.0.0.1r)  r  r  N)r   r   r  escapedPEMPathNamer  r  rE  r~  r   r  r  r  _sslContextFactorymethodrC   
getContextContextTyperT   r   r  ctxrU   rU   rV   test_ssl)  s   
zServerStringTests.test_sslc                 C   s   t  }t|dt }| |tj | |j| | |j	d | |j
d | |jd | |jjt | |jjt@  |j }| |t dS )z
        An SSL string endpoint description with minimal arguments returns
        a properly initialized L{SSL4ServerEndpoint} instance.
        zssl:4321:privateKey=  r  rL   N)r   r   r  r  r  r  rE  r~  r   r  r  r  r  r  rB   r   _optionsrA   r  r  r  rU   rU   rV   test_sslWithDefaults@  s   


z&ServerStringTests.test_sslWithDefaultsz(ssl:1234:privateKey=%s:extraCertChain=%sc                 C   st   t t | jttf }dd dD }|j}| |jd 	d|d 	d | |jd 	d|d 	d dS )zf
        Specifying a chain file loads the contained certificates in the right
        order.
        c                 S   s&   g | ]}t td |f  qS )zthing%d.pem)rD   loadPEMcasPathchild
getContent).0nrU   rU   rV   
<listcomp>k  s    z8ServerStringTests.test_sslChainLoads.<locals>.<listcomp>)r\   r   r   sha1r\   N)
r   r  r   SSL_CHAIN_TEMPLATEr  escapedChainPathNamer  r   extraCertChaindigest)rT   r  expectedChainCertscfrU   rU   rV   test_sslChainLoadsZ  s$   z$ServerStringTests.test_sslChainLoadsc              	   C   s   t |  }|   | t}tt | j	t
t|jf  W d   n1 s,w   Y  | t|jd|jf  dS )zy
        If C{extraCertChain} is passed, it has to contain at least one valid
        certificate in PEM format.
        NzOSpecified chain file '%s' doesn't contain any valid certificates in PEM format.)r9   r  createcloser  r   r   r  r   r-  r  r  rr  r   r8  r3  )rT   fpcaughtrU   rU   rV    test_sslChainFileMustContainCertw  s$   
z2ServerStringTests.test_sslChainFileMustContainCertc                 C   sL   d}t  }t|dtt|}|j}| |jt | 	t
||jj dS )z
        If C{dhParameters} are specified, they are passed as
        L{DiffieHellmanParameters} into L{CertificateOptions}.
        someFilez1ssl:4321:privateKey={}:certKey={}:dhParameters={}N)r   r   r  formatr  r  r  dhParametersrF   r   r9   _dhFile)rT   fileNamer   r  r2  rU   rU   rV   test_sslDHparameters  s   z&ServerStringTests.test_sslDHparametersc                 C   s   t  }t|dttf }| |tj | |j| | 	|j
d | 	|jd | 	|jd | 	|jjt |j }| |t dS )zq
        Lack of a trailing newline in key and cert .pem files should not
        generate an exception.
        r  r)  r  r  N)r   r   r  &escapedNoTrailingNewlineKeyPEMPathName'escapedNoTrailingNewlineCertPEMPathNamer  r  rE  r~  r   r  r  r  r  r  rC   r  r  r  rU   rU   rV   test_sslNoTrailingNewlinePem  s"   	
z.ServerStringTests.test_sslNoTrailingNewlinePemc                 C   sh   t  }t|d}| |tj | |j| | |jd | |j	d | |j
d | |j dS )z
        When passed a UNIX strports description, L{endpoint.serverFromString}
        returns a L{UNIXServerEndpoint} instance initialized with the values
        from the string.
        z0unix:/var/foo/bar:backlog=7:mode=0123:lockfile=1/var/foo/bar   S   N)r   r   r  r  r  rE  r~  r   _addressr  _moder   _wantPID)rT   r   rK  rU   rU   rV   	test_unix  s   zServerStringTests.test_unixc                 C   &   |  ttjdd}| t|d dS )zq
        L{endpoints.serverFromString} raises C{ValueError} when given an
        unknown endpoint type.
        Nftl:andromeda/carcosa/hali/2387Unknown endpoint type: 'ftl')r  r   r   r  r   r8  rT   r  rU   rU   rV   r       z"ServerStringTests.test_unknownTypec                 C   b   t |  t }t|d}ddlm} | |j| | |j	|ddf | |j
tddd d	S )
z
        L{endpoints.serverFromString} looks up plugins of type
        L{IStreamServerEndpoint} and constructs endpoints from them.
        zfake:hello:world:yes=no:up=downr   )fakehelloworldnodown)yesupN)addFakePluginr   r   r  twisted.plugins.fakeendpointrO  rE  parserr   r   r.  dict)rT   notAReactorfakeEndpointrO  rU   rU   rV   test_typeFromPlugin  s   z%ServerStringTests.test_typeFromPluginN)rh   ri   rj   rk   r  r
   skipSSLskipSSLReasonr!  r$  r-  r3  r8  r>  rA  rH  r  r\  rU   rU   rU   rV   r    s&    





r  fakeendpoint.pyc                    sx   ddl j  ttj fdd}| | t|  }|	  t
tj||| tj|j dS )z
    For the duration of C{testCase}, add a fake plugin to twisted.plugins which
    contains some sample endpoint parsers.
    r   Nc                      s(   j   j   tjd d < d S r`   )modulesclearupdater   __path__rU   savedModulessavedPluginPathsysrU   rV   cleanup  s   
zaddFakePlugin.<locals>.cleanup)rg  r`  rJ  listr   rc  r  r9   r  createDirectoryr:   rh   filePathsiblingcopyTor'  ra   rr  )testCasedropinSourcerh  r6  rU   rd  rV   rV    s   


rV  c                   @   sh   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )ClientStringTestszC
    Tests for L{twisted.internet.endpoints.clientFromString}.
    c                 C   j   t  }t|d}| |tj | |j| | |jd | |j	d | |j
d | |jd dS )z
        When passed a TCP strports description, L{endpoints.clientFromString}
        returns a L{TCP4ClientEndpoint} instance initialized with the values
        from the string.
        z=tcp:host=example.com:port=1234:timeout=7:bindAddress=10.0.0.2r`  r)  rC  z10.0.0.2r   Nr   r   clientFromStringr  r  rE  r~  r   _hostr  _timeout_bindAddressrT   r   r  rU   rU   rV   r       zClientStringTests.test_tcpc                 C   rq  )z
        When passed a TCP strports description using positional arguments,
        L{endpoints.clientFromString} returns a L{TCP4ClientEndpoint} instance
        initialized with the values from the string.
        z3tcp:example.com:1234:timeout=7:bindAddress=10.0.0.2r`  r)  rC  rr  Nrs  rx  rU   rU   rV   test_tcpPositionalArgs!  ry  z(ClientStringTests.test_tcpPositionalArgsc                 C   2   t  }t|d}| |jd | |jd dS )z
        When passed a TCP strports description specifying host as a positional
        argument, L{endpoints.clientFromString} returns a L{TCP4ClientEndpoint}
        instance initialized with the values from the string.
        z8tcp:example.com:port=1234:timeout=7:bindAddress=10.0.0.2r`  r)  Nr   r   rt  r   ru  r  rx  rU   rU   rV   test_tcpHostPositionalArg2  s   z+ClientStringTests.test_tcpHostPositionalArgc                 C   r{  )z
        When passed a TCP strports description specifying port as a positional
        argument, L{endpoints.clientFromString} returns a L{TCP4ClientEndpoint}
        instance initialized with the values from the string.
        z8tcp:host=example.com:1234:timeout=7:bindAddress=10.0.0.2r`  r)  Nr|  rx  rU   rU   rV   test_tcpPortPositionalArg@  s   z+ClientStringTests.test_tcpPortPositionalArgc                 C   s0   t  }t|d}| |jd | |j dS )z{
        A TCP strports description may omit I{timeout} or I{bindAddress} to
        allow the default to be used.
        ztcp:host=example.com:port=1234r  N)r   r   rt  r   rv  r   rw  rx  rU   rU   rV   test_tcpDefaultsM  s   z"ClientStringTests.test_tcpDefaultsc                 C   Z   t  }t|d}| |tj | |j| | |jd | |j	d | 
|j dS )z
        When passed a UNIX strports description, L{endpoints.clientFromString}
        returns a L{UNIXClientEndpoint} instance initialized with the values
        from the string.
        z+unix:path=/var/foo/bar:lockfile=1:timeout=9rB  	   Nr   r   rt  r  r  rE  r~  r   r  rv  r   	_checkPIDrx  rU   rU   rV   rH  W     zClientStringTests.test_unixc                 C   s,   t t d}| |jd | |j dS )zz
        A UNIX strports description may omit I{lockfile} or I{timeout} to allow
        the defaults to be used.
        zunix:path=/var/foo/barr  N)r   rt  r   r   rv  r   r  )rT   r  rU   rU   rV   test_unixDefaultsg  s   z#ClientStringTests.test_unixDefaultsc                 C   r  )z
        When passed a UNIX strports description specifying path as a positional
        argument, L{endpoints.clientFromString} returns a L{UNIXClientEndpoint}
        instance initialized with the values from the string.
        z&unix:/var/foo/bar:lockfile=1:timeout=9rB  r  Nr  rx  rU   rU   rV   test_unixPathPositionalArgp  r  z,ClientStringTests.test_unixPathPositionalArgc                 C   rN  )
z
        L{endpoints.clientFromString} looks up plugins of type
        L{IStreamClientEndpoint} and constructs endpoints from them.
        crfake:alpha:beta:cee=dee:num=1r   fakeClientWithReactoralphabetadee1ceenumN)rV  r   r   rt  rW  r  rE  rX  r   r   r.  rY  )rT   rZ  clientEndpointr  rU   rU   rV   r\    s   z%ClientStringTests.test_typeFromPluginc                 C   rI  )zq
        L{endpoints.clientFromString} raises C{ValueError} when given an
        unknown endpoint type.
        NrJ  rK  )r  r   r   rt  r   r8  rL  rU   rU   rV   r    rM  z"ClientStringTests.test_unknownTypec              	   C   sV   t |  t }t|d}ddlm} | |j|j|j	f||ddft
dddf d	S )
z
        L{endpoints.clientFromString} will pass a reactor to plugins
        implementing the L{IStreamClientEndpointStringParserWithReactor}
        interface.
        r  r   r  r  r  r  r  r  N)rV  r   r   rt  rW  r  r   rX  r   r.  rY  )rT   r   r  r  rU   rU   rV   test_stringParserWithReactor  s   
z.ClientStringTests.test_stringParserWithReactorN)rh   ri   rj   rk   r  rz  r}  r~  r  rH  r  r  r\  r  r  rU   rU   rU   rV   rp    s    
	rp  c                   @   rM   )SSLClientStringTestszU
    Tests for L{twisted.internet.endpoints.clientFromString} which require SSL.
    c                    s`  t  }t|dtttf }| |tj | |j| | 	|j
d | 	|jd | 	|jd | 	|jd |j}| |t | 	|jt | |jt@  | }| |t | 	t|jt t|j}|t|j | 	|t dd t dt d	fD }g  G  fd
dd}|j!"|  | 	t#dd  D dd dt#|dd d dS )
        When passed an SSL strports description, L{clientFromString} returns a
        L{SSL4ClientEndpoint} instance initialized with the values from the
        string.
        zdssl:host=example.net:port=4321:privateKey=%s:certKey=%s:bindAddress=10.0.0.3:timeout=3:caCertsDir=%sexample.netr"  r   z10.0.0.3r   c                 S   s,   g | ]}|   d rt| qS )z.pem)basenamelowerendswithrD   r%  r(  r)  xrU   rU   rV   r+    s    z1SSLClientStringTests.test_ssl.<locals>.<listcomp>
thing1.pem
thing2.pemc                          e Zd Z fddZdS )z.SSLClientStringTests.test_ssl.<locals>.ListCtxc                    s   G  fddd}| S )Nc                       r  )zLSSLClientStringTests.test_ssl.<locals>.ListCtx.get_cert_store.<locals>.Storec                    s     | d S r`   r   )rT   cert
addedCertsrU   rV   add_cert  r   zUSSLClientStringTests.test_ssl.<locals>.ListCtx.get_cert_store.<locals>.Store.add_certN)rh   ri   rj   r  rU   r  rU   rV   Store      r  rU   )rT   r  r  rU   rV   get_cert_store  s   z=SSLClientStringTests.test_ssl.<locals>.ListCtx.get_cert_storeN)rh   ri   rj   r  rU   r  rU   rV   ListCtx  r  r  c                 s   s    | ]}t |V  qd S r`   rD   r  rU   rU   rV   	<genexpr>  s    z0SSLClientStringTests.test_ssl.<locals>.<genexpr>c                 S      |   S r`   r0  r  rU   rU   rV   r         z/SSLClientStringTests.test_ssl.<locals>.<lambda>)keyc                 S   r  r`   r  r  rU   rU   rV   r     r  N)$r   r   rt  r  escapedCAsPathNamer  r  rE  r~  r   ru  r  rv  rw  r  rE   r  rB   r   r#  rA   r  r  rD   r  testCertificaterH   _setPrivateKeyrG   r  testPrivateCertificater&  r'  	trustRoot_addCACertsToContextsorted)rT   r   r  certOptionsr   privateCertexpectedCertsr  rU   r  rV   r!    sF   
zSSLClientStringTests.test_sslc                 C   st   t  }t|dtttf }| |tj | |j| | 	|j
d | 	|jd | 	|jd | 	|jd dS )r  zZssl:example.net:4321:privateKey=%s:certKey=%s:bindAddress=10.0.0.3:timeout=3:caCertsDir=%sr  r"  r   r  N)r   r   rt  r  r  r  r  rE  r~  r   ru  r  rv  rw  rx  rU   rU   rV   test_sslPositionalArgs  s   z+SSLClientStringTests.test_sslPositionalArgsc                 C   sz   t  }t|d}| |tj | |j| | |jd | |j	d |j
}| |jt | |j | |j dS )z
        When passed an SSL strports description without extra arguments,
        L{clientFromString} returns a L{SSL4ClientEndpoint} instance
        whose context factory is initialized with default values.
        zssl:example.net:4321r  r"  N)r   r   rt  r  r  rE  r~  r   ru  r  r  r  rB   r   r  r  )rT   r   r  r  rU   rU   rV   r$    s   z)SSLClientStringTests.test_sslWithDefaultsc                 C   sX   G dd dt }td }||_| dd t|jD t	
td g dS )z
        If a certificate in the directory is unreadable,
        L{endpoints._loadCAsFromDir} will ignore that certificate.
        c                   @   s   e Zd Zdd ZdS )zKSSLClientStringTests.test_unreadableCertificate.<locals>.UnreadableFilePathc                 S   s(   t | }|td krtt|S )Nr  )r9   r(  r&  r'  OSErrorr   rb   rU   rU   rV   r(    s   
zVSSLClientStringTests.test_unreadableCertificate.<locals>.UnreadableFilePath.getContentN)rh   ri   rj   r(  rU   rU   rU   rV   UnreadableFilePath  s    r  rm  c                 S   s   g | ]}t |qS rU   r  r  rU   rU   rV   r+  '  s    zCSSLClientStringTests.test_unreadableCertificate.<locals>.<listcomp>r  N)r9   r&  r'  parent	clonePathr   r   _loadCAsFromDir_caCertsrD   r%  r(  )rT   r  casPathClonerU   rU   rV   test_unreadableCertificate  s   
z/SSLClientStringTests.test_unreadableCertificatec                 C   sH   t  }t|d}|j}| |t | |j | }| |t	 dS )z
        When passed an SSL strports description without any extra parameters,
        L{clientFromString} returns a simple non-verifying endpoint that will
        speak SSL.
        z%ssl:host=simple.example.org:port=4321N)
r   r   rt  r  r  rE   r   verifyr  r  )rT   r   r  r  r   rU   rU   rV   test_sslSimple+  s   z#SSLClientStringTests.test_sslSimpleN)	rh   ri   rj   rk   r!  r  r$  r  r  rU   rU   rU   rV   r    s    4r  c                   @   r  ) AdoptedStreamServerEndpointTestszA
    Tests for adopted socket-based stream server endpoints.
    c                 C   s&   t |||}dd |_dd |_|S )z
        Create an L{AdoptedStreamServerEndpoint} which may safely be used with
        an invalid file descriptor.  This is convenient for a number of unit
        tests.
        c                 S   r   r`   rU   ri  rU   rU   rV   r   J  r   zPAdoptedStreamServerEndpointTests._createStubbedAdoptedEndpoint.<locals>.<lambda>c                 S   r   r`   rU   r  rU   rU   rV   r   K  r   )r   AdoptedStreamServerEndpoint_close_setNonBlocking)rT   r   filenoaddressFamilyr   rU   rU   rV   _createStubbedAdoptedEndpointA  s   

z>AdoptedStreamServerEndpointTests._createStubbedAdoptedEndpointc                 C   s2   d}t }| |||}tddd}||||f|fS )a  
        Create a new L{AdoptedStreamServerEndpoint} for use by a test.

        @return: A three-tuple:
            - The endpoint
            - A tuple of the arguments expected to be passed to the underlying
              reactor method
            - An IAddress object which will match the result of
              L{IListeningPort.getHost} on the port returned by the endpoint.
        r  r  r  r)  )r   r  r   )rT   r   r   r  r  rK  r   rU   rU   rV   r%  N  s
   z5AdoptedStreamServerEndpointTests.createServerEndpointc                 C   r  )z
        @return: The ports which were actually adopted by C{reactor} via calls
            to its L{IReactorSocket.adoptStreamPort} implementation.
        )adoptedPortsr   rU   rU   rV   r-  `  s   z0AdoptedStreamServerEndpointTests.expectedServersc                 C   s   i S )zx
        @return: A C{dict} of additional keyword arguments to pass to the
            C{createServerEndpoint}.
        rU   rS   rU   rU   rV   r5  g  s   z+AdoptedStreamServerEndpointTests.listenArgsc                    sR   t    dt}|t  |t tj} fdd}|| |S )z
        L{AdoptedStreamServerEndpoint.listen} can only be used once.  The file
        descriptor given is closed after the first use, and subsequent calls to
        C{listen} return a L{Deferred} that fails with L{AlreadyListened}.
           c                    s    dt j d S r[   )r   r  r  rm  r   rT   rU   rV   listenFailedy  s   zEAdoptedStreamServerEndpointTests.test_singleUse.<locals>.listenFailed)	r   r  r   r,  r   r   r   AlreadyListenedr   )rT   rK  r   r  rU   r  rV   test_singleUsen  s   
z/AdoptedStreamServerEndpointTests.test_singleUsec                    sR   t  }|dt}g   fdd}||_|t } fdd}|| |S )zv
        L{AdoptedStreamServerEndpoint.listen} sets the file description given
        to it to non-blocking.
        r  c                    s     d| f d S )NsetNonBlockingr   r  )eventsrU   rV   r    r^   zTAdoptedStreamServerEndpointTests.test_descriptionNonBlocking.<locals>.setNonBlockingc                        dg  d S )N)r  r  r  r  r  rT   rU   rV   listened  r^   zNAdoptedStreamServerEndpointTests.test_descriptionNonBlocking.<locals>.listened)r   r  r   r  r,  r   r   )rT   r   rK  r  r   r  rU   r  rV   test_descriptionNonBlocking  s   
z<AdoptedStreamServerEndpointTests.test_descriptionNonBlockingc                    sT   t  dt}g   fdd}||_|t } fdd}|| |S )z
        L{AdoptedStreamServerEndpoint.listen} closes its file descriptor after
        adding it to the reactor with L{IReactorSocket.adoptStreamPort}.
        r  c                    s     d| tjf d S )Nr5  )ra   r  r  r  )r  r   rU   rV   r5    s   zEAdoptedStreamServerEndpointTests.test_descriptorClosed.<locals>.closec                    r  )N)r5  r  r\   r  r  r  rU   rV   r    r^   zHAdoptedStreamServerEndpointTests.test_descriptorClosed.<locals>.listened)r   r  r   r  r,  r   r   )rT   rK  r5  r   r  rU   )r  r   rT   rV   test_descriptorClosed  s   
z6AdoptedStreamServerEndpointTests.test_descriptorClosedN)rh   ri   rj   rk   r  r%  r-  r5  r  r  r  rU   rU   rU   rV   r  <  s    r  c                   @   sF   e Zd ZdZejZdd Zdd Zdd Z	dd	 Z
d
d Zdd ZdS )SystemdEndpointPluginTestsz
    Unit tests for the systemd stream server endpoint and endpoint string
    description parser.

    @see: U{systemd<http://www.freedesktop.org/wiki/Software/systemd>}
    c                 C   >   t ttj}|D ]}t|| jr dS q	| d| dS )z
        L{endpoints._SystemdParser} is found as a plugin for
        L{interfaces.IStreamServerEndpointStringParser} interface.
        zDid not find systemd parser in Nri  r2   r   !IStreamServerEndpointStringParserr7  _parserClassr   rT   parsersr   rU   rU   rV   test_pluginDiscovery  s   z/SystemdEndpointPluginTests.test_pluginDiscoveryc                 C      |   }| ttj| dS )zx
        L{endpoints._SystemdParser} instances provide
        L{interfaces.IStreamServerEndpointStringParser}.
        Nr  r   r   r   r  rT   rX  rU   rU   rV   r        
z)SystemdEndpointPluginTests.test_interfacec                 C   sj   t  }g d}d}|  }t||_|j||t|d}| |j| | |j	| | |j
||  dS )a  
        Helper for unit tests for L{endpoints._SystemdParser.parseStreamServer}
        for different address families.

        Handling of the address family given will be verify.  If there is a
        problem a test-failing exception will be raised.

        @param addressFamily: An address family constant, like
            L{socket.AF_INET}.

        @param addressFamilyString: A string which should be recognized by the
            parser as representing C{addressFamily}.
        )r  r  rC     r  r   )domainindexN)r   r  r;   	_sddaemonparseStreamServerr8  rE  r   r   r  r  )rT   r  addressFamilyStringr   descriptorsr  rX  r  rU   rU   rV   _parseStreamServerTest  s   

z1SystemdEndpointPluginTests._parseStreamServerTestc                 C      |  td dS )zC
        IPv4 can be specified using the string C{"INET"}.
        INETN)r  r   rS   rU   rU   rV   test_parseStreamServerINET  r  z5SystemdEndpointPluginTests.test_parseStreamServerINETc                 C   r  )zD
        IPv6 can be specified using the string C{"INET6"}.
        INET6N)r  r   rS   rU   rU   rV   test_parseStreamServerINET6  r  z6SystemdEndpointPluginTests.test_parseStreamServerINET6c                 C   s:   zddl m} W n ty   tdw | |d dS )zS
        A UNIX domain socket can be specified using the string C{"UNIX"}.
        r   )AF_UNIXzPlatform lacks AF_UNIX supportr  N)socketr  ImportErrorr>   SkipTestr  )rT   r  rU   rU   rV   test_parseStreamServerUNIX  s   
z5SystemdEndpointPluginTests.test_parseStreamServerUNIXN)rh   ri   rj   rk   r   _SystemdParserr  r  r   r  r  r  r  rU   rU   rU   rV   r    s    
r  c                   @   .   e Zd ZdZejZdd Zdd Zdd Z	dS )	TCP6ServerEndpointPluginTestsz[
    Unit tests for the TCP IPv6 stream server endpoint string description
    parser.
    c                 C   r  )z
        L{endpoints._TCP6ServerParser} is found as a plugin for
        L{interfaces.IStreamServerEndpointStringParser} interface.
        z*Did not find TCP6ServerEndpoint parser in Nr  r  rU   rU   rV   r  	     z2TCP6ServerEndpointPluginTests.test_pluginDiscoveryc                 C   r  )z{
        L{endpoints._TCP6ServerParser} instances provide
        L{interfaces.IStreamServerEndpointStringParser}.
        Nr  r  rU   rU   rV   r     r  z,TCP6ServerEndpointPluginTests.test_interfacec                 C   sX   t t d}| |t j | |jt | |jd | |jd | |j	d dS )z
        L{serverFromString} returns a L{TCP6ServerEndpoint} instance with a
        'tcp6' endpoint string description.
        z$tcp6:8080:backlog=12:interface=\:\:1i  r  r  N)
r   r  r   r  r   r~  r   r  r  r  r,  rU   rU   rV   test_stringDescription  s   z4TCP6ServerEndpointPluginTests.test_stringDescriptionN)
rh   ri   rj   rk   r   _TCP6ServerParserr  r  r   r  rU   rU   rU   rV   r    s    
r  c                   @   r  )	StandardIOEndpointPluginTestszM
    Unit tests for the Standard I/O endpoint string description parser.
    c                 C   r  )z
        L{endpoints._StandardIOParser} is found as a plugin for
        L{interfaces.IStreamServerEndpointStringParser} interface.
        z*Did not find StandardIOEndpoint parser in Nr  r  rU   rU   rV   r  5  r  z2StandardIOEndpointPluginTests.test_pluginDiscoveryc                 C   r  )z{
        L{endpoints._StandardIOParser} instances provide
        L{interfaces.IStreamServerEndpointStringParser}.
        Nr  r  rU   rU   rV   r   A  r  z,StandardIOEndpointPluginTests.test_interfacec                 C   s.   t t d}| |t j | |jt dS )z
        L{serverFromString} returns a L{StandardIOEndpoint} instance with a
        'stdio' endpoint string description.
        zstdio:N)r   r  r   r  rD  r~  r,  rU   rU   rV   r  K  s   z4StandardIOEndpointPluginTests.test_stringDescriptionN)
rh   ri   rj   rk   r   _StandardIOParserr  r  r   r  rU   rU   rU   rV   r  .  s    
r  c                   @   ru   )ConnectProtocolTestsz'
    Tests for C{connectProtocol}.
    c                 C   sl   t  }t|dd}t }t|| | t|jd |jd d j}| 	|t
j | |d| dS )z
        C{endpoints.connectProtocol} calls the given endpoint's C{connect()}
        method with a factory that will build the given protocol.
        r  r   r\   r   N)r   r   r  r   connectProtocolr   r  r  _wrappedFactoryr  r   r(   rE  r   )rT   r   rK  theProtocolr   rU   rU   rV   "test_connectProtocolCreatesFactoryZ  s   z7ConnectProtocolTests.test_connectProtocolCreatesFactoryc                    s:   t   G  fddd}| }|  t|t  dS )z~
        C{endpoints.connectProtocol} returns the result of calling the given
        endpoint's C{connect()} method.
        c                       r  )zOConnectProtocolTests.test_connectProtocolReturnsConnectResult.<locals>.Endpointc                        S )zR
                Return a marker object for use in our assertion.
                rU   )rT   r   rn  rU   rV   r  t  s   zWConnectProtocolTests.test_connectProtocolReturnsConnectResult.<locals>.Endpoint.connectN)rh   ri   rj   r  rU   r  rU   rV   Endpoints  r  r  N)r   r   rE  r   r  r   )rT   r  rK  rU   r  rV   (test_connectProtocolReturnsConnectResultl  s   z=ConnectProtocolTests.test_connectProtocolReturnsConnectResultN)rh   ri   rj   rk   r  r  rU   rU   rU   rV   r   U  s    r   c                       s4   e Zd ZdZ fddZ fddZdd Z  ZS )UppercaseWrapperProtocolzL
    A wrapper protocol which uppercases all strings passed through it.
    c                       t  |  dS )z
        Uppercase a string passed in from the transport.

        @param data: The string to uppercase.
        @type data: L{bytes}
        N)rW  rc   upperrb   r\  rU   rV   rc        z%UppercaseWrapperProtocol.dataReceivedc                    r
  )z
        Uppercase a string passed out to the transport.

        @param data: The string to uppercase.
        @type data: L{bytes}
        N)rW  r_  r  rb   r\  rU   rV   r_    r  zUppercaseWrapperProtocol.writec                 C   s   |D ]}|  | qdS )zy
        Uppercase a series of strings passed out to the transport.

        @param seq: An iterable of strings.
        Nr^  )rT   seqrP   rU   rU   rV   r    s   z&UppercaseWrapperProtocol.writeSequence)rh   ri   rj   rk   rc   r_  r  rm  rU   rU   r\  rV   r	  ~  s
    		r	  c                   @   r   )UppercaseWrapperFactoryzK
    A wrapper factory which uppercases all strings passed through it.
    N)rh   ri   rj   rk   r	  r   rU   rU   rU   rV   r    s    r  c                   @   ru   )NetstringTrackerz
    A netstring receiver which keeps track of the strings received.

    @ivar strings: A L{list} of received strings, in order.
    c                 C   s
   g | _ d S r`   )stringsrS   rU   rU   rV   rW     rs   zNetstringTracker.__init__c                 C   s   | j | dS )z
        Receive a string and append it to C{self.strings}.

        @param string: The string to be appended to C{self.strings}.
        N)r  ra   )rT   r   rU   rU   rV   stringReceived  s   zNetstringTracker.stringReceivedN)rh   ri   rj   rk   rW   r  rU   rU   rU   rV   r    s    r  c                   @   r7  )	FakeErrorz
    An error which isn't really an error.

    This is raised in the L{wrapClientTLS} tests in place of a
    'real' exception.
    Nr9  rU   rU   rU   rV   r    r:  r  c                   @   r   )WrapperClientEndpointTestsz.
    Tests for L{_WrapperClientEndpoint}.
    c                 C   s6   t  \| _| _t | _t| jt| _t	
t| _d S r`   )r<   rK  	completerr   contextr   _WrapperEndpointr  r   r(   r  r  r   rS   rU   rU   rV   rL    s   z WrapperClientEndpointTests.setUpc                 C   sL   | j | j}| j }| |}|jjd |	  | 
|jdg dS )z
        Any modifications performed by the underlying L{ProtocolWrapper}
        propagate through to the wrapped L{Protocol}.
        s   5:hello,s   HELLON)r   r  r   r  succeedOncerH  r  r   r_  flushr   r  rT   
connectingpumpr  rU   rU   rV   test_wrappingBehavior  s   

z0WrapperClientEndpointTests.test_wrappingBehaviorc                 C   sB   | j | j}| j }| |}|d | |j	 d dS )z
        Methods defined on the wrapped L{Protocol} are accessible from the
        L{Protocol} returned from C{connect}'s L{Deferred}.
        s   spams   4:SPAM,N)
r   r  r   r  r  rH  
sendStringr   clientIOgetOutBufferr  rU   rU   rV   test_methodsAvailable  s
   


z0WrapperClientEndpointTests.test_methodsAvailablec                 C   s6   | j | j}| | | jt  | |t dS )zS
        Connection failures propagate upward to C{connect}'s L{Deferred}.
        N)r   r  r   assertNoResultr  failOncer  r   rT   r   rU   rU   rV   test_connectionFailure  s   
z1WrapperClientEndpointTests.test_connectionFailurec                 C   s0   | j | j}| | |  | |t dS )zM
        Cancellation propagates upward to C{connect}'s L{Deferred}.
        N)r   r  r   r!  r  r   r!   r#  rU   rU   rV   test_connectionCancellation  s   
z6WrapperClientEndpointTests.test_connectionCancellationc                 C   s8   | j | j}| j }| |}| |jj|j dS )z|
        The transport of the wrapped L{Protocol}'s transport is the transport
        passed to C{makeConnection}.
        N)	r   r  r   r  r  rH  rE  r   r  r  rU   rU   rV   *test_transportOfTransportOfWrappedProtocol  s   

zEWrapperClientEndpointTests.test_transportOfTransportOfWrappedProtocolN)
rh   ri   rj   rk   rL  r  r   r$  r%  r&  rU   rU   rU   rV   r    s    		r  c                 C   s   | djS )a,  
    Given a L{MemoryReactor} and the result of calling L{wrapClientTLS},
    extract the L{IOpenSSLClientConnectionCreator} associated with it.

    Implementation presently uses private attributes but could (and should) be
    refactored to just call C{.connect()} on the endpoint, when
    L{HostnameEndpoint} starts directing its C{getaddrinfo} call through the
    reactor it is passed somehow rather than via the global threadpool.

    @param memoryReactor: the reactor attached to the given endpoint.
        (Presently unused, but included so tests won't need to be modified to
        honor it.)

    @param tlsEndpoint: The result of calling L{wrapClientTLS}.

    @return: the client connection creator associated with the endpoint
        wrapper.
    @rtype: L{IOpenSSLClientConnectionCreator}
    N)_wrapperFactory_connectionCreator)r  tlsEndpointrU   rU   rV   connectionCreatorFromEndpoint  s   r*  c                   @   r#  )WrapClientTLSParserTestsz0
    Tests for L{_TLSClientEndpointParser}.
    c                 C   sj   t  }t|td}|j}| |j| | |jd | |j	d | |j
d | |jtd dS )zm
        A L{HostnameEndpoint} is constructed from parameters passed to
        L{clientFromString}.
        z4tls:example.com:443:timeout=10:bindAddress=127.0.0.1r  r  r  r  N)r   r   rt  r6   _wrappedEndpointrE  r~  r   r  r  rv  rw  )rT   r   rK  hostnameEndpointrU   rU   rV   !test_hostnameEndpointConstruction!  s   z:WrapClientTLSParserTests.test_hostnameEndpointConstructionc                 C   s>   t  }t|d}| |jjd t||}| |jd dS )z
        The hostname passed to L{clientFromString} is treated as utf-8 bytes;
        it is then encoded as IDNA when it is passed along to
        L{HostnameEndpoint}, and passed as unicode to L{optionsForClientTLS}.
        s   tls:éxample.example.com:443s   xn--xample-9ua.example.comu   éxample.example.comN)r   r   rt  r   r,  r  r*  	_hostname)rT   r   rK  connectionCreatorrU   rU   rV   test_utf8Encoding2  s   
z*WrapClientTLSParserTests.test_utf8Encodingc                    s|  t  }tt|dgdtttt j	
d}|tt}|j \}}}}}|d | |  dus=J tt }	t|	jj|	jtt jg|	d}
t t|
dtfddd	dtfd
d fdd\}}}jd | |}|jd |   | !jj" | !|jj" | !jj# | !|jj# t$j}| %|tt  dS )z
        When passed a string endpoint description beginning with C{tls:},
        L{clientFromString} returns a client endpoint initialized with the
        values from the string.
        r  z=tls:localhost:4321:privateKey={}:certificate={}:trustRoots={}asciiN)r  r  r/  r  Fc                      r  r`   rU   rU   )plainServerrU   rV   r   q  r   z3WrapClientTLSParserTests.test_tls.<locals>.<lambda>)isClientwrappedFactoryc                      r  r`   rU   rU   )serverProtocolrU   rV   r   t  r   c                      r  r`   rU   rU   )clientProtocolrU   rV   r   u  r   s   hello
s   hi you too
)&r   r   rt  rL  r:  r  r  pemPathr  rr  encoder  r(   r  r)   r  popr   r!  rH   r%  r(  rE   r  originalrD   	chainPathrJ   r=   r   r_  rH  r  r   disconnectingdisconnectedpeerFromTransportr   )rT   r   rK  r   r  r(  r   r  r  
serverCertserverOptionssProtocProtor  plainClientpeerCertificaterU   )r7  r3  r6  rV   test_tlsB  sX   






z!WrapClientTLSParserTests.test_tlsc                 C   s>   t  }t|d}t||}| |jd | |jjd dS )z
        When passed a C{tls:} strports description without extra arguments,
        L{clientFromString} returns a client endpoint whose context factory is
        initialized with default values.
        s   tls:example.com:443r`  r  N)r   r   rt  r*  r   r/  r,  r  )rT   r   rK  creatorrU   rU   rV   test_tlsWithDefaults  s
   
z-WrapClientTLSParserTests.test_tlsWithDefaultsN)rh   ri   rj   rk   r.  r1  rF  rH  rU   rU   rU   rV   r+    s    Ar+  c                 K   s   z| j }| j}W n ty   | j}| j}Y nw |D ]}||vr'td|qi }|| || t||}||| j	< |S )a  
    Create a copy of the given function with the given globals substituted.

    The globals must already exist in the function's existing global scope.

    @param function: any function object.
    @type function: L{types.FunctionType}

    @param newGlobals: each keyword argument should be a global to set in the
        new function's returned scope.
    @type newGlobals: L{dict}

    @return: a new function, like C{function}, but with new global scope.
    z<Name bound by replacingGlobals but not present in module: {})
	func_codefunc_globalsr  __code____globals__	TypeErrorr:  rb  r   rh   )function
newGlobals
codeObjectfuncGlobalsr  mergedGlobalsnewFunctionrU   rU   rV   replacingGlobals  s*   





rT  c                   @   r   )WrapClientTLSTestszj
    Tests for the error-reporting behavior of L{wrapClientTLS} when
    C{pyOpenSSL} is unavailable.
    c                 C   s2   t tjdd}| t|dd}| dt| dS )z
        If SSL is not supported, L{TLSMemoryBIOFactory} will be L{None}, which
        causes C{_wrapper} to also be L{None}.  If C{_wrapper} is L{None}, then
        an exception is raised.
        NrI   zOpenSSL not available)rT  r   wrapClientTLSr  NotImplementedErrorr  r8  )rT   replacednotImplementedrU   rU   rV   test_noOpenSSL  s   z!WrapClientTLSTests.test_noOpenSSLN)rh   ri   rj   rk   rZ  rU   rU   rU   rV   rU    rz  rU  )rU   N)r_  )rk   errnor   r  r   r   r   r   r   typesr   unicodedatar	   r>   r
   zope.interfacer   r   r   zope.interface.interfacer   zope.interface.verifyr   r   twistedr   ru  r   r   r   r   r   r   r   r   twisted.internet.abstractr   twisted.internet.addressr   r   r   r   r   twisted.internet.endpointsr    twisted.internet.errorr!   twisted.internet.interfacesr"   r#   r$   r%   r&   twisted.internet.protocolr'   r(   r)   twisted.internet.stdior*   twisted.internet.taskr+   twisted.internet.testingr,   r   r-   r.   r/   twisted.loggerr0   r1   twisted.pluginr2   twisted.protocolsr3   r4   twisted.pythonr5   twisted.python.compatr6   twisted.python.componentsr7   twisted.python.failurer8   twisted.python.filepathr9   twisted.python.modulesr:   twisted.python.systemdr;   twisted.test.iosimr<   r=   twisted.trialrk  rl  r8  noTrailingNewlineKeyPemPathnoTrailingNewlineCertPemPathrh   r&  r'  r<  r  rr  r  r?  r@  r  r.  OpenSSL.SSLr@   r  rA   rB   rC   twisted.internet.sslrD   rE   rF   rG   rH   twisted.protocols.tlsrJ   twisted.test.test_sslverifyrK   r%  r(  r  r  r]  r^  r  r   r8  rN   r   rm   r   rv   r   r{   r   r   TestCaser   r   r$  r8  r;  r@  rC  rP  IProcessTransportrT  IReactorProcessrn  rz  r  r  r  r  r#  r5  rL  SynchronousTestCaserM  rl  r{  r  r  r  r  r  r  r  r  r  r  r  r  rV  rp  r  r  r  r  r  r   ProtocolWrapperr	  WrappingFactoryr  NetstringReceiverr  r  r  r  r*  r+  rT  rU  rU   rU   rU   rV   <module>   s*  (




	   P)#$  ooks

<  

44 IvHF  q  
b + pU-')!	At$