o
    b;                     @   sj  d Z ddl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mZ ddlmZ G dd	 d	eZG d
d deZG dd dejZG dd dejZG dd dejejejZG dd dejejZeee eee eje G dd dejZG dd dejZ G dd dej!Z"G dd de"Z#G dd de#Z$G dd dZ%G d d! d!ej!Z&d"S )#z!
Tests for error handling in PB.
    )StringIO)deferreactor)log)qual)flavorsjellypb)unittestc                   @      e Zd ZdZdS )AsynchronousExceptionz
    Helper used to test remote methods which return Deferreds which fail with
    exceptions which are not L{pb.Error} subclasses.
    N__name__
__module____qualname____doc__ r   r   D/usr/lib/python3/dist-packages/twisted/spread/test/test_pbfailure.pyr          r   c                   @   r   )SynchronousExceptionzm
    Helper used to test remote methods which raise exceptions which are not
    L{pb.Error} subclasses.
    Nr   r   r   r   r   r      r   r   c                   @   r   )AsynchronousErrorz
    Helper used to test remote methods which return Deferreds which fail with
    exceptions which are L{pb.Error} subclasses.
    Nr   r   r   r   r   r   !   r   r   c                   @   r   )SynchronousErrorzi
    Helper used to test remote methods which raise exceptions which are
    L{pb.Error} subclasses.
    Nr   r   r   r   r   r   (   r   r   c                   @      e Zd ZdS )
JellyErrorNr   r   r   r   r   r   r   r   /       r   c                   @   r   )SecurityErrorNr   r   r   r   r   r   3   r   r   c                   @   sh   e 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dZdddZdS )
SimpleRootc                 C      t tdS )zD
        Fail asynchronously with a non-pb.Error exception.
        zremote asynchronous exception)r   failr   selfr   r   r   remote_asynchronousException>      z'SimpleRoot.remote_asynchronousExceptionc                 C      t d)zC
        Fail synchronously with a non-pb.Error exception.
        zremote synchronous exception)r   r    r   r   r   remote_synchronousExceptionD      z&SimpleRoot.remote_synchronousExceptionc                 C   r   )z@
        Fail asynchronously with a pb.Error exception.
        zremote asynchronous error)r   r   r   r    r   r   r   remote_asynchronousErrorJ   r#   z#SimpleRoot.remote_asynchronousErrorc                 C   r$   )z?
        Fail synchronously with a pb.Error exception.
        zremote synchronous error)r   r    r   r   r   remote_synchronousErrorP   r&   z"SimpleRoot.remote_synchronousErrorc                 C   s   G dd dt j}|d)z>
        Fail with error that is not known to client.
        c                   @   r   )z4SimpleRoot.remote_unknownError.<locals>.UnknownErrorNr   r   r   r   r   UnknownError[   r   r)   zI'm not known to client!)r	   Error)r!   r)   r   r   r   remote_unknownErrorV   s   zSimpleRoot.remote_unknownErrorc                 C      |    d S N)
raiseJellyr    r   r   r   remote_jelly`      zSimpleRoot.remote_jellyc                 C   r,   r-   )raiseSecurityr    r   r   r   remote_securityc   r0   zSimpleRoot.remote_securityc                 C   "   t  }|| j |d  |S r-   )r   DeferredaddCallbackr.   callbackr!   dr   r   r   remote_deferredJellyf      
zSimpleRoot.remote_deferredJellyc                 C   r3   r-   )r   r4   r5   r1   r6   r7   r   r   r   remote_deferredSecurityl   r:   z"SimpleRoot.remote_deferredSecurityNc                 C   r$   )NzI'm jellyable!)r   r!   resultsr   r   r   r.   r      zSimpleRoot.raiseJellyc                 C   r$   )NzI'm secure!)r   r<   r   r   r   r1   u   r>   zSimpleRoot.raiseSecurityr-   )r   r   r   r"   r%   r'   r(   r+   r/   r2   r9   r;   r.   r1   r   r   r   r   r   =   s    

r   c                   @   s   e Zd ZdZdZdd ZdS )SaveProtocolServerFactoryzd
    A L{pb.PBServerFactory} that saves the latest connected client in
    C{protocolInstance}.
    Nc                 C   s
   || _ dS )z3
        Keep track of the given protocol.
        N)protocolInstance)r!   protocolr   r   r   clientConnectionMade   s   
z.SaveProtocolServerFactory.clientConnectionMade)r   r   r   r   r@   rB   r   r   r   r   r?   y   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S )PBConnTestCaser   c                 C   s   |    |   d S r-   )_setUpServer_setUpClientr    r   r   r   setUp   s   zPBConnTestCase.setUpc                 C   s.   t t | _| j| j_tjd| jdd| _d S )Nr   	127.0.0.1)	interface)r?   r   serverFactoryunsafeTracebacksr   	listenTCP
serverPortr    r   r   r   rD      s
   
zPBConnTestCase._setUpServerc                 C   s,   | j  j}t | _td|| j| _d S )NrG   )	rL   getHostportr	   PBClientFactoryclientFactoryr   
connectTCPclientConnector)r!   portNor   r   r   rE      s
   

zPBConnTestCase._setUpClientc                 C   s0   | j jd ur| j jj  t|  |  gS r-   )rI   r@   	transportloseConnectionr   gatherResults_tearDownServer_tearDownClientr    r   r   r   tearDown   s   zPBConnTestCase.tearDownc                 C   s   t | jjS r-   )r   maybeDeferredrL   stopListeningr    r   r   r   rW      s   zPBConnTestCase._tearDownServerc                 C   s   | j   td S r-   )rR   
disconnectr   succeedr    r   r   r   rX      s   

zPBConnTestCase._tearDownClientN)
r   r   r   rJ   rF   rD   rE   rY   rW   rX   r   r   r   r   rC      s    rC   c                   @   s   e Zd ZejjZdd Zdd Zdd Z	dd Z
d	d
 Zdd Zdd Zd$ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# ZdS )%PBFailureTestsc                    s6   fdd j  } fdd}|| |S )Nc                    sF   |    | jd r }t|d | j| j| jfS )NTraceback unavailable
   )trapcompare	tracebackflushLoggedErrorsassertEquallentypevalue)errerrs)exceptionTypeflushr!   r   r   eb   s   

z)PBFailureTests._exceptionTest.<locals>.ebc                    s   |  }|  |S r-   )
callRemote
addErrback)rootr8   )rm   methodr   r   gotRootObject   s   

z4PBFailureTests._exceptionTest.<locals>.gotRootObjectrP   getRootObjectr5   )r!   rq   rk   rl   r8   rr   r   )rm   rk   rl   rq   r!   r   _exceptionTest   s
   

zPBFailureTests._exceptionTestc                 C      |  dtdS )z
        Test that a Deferred returned by a remote method which already has a
        Failure correctly has that error passed back to the calling side.
        asynchronousExceptionT)ru   r   r    r   r   r   test_asynchronousException      z)PBFailureTests.test_asynchronousExceptionc                 C   rv   )zw
        Like L{test_asynchronousException}, but for a method which raises an
        exception synchronously.
        synchronousExceptionT)ru   r   r    r   r   r   test_synchronousException   ry   z(PBFailureTests.test_synchronousExceptionc                 C   rv   )z
        Like L{test_asynchronousException}, but for a method which returns a
        Deferred failing with an L{pb.Error} subclass.
        asynchronousErrorF)ru   r   r    r   r   r   test_asynchronousError   ry   z%PBFailureTests.test_asynchronousErrorc                 C   rv   )z}
        Like L{test_asynchronousError}, but for a method which synchronously
        raises a L{pb.Error} subclass.
        synchronousErrorF)ru   r   r    r   r   r   test_synchronousError   ry   z$PBFailureTests.test_synchronousErrorc                 C   s   |  || |S r-   )re   )r!   resultexpectedResultr   r   r   _success   s   zPBFailureTests._successc                 C   s   |j | j||fd |S )N)callbackArgs)addCallbacksr   )r!   
remoteCallr   rm   r   r   r   _addFailingCallbacks   s   z#PBFailureTests._addFailingCallbacksNc                    s,   j  } fdd}|| |S )z
        Call the given remote method and attach the given errback to the
        resulting Deferred.  If C{exc} is not None, also assert that one
        exception of that type was logged.
        c                    s8    |  }d urfdd}|| |S )Nc                    s    t d | S )Nr`   )re   rf   rd   )ri   )excr!   r   r   
gotFailure   s   z@PBFailureTests._testImpl.<locals>.gotRootObj.<locals>.gotFailure)r   rn   addBoth)objfailureDeferredr   rm   r   expectedrq   r!   r   r   
gotRootObj   s   
z,PBFailureTests._testImpl.<locals>.gotRootObjrs   )r!   rq   r   rm   r   rootDeferredr   r   r   r   	_testImpl   s   

zPBFailureTests._testImplc                        fdd}  dd|S )z
        Test that an exception which is a subclass of L{pb.Error} has more
        information passed across the network to the calling side.
        c                    ,   |  t  | jt  | j| j dS )N+   ra   r   assertNotIsInstancerg   strassertIsInstancerh   r   r    r   r   failureJelly     
z6PBFailureTests.test_jellyFailure.<locals>.failureJellyr   r   r   )r!   r   r   r    r   test_jellyFailure      z PBFailureTests.test_jellyFailurec                    r   )z
        Test that a Deferred which fails with a L{pb.Error} is treated in
        the same way as a synchronously raised L{pb.Error}.
        c                    r   )N  r   r   r    r   r   failureDeferredJelly  r   zFPBFailureTests.test_deferredJellyFailure.<locals>.failureDeferredJellydeferredJellyr   r   )r!   r   r   r    r   test_deferredJellyFailure
  r   z(PBFailureTests.test_deferredJellyFailurec                    r   )z
        A non-jellyable L{pb.Error} subclass raised by a remote method is
        turned into a Failure with a type set to the FQPN of the exception
        type.
        c                         | jd dS )Ns3   twisted.spread.test.test_pbfailure.SynchronousError  re   rg   r   r    r   r   failureUnjellyable     zBPBFailureTests.test_unjellyableFailure.<locals>.failureUnjellyabler~   r   r   )r!   r   r   r    r   test_unjellyableFailure     z&PBFailureTests.test_unjellyableFailurec                    r   )z
        Test that an exception which is a subclass of L{pb.Error} but not
        known on the client side has its type set properly.
        c                    r   )Ns/   twisted.spread.test.test_pbfailure.UnknownError  r   r   r    r   r   failureUnknown-  r   z:PBFailureTests.test_unknownFailure.<locals>.failureUnknownunknownErrorr   r   )r!   r   r   r    r   test_unknownFailure'  r   z"PBFailureTests.test_unknownFailurec                    r   )z
        Test that even if an exception is not explicitly jellyable (by being
        a L{pb.Jellyable} subclass), as long as it is an L{pb.Error}
        subclass it receives the same special treatment.
        c                    r   )N  ra   r   r   rg   r   r   rh   r   r    r   r   failureSecurity<  r   z<PBFailureTests.test_securityFailure.<locals>.failureSecuritysecurityr   r   )r!   r   r   r    r   test_securityFailure5  r   z#PBFailureTests.test_securityFailurec                    r   )z
        Test that a Deferred which fails with a L{pb.Error} which is not
        also a L{pb.Jellyable} is treated in the same way as a synchronously
        raised exception of the same type.
        c                    r   )N  r   r   r    r   r   failureDeferredSecurityK  r   zEPBFailureTests.test_deferredSecurity.<locals>.failureDeferredSecuritydeferredSecurityr   r   )r!   r   r   r    r   test_deferredSecurityD  r   z$PBFailureTests.test_deferredSecurityc                    s    fdd}  dd|tS )z
        Test that attempting to call a method which is not defined correctly
        results in an AttributeError on the calling side.
        c                    s   |  tj  | jd dS )Nr_     )ra   r	   NoSuchMethodrb   rc   r   r    r   r   failureNoSuchY  s   z>PBFailureTests.test_noSuchMethodFailure.<locals>.failureNoSuchnosuchr   )r   AttributeError)r!   r   r   r    r   test_noSuchMethodFailureS  s   z'PBFailureTests.test_noSuchMethodFailurec                    s6    j  }dd }||  fdd}|| |S )z
        Test that a copied failure received from a PB call can be logged
        locally.

        Note: this test needs some serious help: all it really tests is that
        log.err(copiedFailure) doesn't raise an exception.
        c                 S   s
   |  dS )Nrz   )rn   )rootObjr   r   r   	connectedj  s   
z;PBFailureTests.test_copiedFailureLogging.<locals>.connectedc                    s(   t |   t} t|d d S )N   )r   ri   rd   r   re   rf   )failurerj   r    r   r   	exceptiono  s   

z;PBFailureTests.test_copiedFailureLogging.<locals>.exception)rP   rt   r5   ro   )r!   r8   r   r   r   r    r   test_copiedFailureLogging`  s   


z(PBFailureTests.test_copiedFailureLoggingc                    s   t td}ttj|t d}g   fdd}| }|d t|j	| 
t d  d }
|jttd 
|jd	 
|jd
 dS )z
        L{pb.CopiedFailure.throwExceptionIntoGenerator} will throw a
        L{RemoteError} into the given paused generator at the point where it
        last yielded.
        fooinvokerc               
   3   sN    zd V  W n t jy }  z |  W Y d } ~ d S d } ~ ww d d S )NzRemoteError not raised)r	   RemoteErrorappendr   )r   r   r!   r   r   generatorFunc  s   
zFPBFailureTests.test_throwExceptionIntoGenerator.<locals>.generatorFuncNr`   r   ascii)r   r_   )r	   CopyableFailurer   r   unjellyDummyInvokersendassertRaisesStopIterationthrowExceptionIntoGeneratorre   rf   
remoteTyper   encodeargsremoteTraceback)r!   originalcopyr   genr   r   r   r    test_throwExceptionIntoGeneratorx  s   
z/PBFailureTests.test_throwExceptionIntoGeneratorr-   )r   r   r   r
   TestCasere   rb   ru   rx   r{   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r^      s&    
r^   c                   @   s   e Zd ZejjZdZdS )PBFailureUnsafeTestsr`   N)r   r   r   r
   r   failIfEqualsrb   rJ   r   r   r   r   r     s    r   c                   @   s   e Zd ZdZdZdS )r   zZ
    A behaviorless object to be used as the invoker parameter to
    L{jelly.jelly}.
    N)r   r   r   r   serializingPerspectiver   r   r   r   r     s    r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	FailureJellyingTestsz:
    Tests for the interaction of jelly and failures.
    c                 C   sn   t t }| |tt | |tt ttj|t d}| |tt | |tt dS )z
        An unjellied L{CopyableFailure} has a check method which behaves the
        same way as the original L{CopyableFailure}'s check method.
        r   N	r	   r   ZeroDivisionErrorassertIscheckArithmeticErrorr   r   r   )r!   r   copiedr   r   r   test_unjelliedFailureCheck  s   z/FailureJellyingTests.test_unjelliedFailureCheckc                 C   s   t t }| |tt | |tt ttj|t d}t |}ttj|t d}| |tt | |tt dS )aX  
        The object which results from jellying a L{CopyableFailure}, unjellying
        the result, creating a new L{CopyableFailure} from the result of that,
        jellying it, and finally unjellying the result of that has a check
        method which behaves the same way as the original L{CopyableFailure}'s
        check method.
        r   Nr   )r!   r   
copiedOnce
derivativecopiedTwicer   r   r   test_twiceUnjelliedFailureCheck  s   
z4FailureJellyingTests.test_twiceUnjelliedFailureCheckc                 C   sZ   t td}ttj|t d}t }|| tt}d	|}| 
||  dS )a  
        When L{CopiedFailure.printTraceback} is used to print a copied failure
        which was unjellied from a L{CopyableFailure} with C{unsafeTracebacks}
        set to C{False}, the string representation of the exception value is
        included in the output.
        zsome reasonr   z.Traceback from remote host -- {}: some reason
N)r	   r   	Exceptionr   r   r   r   printTracebackr   formatre   getvalue)r!   r   r   outputr   expectedOutputr   r   r    test_printTracebackIncludesValue  s   
z5FailureJellyingTests.test_printTracebackIncludesValueN)r   r   r   r   r   r   r   r   r   r   r   r     s
    r   N)'r   ior   twisted.internetr   r   twisted.pythonr   twisted.python.reflectr   twisted.spreadr   r   r	   twisted.trialr
   r   r   r   r*   r   r   	Jellyable
RemoteCopyr   r   setUnjellyableForClassglobalSecurityallowInstancesOfRootr   PBServerFactoryr?   r   rC   r^   r   r   r   r   r   r   r   <module>   s0   <" k	