diff --git a/CHANGES.rst b/CHANGES.rst index cf0a14a..a53f838 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -20,6 +20,10 @@ develop * Emit `django.core.signals.request_finished` to close DB connection and yield to other greenlets between processing messages from WebSocket. * Back to universal wheels, thanks to PEP-0496 environment markers. +* Expand test suite coverage to start a DDP server instance and perform + a HTTP GET request, no WebSocket/DDP tests yet. Fails in Pyton 3 + because of a bug in `gevent-websocket` + (https://bitbucket.org/noppo/gevent-websocket/issues/54/python-3-support). * Fix for #23 (Python 3 compatibility). * Set `application_name` on PostgreSQL async connection. * Send `django.core.signals.request_finished` when closing WebSocket. diff --git a/dddp/tests.py b/dddp/tests.py index 10c656e..3f98d06 100644 --- a/dddp/tests.py +++ b/dddp/tests.py @@ -1,9 +1,16 @@ """Django DDP test suite.""" +from __future__ import unicode_literals import doctest +import errno import os +import socket import unittest +from django.test import TestCase import dddp.alea +from dddp.main import DDPLauncher +# pylint: disable=E0611, F0401 +from six.moves.urllib_parse import urljoin os.environ['DJANGO_SETTINGS_MODULE'] = 'dddp.test.test_project.settings' @@ -12,12 +19,73 @@ DOCTEST_MODULES = [ ] +class DDPServerTestCase(TestCase): + + """Test case that starts a DDP server.""" + + server_addr = '127.0.0.1' + server_port_range = range(8000, 8080) + ssl_certfile_path = None + ssl_keyfile_path = None + + def setUp(self): + """Fire up the DDP server.""" + self.server_port = 8000 + kwargs = {} + if self.ssl_certfile_path: + kwargs['certfile'] = self.ssl_certfile_path + if self.ssl_keyfile_path: + kwargs['keyfile'] = self.ssl_keyfile_path + self.scheme = 'https' if kwargs else 'http' + for server_port in self.server_port_range: + self.server = DDPLauncher(debug=True) + self.server.add_web_servers( + [ + (self.server_addr, server_port), + ], + **kwargs + ) + try: + self.server.start() + self.server_port = server_port + return # server started + except socket.error as err: + if err.errno != errno.EADDRINUSE: + raise # error wasn't "address in use", re-raise. + continue # port in use, try next port. + raise RuntimeError('Failed to start DDP server.') + + def tearDown(self): + """Shut down the DDP server.""" + self.server.stop() + + def url(self, path): + """Return full URL for given path.""" + return urljoin( + '%s://%s:%d' % (self.scheme, self.server_addr, self.server_port), + path, + ) + + +class LaunchTestCase(DDPServerTestCase): + + """Test that server launches and handles GET request.""" + + def test_get(self): + """Perform HTTP GET.""" + import requests + resp = requests.get(self.url('/')) + self.assertEqual(resp.status_code, 200) + + def load_tests(loader, tests, pattern): """Specify which test cases to run.""" del pattern suite = unittest.TestSuite() # add all TestCase classes from this (current) module for attr in globals().values(): + if attr is DDPServerTestCase: + continue # not meant to be executed, is has no tests. try: if not issubclass(attr, unittest.TestCase): continue # not subclass of TestCase diff --git a/requirements-test.txt b/requirements-test.txt index dc85271..a5c10fa 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,2 +1,2 @@ # things required to run test suite -# (nothing required! we use unittest from stdlib...) +requests==2.9.0 diff --git a/setup.py b/setup.py index 9b0ca55..c310252 100644 --- a/setup.py +++ b/setup.py @@ -150,6 +150,9 @@ setuptools.setup( }, classifiers=CLASSIFIERS, test_suite='dddp.test.run_tests', + tests_require=[ + 'requests', + ], cmdclass={ 'build': Build, },