Mercurial > p > roundup > code
view test/wsgi_liveserver.py @ 8570:16e8bacb8f90
test: strftime formats; Runtime v Parsing error config.ini windows python
strftime formats like "%2d" are not supported by windows python.
So limit testing to non-win32 platform.
In tests RuntimeError (not ParsingError) was returned for an invalid
config.ini parse error with 3.12 and newer. Windows Python 3.11.4
returns RuntimeError as well. Changed guard that chooses RuntimeError
to 3.11.4 or newer.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Mon, 13 Apr 2026 13:28:58 -0400 |
| parents | 3630246c5c36 |
| children |
line wrap: on
line source
# -*- coding: utf-8 -*- """ wsgi-liveserver provides a simple LiverServerTestCase class that can be used to help start a web server in the background to serve a WSGI compliant application for use with testing. Generally it will be used in conjuction with something like Selenium to perform a series of functional tests using a browser. Licensed under the GNU GPL v3 Copyright (c) 2013 John Kristensen (unless explicitly stated otherwise). """ import errno import socket import threading import unittest from wsgiref.simple_server import WSGIRequestHandler, make_server __author__ = 'John Kristensen' __version__ = '0.3.1' __license__ = 'GPLv3' """ Classmethod probe_ports() added by John Rouillard 2024. """ class QuietHandler(WSGIRequestHandler): def log_request(*args, **kwargs): pass class LiveServerTestCase(unittest.TestCase): port_range = (8080, 8090) def create_app(self): """Create your wsgi app and return it.""" raise NotImplementedError def __call__(self, result=None): """ Do some custom setup stuff and then hand off to TestCase to do its thing. """ try: self._pre_setup() super(LiveServerTestCase, self).__call__(result) finally: self._post_teardown() def url_base(self): """Return the url of the test server.""" return 'http://{0}:{1}'.format(self.host, self.port) def _pre_setup(self): """Setup and start the test server in the background.""" self._server = None self.host = 'localhost' self.port = self.port_range[0] self._thread = None # Get the app self.app = self.create_app() # Cycle through the port range to find a free port while self._server is None and self.port <= self.port_range[1]: try: self._server = make_server(self.host, self.port, self.app, handler_class=QuietHandler) except socket.error: self.port += 1 # No free port, raise an exception if self._server is None: raise socket.error('Ports {0}-{1} are all already in use'.format( *self.port_range)) # Start the test server in the background self._thread = threading.Thread(target=self._server.serve_forever) self._thread.start() def _post_teardown(self): """Stop the test server.""" if self._thread is not None: self._server.shutdown() self._server.server_close() self._thread.join() del self._server @classmethod def probe_ports(cls, start=port_range[0], end=port_range[1]): port = start while port <= end: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: s.connect(('127.0.0.1', port)) except socket.error as e: if not hasattr(e, 'args') or e.args[0] != errno.ECONNREFUSED: raise return port else: s.close() port += 1 return None
