o
    Òó·i¬  ã                   @   st  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d„ Z&eeƒG dd„ dƒƒZ'eee'ƒ eeƒG dd„ dƒƒZ(eee'ƒ G dd„ de%ƒZ)G dd„ de%ƒZ*G dd„ dƒZ+d$dd„Z,e fdd „Z-d!Z.G d"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                   C   s   dS )zM
    A fake target function for testing TimerService which does nothing.
    N© r   r   r   úlC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/application/test/test_internet.pyÚfakeTargetFunction)   s   r   c                   @   sF   e Zd ZdZdZdZdZeƒ ZdZ	dd„ Z
dd„ Zdd	„ Zd
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                 C   s   t ƒ | _d S ©N)ÚFakePortÚport©Úselfr   r   r   Ú__init__L   s   zFakeServer.__init__c                    sF   ˆ  j d7  _ |ˆ _t‡ fdd„d�ˆ _ˆ jdur ˆ 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                    s   |   ˆ j¡S r   )ÚerrbackÚcancelException)Údr    r   r   Ú<lambda>Z   ó    z#FakeServer.listen.<locals>.<lambda>)Z	cancellerN)ÚlistenAttemptsÚfactoryr
   ÚresultÚfailImmediatelyr$   )r!   r*   r   r    r   ÚlistenO   s   	
zFakeServer.listenc                 C   s   | 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)r+   Úcallbackr   r    r   r   r   ÚstartedListening_   ó   zFakeServer.startedListeningc                 C   s   | 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   Údeferredr.   r    r   r   r   ÚstoppedListeningg   s   zFakeServer.stoppedListening)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r+   r*   r,   r	   r%   r)   r"   r-   r/   r2   r   r   r   r   r   0   s    r   c                   @   s,   e Zd ZdZdZdd„ Zdd„ Zdd„ ZdS )	r   zs
    Fake L{IListeningPort} implementation.

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

        @return: a L{Deferred} stored in L{FakePort.deferred}
        N)r
   r1   r    r   r   r   ÚstopListening~   s   zFakePort.stopListeningc                 C   ó   d S r   r   r    r   r   r   ÚgetHost‡   ó   zFakePort.getHostc                 C   r8   r   r   r    r   r   r   ÚstartListening‹   r:   zFakePort.startListening)r3   r4   r5   r6   r1   r7   r9   r;   r   r   r   r   r   t   s    	r   c                   @   sr   e Zd Z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d„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚEndpointServiceTestsz4
    Tests for L{twisted.application.internet}.
    c                 C   s$   t ƒ | _tƒ | _t| j| jƒ| _dS )zp
        Construct a stub server, a stub factory, and a
        L{StreamServerEndpointService} to test.
        N)r   Ú
fakeServerr   r*   r   Úsvcr    r   r   r   ÚsetUp˜   s   zEndpointServiceTests.setUpc                 C   s    | j  ¡  |  | j| jj¡ dS )z‡
        L{StreamServerEndpointService.privilegedStartService} calls its
        endpoint's C{listen} method with its factory.
        N)r>   ÚprivilegedStartServiceÚassertIdenticalr*   r=   r    r   r   r   Útest_privilegedStartService¡   s   
z0EndpointServiceTests.test_privilegedStartServiceNc                 C   s*   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)ÚZeroDivisionErrorr=   r,   r>   Ú_raiseSynchronouslyÚassertRaisesÚstartService)r!   Zthunkr   r   r   Ú(test_synchronousRaiseRaisesSynchronously©   s   
z=EndpointServiceTests.test_synchronousRaiseRaisesSynchronouslyc                 C   s   |   | jj¡ dS )zÓ
        L{StreamServerEndpointService.privilegedStartService} should behave the
        same as C{startService} with respect to
        L{EndpointServiceTests.test_synchronousRaiseRaisesSynchronously}.
        N)rG   r>   r@   r    r   r   r   Útest_synchronousRaisePrivileged½   r0   z4EndpointServiceTests.test_synchronousRaisePrivilegedc                 C   s8   | 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)	r>   rF   r=   r+   r$   rC   ÚflushLoggedErrorsÚassertEqualÚlen©r!   Zloggedr   r   r   Útest_failReportsErrorÅ   s   

z*EndpointServiceTests.test_failReportsErrorc                 C   s@   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)
r>   rD   rF   r=   r+   r$   rC   rI   rJ   rK   rL   r   r   r   Ú!test_asynchronousFailReportsErrorÑ   s
   

z6EndpointServiceTests.test_asynchronousFailReportsErrorc                 C   s2   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)rC   r=   r,   r>   rF   rI   rJ   rK   rL   r   r   r   Ú test_synchronousFailReportsErrorß   s   


z5EndpointServiceTests.test_synchronousFailReportsErrorc                 C   s0   | 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)r>   rF   rA   r*   r=   rJ   Úrunningr    r   r   r   Útest_startServiceUnstartedé   s   
z/EndpointServiceTests.test_startServiceUnstartedc                 C   s6   |   ¡  | 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)rB   r>   rF   rJ   r=   r)   rP   r    r   r   r   Útest_startServiceStartedó   s   
z-EndpointServiceTests.test_startServiceStartedc                 C   st   | 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)r>   r@   r=   r/   rF   ÚstopServiceÚaddCallbackÚappendrJ   rK   r2   ZassertFalserP   ©r!   r+   Úlr   r   r   Útest_stopServiceý   s   




z%EndpointServiceTests.test_stopServicec                 C   sH   | 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)r>   r@   rS   ZaddBothrU   rJ   rI   r	   rV   r   r   r   Ú#test_stopServiceBeforeStartFinished  s   

z8EndpointServiceTests.test_stopServiceBeforeStartFinishedc                 C   sZ   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#   )rC   r=   r%   r>   r@   rS   rT   rU   rJ   rI   rK   )r!   r+   rW   ZstoppingErrorsr   r   r   Ú test_stopServiceCancelStartError  s   



z5EndpointServiceTests.test_stopServiceCancelStartErrorr   )r3   r4   r5   r6   r?   rB   rG   rH   rM   rN   rO   rQ   rR   rX   rY   rZ   r   r   r   r   r<   “   s    	



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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                 C   s,   t d| jƒ| _t ¡  | _| j_tƒ | _dS )z1
        Set up a timer service to test.
        é   N)r   ÚcallÚtimerr   r   Úclockr
   r1   r    r   r   r   r?   :  s   zTimerServiceTests.setUpc                 C   s   | j S )z‚
        Function called by L{TimerService} being tested.

        @returns: C{self.deferred}
        @rtype: L{Deferred}
        N)r1   r    r   r   r   r]   B  s   zTimerServiceTests.callc                 C   sV   | 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^   rF   Ú
assertTruerP   ÚassertIsInstanceÚ_loopr   ZLoopingCallrA   r_   r    r   r   r   Útest_startServiceK  s
   
z#TimerServiceTests.test_startServicec                 C   s0   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)rU   r^   r]   rF   rJ   )r!   r+   r   r   r   Ú$test_startServiceRunsCallImmediatelyV  s   
z6TimerServiceTests.test_startServiceRunsCallImmediatelyc                    sB   t  ¡ ‰ ‡ fd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   )ZmaybeReactor©Z
otherClockr   r   ÚgetOtherClockh  ó   zKTimerServiceTests.test_startServiceUsesGlobalReactor.<locals>.getOtherClockZ_maybeGlobalReactorN)	r   r   Úpatchr   r^   rF   rA   rb   r_   )r!   rg   r   rf   r   Ú"test_startServiceUsesGlobalReactor`  s
   
z4TimerServiceTests.test_startServiceUsesGlobalReactorc                 C   sR   | 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^   rF   rS   ÚassertNoResultrJ   rP   r1   r.   ÚobjectrA   ÚsuccessResultOf©r!   r&   r   r   r   Útest_stopServiceWaitso  s   


z'TimerServiceTests.test_stopServiceWaitsc                 C   s8   | 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^   rF   r1   r.   rl   rS   rA   rm   rn   r   r   r   Útest_stopServiceImmediately{  s   

z-TimerServiceTests.test_stopServiceImmediatelyc                 C   sV   | 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^   rF   r1   r$   r   rC   rI   rJ   rK   rS   rA   rm   )r!   Úerrorsr&   r   r   r   Útest_failedCallLogsError…  s   


z*TimerServiceTests.test_failedCallLogsErrorc                 C   óP   t dtƒ}| ¡  t |¡}| ¡  t |¡}tƒ }t|d|ƒ}|  	||¡ dS )zq
        When pickling L{internet.TimerService}, it won't pickle
        L{internet.TimerService._loop}.
        r#   rb   N©
r   r   rF   ÚpickleÚdumpsrS   Úloadsrl   ÚgetattrrA   ©r!   r^   ZdumpedTimerZloadedTimerZnothingÚvaluer   r   r   Ú$test_pickleTimerServiceNotPickleLoop‘  ó   


z6TimerServiceTests.test_pickleTimerServiceNotPickleLoopc                 C   rs   )zy
        When pickling L{internet.TimerService}, it won't pickle
        L{internet.TimerService._loopFinished}.
        r#   Z_loopFinishedNrt   ry   r   r   r   Ú,test_pickleTimerServiceNotPickleLoopFinished¡  r|   z>TimerServiceTests.test_pickleTimerServiceNotPickleLoopFinishedN)r3   r4   r5   r6   r?   r]   rc   rd   rj   ro   rp   rr   r{   r}   r   r   r   r   r[   ,  s    	

r[   c                   @   s   e Zd ZdZd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                 C   s   g | _ g | _g | _d S r   )ÚconnectQueueÚconstructedProtocolsÚpassedFactoriesr    r   r   r   r"   À  s   
zConnectInformation.__init__N)r3   r4   r5   r6   r"   r   r   r   r   r~   ²  s    r~   Fc                    s,   t tƒG ‡ ‡fd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                       s   e Zd Z‡ ‡fdd„ZdS )z.endpointForTesting.<locals>.ClientTestEndpointc                    sD   t ƒ }ˆj ˆ ¡ |j‡ ‡fdd„ƒ}ˆj |¡ ˆr | d ¡ |S )Nc                    s*   ˆ   d ¡}ˆj |¡ tƒ }| |¡ |S r   )ÚbuildProtocolr€   rU   r   ZmakeConnection)ÚignoredÚprotocolÚ	transport)r*   Úinfor   r   ÚcreateProtocolØ  s
   

zNendpointForTesting.<locals>.ClientTestEndpoint.connect.<locals>.createProtocol)r
   r�   rU   rT   r   r.   )r!   r*   r+   r‡   ©ÚfireImmediatelyr†   )r*   r   ÚconnectÔ  s   
z6endpointForTesting.<locals>.ClientTestEndpoint.connectN)r3   r4   r5   rŠ   r   rˆ   r   r   ÚClientTestEndpointÒ  s    r‹   N)r   r   r~   )r‰   r‹   r   rˆ   r   ÚendpointForTestingÆ  s   
rŒ   c                    s0   g ‰ˆ   ˆj¡ |  ‡ ‡fdd„¡ ‡fd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                      s   ˆ   ˆj¡S r   )ZremoveObserverrU   r   ©ÚlogPublisherÚlogsr   r   r'   ÷  r(   zcatchLogs.<locals>.<lambda>c                      s   dd„ ˆ D ƒS )Nc                 S   s   g | ]}t |ƒ‘qS r   )r   )Ú.0Úeventr   r   r   Ú
<listcomp>ø  s    z/catchLogs.<locals>.<lambda>.<locals>.<listcomp>r   r   )r�   r   r   r'   ø  s    N)ZaddObserverrU   Ú
addCleanup)ZtestCaserŽ   r   r�   r   Ú	catchLogsé  s   r”   g      Y@c                   @   s  e Zd ZdZdde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dd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdFd d!„Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Z d>d?„ Z!d@dA„ Z"dBdC„ Z#dDdE„ Z$dS )GÚClientServiceTestsz%
    Tests for L{ClientService}.
    TFc                    s    i }|j tƒ d� |  |¡ |d ‰t|d�\}}g  ‰ |_G ‡ ‡‡fdd„dtƒ}	|	ƒ  |_}
t||
fi |¤Ž‰‡‡‡fdd„}ˆ |¡ |rLˆ ¡  |ˆ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                       s$   e Zd Z”Z‡ ‡‡fdd„Z‡  ZS )z>ClientServiceTests.makeReconnector.<locals>.RememberingFactoryc                    s"   ˆrd S t ƒ  |¡}ˆ |¡ |S r   )Úsuperr‚   rU   )r!   Úaddrr+   )Ú	__class__ÚapplicationProtocolsÚrefuseConnectionsr   r   r‚   5  s
   
zLClientServiceTests.makeReconnector.<locals>.RememberingFactory.buildProtocol)r3   r4   r5   r„   r‚   Ú__classcell__r   )r›   ÚprotocolTyperœ   )rš   r   ÚRememberingFactory2  s    rŸ   c                      s(   d ˆ_ ˆjr
ˆ ¡  ˆ ˆ  ¡ g ¡ d S r   )Ú	_protocolrP   rS   rJ   ÚgetDelayedCallsr   )r_   r!   Úservicer   r   Ústop@  s   z0ClientServiceTests.makeReconnector.<locals>.stopN)	Úupdater   rŒ   r›   r   ÚapplicationFactoryr   r“   rF   )r!   r‰   rF   rž   rœ   ÚkwZnkwÚcqZendpointrŸ   r*   r£   r   )r›   r_   rž   rœ   r!   r¢   r   ÚmakeReconnector  s   !



z"ClientServiceTests.makeReconnectorc                 C   s&   | j dd�\}}|  t|jƒd¡ dS )zL
        When the service is started, a connection attempt is made.
        Fr—   r#   N)r¨   rJ   rK   r   )r!   r§   r¢   r   r   r   rc   M  s   z$ClientServiceTests.test_startServicec                 C   sD   |   ¡ \}}|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¥   rJ   ZnumPortsr�   ZdoStart)r!   r§   r¢   ZfirstAppFactoryZfirstPassedFactoryr   r   r   Útest_startStopFactoryT  s   
z(ClientServiceTests.test_startStopFactoryc                 C   sV   |   ¡ \}}| ¡ }|  |¡ |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¨   rS   rk   r€   rJ   r…   ÚdisconnectingÚconnectionLostr   Ú	Exceptionrm   ©r!   r§   r¢   r&   r„   r   r   r   Útest_stopServiceWhileConnectedb  s   

z1ClientServiceTests.test_stopServiceWhileConnectedc                 C   s„   |   ¡ \}}| ¡ }|  |¡ |jd }|  |jjd¡ | ¡  |  |¡ |  t|jƒd¡ | 	t
tdƒƒ¡ |  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#   zsynthetic connectionLostr\   N)r¨   rS   rk   r€   rJ   r…   rª   rF   rK   r«   r   r¬   r­   r   r   r   Ú#test_startServiceWaitsForDisconnectp  s   


z6ClientServiceTests.test_startServiceWaitsForDisconnectc                 C   sæ   | j dd�\}}|jd  d¡ |jd }| ¡ }|  |¡ | ¡ }|  |¡ | ¡  |  |¡ |  |¡ |  |j	j
d¡ | ttdƒƒ¡ |  |¡ |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   NTzsynthetic connection lostr#   r\   )r¨   r   r.   r€   rS   rk   ÚwhenConnectedrF   rJ   r…   rª   r«   r   r¬   rm   rK   rA   r›   )r!   r§   r¢   ÚfirstÚstoppedZnextProtocolZsecondStoppedr   r   r   Útest_startServiceWhileStopping€  s(   





ÿz1ClientServiceTests.test_startServiceWhileStoppingc                 C   sj   | j d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¨   rS   rm   ÚfailureResultOfr°   r	   rF   r   r.   rA   r›   )r!   r§   r¢   r²   r   r   r   Útest_startServiceWhileStoppedœ  s   
ÿz0ClientServiceTests.test_startServiceWhileStoppedc                 C   sX   t ttƒG dd„ dtƒƒ}| j|d�\}}|jd }|  t |¡¡ |  t |¡¡ 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                   @   s   e Zd ZdZdS )zEClientServiceTests.test_interfacesForTransport.<locals>.FancyProtocolz9
            Provider of various interfaces.
            N)r3   r4   r5   r6   r   r   r   r   ÚFancyProtocol¶  s    r·   )rž   r   N)r   r   r   r   r¨   r€   r`   Z
providedBy)r!   r·   r§   r¢   ZreactorFacingr   r   r   Útest_interfacesForTransport­  s   	
z.ClientServiceTests.test_interfacesForTransportc                 C   sn   t ƒ }| jd|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_ATTEMPTrJ   rK   rS   rm   ©r!   r_   r§   r¢   r&   r   r   r   Útest_stopServiceWhileRetryingÁ  s   
z0ClientServiceTests.test_stopServiceWhileRetryingc                 C   sP   t ƒ }| jd|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¨   rJ   rK   r   rk   rS   rm   r¼   r   r   r   Útest_stopServiceWhileConnectingÎ  s   z2ClientServiceTests.test_stopServiceWhileConnectingc                 C   sš   t ƒ }| j|d�\}}| ¡ }|  | ¡ g ¡ |  |  |¡|jd ¡ |  |jd j	|jd ¡ |  
t|jd ƒt|jd ƒ¡ |  
dt|jd ƒ¡ dS )zy
        When a client connects, the service keeps a reference to the new
        protocol and resets the delay.
        r–   r   rŸ   N)r   r¨   r°   rJ   r¡   rA   rm   r›   r€   r    ÚassertInÚstrr�   )r!   r_   r§   r¢   ZawaitingProtocolr   r   r   Útest_clientConnectedÚ  s$   ÿÿþþz'ClientServiceTests.test_clientConnectedc                 C   s€   t ƒ }| jd|d�\}}|  t|jƒd¡ |jd  ttƒ ƒ¡ | ¡ }|  	|¡ | 
d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                 S   s
   |   t¡S r   )Ztrapr	   )rƒ   r   r   r   r'   ÿ  s   
 z@ClientServiceTests.test_clientConnectionFailed.<locals>.<lambda>r\   N)r   r¨   rJ   rK   r   r$   r   r¬   r°   rk   Z
addErrbackrº   r»   )r!   r_   r§   r¢   r°   r   r   r   Útest_clientConnectionFailedò  s   

z.ClientServiceTests.test_clientConnectionFailedc                 C   sÊ   t ƒ }| j|d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¨   rJ   rK   r   r.   rA   rm   r°   r›   r€   r«   r   r¬   rº   r»   ©r!   r_   r§   r¢   r   r   r   Útest_clientConnectionLost  s   ÿ
ÿz,ClientServiceTests.test_clientConnectionLostÚreturnNc                    s²   t ƒ }ˆ  ‡ ‡fdd„¡ ˆ j|ddd�\}}ˆ  t|jƒd¡ |j d¡ d¡ ˆ  t|jƒd¡ | ¡ ‰ˆ  	ˆ¡ | 
t¡ ˆ  t|jƒd¡ |j d¡ d¡ ˆ  	ˆ¡ dS )	z™
        When the client factory refuses connections by returning None from
        buildProtocol, the factory keeps attempting new connections.
        c                      s   ˆ   ˆt¡S r   )rµ   r	   r   ©r!   r°   r   r   r'   "  r(   zAClientServiceTests.test_clientConnectionRefused.<locals>.<lambda>FT)r_   r‰   rœ   r#   r   N)r   r“   r¨   rJ   rK   r   Úpopr.   r°   rk   rº   r»   rÃ   r   rÆ   r   Útest_clientConnectionRefused  s    
ü

z/ClientServiceTests.test_clientConnectionRefusedc                 C   sT   t ƒ }| j|d�\}}| ¡ }|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¨   rS   r€   r«   r   ÚIndentationErrorrµ   r°   r	   r`   Úcalledr¼   r   r   r   Ú&test_clientConnectionLostWhileStopping>  s   z9ClientServiceTests.test_clientConnectionLostWhileStoppingc                 C   sv   | j d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‰   rF   r   r#   z$Duplicate ClientService.startServiceN)r¨   rJ   rK   r   rF   r”   r¿   )r!   r§   r¢   Úmessagesr   r   r   Útest_startTwiceK  s   z"ClientServiceTests.test_startTwicec           
      C   s®   t ƒ }| jd|d�\}}| ¡ }| ¡ }|j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#   ©ZfailAfterFailuresr   N)	r   r¨   r°   rk   r   r.   rm   rA   r›   )
r!   r_   r§   r¢   ÚaÚbÚcZresultAZresultBZresultCr   r   r   Útest_whenConnectedLaterZ  s   





z*ClientServiceTests.test_whenConnectedLaterc                 C   sÐ  t ƒ }| jd|d�\}}| ¡ }|jdd�}|jdd�}|j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 ¡ |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°   rk   r   r¬   r   r$   rA   rµ   rº   r»   rJ   rK   r.   rm   r›   )r!   r_   r§   r¢   Za0Za1Za2Úa3Úf1Úf2ZAT_LEAST_TWO_ATTEMPTSZresultA0ZresultA3Za4ZresultA4r   r   r   Útest_whenConnectedFailso  sN   




















z*ClientServiceTests.test_whenConnectedFailsc                 C   sŒ   t ƒ }| jd|d�\}}| ¡ }| ¡ }|j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°   rk   rS   rº   r»   rµ   r	   )r!   r_   r§   r¢   rÏ   rÐ   rÑ   r   r   r   Útest_whenConnectedStopService©  s   



z0ClientServiceTests.test_whenConnectedStopServicec                 C   sT   t ƒ }| jd|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$   r¬   rS   rJ   r¡   rm   r¼   r   r   r   Útest_retryCancelled¼  s   z&ClientServiceTests.test_retryCancelledc                 C   s6   t ƒ }| jd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‰   rF   r_   N©r   r¨   rS   ZassertIsNonerm   )r!   r_   Ú_r¢   r&   r   r   r   Ú"test_stopServiceBeforeStartServiceÉ  s   
ÿz5ClientServiceTests.test_stopServiceBeforeStartServicec                 C   sp   t ƒ }| jd|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¬   rS   ra   rµ   rz   r	   )r!   r_   r§   r¢   ZbeforeErrbackAndStopZafterErrbackAndStopr   r   r   Ú'test_whenConnectedErrbacksOnStopServiceÖ  s   ÿÿz:ClientServiceTests.test_whenConnectedErrbacksOnStopServicec                 C   sf   t ƒ }| jd|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   r.   rS   r€   r«   r   rÉ   rm   ©r!   r_   r§   r¢   ÚfirstStopDeferredÚsecondStopDeferredr   r   r   Ú"test_stopServiceWhileDisconnectingï  s   
z5ClientServiceTests.test_stopServiceWhileDisconnectingc                 C   sn   t ƒ }| jd|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   r.   rS   rF   r€   r«   r   rÉ   rm   rß   r   r   r   Útest_stopServiceWhileRestarting  s   
z2ClientServiceTests.test_stopServiceWhileRestartingc                 C   sL   t ƒ }| jd|d�\}}| ¡ }| ¡ }|  |  |¡¡ |  |  |¡¡ dS )zŽ
        Calling L{ClientService.stopService} on a stopped service
        returns a L{Deferred} that has already fired with L{None}.
        Fr¹   NrÛ   )r!   r_   rÜ   r¢   rà   rá   r   r   r   Ú test_stopServiceOnStoppedService  s   z3ClientServiceTests.test_stopServiceOnStoppedServicec                    s8   dg‰ ‡ fdd„}| j |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  d7  < d S ©Nr   r#   r   ©Ú_proto©Zpreparesr   r   ÚprepareConnection2  ó   z[ClientServiceTests.test_prepareConnectionCalledWhenServiceStarts.<locals>.prepareConnectionT)rê   rF   r#   N)r¨   rJ   ©r!   rê   r§   r¢   r   ré   r   Ú-test_prepareConnectionCalledWhenServiceStarts+  s   
ÿz@ClientServiceTests.test_prepareConnectionCalledWhenServiceStartsc                    s:   g ‰ ‡ fdd„}| j |d�\}}|  |jd ˆ d ¡ dS )zf
        The C{prepareConnection} callable is passed the connected protocol
        instance.
        c                    s   ˆ   | ¡ d S r   ©rU   ©Úproto©ÚnewProtocolsr   r   rê   A  s   zVClientServiceTests.test_prepareConnectionCalledWithProtocol.<locals>.prepareConnection©rê   r   N)r¨   rA   r€   rì   r   rñ   r   Ú(test_prepareConnectionCalledWithProtocol:  s   
ÿz;ClientServiceTests.test_prepareConnectionCalledWithProtocolc                    s~   dg‰ ‡ fdd„}t ƒ }| j|d|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                    rå   ræ   r   rç   ré   r   r   rê   P  rë   z]ClientServiceTests.test_prepareConnectionCalledAfterConnectionMade.<locals>.prepareConnectionF)rê   r‰   r_   zconnection attempt failedr#   N)	r   r¨   r   r$   r¬   rJ   rº   r»   r.   ©r!   rê   r_   r§   r¢   r   ré   r   Ú/test_prepareConnectionCalledAfterConnectionMadeI  s   
ÿ
zBClientServiceTests.test_prepareConnectionCalledAfterConnectionMadec                    sn   dg‰ ‡ fdd„}t ƒ }| j||d�\}}|  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                    rå   ræ   r   rç   ré   r   r   rê   g  rë   zUClientServiceTests.test_prepareConnectionCalledOnReconnect.<locals>.prepareConnection©rê   r_   r#   r\   N)	r   r¨   rJ   r€   r«   r   rÉ   rº   r»   rõ   r   ré   r   Ú'test_prepareConnectionCalledOnReconnect`  s   
ÿ
z:ClientServiceTests.test_prepareConnectionCalledOnReconnectc                    s@   t ƒ ‰ ‡ fdd„}| j|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                    re   r   r   rï   ©Úsentinelr   r   rê   ‚  rh   zVClientServiceTests.test_prepareConnectionReturnValueIgnored.<locals>.prepareConnectionró   N)rl   r¨   rm   r°   ZassertNotIdentical)r!   rê   r§   r¢   r+   r   rù   r   Ú(test_prepareConnectionReturnValueIgnoredw  s
   	z;ClientServiceTests.test_prepareConnectionReturnValueIgnoredc                    s`   g ‰t ƒ ‰ ‡ ‡fdd„}| j|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                    s   ˆ  | ¡ ˆ S r   rî   rï   ©ZnewProtocolDeferredrò   r   r   rê   ’  s   
zVClientServiceTests.test_prepareConnectionReturningADeferred.<locals>.prepareConnectionró   Nr   )r
   r¨   r°   rk   r.   rA   r›   rm   )r!   rê   r§   r¢   ÚwhenConnectedDeferredr   rü   r   Ú(test_prepareConnectionReturningADeferredŠ  s   

ÿz;ClientServiceTests.test_prepareConnectionReturningADeferredc                 C   sl   t ƒ }dd„ }| j||d�\}}|jdd�}|  |¡ | t¡ |  |¡ | t¡ |  t|  |¡j	¡ dS )zs
        The connection attempt counts as a failure when the
        C{prepareConnection} callable throws.
        c                 S   s   t ƒ ‚r   )rÉ   rç   r   r   r   rê   ¨  s   zJClientServiceTests.test_prepareConnectionThrows.<locals>.prepareConnectionr÷   r\   rÎ   N)
r   r¨   r°   rk   rº   r»   rA   rÉ   rµ   Útype)r!   r_   rê   r§   r¢   rý   r   r   r   Útest_prepareConnectionThrows¡  s   
ÿ



ÿz/ClientServiceTests.test_prepareConnectionThrows)rÅ   N)%r3   r4   r5   r6   r   r¨   rc   r©   r®   r¯   r³   r¶   r¸   r½   r¾   rÁ   rÂ   rÄ   rÈ   rË   rÍ   rÒ   r×   rØ   rÚ   rÝ   rÞ   râ   rã   rä   rí   rô   rö   rø   rû   rþ   r   r   r   r   r   r•   þ  sL    
ûJ
&:r•   )F)0r6   ru   Zzope.interfacer   Zzope.interface.verifyr   Ztwisted.applicationr   Ztwisted.application.internetr   r   r   Ztwisted.internetr   Ztwisted.internet.deferr	   r
   Ztwisted.internet.interfacesr   r   r   r   r   Ztwisted.internet.protocolr   r   Ztwisted.internet.taskr   Ztwisted.internet.testingr   Ztwisted.loggerr   r   Ztwisted.python.failurer   Ztwisted.trial.unittestr   r   r   r   r   r<   r[   r~   rŒ   r”   r»   r•   r   r   r   r   Ú<module>   s>   
@
  
#