diff --git a/tests/test_client.py b/tests/test_client.py new file mode 100644 index 0000000..ed9faed --- /dev/null +++ b/tests/test_client.py @@ -0,0 +1,93 @@ +import time +from multiprocessing import Process + +from twisted.internet import defer, reactor, error +from twisted.trial import unittest + +import txmsgpackrpc +from txmsgpackrpc.server import MsgpackRPCServer +from txmsgpackrpc.client import connect + + +HOST = 'localhost' +PORT = 8899 + + + +class FakeServer(MsgpackRPCServer): + def __init__(self): + pass + + def remote_wait(self, timeout): + time.sleep(timeout) + return defer.succeed('I am too slow') + + def remote_fail(self): + return defer.fail(RuntimeError) + + + def remote_ok(self): + return defer.succeed('Hi guy') + + + +def run_server(host, port): + reactor.listenTCP(port, FakeServer().getStreamFactory()) + reactor.callLater(10, reactor.stop) + reactor.run() + + + +class ClientTest(unittest.TestCase): + @defer.inlineCallbacks + def setUp(self): + self.server = Process(target=run_server, args=(HOST, PORT)) + self.server.start() + self.tested_proxy = yield connect(HOST, PORT, connectTimeout=None, waitTimeout=None) + + + @defer.inlineCallbacks + def tearDown(self): + yield self.tested_proxy.disconnect() + self.server.terminate() + + + @defer.inlineCallbacks + def test_okRequest(self): + """ + Test request returning callback + """ + real = yield self.tested_proxy.createRequest('ok') + self.assertEqual(real, 'Hi guy') + + + def test_failingRequest(self): + """ + Test request returning errback + """ + real = self.tested_proxy.createRequest('fail') + return self.assertFailure(real, txmsgpackrpc.error.ResponseError) + + + def test_lostConnection(self): + """ + Test request with connection lost on server side + """ + d = self.tested_proxy.createRequest('wait', 3) + self.server.terminate() + return self.assertFailure(d, error.ConnectionDone) + + + def test_lostClientConnection(self): + """ + When stopping factory after done some request, the exception from handler.py:81 is raised. + But the failed deferred must be returned not a synchronous exception raised + """ + def callback(data): + self.tested_proxy.factory.doStop() + self.tested_proxy.disconnect() + d = self.tested_proxy.createRequest('ok') + return self.assertFailure(d, txmsgpackrpc.error.ConnectionError) + + d1 = self.tested_proxy.createRequest('ok') + d1.addBoth(callback) diff --git a/txmsgpackrpc/handler.py b/txmsgpackrpc/handler.py index a3bc3b3..e57b650 100644 --- a/txmsgpackrpc/handler.py +++ b/txmsgpackrpc/handler.py @@ -77,7 +77,7 @@ def delConnection(self, connection): def waitForConnection(self): if not self.factory.continueTrying: - raise ConnectionError("Not connected") + return defer.fail(ConnectionError("Not connected")) if self.connection and self.connection.connected: return defer.succeed(self) @@ -227,7 +227,7 @@ def waitForEmptyPool(self): def waitForConnection(self): if not self.factory.continueTrying: - raise ConnectionError("Not connected") + return defer.fail(ConnectionError("Not connected")) if self.size: return defer.succeed(self) diff --git a/txmsgpackrpc/protocol.py b/txmsgpackrpc/protocol.py index c148a1b..6bcd56d 100644 --- a/txmsgpackrpc/protocol.py +++ b/txmsgpackrpc/protocol.py @@ -81,7 +81,7 @@ def createRequest(self, method, params): @rtype C{t.i.d.Deferred} """ if not self.isConnected(): - raise ConnectionError("Not connected") + defer.fail(ConnectionError("Not connected")) msgid = self.getNextMsgid() message = (MSGTYPE_REQUEST, msgid, method, params) ctx = self.getClientContext()