From: Ben Darnell Date: Thu, 30 Aug 2012 23:44:42 +0000 (-0400) Subject: Replace our hacky homegrown test skipping with unittest.skip. X-Git-Tag: v3.0.0~263^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1a0aea3856f411b237b4f4ed36b0032d355e02c;p=thirdparty%2Ftornado.git Replace our hacky homegrown test skipping with unittest.skip. Add a test runner that makes the output for skipped tests more informative. --- diff --git a/tornado/test/curl_httpclient_test.py b/tornado/test/curl_httpclient_test.py index a6da39fb9..bfda1817e 100644 --- a/tornado/test/curl_httpclient_test.py +++ b/tornado/test/curl_httpclient_test.py @@ -1,5 +1,6 @@ from __future__ import absolute_import, division, with_statement -from tornado.test.httpclient_test import HTTPClientCommonTestCase +from tornado.test import httpclient_test +from tornado.test.util import unittest try: import pycurl @@ -10,16 +11,12 @@ if pycurl is not None: from tornado.curl_httpclient import CurlAsyncHTTPClient -class CurlHTTPClientCommonTestCase(HTTPClientCommonTestCase): +class CurlHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase): def get_http_client(self): client = CurlAsyncHTTPClient(io_loop=self.io_loop) # make sure AsyncHTTPClient magic doesn't give us the wrong class self.assertTrue(isinstance(client, CurlAsyncHTTPClient)) return client - -# Remove the base class from our namespace so the unittest module doesn't -# try to run it again. -del HTTPClientCommonTestCase - -if pycurl is None: - del CurlHTTPClientCommonTestCase +CurlHTTPClientCommonTestCase = unittest.skipIf(pycurl is None, + "pycurl module not present")( + CurlHTTPClientCommonTestCase) diff --git a/tornado/test/httpserver_test.py b/tornado/test/httpserver_test.py index 415727150..69af3a0ed 100644 --- a/tornado/test/httpserver_test.py +++ b/tornado/test/httpserver_test.py @@ -48,6 +48,17 @@ class HelloWorldRequestHandler(RequestHandler): self.finish("Got %d bytes in POST" % len(self.request.body)) +skipIfNoSSL = unittest.skipIf(ssl is None, "ssl module not present") +# In pre-1.0 versions of openssl, SSLv23 clients always send SSLv2 +# ClientHello messages, which are rejected by SSLv3 and TLSv1 +# servers. Note that while the OPENSSL_VERSION_INFO was formally +# introduced in python3.2, it was present but undocumented in +# python 2.7 +skipIfOldSSL = unittest.skipIf( + getattr(ssl, 'OPENSSL_VERSION_INFO', (0, 0)) < (1, 0), + "old version of ssl module and/or openssl") + + class BaseSSLTest(AsyncHTTPSTestCase, LogTrapTestCase): def get_app(self): return Application([('/', HelloWorldRequestHandler, @@ -91,16 +102,18 @@ class SSLTestMixin(object): class SSLv23Test(BaseSSLTest, SSLTestMixin): def get_ssl_version(self): return ssl.PROTOCOL_SSLv23 +SSLv23Test = skipIfNoSSL(SSLv23Test) class SSLv3Test(BaseSSLTest, SSLTestMixin): def get_ssl_version(self): return ssl.PROTOCOL_SSLv3 - +SSLv3Test = skipIfNoSSL(skipIfOldSSL(SSLv3Test)) class TLSv1Test(BaseSSLTest, SSLTestMixin): def get_ssl_version(self): return ssl.PROTOCOL_TLSv1 +TLSv1Test = skipIfNoSSL(skipIfOldSSL(TLSv1Test)) class BadSSLOptionsTest(unittest.TestCase): @@ -132,19 +145,6 @@ class BadSSLOptionsTest(unittest.TestCase): }) -if ssl is None: - del BaseSSLTest - del SSLv23Test -if getattr(ssl, 'OPENSSL_VERSION_INFO', (0, 0)) < (1, 0): - # In pre-1.0 versions of openssl, SSLv23 clients always send SSLv2 - # ClientHello messages, which are rejected by SSLv3 and TLSv1 - # servers. Note that while the OPENSSL_VERSION_INFO was formally - # introduced in python3.2, it was present but undocumented in - # python 2.7 - del SSLv3Test - del TLSv1Test - - class MultipartTestHandler(RequestHandler): def post(self): self.finish({"header": self.request.headers["X-Header-Encoding-Test"], @@ -390,6 +390,6 @@ class UnixSocketTest(AsyncTestCase, LogTrapTestCase): self.assertEqual(body, b("Hello world")) stream.close() server.stop() - -if not hasattr(socket, 'AF_UNIX') or sys.platform == 'cygwin': - del UnixSocketTest +UnixSocketTest = unittest.skipIf( + not hasattr(socket, 'AF_UNIX') or sys.platform == 'cygwin', + "unix sockets not supported on this platform") diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index 3b051d34e..485f630a0 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -3,6 +3,7 @@ from tornado import netutil from tornado.ioloop import IOLoop from tornado.iostream import IOStream, SSLIOStream from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, LogTrapTestCase, get_unused_port +from tornado.test.util import unittest from tornado.util import b from tornado.web import RequestHandler, Application import errno @@ -18,6 +19,7 @@ try: except ImportError: ssl = None +skipIfNoSSL = unittest.skipIf(ssl is None, "ssl module not present") class HelloHandler(RequestHandler): def get(self): @@ -308,7 +310,8 @@ class TestIOStreamMixin(object): # "frozen write buffer" assumption. if (isinstance(server, SSLIOStream) and platform.python_implementation() == 'PyPy'): - return + raise unittest.SkipTest( + "pypy gc causes problems with openssl") except AttributeError: # python 2.5 didn't have platform.python_implementation, # but there was no pypy for 2.5 @@ -359,6 +362,7 @@ class TestIOStreamWebHTTPS(TestIOStreamWebMixin, AsyncHTTPSTestCase, LogTrapTestCase): def _make_client_iostream(self): return SSLIOStream(socket.socket(), io_loop=self.io_loop) +TestIOStreamWebHTTPS = skipIfNoSSL(TestIOStreamWebHTTPS) class TestIOStream(TestIOStreamMixin, AsyncTestCase, LogTrapTestCase): @@ -383,7 +387,4 @@ class TestIOStreamSSL(TestIOStreamMixin, AsyncTestCase, LogTrapTestCase): def _make_client_iostream(self, connection, **kwargs): return SSLIOStream(connection, io_loop=self.io_loop, **kwargs) - -if ssl is None: - del TestIOStreamWebHTTPS - del TestIOStreamSSL +TestIOStreamSSL = skipIfNoSSL(TestIOStreamSSL) diff --git a/tornado/test/process_test.py b/tornado/test/process_test.py index 65e9796f6..ab3ab9aa6 100644 --- a/tornado/test/process_test.py +++ b/tornado/test/process_test.py @@ -13,6 +13,7 @@ from tornado.netutil import bind_sockets from tornado.process import fork_processes, task_id from tornado.simple_httpclient import SimpleAsyncHTTPClient from tornado.testing import LogTrapTestCase, get_unused_port +from tornado.test.util import unittest from tornado.web import RequestHandler, Application # Not using AsyncHTTPTestCase because we need control over the IOLoop. @@ -123,8 +124,5 @@ class ProcessTest(LogTrapTestCase): except Exception: logging.error("exception in child process %d", id, exc_info=True) raise - - -if os.name != 'posix' or sys.platform == 'cygwin': - # All sorts of unixisms here - del ProcessTest +ProcessTest = unittest.skipIf(os.name != 'posix' or sys.platform == 'cygwin', + "non-unix platform")(ProcessTest) diff --git a/tornado/test/runtests.py b/tornado/test/runtests.py index 29c82d4db..cba692f21 100644 --- a/tornado/test/runtests.py +++ b/tornado/test/runtests.py @@ -1,6 +1,7 @@ #!/usr/bin/env python from __future__ import absolute_import, division, with_statement +import textwrap import sys from tornado.test.util import unittest @@ -35,6 +36,17 @@ TEST_MODULES = [ def all(): return unittest.defaultTestLoader.loadTestsFromNames(TEST_MODULES) +class TornadoTextTestRunner(unittest.TextTestRunner): + def run(self, test): + result = super(TornadoTextTestRunner, self).run(test) + if result.skipped: + skip_reasons = set(reason for (test, reason) in result.skipped) + self.stream.write(textwrap.fill( + "Some tests were skipped because: %s" % + ", ".join(sorted(skip_reasons)))) + self.stream.write("\n") + return result + if __name__ == '__main__': # The -W command-line option does not work in a virtualenv with # python 3 (as of virtualenv 1.7), so configure warnings @@ -62,4 +74,5 @@ if __name__ == '__main__': # suppresses this behavior, although this looks like an implementation # detail. http://bugs.python.org/issue15626 kwargs['warnings'] = False + kwargs['testRunner'] = TornadoTextTestRunner tornado.testing.main(**kwargs) diff --git a/tornado/test/simple_httpclient_test.py b/tornado/test/simple_httpclient_test.py index 9c5ea89a3..4ab018431 100644 --- a/tornado/test/simple_httpclient_test.py +++ b/tornado/test/simple_httpclient_test.py @@ -14,23 +14,21 @@ from tornado.httpclient import AsyncHTTPClient from tornado.httputil import HTTPHeaders from tornado.ioloop import IOLoop from tornado.simple_httpclient import SimpleAsyncHTTPClient, _DEFAULT_CA_CERTS -from tornado.test.httpclient_test import HTTPClientCommonTestCase, ChunkHandler, CountdownHandler, HelloWorldHandler +from tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWorldHandler +from tornado.test import httpclient_test from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, LogTrapTestCase, get_unused_port +from tornado.test.util import unittest from tornado.util import b from tornado.web import RequestHandler, Application, asynchronous, url -class SimpleHTTPClientCommonTestCase(HTTPClientCommonTestCase): +class SimpleHTTPClientCommonTestCase(httpclient_test.HTTPClientCommonTestCase): def get_http_client(self): client = SimpleAsyncHTTPClient(io_loop=self.io_loop, force_instance=True) self.assertTrue(isinstance(client, SimpleAsyncHTTPClient)) return client -# Remove the base class from our namespace so the unittest module doesn't -# try to run it again. -del HTTPClientCommonTestCase - class TriggerHandler(RequestHandler): def initialize(self, queue, wake_callback): @@ -218,10 +216,8 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase): # trigger the hanging request to let it clean up after itself self.triggers.popleft()() + @unittest.skipIf(not socket.has_ipv6, 'ipv6 support not present') def test_ipv6(self): - if not socket.has_ipv6: - # python compiled without ipv6 support, so skip this test - return try: self.http_server.listen(self.get_http_port(), address='::1') except socket.gaierror, e: diff --git a/tornado/test/twisted_test.py b/tornado/test/twisted_test.py index 3178f94dd..997dc1298 100644 --- a/tornado/test/twisted_test.py +++ b/tornado/test/twisted_test.py @@ -49,6 +49,8 @@ from tornado.test.util import unittest from tornado.util import import_object from tornado.web import RequestHandler, Application +skipIfNoTwisted = unittest.skipUnless(have_twisted, + "twisted module not present") def save_signal_handlers(): saved = {} @@ -91,7 +93,7 @@ class ReactorWhenRunningTest(ReactorTestCase): def anotherWhenRunningCallback(self): self._anotherWhenRunningCalled = True - +ReactorWhenRunningTest = skipIfNoTwisted(ReactorWhenRunningTest) class ReactorCallLaterTest(ReactorTestCase): def test_callLater(self): @@ -109,6 +111,7 @@ class ReactorCallLaterTest(ReactorTestCase): self._laterCalled = True self._called = self._reactor.seconds() self._reactor.stop() +ReactorCallLaterTest = skipIfNoTwisted(ReactorCallLaterTest) class ReactorTwoCallLaterTest(ReactorTestCase): @@ -137,6 +140,7 @@ class ReactorTwoCallLaterTest(ReactorTestCase): self._later2Called = True self._called2 = self._reactor.seconds() self._reactor.stop() +ReactorTwoCallLaterTest = skipIfNoTwisted(ReactorTwoCallLaterTest) class ReactorCallFromThreadTest(ReactorTestCase): @@ -165,6 +169,7 @@ class ReactorCallFromThreadTest(ReactorTestCase): def testCallFromThread(self): self._reactor.callWhenRunning(self._whenRunningCallback) self._reactor.run() +ReactorCallFromThreadTest = skipIfNoTwisted(ReactorCallFromThreadTest) class ReactorCallInThread(ReactorTestCase): @@ -182,6 +187,7 @@ class ReactorCallInThread(ReactorTestCase): def testCallInThread(self): self._reactor.callWhenRunning(self._whenRunningCallback) self._reactor.run() +ReactorCallInThread = skipIfNoTwisted(ReactorCallInThread) class Reader(object): @@ -314,6 +320,7 @@ class ReactorReaderWriterTest(ReactorTestCase): def testNoWriter(self): self._reactor.callWhenRunning(self._testNoWriter) self._reactor.run() +ReactorReaderWriterTest = skipIfNoTwisted(ReactorReaderWriterTest) # Test various combinations of twisted and tornado http servers, # http clients, and event loop interfaces. @@ -424,17 +431,10 @@ class CompatibilityTests(unittest.TestCase): response = self.twisted_fetch( 'http://localhost:%d' % self.tornado_port, self.run_reactor) self.assertEqual(response, 'Hello from tornado!') +CompatibilityTests = skipIfNoTwisted(CompatibilityTests) -if not have_twisted: - del ReactorWhenRunningTest - del ReactorCallLaterTest - del ReactorTwoCallLaterTest - del ReactorCallFromThreadTest - del ReactorCallInThread - del ReactorReaderWriterTest - del CompatibilityTests -else: +if have_twisted: # Import and run as much of twisted's test suite as possible. # This is unfortunately rather dependent on implementation details, # but there doesn't appear to be a clean all-in-one conformance test diff --git a/tornado/test/wsgi_test.py b/tornado/test/wsgi_test.py index 568bb116e..4eb4bfa93 100644 --- a/tornado/test/wsgi_test.py +++ b/tornado/test/wsgi_test.py @@ -65,19 +65,16 @@ class WSGIApplicationTest(AsyncHTTPTestCase, LogTrapTestCase): # This is kind of hacky, but run some of the HTTPServer tests through # WSGIContainer and WSGIApplication to make sure everything survives # repeated disassembly and reassembly. -from tornado.test.httpserver_test import HTTPConnectionTest -from tornado.test.web_test import WSGISafeWebTest +from tornado.test import httpserver_test +from tornado.test import web_test -class WSGIConnectionTest(HTTPConnectionTest): +class WSGIConnectionTest(httpserver_test.HTTPConnectionTest): def get_app(self): return WSGIContainer(validator(WSGIApplication(self.get_handlers()))) -class WSGIWebTest(WSGISafeWebTest): +class WSGIWebTest(web_test.WSGISafeWebTest): def get_app(self): self.app = WSGIApplication(self.get_handlers(), **self.get_app_kwargs()) return WSGIContainer(validator(self.app)) - -del HTTPConnectionTest -del WSGISafeWebTest