From 266127eeb75c5b8f48c04a3872ce18ac0d553eb7 Mon Sep 17 00:00:00 2001 From: Marcel Hellkamp Date: Thu, 28 Apr 2011 20:25:14 +0200 Subject: tests: Speed up server tests. (cherry picked from commit f6fe0e6d43e211251e3b086a8e291a2fda35cb0b) --- test/servertest.py | 6 +++-- test/test_server.py | 67 ++++++++++++++++++++++++++++++++--------------------- test/testall.py | 2 +- test/tools.py | 9 +++++-- 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/test/servertest.py b/test/servertest.py index 8bf2a68..9080b27 100644 --- a/test/servertest.py +++ b/test/servertest.py @@ -1,4 +1,4 @@ -import sys, os +import sys, os, socket test_root = os.path.dirname(os.path.abspath(__file__)) os.chdir(test_root) sys.path.insert(0, os.path.dirname(test_root)) @@ -21,8 +21,10 @@ if __name__ == '__main__': port = int(sys.argv[2]) try: run(port=port, server=server, quiet=True) + except socket.error: + sys.exit(1) except ImportError: - print "Warning: Could not test %s. Import error." % server + sys.exit(128) except KeyboardInterrupt: pass diff --git a/test/test_server.py b/test/test_server.py index b251b3c..db64a6d 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -9,6 +9,7 @@ import os import signal import socket from subprocess import Popen, PIPE +import tools serverscript = os.path.join(os.path.dirname(__file__), 'servertest.py') @@ -24,38 +25,51 @@ def ping(server, port): class TestServer(unittest.TestCase): server = 'wsgiref' + skip = False def setUp(self): + if self.skip: return # Find a free port for port in range(8800, 8900): self.port = port - if not ping('127.0.0.1', port): break - else: - raise ValueError("Could not find a free port to test networking.") - # Start servertest.py in a subprocess - cmd = [sys.executable, serverscript, self.server, str(self.port)] - cmd += sys.argv[1:] # pass cmdline arguments to subprocesses - self.p = Popen(cmd, stdout=PIPE, stderr=PIPE) - # Wait for the socket to accept connections - for i in xrange(100): - time.sleep(0.1) - # Check if the process has died for some reason - if self.p.poll() != None: break - if ping('127.0.0.1', self.port): break - else: - raise AssertionError("Server took to long to start up.") + # Start servertest.py in a subprocess + cmd = [sys.executable, serverscript, self.server, str(port)] + cmd += sys.argv[1:] # pass cmdline arguments to subprocesses + self.p = Popen(cmd, stdout=PIPE, stderr=PIPE) + # Wait for the socket to accept connections + for i in xrange(100): + time.sleep(0.1) + # Accepts connections? + if ping('127.0.0.1', port): return + # Server died for some reason... + if not self.p.poll() is None: break + rv = self.p.poll() + if rv is None: + raise AssertionError("Server took to long to start up.") + if rv is 128: # Import error + tools.warn("Skipping %r test (ImportError)." % self.server) + self.skip = True + return + if rv is 3: # Port in use + continue + raise AssertionError("Could not find a free port to test server.") def tearDown(self): - while self.p.poll() is None: + if self.skip: return + for i in range(10): + if self.p.poll() != None: break os.kill(self.p.pid, signal.SIGINT) - time.sleep(0.1) - if self.p.poll() is None: - os.kill(self.p.pid, signal.SIGTERM) + time.sleep(0.1*i) + for i in range(10): + if self.p.poll() != None: break + os.kill(self.p.pid, signal.SIGINT) + time.sleep(i) for stream in (self.p.stdout, self.p.stderr): for line in stream: - if tob('Warning') in line \ - or tob('Error') in line or True: - print line.strip().decode('utf8') + if tob('warning') in line.lower(): + tools.warn(line.strip().decode('utf8')) + elif tob('error') in line.lower(): + raise AssertionError(line.strip().decode('utf8')) def fetch(self, url): try: @@ -63,12 +77,11 @@ class TestServer(unittest.TestCase): except Exception, e: return repr(e) - def test_test(self): + def test_simple(self): ''' Test a simple static page with this server adapter. ''' - if self.p.poll() == None: - self.assertEqual(tob('OK'), self.fetch('test')) - #else: - # self.assertTrue(False, "Server process down") + if self.skip: return + self.assertEqual(tob('OK'), self.fetch('test')) + class TestCherryPyServer(TestServer): diff --git a/test/testall.py b/test/testall.py index 852f8d2..73edb4b 100755 --- a/test/testall.py +++ b/test/testall.py @@ -15,7 +15,7 @@ test_names = [os.path.basename(name)[:-3] for name in test_files] if 'help' in sys.argv or '-h' in sys.argv: print print "Command line arguments:" - print + print print "fast: Skip server adapter tests." print "verbose: Print tests even if they pass." print "coverage: Measure code coverage." diff --git a/test/tools.py b/test/tools.py index 221c362..28bf290 100755 --- a/test/tools.py +++ b/test/tools.py @@ -10,6 +10,7 @@ import wsgiref import wsgiref.simple_server import wsgiref.util import wsgiref.validate +import warnings from StringIO import StringIO try: @@ -28,6 +29,10 @@ def tobs(data): ''' Transforms bytes or unicode into a byte stream. ''' return BytesIO(tob(data)) if BytesIO else StringIO(tob(data)) +def warn(message): + warnings.warn(message, stacklevel=2) + + class ServerTestBase(unittest.TestCase): def setUp(self): ''' Create a new Bottle app set it as default_app and register it to urllib2 ''' @@ -67,7 +72,7 @@ class ServerTestBase(unittest.TestCase): response.close() del response return result - + def postmultipart(self, path, fields, files): env = multipart_environ(fields, files) return self.urlopen(path, method='POST', env=env) @@ -97,7 +102,7 @@ class ServerTestBase(unittest.TestCase): err = bottle.request.environ['wsgi.errors'].errors.read() if search not in err: self.fail('The search pattern "%s" is not included in wsgi.error: %s' % (search, err)) - + def multipart_environ(fields, files): boundary = str(uuid.uuid1()) env = {'REQUEST_METHOD':'POST', -- cgit v1.2.1