o
    b8                     @   sr  d Z ddlZddlZddlZddl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 ddlmZmZmZ ddlmZmZ dd	lmZmZmZmZ dd
lmZ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+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1 G dd de+j2Z3G dd de+j4Z5eej6G dd dZ7G dd dZ8dd Z9G dd dZ:G dd de/Z;dd d!Z<G d"d# d#e+j=Z>G d$d% d%e+j=Z?G d&d' d'e+j@ZAG d(d) d)e+jBZCe+DeAeC G d*d+ d+e+j@ZEd,d- ZFe+GeEeF G d.d/ d/e+j=ZHG d0d1 d1e+jIZJG d2d3 d3e+j=ZKG d4d5 d5e+jIZLG d6d7 d7e+jMZNe+DeLeN G d8d9 d9e+jMZOe+DeJeO G d:d; d;e+j=ZPG d<d= d=e+j=ZQG d>d? d?e+j=ZRG d@dA dAe+j=ZSG dBdC dCe+j@e+jBZTe+DeTeT G dDdE dEe+j@e+jBZUe+DeUeU G dFdG dGe+jIe+jMZVe+DeVeV G dHdI dIe+jWZXG dJdK dKe+jWZYG dLdM dMe1jZZ[G dNdO dOe+j\Z]G dPdQ dQe1j^Z_G dRdS dSe1j^Z`dTZadabdacdUdV ZdG dWdX dXe+j=ZeG dYdZ dZe+j=ZfG d[d\ d\e1j^ZgG d]d^ d^e,jhZiG d_d` d`e,jjZkG dadb dbe+j=Zle+Deiek G dcdd dde1j^ZmG dedf dfenZoG dgdh dhe+j@ZpG didj dje+j=ZqG dkdl dle-jrZsee+jtG dmdn dne+j4ZuG dodp dpZvG dqdr dre+j2ZwG dsdt dtevZxG dudv dve1j^ZyG dwdx dxe1j^Zzee+jtG dydz dzZ{G d{d| d|e1j^Z|G d}d~ d~eZ}ee}G dd dZ~G dd de1j^ZG dd de1j^ZdS )z
Tests for Perspective Broker module.

TODO: update protocol level tests to use new connection API, leaving
only specific tests for old API.
    N)deque)BytesIO)Dict)	Interfaceimplementer)checkerscredentialsportal)UnauthorizedLoginUnhandledCredentials)addressmainprotocolreactor)DeferredgatherResultssucceed)ConnectionRefusedError)WrappingFactory)failurelog)	iterbytes)jellypbpublishutil)_FakeConnector)unittestc                   @      e Zd Zdd ZdS )Dummyc                 C   s   t |trdS dS )Nzhello world!zgoodbye, cruel world!)
isinstanceDummyPerspectiveselfuser r%   =/usr/lib/python3/dist-packages/twisted/spread/test/test_pb.pyview_doNothing(   s   
zDummy.view_doNothingN)__name__
__module____qualname__r'   r%   r%   r%   r&   r   '       r   c                   @      e Zd ZdZdd ZdS )r!   zE
    An L{IPerspective} avatar which will be used in some tests.
    c                 C      t  S N)r   r#   r%   r%   r&   perspective_getDummyViewPoint4      z.DummyPerspective.perspective_getDummyViewPointN)r(   r)   r*   __doc__r0   r%   r%   r%   r&   r!   /       r!   c                   @   r   )
DummyRealmc                 G   s.   |D ]}|t ju r|t|dd f  S qd S )Nc                   S      d S r.   r%   r%   r%   r%   r&   <lambda>=       z*DummyRealm.requestAvatar.<locals>.<lambda>)r   IPerspectiver!   )r#   avatarIdmind
interfacesifacer%   r%   r&   requestAvatar:   s
   
zDummyRealm.requestAvatarN)r(   r)   r*   r=   r%   r%   r%   r&   r4   8   s    r4   c                   @   0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )IOPumpz
    Utility to pump data between clients and servers for protocol testing.

    Perhaps this is a utility worthy of being in protocol.py?
    c                 C   s   || _ || _|| _|| _d S r.   )clientserverclientIOserverIO)r#   r@   rA   rB   rC   r%   r%   r&   __init__G   s   
zIOPump.__init__c                 C   sN   d| _ t d }| j s!|  r#t |krdS | j s%|  sdS dS dS dS )z
        Pump until there is no more input or output or until L{stop} is called.
        This does not run any timers, so don't use it with any code that calls
        reactor.callLater.
        F   N)_stoptimepump)r#   timeoutr%   r%   r&   flushM   s   zIOPump.flushc                 C   
   d| _ dS )zd
        Stop a running L{flush} operation, even if data remains to be
        transferred.
        TN)rF   r/   r%   r%   r&   stopZ      
zIOPump.stopc                 C   s   | j d | jd | j  }| j }| j d | jd | j   | j  | jj  | jj  t	|D ]}| j
| q<t	|D ]}| j
| qI|sV|rXdS dS )zX
        Move data back and forth.

        Returns whether any data was moved.
        r      )rB   seekrC   readtruncater@   	transport_checkProducerrA   r   dataReceived)r#   cDatasDatabyter%   r%   r&   rH   a   s"   



zIOPump.pumpN)r(   r)   r*   r2   rD   rJ   rL   rH   r%   r%   r%   r&   r?   @   s    r?   c                    s   d}  |}| |}t }t }|t| |t| t||||}dd }	 fdd}
| |	| | |	| | |
 |  |||fS )al  
    Create a server and a client and connect the two with an
    L{IOPump}.

    @param test: the test case where the client and server will be
        used.
    @type test: L{twisted.trial.unittest.TestCase}

    @param clientFactory: The factory that creates the client object.
    @type clientFactory: L{twisted.spread.pb.PBClientFactory}

    @param serverFactory: The factory that creates the server object.
    @type serverFactory: L{twisted.spread.pb.PBServerFactory}

    @return: a 3-tuple of (client, server, pump)
    @rtype: (L{twisted.spread.pb.Broker}, L{twisted.spread.pb.Broker},
        L{IOPump})
    )	127.0.0.1c                 S   s    | j s| ttj d S d S r.   )disconnectedconnectionLostr   Failurer   CONNECTION_DONE)brokerr%   r%   r&   maybeDisconnect   s   z/connectServerAndClient.<locals>.maybeDisconnectc                      s    j d ttjd d S )N)	connectorreason)clientConnectionLostr   r[   r   r\   r%   clientFactoryr%   r&   disconnectClientFactory   s   
z7connectServerAndClient.<locals>.disconnectClientFactory)buildProtocolStringIOmakeConnectionr   FileWrapperr?   
addCleanuprH   )testrc   serverFactoryaddrclientBrokerserverBrokerclientTransportserverTransportrH   r^   rd   r%   rb   r&   connectServerAndClient{   s   

	

rq   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	_ReconnectingFakeConnectorStatez
    Manages connection notifications for a
    L{_ReconnectingFakeConnector} instance.

    @ivar notifications: pending L{Deferreds} that will fire when the
        L{_ReconnectingFakeConnector}'s connect method is called
    c                 C      t  | _d S r.   )r   notificationsr/   r%   r%   r&   rD         z(_ReconnectingFakeConnectorState.__init__c                 C   s   t  }| j| |S )z
        Connection notification.

        @return: A L{Deferred} that fires when this instance's
            L{twisted.internet.interfaces.IConnector.connect} method
            is called.
        @rtype: L{Deferred}
        )r   rt   
appendleft)r#   notifierr%   r%   r&   notifyOnConnect   s   	z/_ReconnectingFakeConnectorState.notifyOnConnectc                 C   s$   | j r| j  |  | j sdS dS )z1
        Fire all pending notifications.
        N)rt   popcallbackr/   r%   r%   r&   	notifyAll   s   z)_ReconnectingFakeConnectorState.notifyAllN)r(   r)   r*   r2   rD   rx   r{   r%   r%   r%   r&   rr      s
    rr   c                       s,   e Zd ZdZ fddZ fddZ  ZS )_ReconnectingFakeConnectorzc
    A fake L{IConnector} that can fire L{Deferred}s when its
    C{connect} method is called.
    c                    s   t  | || _dS )a  
        @param address: An L{IAddress} provider that represents this
            connector's destination.
        @type address: An L{IAddress} provider.

        @param state: The state instance
        @type state: L{_ReconnectingFakeConnectorState}
        N)superrD   _state)r#   r   state	__class__r%   r&   rD      s   	
z#_ReconnectingFakeConnector.__init__c                    s   t    | j  dS )zM
        A C{connect} implementation that calls C{reconnectCallback}
        N)r}   connectr~   r{   r/   r   r%   r&   r      s   
z"_ReconnectingFakeConnector.connect)r(   r)   r*   r2   rD   r   __classcell__r%   r%   r   r&   r|      s    r|   c                 C   s>   |pt  }tjdd}tt||g}t }t| ||S )z
    Connect a client and server L{Broker} together with an L{IOPump}

    @param realm: realm to use, defaulting to a L{DummyRealm}

    @returns: a 3-tuple (client, server, pump).
       guest)guest)	r4   r   'InMemoryUsernamePasswordDatabaseDontUser   PBServerFactoryr	   PortalPBClientFactoryrq   )rj   realmcheckerrk   rc   r%   r%   r&   connectedServerAndClient   s
   
r   c                   @      e Zd Zdd Zdd ZdS )SimpleRemotec                 C      || _ |d S NrN   )argr#   r   r%   r%   r&   remote_thunk      zSimpleRemote.remote_thunkc                 C      t  r.   )	Exceptionr   r%   r%   r&   remote_knuth   r1   zSimpleRemote.remote_knuthN)r(   r)   r*   r   r   r%   r%   r%   r&   r      s    r   c                   @   r   )NestedRemotec                 C   r-   r.   )r   r/   r%   r%   r&   remote_getSimple  r1   zNestedRemote.remote_getSimpleN)r(   r)   r*   r   r%   r%   r%   r&   r     r+   r   c                   @   r   )
SimpleCopyc                 C      d| _ ddi| _dg| _d S NrN   HelloWorldrj   xyzr/   r%   r%   r&   rD        
zSimpleCopy.__init__Nr(   r)   r*   rD   r%   r%   r%   r&   r     r+   r   c                   @      e Zd ZdS )SimpleLocalCopyNr(   r)   r*   r%   r%   r%   r&   r         r   c                   @   s.   e Zd ZU dZi Zeed f ed< dd ZdS )SimpleFactoryCopyz]
    @cvar allIDs: hold every created instances of this class.
    @type allIDs: C{dict}
    allIDsc                 C   s   || _ | tj|< d S r.   )idr   r   )r#   r   r%   r%   r&   rD     s   zSimpleFactoryCopy.__init__N)	r(   r)   r*   r2   r   r   int__annotations__rD   r%   r%   r%   r&   r     s   
 r   c                 C   sZ   |  dd}|du rtdt|  |tjvr tdtj tj| }|s+td|S )zl
    Factory of L{SimpleFactoryCopy}, getting a created instance given the
    C{id} found in C{state}.
    r   Nz&factory copy state has no 'id' member zfactory class has no ID: z&factory method found no object with id)getRuntimeErrorreprr   r   )r   stateIdinstr%   r%   r&   createFactoryCopy!  s   

r   c                   @   r   )
NestedCopyc                 C   r-   r.   )r   r/   r%   r%   r&   remote_getCopy5  r1   zNestedCopy.remote_getCopyc                 C   s   t |S r.   )r   )r#   valuer%   r%   r&   remote_getFactory8     zNestedCopy.remote_getFactoryN)r(   r)   r*   r   r   r%   r%   r%   r&   r   4      r   c                   @   r   )SimpleCachec                 C   r   r   r   r/   r%   r%   r&   	__init___=  r   zSimpleCache.__init___N)r(   r)   r*   r   r%   r%   r%   r&   r   <  r+   r   c                   @   r   )NestedComplicatedCachec                 C   rs   r.   )VeryVeryComplicatedCacheablecr/   r%   r%   r&   rD   D  ru   zNestedComplicatedCache.__init__c                 C      | j S r.   )r   r/   r%   r%   r&   remote_getCacheG  r1   z&NestedComplicatedCache.remote_getCacheN)r(   r)   r*   rD   r   r%   r%   r%   r&   r   C  r   r   c                   @   ,   e Zd Zdd Zdd Zdd Zdd Zd	S )
r   c                 C   s   d| _ d| _d| _d S )NrN         r   r   foor/   r%   r%   r&   rD   L  s   
z%VeryVeryComplicatedCacheable.__init__c                 C   s   d| _ | jdd d S )N   r   )r   observer
callRemoter/   r%   r%   r&   setFoo4Q     z$VeryVeryComplicatedCacheable.setFoo4c                 C   s   || _ | j| j| jdS )Nr   )r   r   r   r   r#   perspectiver   r%   r%   r&   getStateToCacheAndObserveForU  r   z9VeryVeryComplicatedCacheable.getStateToCacheAndObserveForc                 C   s,   t d |d || jkrd | _d S d S )Nzstopped observingend)r   msgr   r   r   r%   r%   r&   stoppedObservingY  s
   



z-VeryVeryComplicatedCacheable.stoppedObservingN)r(   r)   r*   rD   r   r   r   r%   r%   r%   r&   r   K  s
    r   c                   @   r   )RatherBaroqueCachec                 C   
   || _ d S r.   r   )r#   newFoor%   r%   r&   observe_fooa     
zRatherBaroqueCache.observe_fooc                 C   s   t d d S )Nzthe end of things)r   r   r/   r%   r%   r&   observe_endd     zRatherBaroqueCache.observe_endN)r(   r)   r*   r   r   r%   r%   r%   r&   r   `  r   r   c                   @   r   )
SimpleLocalCachec                 C      | j | d S r.   )__dict__update)r#   r   r%   r%   r&   setCopyableStatel     z!SimpleLocalCache.setCopyableStatec                 C   r   r.   )checkr/   r%   r%   r&   checkMethodo  r1   zSimpleLocalCache.checkMethodc                 C   s   | S r.   r%   r/   r%   r%   r&   	checkSelfr     zSimpleLocalCache.checkSelfc                 C      dS r   r%   r/   r%   r%   r&   r   u  r   zSimpleLocalCache.checkN)r(   r)   r*   r   r   r   r   r%   r%   r%   r&   r   k  
    r   c                   @   $   e Zd Zdd Zdd Zdd ZdS )NestedCachec                 C   rs   r.   )r   r   r/   r%   r%   r&   rD   }  ru   zNestedCache.__init__c                 C   s   | j | j gS r.   r   r/   r%   r%   r&   r     ru   zNestedCache.remote_getCachec                 C   s
   | j |u S r.   r   r#   cacher%   r%   r&   remote_putCache  r   zNestedCache.remote_putCacheN)r(   r)   r*   rD   r   r   r%   r%   r%   r&   r   |  s    r   c                   @   r   )

Observablec                 C   s
   g | _ d S r.   )	observersr/   r%   r%   r&   rD     r   zObservable.__init__c                 C   r   r.   )r   appendr#   obsr%   r%   r&   remote_observe  r   zObservable.remote_observec                 C   r   r.   )r   remover   r%   r%   r&   remote_unobserve  r   zObservable.remote_unobservec                 C   s   | j D ]	}|d| | qd S )Nnotify)r   r   )r#   objr   r%   r%   r&   r     s   
zObservable.notifyN)r(   r)   r*   rD   r   r   r   r%   r%   r%   r&   r     r   r   c                   @   r   )
DeferredRemotec                 C   
   d| _ d S )Nr   runr/   r%   r%   r&   rD     r   zDeferredRemote.__init__c                 C   r   r   r   r   r%   r%   r&   runMe  r   zDeferredRemote.runMec                 C   s   J d)Nr   zshouldn't have been run!r%   r   r%   r%   r&   	dontRunMe  r   zDeferredRemote.dontRunMec                 C   s    t  }|| j| j || _|S )zo
        Return a L{Deferred} to be fired on client side. When fired,
        C{self.runMe} is called.
        )r   addCallbacksr   r   d)r#   r   r%   r%   r&   remote_doItLater  s   zDeferredRemote.remote_doItLaterN)r(   r)   r*   rD   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 )Observerr   Nc                 C   s"   || _ | jd | _|d|  d S )NrN   	unobserve)r   notifiedr   )r#   otherr   r%   r%   r&   remote_notify  s   zObserver.remote_notify)r(   r)   r*   r   r   r  r%   r%   r%   r&   r     s    r   c                   @   r   )NewStyleCopyc                 C   r   r.   )s)r#   r  r%   r%   r&   rD     r   zNewStyleCopy.__init__Nr   r%   r%   r%   r&   r    r+   r  c                   @   s(   e Zd ZdZdZdZdd Zdd ZdS )NewStyleCopy2r   rN   c                 C   s"   t  jd7  _t| }d|_|S )NrN   r   )r  	allocatedobject__new__r   )r#   r   r%   r%   r&   r    s   
zNewStyleCopy2.__new__c                 C   s   t  jd7  _d S r   )r  initializedr/   r%   r%   r&   rD     s   zNewStyleCopy2.__init__N)r(   r)   r*   r  r	  r   r  rD   r%   r%   r%   r&   r    s    r  c                   @   r   )NewStyleCacheCopyc                 C   r   r.   )r   r   r%   r%   r&   r     r1   z.NewStyleCacheCopy.getStateToCacheAndObserveForN)r(   r)   r*   r   r%   r%   r%   r&   r
    r+   r
  c                   @   r   )Echoerc                 C   s   |S r.   r%   r#   str%   r%   r&   remote_echo  r   zEchoer.remote_echoc                 K   s   ||fS r.   r%   )r#   r  kwr%   r%   r&   remote_echoWithKeywords  r   zEchoer.remote_echoWithKeywordsN)r(   r)   r*   r  r  r%   r%   r%   r&   r    r   r  c                   @   r   )CachedReturnerc                 C   r   r.   r   r   r%   r%   r&   rD     r   zCachedReturner.__init__c                 C   r   r.   r  r  r%   r%   r&   remote_giveMeCache  r1   z!CachedReturner.remote_giveMeCacheN)r(   r)   r*   rD   r  r%   r%   r%   r&   r    r   r  c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )NewStyleTestsc                 C   sD   t t | _t  }t| || jd\}| _| _| |	 | _
dS )zY
        Create a pb server using L{Echoer} protocol and connect a client to it.
        )rj   rc   rk   N)r   r   r  rk   r   rq   rA   rH   successResultOfgetRootObjectref)r#   rc   r@   r%   r%   r&   setUp  s   zNewStyleTests.setUpc                 C   s   dt _dt _dt _dS )zp
        Close client and server connections, reset values of L{NewStyleCopy2}
        class variables.
        r   rN   N)r  r  r	  r   r/   r%   r%   r&   tearDown  s   
zNewStyleTests.tearDownc                    s<   t d jd }j   fdd}|| |S )zY
        Create a new style object, send it over the wire, and check the result.
        r   echoc                    s,    | t | jd |  u  d S )Nr   )assertIsInstancer  assertEqualr  assertFalseresorigr#   r%   r&   cb  s   z'NewStyleTests.test_newStyle.<locals>.cbr  r  r   rH   rJ   addCallbackr#   r   r"  r%   r   r&   test_newStyle  s   

zNewStyleTests.test_newStylec                    sV   t   t jd t jd jd }j   fdd}|| |S )zN
        Send a new style object and check the number of allocations.
        rN   r  c                    sF    | t | jd tjd tjd |   d S )Nr   r   rN   )r  r  r  r   r  r	  assertIsNotr  r   r%   r&   r"    s
   z$NewStyleTests.test_alloc.<locals>.cb)	r  r  r  r	  r  r   rH   rJ   r$  r%  r%   r   r&   
test_alloc  s   

	zNewStyleTests.test_allocc                    sB   t d jjd ddd}j   fdd}|| |S )zo
        Create a new style object with keywords,
        send it over the wire, and check the result.
        value1echoWithKeywordsonetwokeyword1keyword2c                    sh    | t  | d t  | d t | d jd | d   | d ddd d S )Nr   rN   r)  r+  r,  r-  )r  tupler  dictr  r  r'  r  r   r%   r&   r"  .  s   z3NewStyleTests.test_newStyleWithKeywords.<locals>.cbr#  r%  r%   r   r&   test_newStyleWithKeywords#  s   

z'NewStyleTests.test_newStyleWithKeywordsN)r(   r)   r*   r  r  r&  r(  r2  r%   r%   r%   r&   r    s    	r  c                   @   s$   e Zd ZdZdZdd Zdd ZdS )ConnectionNotifyServerFactoryaj  
    A server factory which stores the last connection and fires a
    L{Deferred} on connection made. This factory can handle only one
    client connection.

    @ivar protocolInstance: the last protocol instance.
    @type protocolInstance: C{pb.Broker}

    @ivar connectionMade: the deferred fired upon connection.
    @type connectionMade: C{Deferred}
    Nc                 C   s   t j| | t | _dS )z)
        Initialize the factory.
        N)r   r   rD   r   connectionMade)r#   rootr%   r%   r&   rD   I  s   z&ConnectionNotifyServerFactory.__init__c                 C   s.   || _ | jd}| _|dur|d dS dS )zF
        Store the protocol and fire the connection deferred.
        N)protocolInstancer4  rz   )r#   r   r   r%   r%   r&   clientConnectionMadeP  s
   z2ConnectionNotifyServerFactory.clientConnectionMade)r(   r)   r*   r2   r6  rD   r7  r%   r%   r%   r&   r3  :  s
    r3  c                   @   r   )NewStyleCachedTestsc                    sv   t   _d j_tdtt j _t	 }t
d j j|  fdd}| |} jjj}t||gS )zi
        Create a pb server using L{CachedReturner} protocol and connect a
        client to it.
        r   r   	localhostc                    s
   |  _ d S r.   r  r:  r/   r%   r&   gotRooth  r   z*NewStyleCachedTests.setUp.<locals>.gotRoot)r
  r!  r  r   	listenTCPr3  r  rA   r   r   
connectTCPgetHostportr  r$  factoryr4  r   )r#   rc   r;  d1d2r%   r/   r&   r  [  s   
zNewStyleCachedTests.setUpc                 C   s(   | j jjj  | jjj  | j  S )z6
        Close client and server connections.
        )rA   r@  r6  rR   loseConnectionr  r]   stopListeningr/   r%   r%   r&   r  o  s   
zNewStyleCachedTests.tearDownc                    s8    j d j} fdd}||d ||d |S )z
        A new-style cacheable object can be retrieved and re-retrieved over a
        single connection.  The value of an attribute of the cacheable can be
        accessed on the receiving side.
        giveMeCachec                    sF     | t  d| j   j|  |r!|  _ jd jS d S )Nr   rE  )	r  r
  r  r  r'  r!  r  r  r   )r  againr/   r%   r&   r"    s   z2NewStyleCachedTests.test_newStyleCache.<locals>.cbTF)r  r   r!  r$  r%  r%   r/   r&   test_newStyleCachew  s
   z&NewStyleCachedTests.test_newStyleCacheN)r(   r)   r*   r  r  rG  r%   r%   r%   r&   r8  Z  s    r8  c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# ZdS )$BrokerTestsNc                 C   s&   zt d W d S  ty   Y d S w )NNone-None-TESTING.pub)osunlinkOSErrorr/   r%   r%   r&   r    s
   zBrokerTests.tearDownc                 C      |  d|  d S )Nz&This should cause a return value, not fail)r#   errorr%   r%   r&   thunkErrorBad     zBrokerTests.thunkErrorBadc                 C   r   r.   )thunkResultr#   resultr%   r%   r&   thunkResultGood  r   zBrokerTests.thunkResultGoodc                 C   r5   r.   r%   )r#   tbr%   r%   r&   thunkErrorGood  r   zBrokerTests.thunkErrorGoodc                 C   rM  )Nz This should cause an error, not rN  rT  r%   r%   r&   thunkResultBad  rR  zBrokerTests.thunkResultBadc           	      C   s   t | d\}}}G dd dtj}G dd dtj}|d|  |d}| }| }|d|| |  |  |  | |j|d | 	|
d|
d d S )	Nrj   c                   @   r   )z%BrokerTests.test_reference.<locals>.Xc                 S   r   r.   )caughtr   r%   r%   r&   remote_catch  r   z2BrokerTests.test_reference.<locals>.X.remote_catchN)r(   r)   r*   r\  r%   r%   r%   r&   X  r+   r]  c                   @   r   )z%BrokerTests.test_reference.<locals>.Yc                 S   s   | d| d S )Ncatchr   r#   abr%   r%   r&   remote_throw  r   z2BrokerTests.test_reference.<locals>.Y.remote_throwN)r(   r)   r*   rc  r%   r%   r%   r&   Y  r+   rd  r   throwzX should have caught Z)r   r   ReferenceablesetNameForLocalremoteForNamer   rH   assertIsr[  r  remoteMethod)	r#   r   r  rH   r]  rd  r   r   r   r%   r%   r&   test_reference  s   
zBrokerTests.test_referencec                 C   s   t | d\}}}||f||ffD ]5\}}t }|d| |d}d| _|d| jd | j| j |	  |	  | 
| j| jd qd S )NrZ  r      thunkrN   zresult wasn't received.)r   r   rg  rh  expectedThunkResultr   r   rV  rQ  rH   r  rS  )r#   r   r  rH   r   r   r   barr%   r%   r&   test_result  s   

zBrokerTests.test_resultc                 C   r   r.   )nestedRemoterT  r%   r%   r&   refcountResult  r   zBrokerTests.refcountResultc           
   	   C   s   g }g }t | d\}}}t }|d| |d}ttjd D ]}|jjs+|jjr- n|	d
|j|j |  q!tjd }	| |jjd | t||	d|	 dt|  d S )	NrZ  r   
   	getSimplerN   ztransport was not closedz	expected z got )r   r   rg  rh  ranger   MAX_BROKER_REFSrR   closedr   r   r   rH   
assertTruer  len)
r#   ler   r  rH   r   r   ignoexpectedr%   r%   r&   test_tooManyRefs  s   


&zBrokerTests.test_tooManyRefsc                 C   s   t | d\}}}t }|d| |d}|d| j| j |  |  | 	| j
jd | 	| j
jd d | 	| j
jd d d S )	NrZ  r   getCopyrN   r   r   r   rj   )r   r   rg  rh  r   r   rV  rQ  rH   r  rS  r   r   r   )r#   r   r  rH   r   r   r%   r%   r&   	test_copy  s   
zBrokerTests.test_copyc                 C   s   t | d\}}}t }t }|d| |d}|d| |  |d |  |  |d |  |  | |j	d | 
|j	dd d S )NrZ  ra  observerN   rs  zdidn't notifyznotified too much)r   r   r   rg  rh  r   rH   r   assertIsNotNoner   r  )r#   r   r  rH   ra  rb  rar%   r%   r&   test_observe  s   


zBrokerTests.test_observec                 C   s   t | d\}}}t }|d| |d}|  |  g }|d|j |  |  | |j	d |j
d | |j	dd |  |  | |d dd	 d S )
NrZ  r   	doItLaterzDeferred method run too early.rE   zDeferred method run too late.r      zIncorrect result.)r   r   rg  rh  rH   r   r$  r   r  r   r   rz   r  )r#   r   r  rH   r   r{  resultsr%   r%   r&   
test_defer  s    
zBrokerTests.test_deferc                 C   s   t | d\}}}t }|d| |d}|d| j| j |  |  | j	j
}| ||j | `	tjdkr?t  |  |  |  | ||j d S )NrZ  r   rt     )r   r   rg  rh  r   r   rr  rQ  rH   rq  luidassertInlocalObjectssys
hexversiongccollectassertNotIn)r#   r   r  rH   r   ro  rluidr%   r%   r&   test_refcount  s$   


zBrokerTests.test_refcountc                 C   s:  t | d\}}}t }t }|j}|d| |d| |d}|d}g }	|d|	j	|	j |d|	j	|	j g }
|d|
j |d|
j |
  | |
d jd | |
d jd | |
d jd |  |
  | |
d jd	 | t|	d |	d d }| | j|d
 | | |d g }|d||j |
  | |d  | |d|d |j}|
d j}| ||jd ~	~|
  ~
~|
  tjdkrt  |
  | ||jd | ||jd | ||jd | ||jd |  |j!d d S )NrZ  r   xxxgetCacher   rN   r   r   r   zpotential refcounting issuez!other potential refcounting issueputCachezremote cache doesn't have itr  zServer still had it after GCzClient still had it after GCz!Server still had complex after GCz!Client still had complex after GCzobserver was not removed)"r   r   r   r   rg  rh  r   r$  r   
addErrbackrJ   r  r   r   r   r   ry  assertIdenticalr   __self__r   rx  rj  r  r  remotelyCachedObjectsr  r  r  r  r  locallyCachedObjectsassertIsNoner   )r#   r   r  rH   r   obj2vcco2o3collcomplexcpcol2r  baroqueLuidr%   r%   r&   
test_cache4  sj   



zBrokerTests.test_cachec                 C   s  zt d W n	 ty   Y nw t| d\}}}t }|d| |d}g }|d|j	| j
 |  | }| |jd | |jd | |jd | |jd t| d\}}}|d| |d}|d|j	| j
 |  | }| |jd d S )NrI  rZ  r   getPubrN   r   )rJ  rK  rL  r   GetPublisherrg  rh  r   r   r   rQ  rJ   ry   r  activateCalledisActivatedyayIGotPublished_wasCleanWhenLoaded)r#   r   r  rH   r   ro  accumr   r%   r%   r&   test_publishablev  s0   

zBrokerTests.test_publishablec                 C   s   |j | _d S r.   )r   rS  )r#   valr%   r%   r&   gotCopy  ru   zBrokerTests.gotCopyc                 C   s|   t | d\}}}d}t }|d| |d}|d|| j| j |  |  |  | 	| j
|d| j
  d S )NrZ  c   r   
getFactoryz!ID not correct on factory object )r   r   rg  rh  r   r   r  rY  rH   r  rS  )r#   r   r  rH   IDr   r   r%   r%   r&   test_factoryCopy  s   

zBrokerTests.test_factoryCopy)r(   r)   r*   rS  r  rQ  rV  rX  rY  rk  rp  rr  r~  r  r  r  r  r  r  r  r  r%   r%   r%   r&   rH    s&    BrH  s  helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldc                  O   s   | a |ad S r.   )callbackArgscallbackKeyword)argsr  r%   r%   r&   finishedCallback  s   r  c                   @   r   )	Pagerizerc                 O   s   |||| _ | _| _d S r.   )rz   r  r  )r#   rz   r  r  r%   r%   r&   rD     s   zPagerizer.__init__c                 C   s4   t j|td| jg| jR i | j d  | _| _d S )Nd   )r   StringPager	bigStringrz   r  r  r#   	collectorr%   r%   r&   remote_getPages  s   
zPagerizer.remote_getPagesN)r(   r)   r*   rD   r  r%   r%   r%   r&   r    r   r  c                   @   s    e Zd ZdZdd Zdd ZdS )FilePagerizerNc                 O   s    || _ |||| _| _| _d S r.   )filenamerz   r  r  )r#   r  rz   r  r  r%   r%   r&   rD     s   zFilePagerizer.__init__c                 C   s<   t j|t| jd| jg| jR i | j| _d  | _| _d S )Nrb)r   	FilePageropenr  rz   r  r  pagerr  r%   r%   r&   r    s   zFilePagerizer.remote_getPages)r(   r)   r*   r  rD   r  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S )PagingTestsz0
    Test pb objects sending data by pages.
    c                 C   sF   |   | _t| jd}|t W d   dS 1 sw   Y  dS )z?
        Create a file used to test L{util.FilePager}.
        wbN)mktempr  r  writer  )r#   fr%   r%   r&   r    s   
"zPagingTests.setUpc                 C   s   t | d\}}}|dttddd |d}g }t|d|j |s,|	  |r&| 
d|d td	 | 
td
d | 
tddid dS )zg
        Test L{util.StringPager}, passing a callback to fire when all pages
        are sent.
        rZ  r   hellors  r   getPages    r   'Pages received not equal to pages sent!)r  Completed callback not invokedr   N)r   rg  r  r  rh  r   getAllPagesr$  r   rH   r  joinr  r  r  r#   r   r  rH   r   rz  r%   r%   r&   test_pagingWithCallback  s   

z#PagingTests.test_pagingWithCallbackc                 C   sn   t | d\}}}|dtd |d}g }t|d|j |s)|  |r#| 	d
|d td dS )z>
        Test L{util.StringPager} without a callback.
        rZ  r   Nr  r  r   r  )r   rg  r  rh  r   r  r$  r   rH   r  r  r  r  r%   r%   r&   test_pagingWithoutCallback  s   
z&PagingTests.test_pagingWithoutCallbackc           	      C   s   |   }t|d  t| d\}}}t|d}|d| |d}g }t|d	|j
 d}|sE|dkrE|  |d8 }|sE|dks7|sL| d	 | d
|d d
d dS )z@
        Test L{util.FilePager}, sending an empty file.
        wrZ  Nro  r  rs  r   rN   zgetAllPages timed outr  r  )r  r  closer   r  rg  rh  r   r  r$  r   rH   rO  r  r  )	r#   filenameEmptyr   r  rH   	pagerizerr   rz  ttlr%   r%   r&   test_emptyFilePaging  s    


z PagingTests.test_emptyFilePagingc                 C   s   t | d\}}}t| jtddd}|d| |d}g }t|d|j	 |s0|
  |r*| d|d td	 | td
d | tddid | |jjg  dS )z
        Test L{util.FilePager}, passing a callback to fire when all pages
        are sent, and verify that the pager doesn't keep chunks in memory.
        rZ  frodo	   r  ro  r  r  r   r  )r  r  r   N)r   r  r  r  rg  rh  r   r  r$  r   rH   r  r  r  r  r  r  chunksr#   r   r  rH   r  r   rz  r%   r%   r&   test_filePagingWithCallback  s"   

z'PagingTests.test_filePagingWithCallbackc                 C   s   t | d\}}}t| jd}|d| |d}g }t|d|j |s-|	  |r'| 
d|d td | 
|jjg  dS )z<
        Test L{util.FilePager} without a callback.
        rZ  Nro  r  r  r   r  )r   r  r  rg  rh  r   r  r$  r   rH   r  r  r  r  r  r  r%   r%   r&   test_filePagingWithoutCallback%  s   
z*PagingTests.test_filePagingWithoutCallbackN)
r(   r)   r*   r2   r  r  r  r  r  r  r%   r%   r%   r&   r    s    r  c                   @   r   )DumbPublishablec                 C   s   ddiS )Nr  rN   r%   r/   r%   r%   r&   getStateToPublish8  r   z!DumbPublishable.getStateToPublishN)r(   r)   r*   r  r%   r%   r%   r&   r  7  r+   r  c                   @   r   )DumbPubc                 C   r   r   )r  r/   r%   r%   r&   	activated=  r   zDumbPub.activatedN)r(   r)   r*   r  r%   r%   r%   r&   r  <  r+   r  c                   @   r   )r  c                 C   s   t d| _d S )NTESTING)r  pubr/   r%   r%   r&   rD   B  r   zGetPublisher.__init__c                 C   r   r.   )r  r/   r%   r%   r&   remote_getPubE  r1   zGetPublisher.remote_getPubN)r(   r)   r*   rD   r  r%   r%   r%   r&   r  A  r   r  c                   @   8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )DisconnectionTestsz'
    Test disconnection callbacks.
    c                 G   s   t d| )NzI shouldn't have been called: r   )r#   r  r%   r%   r&   rP  Q  r   zDisconnectionTests.errorc                 C   rK   )z.
        Called on broker disconnect.
        rN   N)gotCallbackr/   r%   r%   r&   gotDisconnectedT     
z"DisconnectionTests.gotDisconnectedc                 C   s   |  || j d| _dS )z7
        Called on RemoteReference disconnect.
        rN   N)r  remoteObjectobjectCallbackr#   or%   r%   r&   objectDisconnectedZ  s   
z%DisconnectionTests.objectDisconnectedc                 C   sf   t | d\}}}|  |dt  |d}g }|dt |j |	  | 
t|d d S )NrZ  r  
setBadCopyrN   )r   rH   rg  
BadCopySetrh  r   BadCopyabler  r   rJ   r  ry  )r#   r   r  rH   grz  r%   r%   r&   test_badSerializationa  s   
z(DisconnectionTests.test_badSerializationc                 C   s$  t | d\}}}|  |dt  |d}|  |  |  || j | | j|j |	| j | 
| j|j || j | |j|j | | j|j |	| j | 
|j|j | 
| j|j || j || j || _|ttj | | j | | j d S )NrZ  r  )r   rH   rg  r   rh  notifyOnDisconnectrP  r  disconnectsdontNotifyOnDisconnectr  _disconnecteddisconnectCallbacksr  r  r  rZ   r   r[   r   r\   rx  r  r  )r#   r   r  rH   rr%   r%   r&   test_disconnectionk  s.   
z%DisconnectionTests.test_disconnectionN)	r(   r)   r*   r2   rP  r  r  r  r  r%   r%   r%   r&   r  L  s    
r  c                   @   r   )FreakOutNr   r%   r%   r%   r&   r     r   r   c                   @   r   )r  c                 C   r   r.   )r   )r#   pr%   r%   r&   getStateToCopyFor  r1   zBadCopyable.getStateToCopyForN)r(   r)   r*   r  r%   r%   r%   r&   r    r+   r  c                   @   r   )r  c                 C   r5   r.   r%   )r#   bcr%   r%   r&   remote_setBadCopy  r   zBadCopySet.remote_setBadCopyN)r(   r)   r*   r  r%   r%   r%   r&   r    r+   r  c                   @   s*   e Zd ZdZdd Zd
ddZdd Zd	S )LocalRemoteTestr   c                 C   s   |d S r   r%   )r#   r   r%   r%   r&   	sync_add1  r   zLocalRemoteTest.sync_add1rN   c                 C      || S r.   r%   )r#   r   r   r%   r%   r&   	async_add  r   zLocalRemoteTest.async_addc                 C   r   r.   r  r/   r%   r%   r&   
async_fail  r1   zLocalRemoteTest.async_failN)r   rN   )r(   r)   r*   reportAllTracebacksr  r  r	  r%   r%   r%   r&   r    s
    
r  c                   @   s@   e Zd ZdZd ZZdd Zdd Zdd Zd	d
 Z	dd Z
dS )MyPerspectivez
    @ivar loggedIn: set to C{True} when the avatar is logged in.
    @type loggedIn: C{bool}

    @ivar loggedOut: set to C{True} when the avatar is logged out.
    @type loggedOut: C{bool}
    Fc                 C   r   r.   r9   r#   r9   r%   r%   r&   rD     r   zMyPerspective.__init__c                 C   r   )zT
        Return the avatar identifier which was used to access this avatar.
        r  r/   r%   r%   r&   perspective_getAvatarId  s   z%MyPerspective.perspective_getAvatarIdc                 C   r-   r.   )MyViewr/   r%   r%   r&   perspective_getViewPoint  r1   z&MyPerspective.perspective_getViewPointc                 C   r  )z
        Add the given objects and return the result.  This is a method
        unavailable on L{Echoer}, so it can only be invoked by authenticated
        users who received their avatar from L{TestRealm}.
        r%   r`  r%   r%   r&   perspective_add  s   zMyPerspective.perspective_addc                 C   r   NT	loggedOutr/   r%   r%   r&   logout  r   zMyPerspective.logoutN)r(   r)   r*   r2   loggedInr  rD   r  r  r  r  r%   r%   r%   r&   r    s    r  c                   @   s    e Zd ZdZeZdZdd ZdS )	TestRealma  
    A realm which repeatedly gives out a single instance of L{MyPerspective}
    for non-anonymous logins and which gives out a new instance of L{Echoer}
    for each anonymous login.

    @ivar lastPerspective: The L{MyPerspective} most recently created and
        returned from C{requestAvatar}.

    @ivar perspectiveFactory: A one-argument callable which will be used to
        create avatars to be returned from C{requestAvatar}.
    Nc                 C   s\   |t jksJ |dksJ |tju rt jt dd fS | || _d| j_t j| j| jjfS )z
        Verify that the mind and interface supplied have the expected values
        (this should really be done somewhere else, like inside a test method)
        and return an avatar appropriate for the given identifier.
        BRAINS!c                   S   r5   r.   r%   r%   r%   r%   r&   r6     r7   z)TestRealm.requestAvatar.<locals>.<lambda>T)	r   r8   r   	ANONYMOUSr  perspectiveFactorylastPerspectiver  r  r#   r9   r:   	interfacer%   r%   r&   r=     s   
zTestRealm.requestAvatar)r(   r)   r*   r2   r  r  r  r=   r%   r%   r%   r&   r    s
    r  c                   @   r   )r  c                 C   s
   t |tS r.   )r    r  r"   r%   r%   r&   
view_check  r   zMyView.view_checkN)r(   r)   r*   r  r%   r%   r%   r&   r    r+   r  c                   @       e Zd ZdZdd Zdd ZdS )
LeakyRealmz]
    A realm which hangs onto a reference to the mind object in its logout
    function.
    c                 C   s
   || _ dS )z
        Create a L{LeakyRealm}.

        @param mindEater: a callable that will be called with the C{mind}
        object when it is available
        N)
_mindEater)r#   	mindEaterr%   r%   r&   rD     s   
zLeakyRealm.__init__c                    s*   |    | |tj fddfS )Nc                      s      fS r.   )r  r%   r:   perspr%   r&   r6     s    z*LeakyRealm.requestAvatar.<locals>.<lambda>)r!  r  r   r8   r  r%   r#  r&   r=     s   

zLeakyRealm.requestAvatarN)r(   r)   r*   r2   rD   r=   r%   r%   r%   r&   r     s    	r   c                   @   r,   )NewCredLeakTestsz/
    Tests to try to trigger memory leaks.
    c                    s   d_ fdd}tt|d\}g  |d}|dd}dd	 }||  fd
d}||    dg t	  
   dS )z
        The server does not leak a reference when the client disconnects
        suddenly, even if the cred logout function forms a reference cycle with
        the perspective.
        Nc                    s   t |  _d S r.   )weakrefr  mindRef)r:   r/   r%   r&   
setMindRef  r   z4NewCredLeakTests.test_logoutLeak.<locals>.setMindRef)rj   r   r5  loginr   c                 S   s$   | \}}t  }|dt|d|S )Nrespondr   )r   r   r   r*  )r   	challenge
challengerr:   r%   r%   r&   
cbResponse$  s
   z4NewCredLeakTests.test_logoutLeak.<locals>.cbResponsec                    s*       d ttd d S )NrN   boom)rL   r   rZ   r   r[   r   )_)connectionBrokenrH   rn   r%   r&   rZ   -  s   
z8NewCredLeakTests.test_logoutLeak.<locals>.connectionLostrN   )r'  r   r   rh  r   r$  rJ   r  r  r  r  )r#   r(  rm   r5  r   r-  rZ   r%   )r0  rH   r#   rn   r&   test_logoutLeak  s    


z NewCredLeakTests.test_logoutLeakN)r(   r)   r*   r2   r1  r%   r%   r%   r&   r%  	  r3   r%  c                   @   s   e Zd ZdZdd Zd%ddZeej	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d!d" Zd#d$ ZdS )&NewCredTestsz=
    Tests related to the L{twisted.cred} support in PB.
    c                 C   s0   t  | _t| j| _t| j| _t | _dS )z
        Create a portal with no checkers and wrap it around a simple test
        realm.  Set up a PB server on a TCP port which serves perspectives
        using that portal.
        N)	r  r   r	   r   r3  rk   r   r   rc   r/   r%   r%   r&   r  D  s   zNewCredTests.setUpNc                 C   sR   t | | j| j\| _| _| _t | _tt	
ddd| j| _| j | j dS )a  
        Connect a client obtained from C{clientFactory} and a server
        obtained from the current server factory via an L{IOPump},
        then assign them to the appropriate instance variables

        @ivar clientFactory: the broker client factory
        @ivar clientFactory: L{pb.PBClientFactory} instance

        @ivar client: the client broker
        @type client: L{pb.Broker}

        @ivar server: the server broker
        @type server: L{pb.Broker}

        @ivar pump: the IOPump connecting the client and server
        @type pump: L{IOPump}

        @ivar connector: A connector whose connect method recreates
            the above instance variables
        @type connector: L{twisted.internet.base.IConnector}
        TCPrX   i  N)rq   rc   rk   r@   rA   rH   rr   connectorStater|   r   IPv4Addressr_   rx   r$  establishClientAndServer)r#   _ignoredr%   r%   r&   r6  O  s   
z%NewCredTests.establishClientAndServerc                 C   s0   |  | jjj | j| | j| j| dS )a  
        Asserts that the client broker's transport was closed and then
        mimics the event loop by calling the broker's connectionLost
        callback with C{reason}, followed by C{self.clientFactory}'s
        C{clientConnectionLost}

        @param reason: (optional) the reason to pass to the client
            broker's connectionLost callback
        @type reason: L{Failure}
        N)rx  r@   rR   rw  rZ   rc   ra   r_   )r#   r`   r%   r%   r&   completeClientLostConnectiono  s   z)NewCredTests.completeClientLostConnectionc                    sB        j } fdd} fdd}|| || |S )z
        Assert that L{PBClientFactory.getRootObject}'s Deferred fires with
        a L{RemoteReference}, and that disconnecting it runs its
        disconnection callbacks.
        c                    s     | tj | S r.   )r  r   RemoteReferencerootObjr/   r%   r&   gotRootObject  s   z6NewCredTests.test_getRootObject.<locals>.gotRootObjectc                    s(   t  }| |j  j     |S r.   )r   r  rz   rc   
disconnectr8  )r;  disconnectedDeferredr/   r%   r&   r=    s
   
z3NewCredTests.test_getRootObject.<locals>.disconnectr6  rc   r  r$  )r#   rootObjDeferredr<  r=  r%   r/   r&   test_getRootObject  s   

	
zNewCredTests.test_getRootObjectc                    s(        j } fdd}||S )z
        Test that when a connection is lost, calling a method on a
        RemoteReference obtained from it raises L{DeadReferenceError}.
        c                    s@   t  } |j  fdd}|| j    |S )Nc                    s    tj jd d S )Nmethod)assertRaisesr   DeadReferenceErrorr   )ign)r;  r#   r%   r&   lostConnection  s   zSNewCredTests.test_deadReferenceError.<locals>.gotRootObject.<locals>.lostConnection)r   r  rz   r$  rc   r=  r8  )r;  r>  rF  r/   r:  r&   r<    s   

z;NewCredTests.test_deadReferenceError.<locals>.gotRootObjectr?  )r#   r@  r<  r%   r/   r&   test_deadReferenceError  s   

z$NewCredTests.test_deadReferenceErrorc                    sB   G dd dt j}|  _    j } fdd}||S )z
        Test that if the L{reconnecting} flag is passed with a True value then
        a remote call made from a disconnection notification callback gets a
        result successfully.
        c                   @   r,   )z=NewCredTests.test_clientConnectionLost.<locals>.ReconnectOnceFc                 S   s0   | j  }d| _ tj| |||}|r|  |S r  )reconnectedAlreadyr   r   ra   r   )r#   r_   r`   reconnectingrU  r%   r%   r&   ra     s   zRNewCredTests.test_clientConnectionLost.<locals>.ReconnectOnce.clientConnectionLostN)r(   r)   r*   rH  ra   r%   r%   r%   r&   ReconnectOnce  s    rJ  c                    sH     | tj t }| |j  j      fdd}|	|S )Nc                    s     j  } fdd}||S )Nc                    s6     | tj t }| |j  j     |S r.   )	r  r   r9  r   r  rz   rc   r=  r8  )anotherRootObjr   r/   r%   r&   gotAnotherRootObject  s   
zqNewCredTests.test_clientConnectionLost.<locals>.gotRootObject.<locals>.disconnected.<locals>.gotAnotherRootObject)rc   r  r$  )rE  r   rL  r/   r%   r&   rY     s   

zSNewCredTests.test_clientConnectionLost.<locals>.gotRootObject.<locals>.disconnected)
r  r   r9  r   r  rz   rc   r=  r8  r$  )r;  r   rY   r/   r%   r&   r<    s   

z=NewCredTests.test_clientConnectionLost.<locals>.gotRootObject)r   r   rc   r6  r  r$  )r#   rJ  r@  r<  r%   r/   r&   test_clientConnectionLost  s   

z&NewCredTests.test_clientConnectionLostc                 C   s<   |    | jd}|tt  |t	t
j dS )z
        Test that if a Broker loses its connection without receiving any bytes,
        it doesn't raise any exceptions or log any errors.
        )rX   i90  N)r6  rk   re   rg   r   rh   rf   rZ   r   r[   r   r\   )r#   serverProtor%   r%   r&   test_immediateClose  s   z NewCredTests.test_immediateClosec                 C   s<   t  }|tdd}|dttd | 	|tS )z
        L{PBClientFactory.login} returns a L{Deferred} which is errbacked
        with the L{ConnectionRefusedError} if the underlying connection is
        refused.
           foo   barNz!Test simulated refused connection)
r   r   r)  r   UsernamePasswordclientConnectionFailedr   r[   r   assertFailure)r#   rc   loginDeferredr%   r%   r&   test_loginConnectionRefused  s   
z(NewCredTests.test_loginConnectionRefusedc                    s   j tjdd tdd}d}t  j||} fdd}fdd}|	| |	| fd	d
}|	| 
  j  t  j   d |S )z
        Test that login can be performed with IUsernamePassword credentials and
        that when the connection is dropped the avatar is logged out.
           passr$      userr  c                    s"    jjj | tj  S r.   )rx  r   r  r  r  r   r9  r   loginCompletedr#   r%   r&   cbLogin  s   z.NewCredTests.test_loginLogout.<locals>.cbLoginc                    s    j      d S r.   )rc   r=  r8  ignoredr/   r%   r&   cbDisconnect  s   
z3NewCredTests.test_loginLogout.<locals>.cbDisconnectc                    s      jjj d S r.   )rx  r   r  r  r^  r/   r%   r&   cbLogout&  rR  z/NewCredTests.test_loginLogout.<locals>.cbLogoutN)r	   registerCheckerr   r   r   rR  r   rc   r)  r$  r6  rH   rJ   r  r  rz   )r#   credsr:   r   r]  r`  ra  r%   r[  r&   test_loginLogout  s&   






zNewCredTests.test_loginLogoutc                    s   t   G  fdddtj}|j_jtjdd j	
tddd} fdd}|| fd	d
}||   j  t  j  |S )z
        If a L{RemoteReference} to an L{IPerspective} avatar is decrefed and
        there remain no other references to the avatar on the server, the
        avatar is garbage collected and the logout method called.
        c                       s$   e Zd ZdZdd Z fddZdS )z=NewCredTests.test_logoutAfterDecref.<locals>.EventPerspectivezQ
            An avatar which fires a Deferred when it is logged out.
            c                 S   r5   r.   r%   r  r%   r%   r&   rD   C  r   zFNewCredTests.test_logoutAfterDecref.<locals>.EventPerspective.__init__c                    s     d  d S r.   )rz   r/   r  r%   r&   r  F  r   zDNewCredTests.test_logoutAfterDecref.<locals>.EventPerspective.logoutN)r(   r)   r*   r2   rD   r  r%   r  r%   r&   EventPerspective>  s    re  rQ  r   rP  r  c                    s    S r.   r%   )avatarr  r%   r&   
cbLoggedInS  s   z7NewCredTests.test_logoutAfterDecref.<locals>.cbLoggedInc                    s      jjji  d S r.   )r  rk   r6  _localCleanupr^  r/   r%   r&   cbLoggedOutZ  s   z8NewCredTests.test_logoutAfterDecref.<locals>.cbLoggedOut)r   r   Avatarr   r  r	   rb  r   r   rc   r)  r   rR  r$  r6  rH   rJ   r  r  )r#   re  r   rg  ri  r%   )r  r#   r&   test_logoutAfterDecref6  s$   




z#NewCredTests.test_logoutAfterDecrefc                    s    j tjddd  jtddd} jtddd}t||g}dd }|	|  fd	d
}|	|  
   j  |S )z
        Two different correct login attempts can be made on the same root
        object at the same time and produce two different resulting avatars.
        rQ  s   quux)r   bazrP  r     bazc                 S   s    | \}}t |d|dgS )NgetAvatarId)r   r   )rU  firstsecondr%   r%   r&   rg  }  s   z5NewCredTests.test_concurrentLogin.<locals>.cbLoggedInc                    s$   | \}}  |d   |d d S )NrP  rm  )r  )r   ro  rp  r/   r%   r&   cbAvatarIds  s   z6NewCredTests.test_concurrentLogin.<locals>.cbAvatarIds)r	   rb  r   r   rc   r)  r   rR  r   r$  r6  rH   rJ   )r#   
firstLoginsecondLoginr   rg  rq  r%   r/   r&   test_concurrentLoginl  s"   


z!NewCredTests.test_concurrentLoginc                    s    j tjdd  jtdd} jtdd} |t	  |t	 t
||g} fdd}||     j  |S )zz
        Test that a login attempt with an invalid user or invalid password
        fails in the appropriate way.
        rW  rX  s
   nosuchuserrY  s	   wrongpassc                         t} t|d d S )Nr   )flushLoggedErrorsr
   r  ry  ignoreerrorsr/   r%   r&   cleanup     
z;NewCredTests.test_badUsernamePasswordLogin.<locals>.cleanup)r	   rb  r   r   rc   r)  r   rR  rT  r
   r   r$  r6  rH   rJ   )r#   rr  rs  r   rz  r%   r/   r&   test_badUsernamePasswordLogin  s"   




z*NewCredTests.test_badUsernamePasswordLoginc                 C   sX   | j t  | jt d}dd }|| || j	d | 
  | j  |S )z
        Verify that a PB server using a portal configured with a checker which
        allows IAnonymous credentials can be logged into using IAnonymous
        credentials.
        r  c                 S      |  ddS Nr  {   r_  rZ  r%   r%   r&   rg    ru   z4NewCredTests.test_anonymousLogin.<locals>.cbLoggedInr  )r	   rb  r   AllowAnonymousAccessrc   r)  r   	Anonymousr$  r  r6  rH   rJ   )r#   r   rg  r%   r%   r&   test_anonymousLogin  s   

z NewCredTests.test_anonymousLoginc                    s^    j tjdd  jt d} |t	  fdd}|
|     j  |S )zg
        Verify that without an anonymous checker set up, anonymous login is
        rejected.
        passrX  r  c                    ru  r   )rv  r   r  ry  rw  r/   r%   r&   rz    r{  z=NewCredTests.test_anonymousLoginNotPermitted.<locals>.cleanup)r	   rb  r   r   rc   r)  r   r  rT  r   r$  r6  rH   rJ   r#   r   rz  r%   r/   r&   test_anonymousLoginNotPermitted  s   


z,NewCredTests.test_anonymousLoginNotPermittedc                 C   sl   | j t  | j tjdd | jt d}dd }|	| |	| j
d |   | j  |S )z
        Like L{test_anonymousLogin} but against a portal with a checker for
        both IAnonymous and IUsernamePassword.
        rW  rX  r  c                 S   r}  r~  r_  rZ  r%   r%   r&   r]    ru   zENewCredTests.test_anonymousLoginWithMultipleCheckers.<locals>.cbLoginr  )r	   rb  r   r  r   rc   r)  r   r  r$  r  r6  rH   rJ   r#   r   r]  r%   r%   r&   'test_anonymousLoginWithMultipleCheckers  s   


z4NewCredTests.test_anonymousLoginWithMultipleCheckersc                 C   sp   | j t  | j tjdd | jtddd}dd }|	| |	| j
d |   | j  |S )z
        Like L{test_anonymousLoginWithMultipleCheckers} but check that
        username/password authentication works.
        rW  rX  rY  r  c                 S   s   |  dddS )Naddr     r_  rZ  r%   r%   r&   r]    r   zINewCredTests.test_authenticatedLoginWithMultipleCheckers.<locals>.cbLoginr  )r	   rb  r   r  r   rc   r)  r   rR  r$  r  r6  rH   rJ   r  r%   r%   r&   +test_authenticatedLoginWithMultipleCheckers  s   


z8NewCredTests.test_authenticatedLoginWithMultipleCheckersc                 C   sp   | j tjdd | jtddd}dd }|| dd }|| || j	 | 
  | j  |S )	zb
        Verify that a viewpoint can be retrieved after authenticating with
        cred.
        rW  rX  rY  r  c                 S   
   |  dS )NgetViewPointr_  rZ  r%   r%   r&   r]    r   z'NewCredTests.test_view.<locals>.cbLoginc                 S   r  )Nr   r_  )	viewpointr%   r%   r&   cbView  r   z&NewCredTests.test_view.<locals>.cbView)r	   rb  r   r   rc   r)  r   rR  r$  rx  r6  rH   rJ   )r#   r   r]  r  r%   r%   r&   	test_view
  s   



zNewCredTests.test_viewr.   )r(   r)   r*   r2   r  r6  r   r[   r   r\   r8  rA  rG  rM  rO  rV  rd  rk  rt  r|  r  r  r  r  r  r%   r%   r%   r&   r2  ?  s(    

!
3
16%r2  c                   @   r   )NonSubclassingPerspectivec                 C   r5   r.   r%   r  r%   r%   r&   rD   *  r   z"NonSubclassingPerspective.__init__c                 C   s(   | || }| || }||||fS r.   )unserialize	serialize)r#   r]   messager  kwargsr%   r%   r&   perspectiveMessageReceived.  s   z4NonSubclassingPerspective.perspectiveMessageReceivedc                 C   r   r  r  r/   r%   r%   r&   r  4  r   z NonSubclassingPerspective.logoutN)r(   r)   r*   rD   r  r  r%   r%   r%   r&   r  (  s    r  c                   @   r  )NSPTestsz
    Tests for authentication against a realm where the L{IPerspective}
    implementation is not a subclass of L{Avatar}.
    c                 C   s   t  | _t| j_t| j| _t | _| j	dd | j
| j tt| j| _tjd| jdd| _| | jj | j j| _d S )NrY  rW  r   rX   )r  )r  r   r  r  r	   r   r   r   r   addUserrb  r   r   r   r@  r   r<  r?  ri   rD  r>  portnor/   r%   r%   r&   r  >  s   
zNSPTests.setUpc                    sn   t    tddd}tdj  |dd  |j	ddd	d
if  fdd}|| |S )z
        An L{IPerspective} implementation which does not subclass
        L{Avatar} can expose remote methods for the client to call.
        rY  rW  r  rX   c                 S   s   | j ddddS )NANYTHINGhererl  )ro  r_  )r  r%   r%   r&   r6   R  s    z#NSPTests.test_NSP.<locals>.<lambda>r  )r  ro  rl  c                    s$       jjD ]}|j  qd S r.   )r=  r@  	protocolsrR   rC  )r_  r  r@  r#   r%   r&   rz  U  s   z"NSPTests.test_NSP.<locals>.cleanup)
r   r   r)  r   rR  r   r=  r  r$  r  r  r%   r  r&   test_NSPJ  s   
zNSPTests.test_NSPN)r(   r)   r*   r2   r  r  r%   r%   r%   r&   r  8  s    r  c                   @   r  )
IForwardedzA
    Interface used for testing L{util.LocalAsyncForwarder}.
    c                   C   r   )z,
        Simple synchronous method.
        Nr%   r%   r%   r%   r&   	forwardMec  r7   zIForwarded.forwardMec                   C   r   )z-
        Simple asynchronous method.
        Nr%   r%   r%   r%   r&   forwardDeferredh  r7   zIForwarded.forwardDeferredN)r(   r)   r*   r2   r  r  r%   r%   r%   r&   r  ^  s    r  c                   @   s0   e Zd ZdZdZdZdd Zdd Zdd Zd	S )
	Forwardedz
    Test implementation of L{IForwarded}.

    @ivar forwarded: set if C{forwardMe} is called.
    @type forwarded: C{bool}
    @ivar unforwarded: set if C{dontForwardMe} is called.
    @type unforwarded: C{bool}
    Fc                 C   rK   )z6
        Set a local flag to test afterwards.
        TN)	forwardedr/   r%   r%   r&   r  |  r  zForwarded.forwardMec                 C   rK   )zv
        Set a local flag to test afterwards. This should not be called as it's
        not in the interface.
        TN)unforwardedr/   r%   r%   r&   dontForwardMe  rM   zForwarded.dontForwardMec                 C   s   t dS )z0
        Asynchronously return C{True}.
        T)r   r/   r%   r%   r&   r    s   zForwarded.forwardDeferredN)	r(   r)   r*   r2   r  r  r  r  r  r%   r%   r%   r&   r  n  s    	r  c                   @   r  )SpreadUtilTestsz+
    Tests for L{twisted.spread.util}.
    c                 C   s   t  }| |ddd dS )zk
        Call a synchronous method of a L{util.LocalAsRemote} object and check
        the result.
        add1r   r   N)r  r  r   r  r%   r%   r&   	test_sync  s   zSpreadUtilTests.test_syncc                 C   s:   t  }t  }|jdddd}| |t || jd |S )zm
        Call an asynchronous method of a L{util.LocalAsRemote} object and check
        the result.
        r  r   r   )r   r  )r  r   r  r   r$  r  )r#   r  r   r%   r%   r&   
test_async  s   zSpreadUtilTests.test_asyncc                    s4   t  }|d} fdd}| fdd| |S )zG
        Test an asynchronous failure on a remote method call.
        rO  c                    s     | tj | t d S r.   )r  r   r[   trapr   )r  r/   r%   r&   eb  s   z*SpreadUtilTests.test_asyncFail.<locals>.ebc                    s
     dS )Nzsupposed to failrN  r  r/   r%   r&   r6     s   
 z0SpreadUtilTests.test_asyncFail.<locals>.<lambda>)r  r   r   )r#   r  r   r  r%   r/   r&   test_asyncFail  s
   
zSpreadUtilTests.test_asyncFailc                 C   s$   t  }|d}| |dd dS )zM
        Test the C{remoteMethod} facility of L{util.LocalAsRemote}.
        r  r   r   N)r  rj  r  )r#   r  mr%   r%   r&   test_remoteMethod  s   
z!SpreadUtilTests.test_remoteMethodc                 C   sl   t  }t|t}|d | |j |d | |j |d}g }|	|j
 | |d d dS )ze
        Test a call to L{util.LocalAsyncForwarder} using L{Forwarded} local
        object.
        r  r  r  r   rN   N)r  r   LocalAsyncForwarderr  r   rx  r  r  r  r$  r   r  )r#   r  lfrrrz  r%   r%   r&   test_localAsyncForwarder  s   


z(SpreadUtilTests.test_localAsyncForwarderN)	r(   r)   r*   r2   r  r  r  r  r  r%   r%   r%   r&   r    s    r  c                   @   r>   )PBWithSecurityOptionsTestsz&
    Test security customization.
    c                 C   s&   t  }|d}| |jtj dS )zl
        By default, client broker should use C{jelly.globalSecurity} as
        security settings.
        N)r   r   re   ri  securityr   globalSecurityr#   r@  r]   r%   r%   r&   !test_clientDefaultSecurityOptions  s   
z<PBWithSecurityOptionsTests.test_clientDefaultSecurityOptionsc                 C   s*   t t }|d}| |jtj dS )zl
        By default, server broker should use C{jelly.globalSecurity} as
        security settings.
        N)r   r   r  re   ri  r  r   r  r  r%   r%   r&   !test_serverDefaultSecurityOptions  s   
z<PBWithSecurityOptionsTests.test_serverDefaultSecurityOptionsc                 C   s0   t  }tj|d}|d}| |j| dS )zs
        Check that the security settings are passed from the client factory to
        the broker object.
        r  N)r   SecurityOptionsr   r   re   ri  r  r#   r  r@  r]   r%   r%   r&    test_clientSecurityCustomization  s   
z;PBWithSecurityOptionsTests.test_clientSecurityCustomizationc                 C   s4   t  }tjt |d}|d}| |j| dS )zs
        Check that the security settings are passed from the server factory to
        the broker object.
        r  N)r   r  r   r   r  re   ri  r  r  r%   r%   r&    test_serverSecurityCustomization  s   
z;PBWithSecurityOptionsTests.test_serverSecurityCustomizationN)r(   r)   r*   r2   r  r  r  r  r%   r%   r%   r&   r    s    		
r  r.   )r2   r  rJ  r  rG   r&  collectionsr   ior   rf   typingr   zope.interfacer   r   twisted.credr   r   r	   twisted.cred.errorr
   r   twisted.internetr   r   r   r   twisted.internet.deferr   r   r   twisted.internet.errorr   twisted.protocols.policiesr   twisted.pythonr   r   twisted.python.compatr   twisted.spreadr   r   r   r   twisted.test.proto_helpersr   twisted.trialr   Viewabler   rj  r!   IRealmr4   r?   rq   rr   r|   r   rf  r   r   Copyabler   
RemoteCopyr   setUnjellyableForClassr   r   setUnjellyableFactoryForClassr   	Cacheabler   r   r   RemoteCacher   r   r   r   r   r   r  r  r
  Rootr  r  SynchronousTestCaser  r   r3  TestCaser8  rH  r  r  r  r  r  r  r  Publishabler  RemotePublishedr  r  r  r   r   r  r  LocalAsRemoter  r8   r  r  r  r   r%  r2  r  r  r  r  r  r  r%   r%   r%   r&   <module>   s   	;3!
	
R 7  lC#!6   l&!@