Commits

agronholm  committed 132a63c

Added integration tests

  • Participants
  • Parent commits 5c0af7e

Comments (0)

Files changed (1)

File tests/test_integration.py

+"""
+Tests every client against every server.
+"""
+
+from wsgiref.simple_server import make_server
+
+from nose.twistedtools import deferred, reactor
+from nose.tools import eq_, raises
+from twisted.web.server import Site
+from twisted.internet.defer import inlineCallbacks
+import web
+
+from pyhttprpc import ApplicationError
+from pyhttprpc.server.twisted_server import TwistedRPCResource
+from pyhttprpc.client.twisted_client import TwistedRPCClient
+from pyhttprpc.client.httplib_client import HttpRPCClient
+from pyhttprpc.client.httplib2_client import Http2RPCClient
+from pyhttprpc.client.urllib2_client import Urllib2RPCClient
+from pyhttprpc.server.wsgi_server import PyRPCWSGIApplication
+from pyhttprpc.server.webcore_server import WebCorePyRPCController
+from threading import Thread
+
+
+TESTURL = 'http://localhost:8124/'
+
+class Person(object):
+    def __init__(self, firstname, lastname, position):
+        self.firstname = firstname
+        self.lastname = lastname
+        self.position = position
+
+    def __str__(self):
+        return '%s %s, %s' % (self.firstname, self.lastname, self.position)
+
+
+class DummyException(Exception):
+    pass
+
+class DummyService(object):
+    def promote(self, person):
+        person.position = 'manager'
+        return person
+
+    def raise_exception(self):
+        raise DummyException('Test exception')
+
+
+class Client(object):
+    def __init__(self, name, client):
+        self.name = name
+        self.client = client
+        self.client.add_allowed_import('test_integration\..*')
+
+    def test_serialization(self):
+        joe = Person('Joe', 'Average', 'janitor')
+        joe = self.client.execute('promote', joe)
+        eq_(type(joe), Person)
+        eq_(joe.position, 'manager')
+
+    @raises(DummyException)
+    def test_exception(self):
+        try:
+            e = self.client.execute('raise_exception')
+        except ApplicationError, e:
+            eq_(str(e.__cause__), 'Test exception')
+            raise e.__cause__
+
+
+class TwistedClient(Client):
+    @deferred(2)
+    @inlineCallbacks
+    def test_serialization(self):
+        joe = Person('Joe', 'Average', 'janitor')
+        joe = yield self.client.execute('promote', joe)
+        eq_(type(joe), Person)
+        eq_(joe.position, 'manager')
+
+    @raises(DummyException)
+    @deferred(2)
+    @inlineCallbacks
+    def test_exception(self):
+        try:
+            e = yield self.client.execute('raise_exception')
+        except ApplicationError, e:
+            eq_(str(e.__cause__), 'Test exception')
+            raise e.__cause__
+
+
+class Server(object):
+    def __init__(self, name, port, app):
+        self.name = name
+        self.port = port
+        self.app = app
+        if hasattr(app, 'add_allowed_import'):
+            self.app.add_allowed_import('test_integration\..*')
+
+    def setup(self):
+        self.server = make_server('localhost', self.port, self.app)
+        self.server.RequestHandlerClass.log_message = lambda *args: None
+        self.thread = Thread(target=self.server.serve_forever)
+        self.thread.daemon = True
+        self.thread.start()
+
+    def teardown(self):
+        self.server = None
+        self.thread = None
+
+
+class TwistedServer(Server):
+    def setup(self):
+        reactor.callFromThread(reactor.listenTCP, self.port, Site(self.app))
+
+    def teardown(self):
+        pass
+
+
+def make_servers():
+    yield Server('WSGI', 8124, PyRPCWSGIApplication(DummyService()))
+    
+    root = WebCorePyRPCController(DummyService())
+    root.add_allowed_import('test_integration\..*')
+    app = web.core.Application.factory(root=root, debug=False)
+    yield Server('WebCore', 8125, app)
+
+    resource = TwistedRPCResource(DummyService(), reactor)
+    yield TwistedServer('Twisted', 8126, resource)
+
+
+def make_clients(port):
+    url = 'http://localhost:%d/' % port
+    yield Client('httplib', HttpRPCClient(url))
+    yield Client('httplib2', Http2RPCClient(url))
+    yield Client('urllib2', Urllib2RPCClient(url))
+    yield TwistedClient('twisted', TwistedRPCClient(url, reactor))
+
+
+def test_integration():
+    func_names = [n for n in dir(Client) if n.startswith('test_')]
+    for server in make_servers():
+        server.setup()
+        for client in make_clients(server.port):
+            for funcname in func_names:
+                func = getattr(client, funcname)
+                run_test = lambda: func()
+                run_test.description = \
+                    '%s <-> %s (%s)' % (client.name, server.name, funcname)
+                yield run_test
+        server.teardown()