Index: third_party/twisted_8_1/twisted/test/test_pb.py |
diff --git a/third_party/twisted_8_1/twisted/test/test_pb.py b/third_party/twisted_8_1/twisted/test/test_pb.py |
deleted file mode 100644 |
index 9d3e1b961739d7eb508a42e71b328ccc676d0103..0000000000000000000000000000000000000000 |
--- a/third_party/twisted_8_1/twisted/test/test_pb.py |
+++ /dev/null |
@@ -1,1618 +0,0 @@ |
-# Copyright (c) 2001-2008 Twisted Matrix Laboratories. |
-# See LICENSE for details. |
- |
-""" |
-Tests for Perspective Broker module. |
- |
-TODO: update protocol level tests to use new connection API, leaving |
-only specific tests for old API. |
-""" |
- |
-# issue1195 TODOs: replace pump.pump() with something involving Deferreds. |
-# Clean up warning suppression. Find a better replacement for the handful of |
-# reactor.callLater(0.1, ..) calls. |
- |
-import sys, os, time, gc |
- |
-from cStringIO import StringIO |
-from zope.interface import implements, Interface |
- |
-from twisted.trial import unittest |
- |
-from twisted.spread import pb, util, publish, jelly |
-from twisted.internet import protocol, main, reactor, defer |
-from twisted.internet.error import ConnectionRefusedError |
-from twisted.internet.defer import Deferred, gatherResults |
-from twisted.python import failure, log |
-from twisted.cred.error import UnauthorizedLogin, UnhandledCredentials |
-from twisted.cred import portal, checkers, credentials |
- |
- |
-class Dummy(pb.Viewable): |
- def view_doNothing(self, user): |
- if isinstance(user, DummyPerspective): |
- return 'hello world!' |
- else: |
- return 'goodbye, cruel world!' |
- |
- |
-class DummyPerspective(pb.Avatar): |
- def perspective_getDummyViewPoint(self): |
- return Dummy() |
- |
- |
-class DummyRealm(object): |
- implements(portal.IRealm) |
- |
- def requestAvatar(self, avatarId, mind, *interfaces): |
- for iface in interfaces: |
- if iface is pb.IPerspective: |
- return iface, DummyPerspective(), lambda: None |
- |
- |
-class IOPump: |
- """ |
- Utility to pump data between clients and servers for protocol testing. |
- |
- Perhaps this is a utility worthy of being in protocol.py? |
- """ |
- def __init__(self, client, server, clientIO, serverIO): |
- self.client = client |
- self.server = server |
- self.clientIO = clientIO |
- self.serverIO = serverIO |
- |
- def flush(self): |
- """ |
- Pump until there is no more input or output. This does not run any |
- timers, so don't use it with any code that calls reactor.callLater. |
- """ |
- # failsafe timeout |
- timeout = time.time() + 5 |
- while self.pump(): |
- if time.time() > timeout: |
- return |
- |
- def pump(self): |
- """ |
- Move data back and forth. |
- |
- Returns whether any data was moved. |
- """ |
- self.clientIO.seek(0) |
- self.serverIO.seek(0) |
- cData = self.clientIO.read() |
- sData = self.serverIO.read() |
- self.clientIO.seek(0) |
- self.serverIO.seek(0) |
- self.clientIO.truncate() |
- self.serverIO.truncate() |
- self.client.transport._checkProducer() |
- self.server.transport._checkProducer() |
- for byte in cData: |
- self.server.dataReceived(byte) |
- for byte in sData: |
- self.client.dataReceived(byte) |
- if cData or sData: |
- return 1 |
- else: |
- return 0 |
- |
- |
-def connectedServerAndClient(): |
- """ |
- Returns a 3-tuple: (client, server, pump). |
- """ |
- clientBroker = pb.Broker() |
- checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(guest='guest') |
- factory = pb.PBServerFactory(portal.Portal(DummyRealm(), [checker])) |
- serverBroker = factory.buildProtocol(('127.0.0.1',)) |
- |
- clientTransport = StringIO() |
- serverTransport = StringIO() |
- clientBroker.makeConnection(protocol.FileWrapper(clientTransport)) |
- serverBroker.makeConnection(protocol.FileWrapper(serverTransport)) |
- pump = IOPump(clientBroker, serverBroker, clientTransport, serverTransport) |
- # Challenge-response authentication: |
- pump.flush() |
- return clientBroker, serverBroker, pump |
- |
- |
-class SimpleRemote(pb.Referenceable): |
- def remote_thunk(self, arg): |
- self.arg = arg |
- return arg + 1 |
- |
- def remote_knuth(self, arg): |
- raise Exception() |
- |
- |
-class NestedRemote(pb.Referenceable): |
- def remote_getSimple(self): |
- return SimpleRemote() |
- |
- |
-class SimpleCopy(pb.Copyable): |
- def __init__(self): |
- self.x = 1 |
- self.y = {"Hello":"World"} |
- self.z = ['test'] |
- |
- |
-class SimpleLocalCopy(pb.RemoteCopy): |
- pass |
- |
-pb.setCopierForClass(SimpleCopy, SimpleLocalCopy) |
- |
- |
-class SimpleFactoryCopy(pb.Copyable): |
- """ |
- @cvar allIDs: hold every created instances of this class. |
- @type allIDs: C{dict} |
- """ |
- allIDs = {} |
- def __init__(self, id): |
- self.id = id |
- SimpleFactoryCopy.allIDs[id] = self |
- |
- |
-def createFactoryCopy(state): |
- """ |
- Factory of L{SimpleFactoryCopy}, getting a created instance given the |
- C{id} found in C{state}. |
- """ |
- stateId = state.get("id", None) |
- if stateId is None: |
- raise RuntimeError("factory copy state has no 'id' member %s" % |
- (repr(state),)) |
- if not stateId in SimpleFactoryCopy.allIDs: |
- raise RuntimeError("factory class has no ID: %s" % |
- (SimpleFactoryCopy.allIDs,)) |
- inst = SimpleFactoryCopy.allIDs[stateId] |
- if not inst: |
- raise RuntimeError("factory method found no object with id") |
- return inst |
- |
-pb.setFactoryForClass(SimpleFactoryCopy, createFactoryCopy) |
- |
- |
-class NestedCopy(pb.Referenceable): |
- def remote_getCopy(self): |
- return SimpleCopy() |
- |
- def remote_getFactory(self, value): |
- return SimpleFactoryCopy(value) |
- |
- |
- |
-class SimpleCache(pb.Cacheable): |
- def __init___(self): |
- self.x = 1 |
- self.y = {"Hello":"World"} |
- self.z = ['test'] |
- |
- |
-class NestedComplicatedCache(pb.Referenceable): |
- def __init__(self): |
- self.c = VeryVeryComplicatedCacheable() |
- |
- def remote_getCache(self): |
- return self.c |
- |
- |
-class VeryVeryComplicatedCacheable(pb.Cacheable): |
- def __init__(self): |
- self.x = 1 |
- self.y = 2 |
- self.foo = 3 |
- |
- def setFoo4(self): |
- self.foo = 4 |
- self.observer.callRemote('foo',4) |
- |
- def getStateToCacheAndObserveFor(self, perspective, observer): |
- self.observer = observer |
- return {"x": self.x, |
- "y": self.y, |
- "foo": self.foo} |
- |
- def stoppedObserving(self, perspective, observer): |
- log.msg("stopped observing") |
- observer.callRemote("end") |
- if observer == self.observer: |
- self.observer = None |
- |
- |
-class RatherBaroqueCache(pb.RemoteCache): |
- def observe_foo(self, newFoo): |
- self.foo = newFoo |
- |
- def observe_end(self): |
- log.msg("the end of things") |
- |
-pb.setCopierForClass(VeryVeryComplicatedCacheable, RatherBaroqueCache) |
- |
- |
-class SimpleLocalCache(pb.RemoteCache): |
- def setCopyableState(self, state): |
- self.__dict__.update(state) |
- |
- def checkMethod(self): |
- return self.check |
- |
- def checkSelf(self): |
- return self |
- |
- def check(self): |
- return 1 |
- |
-pb.setCopierForClass(SimpleCache, SimpleLocalCache) |
- |
- |
-class NestedCache(pb.Referenceable): |
- def __init__(self): |
- self.x = SimpleCache() |
- |
- def remote_getCache(self): |
- return [self.x,self.x] |
- |
- def remote_putCache(self, cache): |
- return (self.x is cache) |
- |
- |
-class Observable(pb.Referenceable): |
- def __init__(self): |
- self.observers = [] |
- |
- def remote_observe(self, obs): |
- self.observers.append(obs) |
- |
- def remote_unobserve(self, obs): |
- self.observers.remove(obs) |
- |
- def notify(self, obj): |
- for observer in self.observers: |
- observer.callRemote('notify', self, obj) |
- |
- |
-class DeferredRemote(pb.Referenceable): |
- def __init__(self): |
- self.run = 0 |
- |
- def runMe(self, arg): |
- self.run = arg |
- return arg + 1 |
- |
- def dontRunMe(self, arg): |
- assert 0, "shouldn't have been run!" |
- |
- def remote_doItLater(self): |
- d = defer.Deferred() |
- d.addCallbacks(self.runMe, self.dontRunMe) |
- self.d = d |
- return d |
- |
- |
-class Observer(pb.Referenceable): |
- notified = 0 |
- obj = None |
- def remote_notify(self, other, obj): |
- self.obj = obj |
- self.notified = self.notified + 1 |
- other.callRemote('unobserve',self) |
- |
- |
-class NewStyleCopy(pb.Copyable, pb.RemoteCopy, object): |
- def __init__(self, s): |
- self.s = s |
-pb.setUnjellyableForClass(NewStyleCopy, NewStyleCopy) |
- |
- |
-class NewStyleCopy2(pb.Copyable, pb.RemoteCopy, object): |
- allocated = 0 |
- initialized = 0 |
- value = 1 |
- |
- def __new__(self): |
- NewStyleCopy2.allocated += 1 |
- inst = object.__new__(self) |
- inst.value = 2 |
- return inst |
- |
- def __init__(self): |
- NewStyleCopy2.initialized += 1 |
- |
-pb.setUnjellyableForClass(NewStyleCopy2, NewStyleCopy2) |
- |
- |
-class NewStyleCacheCopy(pb.Cacheable, pb.RemoteCache, object): |
- def getStateToCacheAndObserveFor(self, perspective, observer): |
- return self.__dict__ |
- |
-pb.setCopierForClass(NewStyleCacheCopy, NewStyleCacheCopy) |
- |
- |
-class Echoer(pb.Root): |
- def remote_echo(self, st): |
- return st |
- |
- |
-class CachedReturner(pb.Root): |
- def __init__(self, cache): |
- self.cache = cache |
- def remote_giveMeCache(self, st): |
- return self.cache |
- |
- |
-class NewStyleTestCase(unittest.TestCase): |
- def setUp(self): |
- """ |
- Create a pb server using L{Echoer} protocol and connect a client to it. |
- """ |
- self.server = reactor.listenTCP(0, pb.PBServerFactory(Echoer())) |
- clientFactory = pb.PBClientFactory() |
- reactor.connectTCP("localhost", self.server.getHost().port, |
- clientFactory) |
- def gotRoot(ref): |
- self.ref = ref |
- return clientFactory.getRootObject().addCallback(gotRoot) |
- |
- |
- def tearDown(self): |
- """ |
- Close client and server connections, reset values of L{NewStyleCopy2} |
- class variables. |
- """ |
- NewStyleCopy2.allocated = 0 |
- NewStyleCopy2.initialized = 0 |
- NewStyleCopy2.value = 1 |
- self.ref.broker.transport.loseConnection() |
- return self.server.stopListening() |
- |
- def test_newStyle(self): |
- """ |
- Create a new style object, send it over the wire, and check the result. |
- """ |
- orig = NewStyleCopy("value") |
- d = self.ref.callRemote("echo", orig) |
- def cb(res): |
- self.failUnless(isinstance(res, NewStyleCopy)) |
- self.failUnlessEqual(res.s, "value") |
- self.failIf(res is orig) # no cheating :) |
- d.addCallback(cb) |
- return d |
- |
- def test_alloc(self): |
- """ |
- Send a new style object and check the number of allocations. |
- """ |
- orig = NewStyleCopy2() |
- self.failUnlessEqual(NewStyleCopy2.allocated, 1) |
- self.failUnlessEqual(NewStyleCopy2.initialized, 1) |
- d = self.ref.callRemote("echo", orig) |
- def cb(res): |
- # receiving the response creates a third one on the way back |
- self.failUnless(isinstance(res, NewStyleCopy2)) |
- self.failUnlessEqual(res.value, 2) |
- self.failUnlessEqual(NewStyleCopy2.allocated, 3) |
- self.failUnlessEqual(NewStyleCopy2.initialized, 1) |
- self.failIf(res is orig) # no cheating :) |
- # sending the object creates a second one on the far side |
- d.addCallback(cb) |
- return d |
- |
- |
- |
-class ConnectionNotifyServerFactory(pb.PBServerFactory): |
- """ |
- A server factory which stores the last connection and fires a |
- L{defer.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{defer.Deferred} |
- """ |
- protocolInstance = None |
- |
- def __init__(self, root): |
- """ |
- Initialize the factory. |
- """ |
- pb.PBServerFactory.__init__(self, root) |
- self.connectionMade = defer.Deferred() |
- |
- |
- def clientConnectionMade(self, protocol): |
- """ |
- Store the protocol and fire the connection deferred. |
- """ |
- self.protocolInstance = protocol |
- self.connectionMade.callback(None) |
- |
- |
- |
-class NewStyleCachedTestCase(unittest.TestCase): |
- def setUp(self): |
- """ |
- Create a pb server using L{CachedReturner} protocol and connect a |
- client to it. |
- """ |
- self.orig = NewStyleCacheCopy() |
- self.orig.s = "value" |
- self.server = reactor.listenTCP(0, |
- ConnectionNotifyServerFactory(CachedReturner(self.orig))) |
- clientFactory = pb.PBClientFactory() |
- reactor.connectTCP("localhost", self.server.getHost().port, |
- clientFactory) |
- def gotRoot(ref): |
- self.ref = ref |
- d1 = clientFactory.getRootObject().addCallback(gotRoot) |
- d2 = self.server.factory.connectionMade |
- return defer.gatherResults([d1, d2]) |
- |
- |
- def tearDown(self): |
- """ |
- Close client and server connections. |
- """ |
- self.server.factory.protocolInstance.transport.loseConnection() |
- self.ref.broker.transport.loseConnection() |
- return self.server.stopListening() |
- |
- |
- def test_newStyleCache(self): |
- """ |
- Get the object from the cache, and checks its properties. |
- """ |
- d = self.ref.callRemote("giveMeCache", self.orig) |
- def cb(res): |
- self.failUnless(isinstance(res, NewStyleCacheCopy)) |
- self.failUnlessEqual(res.s, "value") |
- self.failIf(res is self.orig) # no cheating :) |
- d.addCallback(cb) |
- return d |
- |
- |
- |
-class BrokerTestCase(unittest.TestCase): |
- thunkResult = None |
- |
- def tearDown(self): |
- try: |
- # from RemotePublished.getFileName |
- os.unlink('None-None-TESTING.pub') |
- except OSError: |
- pass |
- |
- def thunkErrorBad(self, error): |
- self.fail("This should cause a return value, not %s" % (error,)) |
- |
- def thunkResultGood(self, result): |
- self.thunkResult = result |
- |
- def thunkErrorGood(self, tb): |
- pass |
- |
- def thunkResultBad(self, result): |
- self.fail("This should cause an error, not %s" % (result,)) |
- |
- def test_reference(self): |
- c, s, pump = connectedServerAndClient() |
- |
- class X(pb.Referenceable): |
- def remote_catch(self,arg): |
- self.caught = arg |
- |
- class Y(pb.Referenceable): |
- def remote_throw(self, a, b): |
- a.callRemote('catch', b) |
- |
- s.setNameForLocal("y", Y()) |
- y = c.remoteForName("y") |
- x = X() |
- z = X() |
- y.callRemote('throw', x, z) |
- pump.pump() |
- pump.pump() |
- pump.pump() |
- self.assertIdentical(x.caught, z, "X should have caught Z") |
- |
- # make sure references to remote methods are equals |
- self.assertEquals(y.remoteMethod('throw'), y.remoteMethod('throw')) |
- |
- def test_result(self): |
- c, s, pump = connectedServerAndClient() |
- for x, y in (c, s), (s, c): |
- # test reflexivity |
- foo = SimpleRemote() |
- x.setNameForLocal("foo", foo) |
- bar = y.remoteForName("foo") |
- self.expectedThunkResult = 8 |
- bar.callRemote('thunk',self.expectedThunkResult - 1 |
- ).addCallbacks(self.thunkResultGood, self.thunkErrorBad) |
- # Send question. |
- pump.pump() |
- # Send response. |
- pump.pump() |
- # Shouldn't require any more pumping than that... |
- self.assertEquals(self.thunkResult, self.expectedThunkResult, |
- "result wasn't received.") |
- |
- def refcountResult(self, result): |
- self.nestedRemote = result |
- |
- def test_tooManyRefs(self): |
- l = [] |
- e = [] |
- c, s, pump = connectedServerAndClient() |
- foo = NestedRemote() |
- s.setNameForLocal("foo", foo) |
- x = c.remoteForName("foo") |
- for igno in xrange(pb.MAX_BROKER_REFS + 10): |
- if s.transport.closed or c.transport.closed: |
- break |
- x.callRemote("getSimple").addCallbacks(l.append, e.append) |
- pump.pump() |
- expected = (pb.MAX_BROKER_REFS - 1) |
- self.assertTrue(s.transport.closed, "transport was not closed") |
- self.assertEquals(len(l), expected, |
- "expected %s got %s" % (expected, len(l))) |
- |
- def test_copy(self): |
- c, s, pump = connectedServerAndClient() |
- foo = NestedCopy() |
- s.setNameForLocal("foo", foo) |
- x = c.remoteForName("foo") |
- x.callRemote('getCopy' |
- ).addCallbacks(self.thunkResultGood, self.thunkErrorBad) |
- pump.pump() |
- pump.pump() |
- self.assertEquals(self.thunkResult.x, 1) |
- self.assertEquals(self.thunkResult.y['Hello'], 'World') |
- self.assertEquals(self.thunkResult.z[0], 'test') |
- |
- def test_observe(self): |
- c, s, pump = connectedServerAndClient() |
- |
- # this is really testing the comparison between remote objects, to make |
- # sure that you can *UN*observe when you have an observer architecture. |
- a = Observable() |
- b = Observer() |
- s.setNameForLocal("a", a) |
- ra = c.remoteForName("a") |
- ra.callRemote('observe',b) |
- pump.pump() |
- a.notify(1) |
- pump.pump() |
- pump.pump() |
- a.notify(10) |
- pump.pump() |
- pump.pump() |
- self.assertNotIdentical(b.obj, None, "didn't notify") |
- self.assertEquals(b.obj, 1, 'notified too much') |
- |
- def test_defer(self): |
- c, s, pump = connectedServerAndClient() |
- d = DeferredRemote() |
- s.setNameForLocal("d", d) |
- e = c.remoteForName("d") |
- pump.pump(); pump.pump() |
- results = [] |
- e.callRemote('doItLater').addCallback(results.append) |
- pump.pump(); pump.pump() |
- self.assertFalse(d.run, "Deferred method run too early.") |
- d.d.callback(5) |
- self.assertEquals(d.run, 5, "Deferred method run too late.") |
- pump.pump(); pump.pump() |
- self.assertEquals(results[0], 6, "Incorrect result.") |
- |
- |
- def test_refcount(self): |
- c, s, pump = connectedServerAndClient() |
- foo = NestedRemote() |
- s.setNameForLocal("foo", foo) |
- bar = c.remoteForName("foo") |
- bar.callRemote('getSimple' |
- ).addCallbacks(self.refcountResult, self.thunkErrorBad) |
- |
- # send question |
- pump.pump() |
- # send response |
- pump.pump() |
- |
- # delving into internal structures here, because GC is sort of |
- # inherently internal. |
- rluid = self.nestedRemote.luid |
- self.assertIn(rluid, s.localObjects) |
- del self.nestedRemote |
- # nudge the gc |
- if sys.hexversion >= 0x2000000 and os.name != "java": |
- gc.collect() |
- # try to nudge the GC even if we can't really |
- pump.pump() |
- pump.pump() |
- pump.pump() |
- self.assertNotIn(rluid, s.localObjects) |
- |
- def test_cache(self): |
- c, s, pump = connectedServerAndClient() |
- obj = NestedCache() |
- obj2 = NestedComplicatedCache() |
- vcc = obj2.c |
- s.setNameForLocal("obj", obj) |
- s.setNameForLocal("xxx", obj2) |
- o2 = c.remoteForName("obj") |
- o3 = c.remoteForName("xxx") |
- coll = [] |
- o2.callRemote("getCache" |
- ).addCallback(coll.append).addErrback(coll.append) |
- o2.callRemote("getCache" |
- ).addCallback(coll.append).addErrback(coll.append) |
- complex = [] |
- o3.callRemote("getCache").addCallback(complex.append) |
- o3.callRemote("getCache").addCallback(complex.append) |
- pump.flush() |
- # `worst things first' |
- self.assertEquals(complex[0].x, 1) |
- self.assertEquals(complex[0].y, 2) |
- self.assertEquals(complex[0].foo, 3) |
- |
- vcc.setFoo4() |
- pump.flush() |
- self.assertEquals(complex[0].foo, 4) |
- self.assertEquals(len(coll), 2) |
- cp = coll[0][0] |
- self.assertIdentical(cp.checkMethod().im_self, cp, |
- "potential refcounting issue") |
- self.assertIdentical(cp.checkSelf(), cp, |
- "other potential refcounting issue") |
- col2 = [] |
- o2.callRemote('putCache',cp).addCallback(col2.append) |
- pump.flush() |
- # The objects were the same (testing lcache identity) |
- self.assertTrue(col2[0]) |
- # test equality of references to methods |
- self.assertEquals(o2.remoteMethod("getCache"), |
- o2.remoteMethod("getCache")) |
- |
- # now, refcounting (similiar to testRefCount) |
- luid = cp.luid |
- baroqueLuid = complex[0].luid |
- self.assertIn(luid, s.remotelyCachedObjects, |
- "remote cache doesn't have it") |
- del coll |
- del cp |
- pump.flush() |
- del complex |
- del col2 |
- # extra nudge... |
- pump.flush() |
- # del vcc.observer |
- # nudge the gc |
- if sys.hexversion >= 0x2000000 and os.name != "java": |
- gc.collect() |
- # try to nudge the GC even if we can't really |
- pump.flush() |
- # The GC is done with it. |
- self.assertNotIn(luid, s.remotelyCachedObjects, |
- "Server still had it after GC") |
- self.assertNotIn(luid, c.locallyCachedObjects, |
- "Client still had it after GC") |
- self.assertNotIn(baroqueLuid, s.remotelyCachedObjects, |
- "Server still had complex after GC") |
- self.assertNotIn(baroqueLuid, c.locallyCachedObjects, |
- "Client still had complex after GC") |
- self.assertIdentical(vcc.observer, None, "observer was not removed") |
- |
- def test_publishable(self): |
- try: |
- os.unlink('None-None-TESTING.pub') # from RemotePublished.getFileName |
- except OSError: |
- pass # Sometimes it's not there. |
- c, s, pump = connectedServerAndClient() |
- foo = GetPublisher() |
- # foo.pub.timestamp = 1.0 |
- s.setNameForLocal("foo", foo) |
- bar = c.remoteForName("foo") |
- accum = [] |
- bar.callRemote('getPub').addCallbacks(accum.append, self.thunkErrorBad) |
- pump.flush() |
- obj = accum.pop() |
- self.assertEquals(obj.activateCalled, 1) |
- self.assertEquals(obj.isActivated, 1) |
- self.assertEquals(obj.yayIGotPublished, 1) |
- # timestamp's dirty, we don't have a cache file |
- self.assertEquals(obj._wasCleanWhenLoaded, 0) |
- c, s, pump = connectedServerAndClient() |
- s.setNameForLocal("foo", foo) |
- bar = c.remoteForName("foo") |
- bar.callRemote('getPub').addCallbacks(accum.append, self.thunkErrorBad) |
- pump.flush() |
- obj = accum.pop() |
- # timestamp's clean, our cache file is up-to-date |
- self.assertEquals(obj._wasCleanWhenLoaded, 1) |
- |
- def gotCopy(self, val): |
- self.thunkResult = val.id |
- |
- |
- def test_factoryCopy(self): |
- c, s, pump = connectedServerAndClient() |
- ID = 99 |
- obj = NestedCopy() |
- s.setNameForLocal("foo", obj) |
- x = c.remoteForName("foo") |
- x.callRemote('getFactory', ID |
- ).addCallbacks(self.gotCopy, self.thunkResultBad) |
- pump.pump() |
- pump.pump() |
- pump.pump() |
- self.assertEquals(self.thunkResult, ID, |
- "ID not correct on factory object %s" % (self.thunkResult,)) |
- |
- |
-bigString = "helloworld" * 50 |
- |
-callbackArgs = None |
-callbackKeyword = None |
- |
-def finishedCallback(*args, **kw): |
- global callbackArgs, callbackKeyword |
- callbackArgs = args |
- callbackKeyword = kw |
- |
- |
-class Pagerizer(pb.Referenceable): |
- def __init__(self, callback, *args, **kw): |
- self.callback, self.args, self.kw = callback, args, kw |
- |
- def remote_getPages(self, collector): |
- util.StringPager(collector, bigString, 100, |
- self.callback, *self.args, **self.kw) |
- self.args = self.kw = None |
- |
- |
-class FilePagerizer(pb.Referenceable): |
- pager = None |
- |
- def __init__(self, filename, callback, *args, **kw): |
- self.filename = filename |
- self.callback, self.args, self.kw = callback, args, kw |
- |
- def remote_getPages(self, collector): |
- self.pager = util.FilePager(collector, file(self.filename), |
- self.callback, *self.args, **self.kw) |
- self.args = self.kw = None |
- |
- |
- |
-class PagingTestCase(unittest.TestCase): |
- """ |
- Test pb objects sending data by pages. |
- """ |
- |
- def setUp(self): |
- """ |
- Create a file used to test L{util.FilePager}. |
- """ |
- self.filename = self.mktemp() |
- fd = file(self.filename, 'w') |
- fd.write(bigString) |
- fd.close() |
- |
- |
- def test_pagingWithCallback(self): |
- """ |
- Test L{util.StringPager}, passing a callback to fire when all pages |
- are sent. |
- """ |
- c, s, pump = connectedServerAndClient() |
- s.setNameForLocal("foo", Pagerizer(finishedCallback, 'hello', value=10)) |
- x = c.remoteForName("foo") |
- l = [] |
- util.getAllPages(x, "getPages").addCallback(l.append) |
- while not l: |
- pump.pump() |
- self.assertEquals(''.join(l[0]), bigString, |
- "Pages received not equal to pages sent!") |
- self.assertEquals(callbackArgs, ('hello',), |
- "Completed callback not invoked") |
- self.assertEquals(callbackKeyword, {'value': 10}, |
- "Completed callback not invoked") |
- |
- |
- def test_pagingWithoutCallback(self): |
- """ |
- Test L{util.StringPager} without a callback. |
- """ |
- c, s, pump = connectedServerAndClient() |
- s.setNameForLocal("foo", Pagerizer(None)) |
- x = c.remoteForName("foo") |
- l = [] |
- util.getAllPages(x, "getPages").addCallback(l.append) |
- while not l: |
- pump.pump() |
- self.assertEquals(''.join(l[0]), bigString, |
- "Pages received not equal to pages sent!") |
- |
- |
- def test_emptyFilePaging(self): |
- """ |
- Test L{util.FilePager}, sending an empty file. |
- """ |
- filenameEmpty = self.mktemp() |
- fd = file(filenameEmpty, 'w') |
- fd.close() |
- c, s, pump = connectedServerAndClient() |
- pagerizer = FilePagerizer(filenameEmpty, None) |
- s.setNameForLocal("bar", pagerizer) |
- x = c.remoteForName("bar") |
- l = [] |
- util.getAllPages(x, "getPages").addCallback(l.append) |
- ttl = 10 |
- while not l and ttl > 0: |
- pump.pump() |
- ttl -= 1 |
- if not ttl: |
- self.fail('getAllPages timed out') |
- self.assertEquals(''.join(l[0]), '', |
- "Pages received not equal to pages sent!") |
- |
- |
- def test_filePagingWithCallback(self): |
- """ |
- 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. |
- """ |
- c, s, pump = connectedServerAndClient() |
- pagerizer = FilePagerizer(self.filename, finishedCallback, |
- 'frodo', value = 9) |
- s.setNameForLocal("bar", pagerizer) |
- x = c.remoteForName("bar") |
- l = [] |
- util.getAllPages(x, "getPages").addCallback(l.append) |
- while not l: |
- pump.pump() |
- self.assertEquals(''.join(l[0]), bigString, |
- "Pages received not equal to pages sent!") |
- self.assertEquals(callbackArgs, ('frodo',), |
- "Completed callback not invoked") |
- self.assertEquals(callbackKeyword, {'value': 9}, |
- "Completed callback not invoked") |
- self.assertEquals(pagerizer.pager.chunks, []) |
- |
- |
- def test_filePagingWithoutCallback(self): |
- """ |
- Test L{util.FilePager} without a callback. |
- """ |
- c, s, pump = connectedServerAndClient() |
- pagerizer = FilePagerizer(self.filename, None) |
- s.setNameForLocal("bar", pagerizer) |
- x = c.remoteForName("bar") |
- l = [] |
- util.getAllPages(x, "getPages").addCallback(l.append) |
- while not l: |
- pump.pump() |
- self.assertEquals(''.join(l[0]), bigString, |
- "Pages received not equal to pages sent!") |
- self.assertEquals(pagerizer.pager.chunks, []) |
- |
- |
- |
-class DumbPublishable(publish.Publishable): |
- def getStateToPublish(self): |
- return {"yayIGotPublished": 1} |
- |
- |
-class DumbPub(publish.RemotePublished): |
- def activated(self): |
- self.activateCalled = 1 |
- |
- |
-class GetPublisher(pb.Referenceable): |
- def __init__(self): |
- self.pub = DumbPublishable("TESTING") |
- |
- def remote_getPub(self): |
- return self.pub |
- |
- |
-pb.setCopierForClass(DumbPublishable, DumbPub) |
- |
-class DisconnectionTestCase(unittest.TestCase): |
- """ |
- Test disconnection callbacks. |
- """ |
- |
- def error(self, *args): |
- raise RuntimeError("I shouldn't have been called: %s" % (args,)) |
- |
- |
- def gotDisconnected(self): |
- """ |
- Called on broker disconnect. |
- """ |
- self.gotCallback = 1 |
- |
- def objectDisconnected(self, o): |
- """ |
- Called on RemoteReference disconnect. |
- """ |
- self.assertEquals(o, self.remoteObject) |
- self.objectCallback = 1 |
- |
- def test_badSerialization(self): |
- c, s, pump = connectedServerAndClient() |
- pump.pump() |
- s.setNameForLocal("o", BadCopySet()) |
- g = c.remoteForName("o") |
- l = [] |
- g.callRemote("setBadCopy", BadCopyable()).addErrback(l.append) |
- pump.flush() |
- self.assertEquals(len(l), 1) |
- |
- def test_disconnection(self): |
- c, s, pump = connectedServerAndClient() |
- pump.pump() |
- s.setNameForLocal("o", SimpleRemote()) |
- |
- # get a client reference to server object |
- r = c.remoteForName("o") |
- pump.pump() |
- pump.pump() |
- pump.pump() |
- |
- # register and then unregister disconnect callbacks |
- # making sure they get unregistered |
- c.notifyOnDisconnect(self.error) |
- self.assertIn(self.error, c.disconnects) |
- c.dontNotifyOnDisconnect(self.error) |
- self.assertNotIn(self.error, c.disconnects) |
- |
- r.notifyOnDisconnect(self.error) |
- self.assertIn(r._disconnected, c.disconnects) |
- self.assertIn(self.error, r.disconnectCallbacks) |
- r.dontNotifyOnDisconnect(self.error) |
- self.assertNotIn(r._disconnected, c.disconnects) |
- self.assertNotIn(self.error, r.disconnectCallbacks) |
- |
- # register disconnect callbacks |
- c.notifyOnDisconnect(self.gotDisconnected) |
- r.notifyOnDisconnect(self.objectDisconnected) |
- self.remoteObject = r |
- |
- # disconnect |
- c.connectionLost(failure.Failure(main.CONNECTION_DONE)) |
- self.assertTrue(self.gotCallback) |
- self.assertTrue(self.objectCallback) |
- |
- |
-class FreakOut(Exception): |
- pass |
- |
- |
-class BadCopyable(pb.Copyable): |
- def getStateToCopyFor(self, p): |
- raise FreakOut() |
- |
- |
-class BadCopySet(pb.Referenceable): |
- def remote_setBadCopy(self, bc): |
- return None |
- |
- |
-class LocalRemoteTest(util.LocalAsRemote): |
- reportAllTracebacks = 0 |
- |
- def sync_add1(self, x): |
- return x + 1 |
- |
- def async_add(self, x=0, y=1): |
- return x + y |
- |
- def async_fail(self): |
- raise RuntimeError() |
- |
- |
- |
-class TestRealm(object): |
- """ |
- 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. |
- """ |
- |
- def __init__(self): |
- self.p = MyPerspective() |
- |
- def requestAvatar(self, avatarId, mind, interface): |
- """ |
- 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. |
- """ |
- assert interface == pb.IPerspective |
- assert mind == "BRAINS!" |
- if avatarId is checkers.ANONYMOUS: |
- return pb.IPerspective, Echoer(), lambda: None |
- else: |
- self.p.loggedIn = 1 |
- return pb.IPerspective, self.p, self.p.logout |
- |
- |
- |
-class MyPerspective(pb.Avatar): |
- |
- implements(pb.IPerspective) |
- |
- loggedIn = loggedOut = False |
- |
- def __init__(self): |
- pass |
- |
- |
- def perspective_getViewPoint(self): |
- return MyView() |
- |
- |
- def perspective_add(self, a, b): |
- """ |
- 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}. |
- """ |
- return a + b |
- |
- |
- def logout(self): |
- self.loggedOut = True |
- |
- |
- |
-class MyView(pb.Viewable): |
- |
- def view_check(self, user): |
- return isinstance(user, MyPerspective) |
- |
- |
- |
-class NewCredTestCase(unittest.TestCase): |
- """ |
- Tests related to the L{twisted.cred} support in PB. |
- """ |
- def setUp(self): |
- """ |
- 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. |
- """ |
- self.realm = TestRealm() |
- self.portal = portal.Portal(self.realm) |
- self.factory = pb.PBServerFactory(self.portal) |
- self.port = reactor.listenTCP(0, self.factory, interface="127.0.0.1") |
- self.portno = self.port.getHost().port |
- |
- |
- def tearDown(self): |
- """ |
- Shut down the TCP port created by L{setUp}. |
- """ |
- return self.port.stopListening() |
- |
- def getFactoryAndRootObject(self, clientFactory=pb.PBClientFactory): |
- factory = clientFactory() |
- rootObjDeferred = factory.getRootObject() |
- reactor.connectTCP('127.0.0.1', self.portno, factory) |
- return factory, rootObjDeferred |
- |
- |
- def test_getRootObject(self): |
- """ |
- Assert only that L{PBClientFactory.getRootObject}'s Deferred fires with |
- a L{RemoteReference}. |
- """ |
- factory, rootObjDeferred = self.getFactoryAndRootObject() |
- |
- def gotRootObject(rootObj): |
- self.failUnless(isinstance(rootObj, pb.RemoteReference)) |
- disconnectedDeferred = defer.Deferred() |
- rootObj.notifyOnDisconnect(disconnectedDeferred.callback) |
- factory.disconnect() |
- return disconnectedDeferred |
- |
- return rootObjDeferred.addCallback(gotRootObject) |
- |
- |
- def test_deadReferenceError(self): |
- """ |
- Test that when a connection is lost, calling a method on a |
- RemoteReference obtained from it raises DeadReferenceError. |
- """ |
- factory, rootObjDeferred = self.getFactoryAndRootObject() |
- |
- def gotRootObject(rootObj): |
- disconnectedDeferred = defer.Deferred() |
- rootObj.notifyOnDisconnect(disconnectedDeferred.callback) |
- |
- def lostConnection(ign): |
- self.assertRaises( |
- pb.DeadReferenceError, |
- rootObj.callRemote, 'method') |
- |
- disconnectedDeferred.addCallback(lostConnection) |
- factory.disconnect() |
- return disconnectedDeferred |
- |
- return rootObjDeferred.addCallback(gotRootObject) |
- |
- |
- def test_clientConnectionLost(self): |
- """ |
- 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. |
- """ |
- class ReconnectOnce(pb.PBClientFactory): |
- reconnectedAlready = False |
- def clientConnectionLost(self, connector, reason): |
- reconnecting = not self.reconnectedAlready |
- self.reconnectedAlready = True |
- if reconnecting: |
- connector.connect() |
- return pb.PBClientFactory.clientConnectionLost( |
- self, connector, reason, reconnecting) |
- |
- factory, rootObjDeferred = self.getFactoryAndRootObject(ReconnectOnce) |
- |
- def gotRootObject(rootObj): |
- self.assertIsInstance(rootObj, pb.RemoteReference) |
- |
- d = defer.Deferred() |
- rootObj.notifyOnDisconnect(d.callback) |
- factory.disconnect() |
- |
- def disconnected(ign): |
- d = factory.getRootObject() |
- |
- def gotAnotherRootObject(anotherRootObj): |
- self.assertIsInstance(anotherRootObj, pb.RemoteReference) |
- |
- d = defer.Deferred() |
- anotherRootObj.notifyOnDisconnect(d.callback) |
- factory.disconnect() |
- return d |
- return d.addCallback(gotAnotherRootObject) |
- return d.addCallback(disconnected) |
- return rootObjDeferred.addCallback(gotRootObject) |
- |
- |
- def test_immediateClose(self): |
- """ |
- Test that if a Broker loses its connection without receiving any bytes, |
- it doesn't raise any exceptions or log any errors. |
- """ |
- serverProto = self.factory.buildProtocol(('127.0.0.1', 12345)) |
- serverProto.makeConnection(protocol.FileWrapper(StringIO())) |
- serverProto.connectionLost(failure.Failure(main.CONNECTION_DONE)) |
- |
- |
- def test_loginConnectionRefused(self): |
- """ |
- L{PBClientFactory.login} returns a L{Deferred} which is errbacked |
- with the L{ConnectionRefusedError} if the underlying connection is |
- refused. |
- """ |
- clientFactory = pb.PBClientFactory() |
- loginDeferred = clientFactory.login( |
- credentials.UsernamePassword("foo", "bar")) |
- clientFactory.clientConnectionFailed( |
- None, |
- failure.Failure( |
- ConnectionRefusedError("Test simulated refused connection"))) |
- return self.assertFailure(loginDeferred, ConnectionRefusedError) |
- |
- |
- def test_loginLogout(self): |
- """ |
- Test that login can be performed with IUsernamePassword credentials and |
- that when the connection is dropped the avatar is logged out. |
- """ |
- self.portal.registerChecker( |
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass')) |
- factory = pb.PBClientFactory() |
- creds = credentials.UsernamePassword("user", "pass") |
- |
- # NOTE: real code probably won't need anything where we have the |
- # "BRAINS!" argument, passing None is fine. We just do it here to |
- # test that it is being passed. It is used to give additional info to |
- # the realm to aid perspective creation, if you don't need that, |
- # ignore it. |
- mind = "BRAINS!" |
- |
- d = factory.login(creds, mind) |
- def cbLogin(perspective): |
- self.assertEquals(self.realm.p.loggedIn, 1) |
- self.assert_(isinstance(perspective, pb.RemoteReference)) |
- |
- factory.disconnect() |
- d = Deferred() |
- reactor.callLater(1.0, d.callback, None) |
- return d |
- d.addCallback(cbLogin) |
- |
- def cbLogout(ignored): |
- self.assertEquals(self.realm.p.loggedOut, 1) |
- d.addCallback(cbLogout) |
- |
- reactor.connectTCP("127.0.0.1", self.portno, factory) |
- return d |
- |
- |
- def test_badUsernamePasswordLogin(self): |
- """ |
- Test that a login attempt with an invalid user or invalid password |
- fails in the appropriate way. |
- """ |
- self.portal.registerChecker( |
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass')) |
- factory = pb.PBClientFactory() |
- |
- firstLogin = factory.login( |
- credentials.UsernamePassword('nosuchuser', 'pass')) |
- secondLogin = factory.login( |
- credentials.UsernamePassword('user', 'wrongpass')) |
- |
- self.assertFailure(firstLogin, UnauthorizedLogin) |
- self.assertFailure(secondLogin, UnauthorizedLogin) |
- d = gatherResults([firstLogin, secondLogin]) |
- |
- def cleanup(passthrough): |
- self.flushLoggedErrors(UnauthorizedLogin) |
- factory.disconnect() |
- return passthrough |
- d.addBoth(cleanup) |
- |
- reactor.connectTCP("127.0.0.1", self.portno, factory) |
- return d |
- |
- |
- def test_anonymousLogin(self): |
- """ |
- Verify that a PB server using a portal configured with an checker which |
- allows IAnonymous credentials can be logged into using IAnonymous |
- credentials. |
- """ |
- self.portal.registerChecker(checkers.AllowAnonymousAccess()) |
- factory = pb.PBClientFactory() |
- d = factory.login(credentials.Anonymous(), "BRAINS!") |
- |
- def cbLoggedIn(perspective): |
- return perspective.callRemote('echo', 123) |
- d.addCallback(cbLoggedIn) |
- |
- d.addCallback(self.assertEqual, 123) |
- |
- def cleanup(passthrough): |
- factory.disconnect() |
- d = Deferred() |
- reactor.callLater(1.0, d.callback, None) |
- return d |
- d.addBoth(cleanup) |
- |
- reactor.connectTCP("127.0.0.1", self.portno, factory) |
- return d |
- |
- |
- def test_anonymousLoginNotPermitted(self): |
- """ |
- Verify that without an anonymous checker set up, anonymous login is |
- rejected. |
- """ |
- self.portal.registerChecker( |
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass')) |
- factory = pb.PBClientFactory() |
- d = factory.login(credentials.Anonymous(),"BRAINS!") |
- self.assertFailure(d, UnhandledCredentials) |
- |
- def cleanup(passthrough): |
- self.flushLoggedErrors(UnhandledCredentials) |
- factory.disconnect() |
- return passthrough |
- d.addBoth(cleanup) |
- |
- reactor.connectTCP('127.0.0.1', self.portno, factory) |
- return d |
- |
- |
- def test_anonymousLoginWithMultipleCheckers(self): |
- """ |
- Like L{test_anonymousLogin} but against a portal with a checker for |
- both IAnonymous and IUsernamePassword. |
- """ |
- self.portal.registerChecker(checkers.AllowAnonymousAccess()) |
- self.portal.registerChecker( |
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass')) |
- factory = pb.PBClientFactory() |
- d = factory.login(credentials.Anonymous(), "BRAINS!") |
- |
- def cbLogin(perspective): |
- return perspective.callRemote('echo', 123) |
- d.addCallback(cbLogin) |
- |
- d.addCallback(self.assertEqual, 123) |
- |
- def cleanup(passthrough): |
- factory.disconnect() |
- return passthrough |
- d.addBoth(cleanup) |
- |
- reactor.connectTCP('127.0.0.1', self.portno, factory) |
- return d |
- |
- |
- def test_authenticatedLoginWithMultipleCheckers(self): |
- """ |
- Like L{test_anonymousLoginWithMultipleCheckers} but check that |
- username/password authentication works. |
- """ |
- self.portal.registerChecker(checkers.AllowAnonymousAccess()) |
- self.portal.registerChecker( |
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass')) |
- factory = pb.PBClientFactory() |
- d = factory.login( |
- credentials.UsernamePassword('user', 'pass'), "BRAINS!") |
- |
- def cbLogin(perspective): |
- return perspective.callRemote('add', 100, 23) |
- d.addCallback(cbLogin) |
- |
- d.addCallback(self.assertEqual, 123) |
- |
- def cleanup(passthrough): |
- factory.disconnect() |
- return passthrough |
- d.addBoth(cleanup) |
- |
- reactor.connectTCP('127.0.0.1', self.portno, factory) |
- return d |
- |
- |
- def test_view(self): |
- """ |
- Verify that a viewpoint can be retrieved after authenticating with |
- cred. |
- """ |
- self.portal.registerChecker( |
- checkers.InMemoryUsernamePasswordDatabaseDontUse(user='pass')) |
- factory = pb.PBClientFactory() |
- d = factory.login( |
- credentials.UsernamePassword("user", "pass"), "BRAINS!") |
- |
- def cbLogin(perspective): |
- return perspective.callRemote("getViewPoint") |
- d.addCallback(cbLogin) |
- |
- def cbView(viewpoint): |
- return viewpoint.callRemote("check") |
- d.addCallback(cbView) |
- |
- d.addCallback(self.failUnless) |
- |
- def cleanup(passthrough): |
- factory.disconnect() |
- d = Deferred() |
- reactor.callLater(1.0, d.callback, None) |
- return d |
- d.addBoth(cleanup) |
- |
- reactor.connectTCP("127.0.0.1", self.portno, factory) |
- return d |
- |
- |
- |
-class NonSubclassingPerspective: |
- implements(pb.IPerspective) |
- |
- # IPerspective implementation |
- def perspectiveMessageReceived(self, broker, message, args, kwargs): |
- args = broker.unserialize(args, self) |
- kwargs = broker.unserialize(kwargs, self) |
- return broker.serialize((message, args, kwargs)) |
- |
- # Methods required by TestRealm |
- def logout(self): |
- self.loggedOut = True |
- |
- |
- |
-class NSPTestCase(unittest.TestCase): |
- def setUp(self): |
- self.realm = TestRealm() |
- self.realm.p = NonSubclassingPerspective() |
- self.portal = portal.Portal(self.realm) |
- self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse() |
- self.checker.addUser("user", "pass") |
- self.portal.registerChecker(self.checker) |
- self.factory = pb.PBServerFactory(self.portal) |
- self.port = reactor.listenTCP(0, self.factory, interface="127.0.0.1") |
- self.portno = self.port.getHost().port |
- |
- def tearDown(self): |
- return self.port.stopListening() |
- |
- def test_NSP(self): |
- factory = pb.PBClientFactory() |
- d = factory.login(credentials.UsernamePassword('user', 'pass'), |
- "BRAINS!") |
- reactor.connectTCP('127.0.0.1', self.portno, factory) |
- d.addCallback(lambda p: p.callRemote('ANYTHING', 'here', bar='baz')) |
- d.addCallback(self.assertEquals, |
- ('ANYTHING', ('here',), {'bar': 'baz'})) |
- d.addCallback(lambda res: factory.disconnect()) |
- return d |
- |
- |
- |
-class IForwarded(Interface): |
- """ |
- Interface used for testing L{util.LocalAsyncForwarder}. |
- """ |
- |
- def forwardMe(): |
- """ |
- Simple synchronous method. |
- """ |
- |
- def forwardDeferred(): |
- """ |
- Simple asynchronous method. |
- """ |
- |
- |
-class Forwarded: |
- """ |
- 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} |
- """ |
- implements(IForwarded) |
- forwarded = False |
- unforwarded = False |
- |
- def forwardMe(self): |
- """ |
- Set a local flag to test afterwards. |
- """ |
- self.forwarded = True |
- |
- def dontForwardMe(self): |
- """ |
- Set a local flag to test afterwards. This should not be called as it's |
- not in the interface. |
- """ |
- self.unforwarded = True |
- |
- def forwardDeferred(self): |
- """ |
- Asynchronously return C{True}. |
- """ |
- return defer.succeed(True) |
- |
- |
-class SpreadUtilTestCase(unittest.TestCase): |
- """ |
- Tests for L{twisted.spread.util}. |
- """ |
- |
- def test_sync(self): |
- """ |
- Call a synchronous method of a L{util.LocalAsRemote} object and check |
- the result. |
- """ |
- o = LocalRemoteTest() |
- self.assertEquals(o.callRemote("add1", 2), 3) |
- |
- def test_async(self): |
- """ |
- Call an asynchronous method of a L{util.LocalAsRemote} object and check |
- the result. |
- """ |
- o = LocalRemoteTest() |
- o = LocalRemoteTest() |
- d = o.callRemote("add", 2, y=4) |
- self.assertTrue(isinstance(d, defer.Deferred)) |
- d.addCallback(self.assertEquals, 6) |
- return d |
- |
- def test_asyncFail(self): |
- """ |
- Test a asynchronous failure on a remote method call. |
- """ |
- l = [] |
- o = LocalRemoteTest() |
- d = o.callRemote("fail") |
- def eb(f): |
- self.assertTrue(isinstance(f, failure.Failure)) |
- f.trap(RuntimeError) |
- d.addCallbacks(lambda res: self.fail("supposed to fail"), eb) |
- return d |
- |
- def test_remoteMethod(self): |
- """ |
- Test the C{remoteMethod} facility of L{util.LocalAsRemote}. |
- """ |
- o = LocalRemoteTest() |
- m = o.remoteMethod("add1") |
- self.assertEquals(m(3), 4) |
- |
- def test_localAsyncForwarder(self): |
- """ |
- Test a call to L{util.LocalAsyncForwarder} using L{Forwarded} local |
- object. |
- """ |
- f = Forwarded() |
- lf = util.LocalAsyncForwarder(f, IForwarded) |
- lf.callRemote("forwardMe") |
- self.assertTrue(f.forwarded) |
- lf.callRemote("dontForwardMe") |
- self.assertFalse(f.unforwarded) |
- rr = lf.callRemote("forwardDeferred") |
- l = [] |
- rr.addCallback(l.append) |
- self.assertEqual(l[0], 1) |
- |
- |
- |
-class PBWithSecurityOptionsTest(unittest.TestCase): |
- """ |
- Test security customization. |
- """ |
- |
- def test_clientDefaultSecurityOptions(self): |
- """ |
- By default, client broker should use C{jelly.globalSecurity} as |
- security settings. |
- """ |
- factory = pb.PBClientFactory() |
- broker = factory.buildProtocol(None) |
- self.assertIdentical(broker.security, jelly.globalSecurity) |
- |
- |
- def test_serverDefaultSecurityOptions(self): |
- """ |
- By default, server broker should use C{jelly.globalSecurity} as |
- security settings. |
- """ |
- factory = pb.PBServerFactory(Echoer()) |
- broker = factory.buildProtocol(None) |
- self.assertIdentical(broker.security, jelly.globalSecurity) |
- |
- |
- def test_clientSecurityCustomization(self): |
- """ |
- Check that the security settings are passed from the client factory to |
- the broker object. |
- """ |
- security = jelly.SecurityOptions() |
- factory = pb.PBClientFactory(security=security) |
- broker = factory.buildProtocol(None) |
- self.assertIdentical(broker.security, security) |
- |
- |
- def test_serverSecurityCustomization(self): |
- """ |
- Check that the security settings are passed from the server factory to |
- the broker object. |
- """ |
- security = jelly.SecurityOptions() |
- factory = pb.PBServerFactory(Echoer(), security=security) |
- broker = factory.buildProtocol(None) |
- self.assertIdentical(broker.security, security) |
- |