
    YfM                        d Z ddl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mZmZmZmZ dd
lmZmZ ddlmZ ddlmZ ddlmZm Z  ddl!m"Z" ddl#m$Z$m%Z% d Z& ee           G d d                      Z' eee'            ee           G d d                      Z( eee'            G d de%          Z) G d de%          Z* G d d          Z+d!dZ,e fdZ-dZ. G d d e$          Z/dS )"z
Tests for (new code in) L{twisted.application.internet}.

@var AT_LEAST_ONE_ATTEMPT: At least enough seconds for L{ClientService} to make
    one attempt.
    N)implementer)verifyClass)internet)ClientServiceStreamServerEndpointServiceTimerService)task)CancelledErrorDeferred)IFileDescriptorReceiverIHalfCloseableProtocolIListeningPortIStreamClientEndpointIStreamServerEndpoint)FactoryProtocol)Clock)StringTransport)formatEventglobalLogPublisher)Failure)SynchronousTestCaseTestCasec                      dS )zM
    A fake target function for testing TimerService which does nothing.
    N r       X/var/www/html/env/lib/python3.11/site-packages/twisted/application/test/test_internet.pyfakeTargetFunctionr   )   s	     	Dr   c                   N    e Zd ZdZdZdZdZ e            ZdZ	d Z
d Zd Zd ZdS )
FakeServeraq  
    In-memory implementation of L{IStreamServerEndpoint}.

    @ivar result: The L{Deferred} resulting from the call to C{listen}, after
        C{listen} has been called.

    @ivar factory: The factory passed to C{listen}.

    @ivar cancelException: The exception to errback C{self.result} when it is
        cancelled.

    @ivar port: The L{IListeningPort} which C{listen}'s L{Deferred} will fire
        with.

    @ivar listenAttempts: The number of times C{listen} has been invoked.

    @ivar failImmediately: If set, the exception to fail the L{Deferred}
        returned from C{listen} before it is returned.
    Nr   c                 ,    t                      | _        d S N)FakePortportselfs    r   __init__zFakeServer.__init__L   s    JJ			r   c                       xj         dz  c_         | _        t           fd           _         j         j                             j                    j        S )z
        Return a Deferred and store it for future use.  (Implementation of
        L{IStreamServerEndpoint}).

        @param factory: the factory to listen with

        @return: a L{Deferred} stored in L{FakeServer.result}
           c                 8    |                      j                  S r"   )errbackcancelException)dr&   s    r   <lambda>z#FakeServer.listen.<locals>.<lambda>Z   s    199T=Q3R3R r   )	canceller)listenAttemptsfactoryr   resultfailImmediatelyr+   )r&   r1   s   ` r   listenzFakeServer.listenO   sf     	q )R)R)R)RSSS+K 4555{r   c                 D    | j                             | j                   dS )z
        Test code should invoke this method after causing C{listen} to be
        invoked in order to fire the L{Deferred} previously returned from
        C{listen}.
        N)r2   callbackr$   r%   s    r   startedListeningzFakeServer.startedListening_   s"     	TY'''''r   c                 D    | j         j                            d           dS )a  
        Test code should invoke this method after causing C{stopListening} to
        be invoked on the port fired from the L{Deferred} returned from
        C{listen} in order to cause the L{Deferred} returned from
        C{stopListening} to fire.
        N)r$   deferredr6   r%   s    r   stoppedListeningzFakeServer.stoppedListeningg   s#     		##D)))))r   )__name__
__module____qualname____doc__r2   r1   r3   r
   r,   r0   r'   r4   r7   r:   r   r   r   r    r    0   s}         ( FGO$n&&ON     ( ( (* * * * *r   r    c                   (    e Zd ZdZdZd Zd Zd ZdS )r#   zs
    Fake L{IListeningPort} implementation.

    @ivar deferred: The L{Deferred} returned by C{stopListening}.
    Nc                 6    t                      | _        | j        S )z`
        Stop listening.

        @return: a L{Deferred} stored in L{FakePort.deferred}
        )r   r9   r%   s    r   stopListeningzFakePort.stopListening~   s     !

}r   c                     d S r"   r   r%   s    r   getHostzFakePort.getHost       r   c                     d S r"   r   r%   s    r   startListeningzFakePort.startListening   rD   r   )r;   r<   r=   r>   r9   rA   rC   rF   r   r   r   r#   r#   t   sR          H        r   r#   c                   \    e Zd ZdZd Zd ZddZd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd ZdS )EndpointServiceTestsz4
    Tests for L{twisted.application.internet}.
    c                     t                      | _        t                      | _        t	          | j        | j                  | _        dS )zp
        Construct a stub server, a stub factory, and a
        L{StreamServerEndpointService} to test.
        N)r    
fakeServerr   r1   r   svcr%   s    r   setUpzEndpointServiceTests.setUp   s3    
 %,,yy.tMMr   c                     | j                                          |                     | j        | j        j                   dS )z
        L{StreamServerEndpointService.privilegedStartService} calls its
        endpoint's C{listen} method with its factory.
        N)rK   privilegedStartServiceassertIdenticalr1   rJ   r%   s    r   test_privilegedStartServicez0EndpointServiceTests.test_privilegedStartService   s;    
 	'')))T\4?+BCCCCCr   Nc                     t                      | j        _        d| j        _        |                     t           |p| j        j                   dS )a@  
        L{StreamServerEndpointService.startService} should raise synchronously
        if the L{Deferred} returned by its wrapped
        L{IStreamServerEndpoint.listen} has already fired with an errback and
        the L{StreamServerEndpointService}'s C{_raiseSynchronously} flag has
        been set.  This feature is necessary to preserve compatibility with old
        behavior of L{twisted.internet.strports.service}, which is to return a
        service which synchronously raises an exception from C{startService}
        (so that, among other things, twistd will not start running).  However,
        since L{IStreamServerEndpoint.listen} may fail asynchronously, it is a
        bad idea to rely on this behavior.

        @param thunk: If specified, a callable to execute in place of
            C{startService}.
        TN)ZeroDivisionErrorrJ   r3   rK   _raiseSynchronouslyassertRaisesstartService)r&   thunks     r   (test_synchronousRaiseRaisesSynchronouslyz=EndpointServiceTests.test_synchronousRaiseRaisesSynchronously   sE      +<*=*=''+$+U-Kdh6KLLLLLr   c                 D    |                      | j        j                   dS )z
        L{StreamServerEndpointService.privilegedStartService} should behave the
        same as C{startService} with respect to
        L{EndpointServiceTests.test_synchronousRaiseRaisesSynchronously}.
        N)rW   rK   rN   r%   s    r   test_synchronousRaisePrivilegedz4EndpointServiceTests.test_synchronousRaisePrivileged   s#     	55dh6UVVVVVr   c                    | j                                          | j        j                            t                                 |                     t
                    }|                     t          |          d           dS )a  
        L{StreamServerEndpointService.startService} and
        L{StreamServerEndpointService.privilegedStartService} should both log
        an exception when the L{Deferred} returned from their wrapped
        L{IStreamServerEndpoint.listen} fails.
        r)   N)	rK   rU   rJ   r2   r+   rR   flushLoggedErrorsassertEquallenr&   loggeds     r   test_failReportsErrorz*EndpointServiceTests.test_failReportsError   sn     	&&'8':':;;;''(9::Va(((((r   c                     d| j         _        | j                                          | j        j                            t                                 |                     t                    }|                     t          |          d           dS )aB  
        L{StreamServerEndpointService.startService} and
        L{StreamServerEndpointService.privilegedStartService} should both log
        an exception when the L{Deferred} returned from their wrapped
        L{IStreamServerEndpoint.listen} fails asynchronously, even if
        C{_raiseSynchronously} is set.
        Tr)   N)
rK   rS   rU   rJ   r2   r+   rR   r[   r\   r]   r^   s     r   !test_asynchronousFailReportsErrorz6EndpointServiceTests.test_asynchronousFailReportsError   sx     (,$&&'8':':;;;''(9::Va(((((r   c                     t                      | j        _        | j                                         |                     t                     }|                     t          |          d           dS )z
        Without the C{_raiseSynchronously} compatibility flag, failing
        immediately has the same behavior as failing later; it logs the error.
        r)   N)rR   rJ   r3   rK   rU   r[   r\   r]   r^   s     r    test_synchronousFailReportsErrorz5EndpointServiceTests.test_synchronousFailReportsError   s^    
 +<*=*='''(9::Va(((((r   c                     | j                                          |                     | j        | j        j                   |                     | j         j        d           dS )z
        L{StreamServerEndpointService.startService} sets the C{running} flag,
        and calls its endpoint's C{listen} method with its factory, if it
        has not yet been started.
        TN)rK   rU   rO   r1   rJ   r\   runningr%   s    r   test_startServiceUnstartedz/EndpointServiceTests.test_startServiceUnstarted   sV     	T\4?+BCCC)400000r   c                     |                                   | j                                         |                     | j        j        d           |                     | j        j        d           dS )z
        L{StreamServerEndpointService.startService} sets the C{running} flag,
        but nothing else, if the service has already been started.
        r)   TN)rP   rK   rU   r\   rJ   r0   rf   r%   s    r   test_startServiceStartedz-EndpointServiceTests.test_startServiceStarted   sf    
 	((***7;;;)400000r   c                    | j                                          | j                                         | j                                          | j                                         }g }|                    |j                   |                     t          |          d           | j        
                                 |                     t          |          d           |                     | j         j                   dS )z
        L{StreamServerEndpointService.stopService} calls C{stopListening} on
        the L{IListeningPort} returned from its endpoint, returns the
        C{Deferred} from stopService, and sets C{running} to C{False}.
        r   r)   N)rK   rN   rJ   r7   rU   stopServiceaddCallbackappendr\   r]   r:   assertFalserf   r&   r2   ls      r   test_stopServicez%EndpointServiceTests.test_stopService   s     	'')))((***%%''18$$$Q###((***Q###)*****r   c                 ,   | j                                          | j                                         }g }|                    |j                   |                     |dg           |                     |                     t                    g            dS )z
        L{StreamServerEndpointService.stopService} cancels the L{Deferred}
        returned by C{listen} if it has not yet fired.  No error will be logged
        about the cancellation of the listen attempt.
        N)rK   rN   rk   addBothrm   r\   r[   r
   ro   s      r   #test_stopServiceBeforeStartFinishedz8EndpointServiceTests.test_stopServiceBeforeStartFinished  s     	'')))%%''qx   TF###//??DDDDDr   c                 z   t                      | j        _        | j                                         | j                                        }g }|                    |j                   |                     |dg           | 	                    t                     }|                     t          |          d           dS )z
        L{StreamServerEndpointService.stopService} cancels the L{Deferred}
        returned by C{listen} if it has not fired yet.  An error will be logged
        if the resulting exception is not L{CancelledError}.
        Nr)   )rR   rJ   r,   rK   rN   rk   rl   rm   r\   r[   r]   )r&   r2   rp   stoppingErrorss       r    test_stopServiceCancelStartErrorz5EndpointServiceTests.test_stopServiceCancelStartError  s     +<*=*=''')))%%''18$$$TF###//0ABB^,,a00000r   r"   )r;   r<   r=   r>   rL   rP   rW   rY   r`   rb   rd   rg   ri   rq   rt   rw   r   r   r   rH   rH      s         N N ND D DM M M M(W W W
) 
) 
)) ) )) ) )1 1 11 1 1+ + +$E E E1 1 1 1 1r   rH   c                   N    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd ZdS )TimerServiceTestsa)  
    Tests for L{twisted.application.internet.TimerService}.

    @type timer: L{TimerService}
    @ivar timer: service to test

    @type clock: L{task.Clock}
    @ivar clock: source of time

    @type deferred: L{Deferred}
    @ivar deferred: deferred returned by L{TimerServiceTests.call}.
    c                     t          d| j                  | _        t          j                    x| _        | j        _        t                      | _        dS )z1
        Set up a timer service to test.
           N)r   calltimerr	   r   clockr   r9   r%   s    r   rL   zTimerServiceTests.setUp:  s=     "!TY//
(,
4
TZ% 

r   c                     | j         S )z
        Function called by L{TimerService} being tested.

        @returns: C{self.deferred}
        @rtype: L{Deferred}
        )r9   r%   s    r   r|   zTimerServiceTests.callB  s     }r   c                 j   | j                                          |                     | j         j        d           |                     | j         j        t          j                   |                     | j	        | j         j        j	                   |                     | j         j        j        d           dS )z
        When L{TimerService.startService} is called, it marks itself
        as running, creates a L{task.LoopingCall} and starts it.
        zService is startedzLoopingCall is startedN)
r}   rU   
assertTruerf   assertIsInstance_loopr	   LoopingCallrO   r~   r%   s    r   test_startServicez#TimerServiceTests.test_startServiceK  s    
 	
!!!
*,@AAAdj.0@AAATZ)9)?@@@
(02JKKKKKr   c                     g }|j         di f| j        _        | j                                         |                     dg|           dS )zi
        When L{TimerService.startService} is called, it calls the function
        immediately.
        r"   N)rm   r}   r|   rU   r\   )r&   r2   s     r   $test_startServiceRunsCallImmediatelyz6TimerServiceTests.test_startServiceRunsCallImmediatelyV  sM    
 !='26

!!!$(((((r   c                     t          j                    fd}|                     t          d|           | j                                         |                     | j        j        j                   dS )z
        L{TimerService.startService} uses L{internet._maybeGlobalReactor} to
        choose the reactor to pass to L{task.LoopingCall}
        uses the global reactor.
        c                     S r"   r   )maybeReactor
otherClocks    r   getOtherClockzKTimerServiceTests.test_startServiceUsesGlobalReactor.<locals>.getOtherClockh  s	    r   _maybeGlobalReactorN)	r	   r   patchr   r}   rU   rO   r   r~   )r&   r   r   s     @r   "test_startServiceUsesGlobalReactorz4TimerServiceTests.test_startServiceUsesGlobalReactor`  sz     Z\\
	 	 	 	 	 	

82MBBB
!!!Z)9)?@@@@@r   c                 r   | j                                          | j                                         }|                     |           |                     d| j         j                   | j                            t                                 | 	                    | 
                    |          d           dS )z
        When L{TimerService.stopService} is called while a call is in progress.
        the L{Deferred} returned doesn't fire until after the call finishes.
        TN)r}   rU   rk   assertNoResultr\   rf   r9   r6   objectrO   successResultOfr&   r-   s     r   test_stopServiceWaitsz'TimerServiceTests.test_stopServiceWaitso  s    
 	
!!!J""$$Atz1222vxx(((T11!44d;;;;;r   c                    | j                                          | j                            t	                                 | j                                         }|                     |                     |          d           dS )z
        When L{TimerService.stopService} is called while a call isn't in progress.
        the L{Deferred} returned has already been fired.
        N)r}   rU   r9   r6   r   rk   rO   r   r   s     r   test_stopServiceImmediatelyz-TimerServiceTests.test_stopServiceImmediately{  so    
 	
!!!vxx(((J""$$T11!44d;;;;;r   c                    | j                                          | j                            t	          t                                           |                     t
                    }|                     dt          |                     | j         	                                }| 
                    |                     |          d           dS )z
        When function passed to L{TimerService} returns a deferred that errbacks,
        the exception is logged, and L{TimerService.stopService} doesn't raise an error.
        r)   N)r}   rU   r9   r+   r   rR   r[   r\   r]   rk   rO   r   )r&   errorsr-   s      r   test_failedCallLogsErrorz*TimerServiceTests.test_failedCallLogsError  s    
 	
!!!g&7&9&9::;;;''(9::CKK(((J""$$T11!44d;;;;;r   c                 :   t          dt                    }|                                 t          j        |          }|                                 t          j        |          }t                      }t          |d|          }| 	                    ||           dS )zq
        When pickling L{internet.TimerService}, it won't pickle
        L{internet.TimerService._loop}.
        r)   r   N
r   r   rU   pickledumpsrk   loadsr   getattrrO   r&   r}   dumpedTimerloadedTimernothingvalues         r   $test_pickleTimerServiceNotPickleLoopz6TimerServiceTests.test_pickleTimerServiceNotPickleLoop  s     Q 233l5))l;//((Wg66We,,,,,r   c                 :   t          dt                    }|                                 t          j        |          }|                                 t          j        |          }t                      }t          |d|          }| 	                    ||           dS )zy
        When pickling L{internet.TimerService}, it won't pickle
        L{internet.TimerService._loopFinished}.
        r)   _loopFinishedNr   r   s         r   ,test_pickleTimerServiceNotPickleLoopFinishedz>TimerServiceTests.test_pickleTimerServiceNotPickleLoopFinished  s     Q 233l5))l;//((_g>>We,,,,,r   N)r;   r<   r=   r>   rL   r|   r   r   r   r   r   r   r   r   r   r   r   ry   ry   ,  s         # # #  	L 	L 	L) ) )A A A
< 
< 
<< < <
< 
< 
<- - - - - - - -r   ry   c                       e Zd ZdZd ZdS )ConnectInformationa  
    Information about C{endpointForTesting}

    @ivar connectQueue: a L{list} of L{Deferred} returned from C{connect}.  If
        these are not already fired, you can fire them with no value and they
        will trigger building a factory.

    @ivar constructedProtocols: a L{list} of protocols constructed.

    @ivar passedFactories: a L{list} of L{IProtocolFactory}; the ones actually
        passed to the underlying endpoint / i.e. the reactor.
    c                 0    g | _         g | _        g | _        d S r"   )connectQueueconstructedProtocolspassedFactoriesr%   s    r   r'   zConnectInformation.__init__  s     $&!!r   N)r;   r<   r=   r>   r'   r   r   r   r   r     s-         " " " " "r   r   Fc                      t          t                     G  fdd                      }t                       |            fS )aD  
    Make a sample endpoint for testing.

    @param fireImmediately: If true, fire all L{Deferred}s returned from
        C{connect} immedaitely.

    @return: a 2-tuple of C{(information, endpoint)}, where C{information} is a
        L{ConnectInformation} describing the operations in progress on
        C{endpoint}.
    c                       e Zd Z fdZdS ).endpointForTesting.<locals>.ClientTestEndpointc                     t                      }j                                       |j        fd            }j                            |           r|                    d            |S )Nc                                          d           }j                            |           t                      }|                    |           |S r"   )buildProtocolr   rm   r   makeConnection)ignoredprotocol	transportr1   infos      r   createProtocolzNendpointForTesting.<locals>.ClientTestEndpoint.connect.<locals>.createProtocol  sQ    "0066)00:::+--	''	222r   )r   r   rm   rl   r   r6   )r&   r1   r2   r   fireImmediatelyr   s    `  r   connectz6endpointForTesting.<locals>.ClientTestEndpoint.connect  s    ZZF ''000             $$V,,, &%%%Mr   N)r;   r<   r=   r   )r   r   s   r   ClientTestEndpointr     s3        	 	 	 	 	 	 	 	r   r   )r   r   r   )r   r   r   s   ` @r   endpointForTestingr     ss     &''          ('$ D##%%%%r   c                 z    g                      j                   |                     fd           fdS )a6  
    Catch the global log stream.

    @param testCase: The test case to add a cleanup to.

    @param logPublisher: the log publisher to add and remove observers for.

    @return: a 0-argument callable that returns a list of textual log messages
        for comparison.
    @rtype: L{list} of L{unicode}
    c                  8                          j                  S r"   )removeObserverrm   )logPublisherlogss   r   r.   zcatchLogs.<locals>.<lambda>  s     ; ;DK H H r   c                      d  D             S )Nc                 ,    g | ]}t          |          S r   )r   ).0events     r   
<listcomp>z/catchLogs.<locals>.<lambda>.<locals>.<listcomp>  s     9995K&&999r   r   )r   s   r   r.   zcatchLogs.<locals>.<lambda>  s    99D999 r   )addObserverrm   
addCleanup)testCaser   r   s    `@r   	catchLogsr     sQ     DT[)))HHHHHIII99999r   g      Y@c                       e Zd ZdZddefdZd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d  Z"d! Z#d"S )#ClientServiceTestsz%
    Tests for L{ClientService}.
    Tc                     i }|                     t                                 |                     |           |d         t          |          \  }}g x|_         G fddt                    } |            x|_        }	t          ||	fi | fd}
                     |
           |r                                 |fS )aL  
        Create a L{ClientService} along with a L{ConnectInformation} indicating
        the connections in progress on its endpoint.

        @param fireImmediately: Should all of the endpoint connection attempts
            fire synchronously?
        @type fireImmediately: L{bool}

        @param startService: Should the L{ClientService} be started before
            being returned?
        @type startService: L{bool}

        @param protocolType: a 0-argument callable returning a new L{IProtocol}
            provider to be used for application-level protocol connections.

        @param kw: Arbitrary keyword arguments to be passed on to
            L{ClientService}

        @return: a 2-tuple of L{ConnectInformation} (for information about test
            state) and L{ClientService} (the system under test).  The
            L{ConnectInformation} has 2 additional attributes;
            C{applicationFactory} and C{applicationProtocols}, which refer to
            the unwrapped protocol factory and protocol instances passed in to
            L{ClientService} respectively.
        r~   r~   r   c                   &     e Zd ZZ fdZ xZS )>ClientServiceTests.makeReconnector.<locals>.RememberingFactoryc                 t    t                                          |          }                    |           |S r"   )superr   rm   )r&   addrr2   	__class__applicationProtocolss      r   r   zLClientServiceTests.makeReconnector.<locals>.RememberingFactory.buildProtocol0  s3    ..t44$++F333r   )r;   r<   r=   r   r   __classcell__)r   r   protocolTypes   @r   RememberingFactoryr   -  sC        #H         r   r   c                      d _         j        r                                                                                      g            d S r"   )	_protocolrf   rk   r\   getDelayedCalls)r~   r&   services   r   stopz0ClientServiceTests.makeReconnector.<locals>.stop9  sQ     $G &##%%% U2244b99999r   )	updater   r   r   r   applicationFactoryr   r   rU   )r&   r   rU   r   kwnkwcqendpointr   r1   r   r   r~   r   s   `  `       @@@r   makeReconnectorz"ClientServiceTests.makeReconnector  s%   8 


!!!

2G)/JJJH :<;r6	 	 	 	 	 	 	 	 	 	 	 +=*<*>*>>'99S99	: 	: 	: 	: 	: 	: 	: 	 	#  """7{r   c                     |                      d          \  }}|                     t          |j                  d           dS )zL
        When the service is started, a connection attempt is made.
        Fr   r)   N)r   r\   r]   r   )r&   r   r   s      r   r   z$ClientServiceTests.test_startServiceF  sD     **5*AAGR_--q11111r   c                     |                                  \  }}|j        }|                     |j        d           |j        d         }|                                 |                     |j        d           dS )a!  
        Although somewhat obscure, L{IProtocolFactory} includes both C{doStart}
        and C{doStop} methods; ensure that when these methods are called on the
        factory that was passed to the reactor, the factory that was passed
        from the application receives them.
        r   r)   N)r   r   r\   numPortsr   doStart)r&   r   r   firstAppFactoryfirstPassedFactorys        r   test_startStopFactoryz(ClientServiceTests.test_startStopFactoryM  sy     **,,G/11555/2""$$$1155555r   c                 f   |                                  \  }}|                                }|                     |           |j        d         }|                     |j        j        d           |                    t          t                                           | 
                    |           dS )z
        When the service is stopped, no further connect attempts are made.  The
        returned L{Deferred} fires when all outstanding connections have been
        stopped.
        r   TN)r   rk   r   r   r\   r   disconnectingconnectionLostr   	Exceptionr   r&   r   r   r-   r   s        r   test_stopServiceWhileConnectedz1ClientServiceTests.test_stopServiceWhileConnected[  s     **,,G!!A*1-+94@@@	 4 4555Qr   c                 .   |                                  \  }}|                                }|                     |           |j        d         }|                     |j        j        d           |                                 |                     |           |                     t          |j                  d           |	                    t          t                                           |                     t          |j                  d           dS )z
        When L{ClientService} is restarted after having been connected, it
        waits to start connecting until after having disconnected.
        r   Tr)   r{   N)r   rk   r   r   r\   r   r   rU   r]   r   r   r   r   s        r   #test_startServiceWaitsForDisconnectz6ClientServiceTests.test_startServiceWaitsForDisconnecti  s    
 **,,G!!A*1-+94@@@AR455q999	 4 4555R455q99999r   c                    |                      d          \  }}|j        d                             d           |j        d         }|                                }|                     |           |                                }|                     |           |                                 |                     |           |                     |           |                     |j	        j
        d           |                    t          t                                           |                     |           |j        d                             d           |                     t          |j                  d           |                     |                     |          |j        d                    |                                }|                     |           dS )a%  
        When L{ClientService} is stopping - that is,
        L{ClientService.stopService} has been called, but the L{Deferred} it
        returns has not fired yet - calling L{startService} will cause a new
        connection to be made, and new calls to L{whenConnected} to succeed.
        Fr   r   NTr)   r{   )r   r   r6   r   rk   r   whenConnectedrU   r\   r   r   r   r   r   r   r]   rO   r   )r&   r   r   firststoppednextProtocolsecondStoppeds          r   test_startServiceWhileStoppingz1ClientServiceTests.test_startServiceWhileStoppingy  s    **5*AAG
##D)))'*%%''G$$$,,..L)))L)))G$$$6===WY[[11222W%%%
##D)))R455q999  ..0G0J	
 	
 	
  ++--M*****r   c                    |                      d          \  }}|                                }|                     |           |                     |                                t
                     |                                 |j        d                             d           | 	                    |j
        d         |                     |                                                     dS )a  
        When L{ClientService} is stopped - that is,
        L{ClientService.stopService} has been called and the L{Deferred} it
        returns has fired - calling L{startService} will cause a new connection
        to be made, and new calls to L{whenConnected} to succeed.
        Fr   N)r   rk   r   failureResultOfr   r
   rU   r   r6   rO   r   )r&   r   r   r   s       r   test_startServiceWhileStoppedz0ClientServiceTests.test_startServiceWhileStopped  s     **5*AAG%%''W%%%W2244nEEE
$$T***#B')=)=g>S>S>U>U)V)V	
 	
 	
 	
 	
r   c                 T   t          t          t                     G d dt                                }|                     |          \  }}|j        d         }|                     t          j        |                     |                     t          j        |                     dS )aC  
        If the protocol objects returned by the factory given to
        L{ClientService} provide special "marker" interfaces for their
        transport - L{IHalfCloseableProtocol} or L{IFileDescriptorReceiver} -
        those interfaces will be provided by the protocol objects passed on to
        the reactor.
        c                       e Zd ZdZdS )EClientServiceTests.test_interfacesForTransport.<locals>.FancyProtocolz9
            Provider of various interfaces.
            N)r;   r<   r=   r>   r   r   r   FancyProtocolr    s           r   r  )r   r   N)r   r   r   r   r   r   r   
providedBy)r&   r  r   r   reactorFacings        r   test_interfacesForTransportz.ClientServiceTests.test_interfacesForTransport  s     
+-D	E	E	 	 	 	 	H 	 	 
F	E	
 ***FFG/2/:=IIJJJ.9-HHIIIIIr   c                    t                      }|                     d|          \  }}|j        d                             t	                                 |                    t                     |                     t          |j                  d           |	                                }|j        d                             t	                                 | 
                    |           dS )zU
        When the service is stopped while retrying, the retry is cancelled.
        Fr   r~   r   r{   r)   N)r   r   r   r+   r   advanceAT_LEAST_ONE_ATTEMPTr\   r]   rk   r   r&   r~   r   r   r-   s        r   test_stopServiceWhileRetryingz0ClientServiceTests.test_stopServiceWhileRetrying  s     **5*NNG
""9;;///*+++R_--q111!!
""9;;///Qr   c                 8   t                      }|                     d|          \  }}|                     t          |j                  d           |                     |j        d                    |                                }|                     |           dS )zv
        When the service is stopped while initially connecting, the connection
        attempt is cancelled.
        Fr  r)   r   N)r   r   r\   r]   r   r   rk   r   r  s        r   test_stopServiceWhileConnectingz2ClientServiceTests.test_stopServiceWhileConnecting  s    
 **5*NNGR_--q111BOA.///!!Qr   c                 4   t                      }|                     |          \  }}|                                }|                     |                                g            |                     |                     |          |j        d                    dS )zy
        When a client connects, the service keeps a reference to the new
        protocol and resets the delay.
        r   r   N)r   r   r   r\   r   rO   r   r   )r&   r~   r   r   awaitingProtocols        r   test_clientConnectedz'ClientServiceTests.test_clientConnected  s    
 ***77G"0022..00"555  !122B4KA4N	
 	
 	
 	
 	
r   c                    t                      }|                     d|          \  }}|                     t          |j                  d           |j        d                             t          t                                           |                                }| 	                    |           |
                    d            |                    t                     |                     t          |j                  d           dS )z
        When a client connection fails, the service removes its reference
        to the protocol and tries again after a timeout.
        Fr  r)   r   c                 6    |                      t                    S r"   )trapr
   )r   s    r   r.   z@ClientServiceTests.test_clientConnectionFailed.<locals>.<lambda>  s    n1M1M r   r{   N)r   r   r\   r]   r   r+   r   r   r   r   
addErrbackr  r  )r&   r~   r   r   r   s        r   test_clientConnectionFailedz.ClientServiceTests.test_clientConnectionFailed  s    
 **5*NNGR_--q111
""79;;#7#7888--//M*** 	  !M!MNNN*+++R_--q11111r   c                    t                      }|                     |d          \  }}|                     t          |j                  d           |j        d                             d           |                     t          |j                  d           |                     |                     |                                          |j	        d                    |j
        d                             t          t                                           |                    t                     |                     t          |j                  d           |j        d                             d           |                     |                     |                                          |j	        d                    dS )z~
        When a client connection is lost, the service removes its reference
        to the protocol and calls retry.
        F)r~   r   r)   r   Nr{   )r   r   r\   r]   r   r6   rO   r   r   r   r   r   r   r   r  r  )r&   r~   r   r   s       r   test_clientConnectionLostz,ClientServiceTests.test_clientConnectionLost  s   
 ***NNGR_--q111
##D)))R_--q111  !6!6!8!8992;RST;U	
 	
 	
 	"11')++2F2FGGG*+++R_--q111
##D)))  !6!6!8!8992;RST;U	
 	
 	
 	
 	
r   c                 |   t                      }|                     |          \  }}|                                }|j        d                             t          t                                           |                     |                                t                     | 
                    |j                   dS )z
        When a client connection is lost while the service is stopping, the
        protocol stopping deferred is called and the reference to the protocol
        is removed.
        r   r   N)r   r   rk   r   r   r   IndentationErrorr  r   r
   r   calledr  s        r   &test_clientConnectionLostWhileStoppingz9ClientServiceTests.test_clientConnectionLostWhileStopping  s     ***77G!!
"11':J:L:L2M2MNNNW2244nEEE!!!!!r   c                    |                      dd          \  }}|                     t          |j                  d           |                                 |                     t          |j                  d           t          |           }|                                 |                     t          |j                  d           |                     d |            d                    dS )z
        If L{ClientService} is started when it's already started, it will log a
        complaint and do nothing else (in particular it will not make
        additional connections).
        F)r   rU   r   r)   z$Duplicate ClientService.startServiceN)r   r\   r]   r   rU   r   assertIn)r&   r   r   messagess       r   test_startTwicez"ClientServiceTests.test_startTwice  s     **5u*UUGR_--q111R_--q111T??R_--q111<hhjjmLLLLLr   c                    t                      }|                     d|          \  }}|                                }|                                }|                    d          }|                     |           |                     |           |                     |           |j        d                             d           |                     |          }|                     |          }|                     |          }	|                     ||           |                     ||	           |                     ||j        d                    dS )z{
        L{ClientService.whenConnected} returns a L{Deferred} that fires when a
        connection is established.
        Fr  r)   failAfterFailuresr   N)	r   r   r   r   r   r6   r   rO   r   )
r&   r~   r   r   abcresultAresultBresultCs
             r   test_whenConnectedLaterz*ClientServiceTests.test_whenConnectedLater"  sA   
 **5*NNG!!##!!##!!A!66AAA
##D)))&&q))&&q))&&q))Wg...Wg...Wb&=a&@AAAAAr   c                    t                      }|                     d|          \  }}|                                }|                    d          }|                    d          }|                    d          }|                     |           |                     |           |                     |           |                     |           t	          t                                }|j        d                             |           |                     |           |                     | 	                    |t
                    |           |                     |           |                     |           |
                    t                     |                     t          |j                  d           |                     |           |                     |           |                     |           t	          t                                }	|j        d                             |	           |                     |           |                     | 	                    |t
                    |	           |                     |           t          }
|
                    |
           |                     t          |j                  d           |                     |           |                     |           |j        d                             d           |                     |          }|                     |          }|                     ||           |                     ||j        d                    |                    d          }|                     |          }|                     ||           dS )	z
        L{ClientService.whenConnected} returns a L{Deferred} that fails, if
        asked, when some number of connections have failed.
        Fr  r)   r%  r{      r   N)r   r   r   r   r   r   r   r+   rO   r  r  r  r\   r]   r6   r   r   )r&   r~   r   r   a0a1a2a3f1f2AT_LEAST_TWO_ATTEMPTSresultA0resultA3a4resultA4s                  r   test_whenConnectedFailsz*ClientServiceTests.test_whenConnectedFails7  s`   
 **5*NNG""$$""Q"77""Q"77""Q"77BBBBY[[!!
""2&&&BT11"i@@"EEEBB*+++R_--q111BBBY[[!!
""2&&&BT11"i@@"EEEB 4+,,,R_--q111BB
##D)))''++''++Xx000Xr'>q'ABBB ""Q"77''++Xx00000r   c                 N   t                      }|                     d|          \  }}|                                }|                                }|                    d          }|                     |           |                     |           |                     |           |                                 |                    t                     |                     |t                     |                     |t                     |                     |t                     dS )z
        L{ClientService.whenConnected} returns a L{Deferred} that fails when
        L{ClientService.stopService} is called.
        Fr  r)   r%  N)	r   r   r   r   rk   r  r  r  r
   )r&   r~   r   r   r'  r(  r)  s          r   test_whenConnectedStopServicez0ClientServiceTests.test_whenConnectedStopServiceq  s
   
 **5*NNG!!##!!##!!A!66AAA*+++Q///Q///Q/////r   c                 R   t                      }|                     d|          \  }}|j        d                             t	          d                     |                                }|                     |                                g            |                     |           dS )z
        When L{ClientService.stopService} is called while waiting between
        connection attempts, the pending reconnection attempt is cancelled and
        the service is stopped immediately.
        Fr  r   no connectionN)	r   r   r   r+   r   rk   r\   r   r   r  s        r   test_retryCancelledz&ClientServiceTests.test_retryCancelled  s     **5*NNG
""9_#=#=>>>!!..00"555Qr   c                     t                      }|                     dd|          \  }}|                                }|                     |                     |                     dS )z
        Calling L{ClientService.stopService} before
        L{ClientService.startService} returns a L{Deferred} that has
        already fired with L{None}.
        F)r   rU   r~   Nr   r   rk   assertIsNoner   )r&   r~   _r   r-   s        r   "test_stopServiceBeforeStartServicez5ClientServiceTests.test_stopServiceBeforeStartService  sm     ))!U * 
 

7 !!$..q1122222r   c                    t                      }|                     d|          \  }}|                                }|j        d                             t          d                     |                                 |                                }|                     |                     |          j	        t                     |                     |                     |          j	        t                     dS )z
        L{ClientService.whenConnected} returns a L{Deferred} that
        errbacks with L{CancelledError} if
        L{ClientService.stopService} is called between connection
        attempts.
        Fr  r   r?  N)r   r   r   r   r+   r   rk   r   r  r   r
   )r&   r~   r   r   beforeErrbackAndStopafterErrbackAndStops         r   'test_whenConnectedErrbacksOnStopServicez:ClientServiceTests.test_whenConnectedErrbacksOnStopService  s     **5*NNG&4466 	""9_#=#=>>>%3355  !566<n	
 	
 	
 	  !455;^	
 	
 	
 	
 	
r   c                    t                      }|                     d|          \  }}|j        d                             d           |                                }|                                }|j        d                             t          t                                           | 	                    |           | 	                    |           dS )z
        Calling L{ClientService.stopService} twice after it has
        connected (that is, stopping it while it is disconnecting)
        returns a L{Deferred} each time that fires when the
        disconnection has completed.
        Fr  r   N)
r   r   r   r6   rk   r   r   r   r  r   r&   r~   r   r   firstStopDeferredsecondStopDeferreds         r   "test_stopServiceWhileDisconnectingz5ClientServiceTests.test_stopServiceWhileDisconnecting  s     **5*NNG
##D))) $//11$0022 	"11':J:L:L2M2MNNN.////00000r   c                    t                      }|                     d|          \  }}|j        d                             d           |                                }|                                 |                                }|j        d                             t          t                                           | 
                    |           | 
                    |           dS )z
        Calling L{ClientService.stopService} after calling a
        reconnection attempt returns a L{Deferred} that fires when the
        disconnection has completed.
        Fr  r   N)r   r   r   r6   rk   rU   r   r   r   r  r   rK  s         r   test_stopServiceWhileRestartingz2ClientServiceTests.test_stopServiceWhileRestarting  s     **5*NNG
##D))) $//11$0022 	"11':J:L:L2M2MNNN.////00000r   c                 F   t                      }|                     d|          \  }}|                                }|                                }|                     |                     |                     |                     |                     |                     dS )z
        Calling L{ClientService.stopService} on a stopped service
        returns a L{Deferred} that has already fired with L{None}.
        Fr  NrB  )r&   r~   rD  r   rL  rM  s         r    test_stopServiceOnStoppedServicez3ClientServiceTests.test_stopServiceOnStoppedService  s    
 ))%u)MM
7#//11$0022$../@AABBB$../ABBCCCCCr   c                     dgfd}|                      |d          \  }}|                     dd                    dS )z
        The C{prepareConnection} callable is called after
        L{ClientService.startService} once the connection is made.
        r   c                 (    dxx         dz  cc<   d S Nr   r)   r   _protopreparess    r   prepareConnectionz[ClientServiceTests.test_prepareConnectionCalledWhenServiceStarts.<locals>.prepareConnection      QKKK1KKKKKr   T)rY  rU   r)   N)r   r\   )r&   rY  r   r   rX  s       @r   -test_prepareConnectionCalledWhenServiceStartsz@ClientServiceTests.test_prepareConnectionCalledWhenServiceStarts  sl    
 3	 	 	 	 	 **/d + 
 
G 	HQK(((((r   c                     g fd}|                      |          \  }}|                     |j        d         d                    dS )zf
        The C{prepareConnection} callable is passed the connected protocol
        instance.
        c                 2                         |            d S r"   rm   )protonewProtocolss    r   rY  zVClientServiceTests.test_prepareConnectionCalledWithProtocol.<locals>.prepareConnection	  s    &&&&&r   rY  r   N)r   rO   r   )r&   rY  r   r   r`  s       @r   (test_prepareConnectionCalledWithProtocolz;ClientServiceTests.test_prepareConnectionCalledWithProtocol  sp    
 	' 	' 	' 	' 	' **/ + 
 
G 	R4Q7aIIIIIr   c                    dgfd}t                      }|                     |d|          \  }}|j        d                             t	          d                     |                     dd                    |                    t                     |j        d                             d           |                     dd                    dS )zf
        The C{prepareConnection} callback is invoked only once a connection is
        made.
        r   c                 (    dxx         dz  cc<   d S rU  r   rV  s    r   rY  z]ClientServiceTests.test_prepareConnectionCalledAfterConnectionMade.<locals>.prepareConnection  rZ  r   F)rY  r   r~   zconnection attempt failedr)   N)	r   r   r   r+   r   r\   r  r  r6   r&   rY  r~   r   r   rX  s        @r   /test_prepareConnectionCalledAfterConnectionMadezBClientServiceTests.test_prepareConnectionCalledAfterConnectionMade  s    
 3	 	 	 	 	 **/e + 
 
G 	""9-H#I#IJJJHQK(((*+++
##D)))HQK(((((r   c                 ~   dgfd}t                      }|                     ||          \  }}|                     dd                    |j        d                             t          t                                           |                    t                     |                     dd                    dS )z
        The C{prepareConnection} callback is invoked each time a connection is
        made, including on reconnection.
        r   c                 (    dxx         dz  cc<   d S rU  r   rV  s    r   rY  zUClientServiceTests.test_prepareConnectionCalledOnReconnect.<locals>.prepareConnection/  rZ  r   rY  r~   r)   r{   N)	r   r   r\   r   r   r   r  r  r  re  s        @r   'test_prepareConnectionCalledOnReconnectz:ClientServiceTests.test_prepareConnectionCalledOnReconnect(  s    
 3	 	 	 	 	 **/u + 
 
G 	HQK((( 	"11':J:L:L2M2MNNN*+++HQK(((((r   c                     t                      fd}|                     |          \  }}|                     |                                          }|                     |           dS )a?  
        The C{prepareConnection} return value is ignored when it does not
        indicate a failure. Even though the callback participates in the
        internal new-connection L{Deferred} chain for error propagation
        purposes, any successful result does not affect the ultimate return
        value.
        c                     S r"   r   )r_  sentinels    r   rY  zVClientServiceTests.test_prepareConnectionReturnValueIgnored.<locals>.prepareConnectionJ  s    Or   ra  N)r   r   r   r   assertNotIdentical)r&   rY  r   r   r2   rm  s        @r   (test_prepareConnectionReturnValueIgnoredz;ClientServiceTests.test_prepareConnectionReturnValueIgnored?  s     88	 	 	 	 	 **=N*OOG%%g&;&;&=&=>>&11111r   c                 L   g t                      fd}|                     |          \  }}|                                }|                     |                               d           |                     |j        d         |                     |                     dS )z
        The C{prepareConnection} callable returns a deferred and calls to
        L{ClientService.whenConnected} wait until it fires.
        c                 2                         |            S r"   r^  )r_  newProtocolDeferredr`  s    r   rY  zVClientServiceTests.test_prepareConnectionReturningADeferred.<locals>.prepareConnectionZ  s    &&&&&r   ra  Nr   )r   r   r   r   r6   rO   r   r   )r&   rY  r   r   whenConnectedDeferredrr  r`  s        @@r   (test_prepareConnectionReturningADeferredz;ClientServiceTests.test_prepareConnectionReturningADeferredR  s    
 &jj	' 	' 	' 	' 	' 	' **=N*OOG ' 5 5 7 71222$$T***#A&(<(<=R(S(S	
 	
 	
 	
 	
r   c                    t                      }d }|                     ||          \  }}|                    d          }|                     |           |                    t
                     |                     |           |                    t
                     |                     t          |                     |          j	                   dS )zs
        The connection attempt counts as a failure when the
        C{prepareConnection} callable throws.
        c                     t                      r"   )r  )rW  s    r   rY  zJClientServiceTests.test_prepareConnectionThrows.<locals>.prepareConnectionp  s    "$$$r   ri  r{   r%  N)
r   r   r   r   r  r  rO   r  r  type)r&   r~   rY  r   r   rs  s         r   test_prepareConnectionThrowsz/ClientServiceTests.test_prepareConnectionThrowsi  s    
 	% 	% 	% **/u + 
 
G !( 5 5 5 J J1222*+++1222*+++d223HIIN	
 	
 	
 	
 	
r   N)$r;   r<   r=   r>   r   r   r   r   r   r   r   r  r	  r  r  r  r  r  r  r#  r-  r;  r=  r@  rE  rI  rN  rP  rR  r[  rb  rf  rj  ro  rt  rx  r   r   r   r   r     s        
 #HA A A AF2 2 26 6 6     : : : + + +8
 
 
"J J J(     
  
  
 
 
 
2 2 2"
 
 
*" " "M M MB B B*81 81 81t0 0 0&     3 3 3
 
 
21 1 1.1 1 10D D D) ) )J J J) ) ).) ) ).2 2 2&
 
 
.
 
 
 
 
r   r   )F)0r>   r   zope.interfacer   zope.interface.verifyr   twisted.applicationr   twisted.application.internetr   r   r   twisted.internetr	   twisted.internet.deferr
   r   twisted.internet.interfacesr   r   r   r   r   twisted.internet.protocolr   r   twisted.internet.taskr   twisted.internet.testingr   twisted.loggerr   r   twisted.python.failurer   twisted.trial.unittestr   r   r   r    r#   rH   ry   r   r   r   r  r   r   r   r   <module>r     s0  
   & & & & & & - - - - - - ( ( ( ( ( (         
 " ! ! ! ! ! ; ; ; ; ; ; ; ;              8 7 7 7 7 7 7 7 ' ' ' ' ' ' 4 4 4 4 4 4 : : : : : : : : * * * * * * @ @ @ @ @ @ @ @	 	 	 "##=* =* =* =* =* =* =* $#=*@ !: . . . ^       6 !: . . .V1 V1 V1 V1 V18 V1 V1 V1rC- C- C- C- C- C- C- C-L" " " " " " " "( &  &  &  &F &8 : : : :$  B

 B

 B

 B

 B

, B

 B

 B

 B

 B

r   