U
    
W[I<  ã                   @   sl  d Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZmZmZ ddlmZ 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e%ƒZ&G d d!„ d!ej!ƒZ'd"S )#z!
Tests for error handling in PB.
é    )ÚreactorÚdefer)Úlog)ÚNativeStringIO)Úqual)ÚpbÚflavorsÚjelly)Úunittestc                   @   s   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      s   r   c                   @   s   e Zd ZdZdS )ÚSynchronousExceptionzm
    Helper used to test remote methods which raise exceptions which are not
    L{pb.Error} subclasses.
    Nr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdS )Ú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      s   r   c                   @   s   e Zd ZdZdS )ÚSynchronousErrorzi
    Helper used to test remote methods which raise exceptions which are
    L{pb.Error} subclasses.
    Nr   r   r   r   r   r   '   s   r   c                   @   s   e Zd ZdS )Ú
JellyErrorN©r   r   r   r   r   r   r   r   /   s   r   c                   @   s   e Zd ZdS )ÚSecurityErrorNr   r   r   r   r   r   4   s   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   s   t  tdƒ¡S )zD
        Fail asynchronously with a non-pb.Error exception.
        zremote asynchronous exception)r   Úfailr   ©Úselfr   r   r   Úremote_asynchronousException@   s    z'SimpleRoot.remote_asynchronousExceptionc                 C   s   t dƒ‚dS )zC
        Fail synchronously with a non-pb.Error exception.
        zremote synchronous exceptionN)r   r   r   r   r   Úremote_synchronousExceptionG   s    z&SimpleRoot.remote_synchronousExceptionc                 C   s   t  tdƒ¡S )z@
        Fail asynchronously with a pb.Error exception.
        zremote asynchronous error)r   r   r   r   r   r   r   Úremote_asynchronousErrorN   s    z#SimpleRoot.remote_asynchronousErrorc                 C   s   t dƒ‚dS )z?
        Fail synchronously with a pb.Error exception.
        zremote synchronous errorN)r   r   r   r   r   Úremote_synchronousErrorU   s    z"SimpleRoot.remote_synchronousErrorc                 C   s   G dd„ dt jƒ}|dƒ‚dS )z>
        Fail with error that is not known to client.
        c                   @   s   e Zd ZdS )z4SimpleRoot.remote_unknownError.<locals>.UnknownErrorNr   r   r   r   r   ÚUnknownError`   s   r!   zI'm not known to client!N)r   ÚError)r   r!   r   r   r   Úremote_unknownError\   s    zSimpleRoot.remote_unknownErrorc                 C   s   |   ¡  d S ©N)Ú
raiseJellyr   r   r   r   Úremote_jellye   s    zSimpleRoot.remote_jellyc                 C   s   |   ¡  d S r$   )ÚraiseSecurityr   r   r   r   Úremote_securityi   s    zSimpleRoot.remote_securityc                 C   s"   t  ¡ }| | j¡ | d ¡ |S r$   )r   ÚDeferredÚaddCallbackr%   Úcallback©r   Údr   r   r   Úremote_deferredJellym   s    
zSimpleRoot.remote_deferredJellyc                 C   s"   t  ¡ }| | j¡ | d ¡ |S r$   )r   r)   r*   r'   r+   r,   r   r   r   Úremote_deferredSecurityt   s    
z"SimpleRoot.remote_deferredSecurityNc                 C   s   t dƒ‚d S )NzI'm jellyable!)r   ©r   Zresultsr   r   r   r%   {   s    zSimpleRoot.raiseJellyc                 C   s   t dƒ‚d S )NzI'm secure!)r   r0   r   r   r   r'      s    zSimpleRoot.raiseSecurity)N)N)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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   Zprotocolr   r   r   ÚclientConnectionMade‹   s    z.SaveProtocolServerFactory.clientConnectionMade)r   r   r   r   r2   r3   r   r   r   r   r1   „   s   r1   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)Z	interface)r1   r   ÚserverFactoryÚunsafeTracebacksr   Z	listenTCPÚ
serverPortr   r   r   r   r5   ›   s    
zPBConnTestCase._setUpServerc                 C   s,   | j  ¡ j}t ¡ | _t d|| j¡| _d S )Nr8   )	r;   ZgetHostZportr   ZPBClientFactoryÚclientFactoryr   Z
connectTCPÚclientConnector)r   ZportNor   r   r   r6   ¡   s    
zPBConnTestCase._setUpClientc                 C   s0   | j jd k	r| j jj ¡  t |  ¡ |  ¡ g¡S r$   )r9   r2   Z	transportZloseConnectionr   ZgatherResultsÚ_tearDownServerÚ_tearDownClientr   r   r   r   ÚtearDown§   s    þzPBConnTestCase.tearDownc                 C   s   t  | jj¡S r$   )r   ZmaybeDeferredr;   ZstopListeningr   r   r   r   r>   ¯   s    zPBConnTestCase._tearDownServerc                 C   s   | j  ¡  t d ¡S r$   )r=   Z
disconnectr   Zsucceedr   r   r   r   r?   ³   s    
zPBConnTestCase._tearDownClientN)
r   r   r   r:   r7   r5   r6   r@   r>   r?   r   r   r   r   r4   “   s   r4   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¡ ˆr6ˆ ˆ ¡}ˆ 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)Úrootr-   )rP   Úmethodr   r   ÚgotRootObjectÆ   s    

z4PBFailureTests._exceptionTest.<locals>.gotRootObject©r<   ÚgetRootObjectr*   )r   rT   rN   rO   r-   rU   r   )rP   rN   rO   rT   r   r   Ú_exceptionTest½   s
    

zPBFailureTests._exceptionTestc                 C   s   |   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.
        ZasynchronousExceptionT)rX   r   r   r   r   r   Útest_asynchronousExceptionÎ   s
      ÿz)PBFailureTests.test_asynchronousExceptionc                 C   s   |   dtd¡S )zw
        Like L{test_asynchronousException}, but for a method which raises an
        exception synchronously.
        ÚsynchronousExceptionT)rX   r   r   r   r   r   Útest_synchronousException×   s
      ÿz(PBFailureTests.test_synchronousExceptionc                 C   s   |   dtd¡S )z
        Like L{test_asynchronousException}, but for a method which returns a
        Deferred failing with an L{pb.Error} subclass.
        ZasynchronousErrorF)rX   r   r   r   r   r   Útest_asynchronousErrorà   s
      ÿz%PBFailureTests.test_asynchronousErrorc                 C   s   |   dtd¡S )z}
        Like L{test_asynchronousError}, but for a method which synchronously
        raises a L{pb.Error} subclass.
        ÚsynchronousErrorF)rX   r   r   r   r   r   Útest_synchronousErroré   s
      ÿz$PBFailureTests.test_synchronousErrorc                 C   s   |   ||¡ |S r$   )rH   )r   ÚresultÚexpectedResultr   r   r   Ú_successò   s    zPBFailureTests._successc                 C   s   |j | j||fd |S )N)ZcallbackArgs)ZaddCallbacksra   )r   Z
remoteCallr`   rP   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 k	r4‡‡fdd„}| |¡ |S )Nc                    s   ˆ  tˆ ˆ ¡ƒd¡ | S )NrC   )rH   rI   rG   )rL   )Úexcr   r   r   Ú
gotFailure  s    z@PBFailureTests._testImpl.<locals>.gotRootObj.<locals>.gotFailure)rb   rQ   ZaddBoth)ÚobjZfailureDeferredrd   ©rP   rc   ÚexpectedrT   r   r   r   Ú
gotRootObj  s
    
z,PBFailureTests._testImpl.<locals>.gotRootObjrV   )r   rT   rg   rP   rc   ZrootDeferredrh   r   rf   r   Ú	_testImplý   s    

zPBFailureTests._testImplc                    s   ‡ 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                    s,   |   t¡ ˆ  | jt¡ ˆ  | j| j¡ dS )Né+   ©rD   r   ÚassertNotIsInstancerJ   ÚstrÚassertIsInstancerK   ©r   r   r   r   ÚfailureJelly  s    
z6PBFailureTests.test_jellyFailure.<locals>.failureJellyr	   rj   ©ri   )r   rp   r   r   r   Útest_jellyFailure  s    z PBFailureTests.test_jellyFailurec                    s   ‡ fdd„}ˆ   dd|¡S )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                    s,   |   t¡ ˆ  | jt¡ ˆ  | j| j¡ dS )Né®  rk   ro   r   r   r   ÚfailureDeferredJelly"  s    
zFPBFailureTests.test_deferredJellyFailure.<locals>.failureDeferredJellyZdeferredJellyrs   rq   )r   rt   r   r   r   Útest_deferredJellyFailure  s    z(PBFailureTests.test_deferredJellyFailurec                    s   ‡ fdd„}ˆ   dd|¡S )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                    s   ˆ   | jd¡ dS )Ns3   twisted.spread.test.test_pbfailure.SynchronousErroré¯  ©rH   rJ   ro   r   r   r   ÚfailureUnjellyable0  s
    þzBPBFailureTests.test_unjellyableFailure.<locals>.failureUnjellyabler]   rv   rq   )r   rx   r   r   r   Útest_unjellyableFailure*  s    z&PBFailureTests.test_unjellyableFailurec                    s   ‡ fdd„}ˆ   dd|¡S )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                    s   ˆ   | jd¡ dS )Ns/   twisted.spread.test.test_pbfailure.UnknownErroréÖ  rw   ro   r   r   r   ÚfailureUnknown=  s
     ÿz:PBFailureTests.test_unknownFailure.<locals>.failureUnknownZunknownErrorrz   rq   )r   r{   r   r   r   Útest_unknownFailure8  s    z"PBFailureTests.test_unknownFailurec                    s   ‡ fdd„}ˆ   dd|¡S )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                    s,   |   t¡ ˆ  | jt¡ ˆ  | j| j¡ dS )NéÌ  ©rD   r   rl   rJ   rm   rn   rK   ro   r   r   r   ÚfailureSecurityJ  s    
z<PBFailureTests.test_securityFailure.<locals>.failureSecurityZsecurityr}   rq   )r   r   r   r   r   Útest_securityFailureD  s    z#PBFailureTests.test_securityFailurec                    s   ‡ fdd„}ˆ   dd|¡S )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                    s,   |   t¡ ˆ  | jt¡ ˆ  | j| j¡ dS )Néø§  r~   ro   r   r   r   ÚfailureDeferredSecurityX  s    
zEPBFailureTests.test_deferredSecurity.<locals>.failureDeferredSecurityZdeferredSecurityr   rq   )r   r‚   r   r   r   Útest_deferredSecurityR  s    ÿ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 )NrB   é¤  )rD   r   ZNoSuchMethodrE   rF   ro   r   r   r   ÚfailureNoSuchf  s    z>PBFailureTests.test_noSuchMethodFailure.<locals>.failureNoSuchZnosuchr„   )ri   ÚAttributeError)r   r…   r   r   r   Útest_noSuchMethodFailurea  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   )rQ   )ZrootObjr   r   r   Ú	connectedw  s    z;PBFailureTests.test_copiedFailureLogging.<locals>.connectedc                    s(   t  | ¡ ˆ  t¡}ˆ  t|ƒd¡ d S )Né   )r   rL   rG   r   rH   rI   )ZfailurerM   r   r   r   Ú	exception{  s    

z;PBFailureTests.test_copiedFailureLogging.<locals>.exception)r<   rW   r*   rR   )r   r-   rˆ   rŠ   r   r   r   Útest_copiedFailureLoggingm  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©Zinvokerc               
   3   sH   z
d V  W n. t jk
r8 }  zˆ  | ¡ W 5 d } ~ X Y nX ˆ d¡ d S )NzRemoteError not raised)r   ZRemoteErrorÚappendr   )rc   ©rŠ   r   r   r   ÚgeneratorFunc  s
    
zFPBFailureTests.test_throwExceptionIntoGenerator.<locals>.generatorFuncNrC   r   Úascii)rŒ   rB   )r   ÚCopyableFailurer†   r	   ÚunjellyÚDummyInvokerÚsendZassertRaisesÚStopIterationZthrowExceptionIntoGeneratorrH   rI   Z
remoteTyper   ÚencodeÚargsZremoteTraceback)r   ÚoriginalÚcopyr   Úgenrc   r   r   r   Ú test_throwExceptionIntoGenerator„  s    
z/PBFailureTests.test_throwExceptionIntoGenerator)N)r   r   r   r
   ÚTestCaserH   rE   rX   rY   r[   r\   r^   ra   rb   ri   rr   ru   ry   r|   r€   rƒ   r‡   r‹   rœ   r   r   r   r   rA   ¹   s$   				
rA   c                   @   s   e Zd ZejjZdZdS )ÚPBFailureUnsafeTestsrC   N)r   r   r   r
   r   ZfailIfEqualsrE   r:   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   Z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’   ÚZeroDivisionErrorZassertIsZ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™   Z
copiedOnceZ
derivativeZ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   ZprintTracebackr   ÚformatrH   Úgetvalue)r   r™   r£   ÚoutputrŠ   Z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   Ztwisted.internetr   r   Ztwisted.pythonr   Ztwisted.python.compatr   Ztwisted.python.reflectr   Ztwisted.spreadr   r   r	   Ztwisted.trialr
   r¦   r   r   r"   r   r   Z	JellyableZ
RemoteCopyr   r   ZsetUnjellyableForClassZglobalSecurityZallowInstancesOfZRootr   ZPBServerFactoryr1   r   r4   rA   rž   Úobjectr”   rŸ   r   r   r   r   Ú<module>   s.   E& g	