import contextlib import os import sys if sys.version_info[:2] == (2, 6): # pragma: no cover import unittest2 as unittest else: # pragma: no cover import unittest from waitress import runner class Test_match(unittest.TestCase): def test_empty(self): self.assertRaisesRegexp( ValueError, "^Malformed application ''$", runner.match, '') def test_module_only(self): self.assertRaisesRegexp( ValueError, r"^Malformed application 'foo\.bar'$", runner.match, 'foo.bar') def test_bad_module(self): self.assertRaisesRegexp( ValueError, r"^Malformed application 'foo#bar:barney'$", runner.match, 'foo#bar:barney') def test_module_obj(self): self.assertTupleEqual( runner.match('foo.bar:fred.barney'), ('foo.bar', 'fred.barney')) class Test_resolve(unittest.TestCase): def test_bad_module(self): self.assertRaises( ImportError, runner.resolve, 'nonexistent', 'nonexistent_function') def test_nonexistent_function(self): self.assertRaisesRegexp( AttributeError, r"has no attribute 'nonexistent_function'", runner.resolve, 'os.path', 'nonexistent_function') def test_simple_happy_path(self): from os.path import exists self.assertIs(runner.resolve('os.path', 'exists'), exists) def test_complex_happy_path(self): # Ensure we can recursively resolve object attributes if necessary. self.assertEquals( runner.resolve('os.path', 'exists.__name__'), 'exists') class Test_run(unittest.TestCase): def match_output(self, argv, code, regex): argv = ['waitress-serve'] + argv with capture() as captured: self.assertEqual(runner.run(argv=argv), code) self.assertRegexpMatches(captured.getvalue(), regex) captured.close() def test_bad(self): self.match_output( ['--bad-opt'], 1, '^Error: option --bad-opt not recognized') def test_help(self): self.match_output( ['--help'], 0, "^Usage:\n\n waitress-serve") def test_no_app(self): self.match_output( [], 1, "^Error: Specify one application only") def test_multiple_apps_app(self): self.match_output( ['a:a', 'b:b'], 1, "^Error: Specify one application only") def test_bad_apps_app(self): self.match_output( ['a'], 1, "^Error: Malformed application 'a'") def test_bad_app_module(self): self.match_output( ['nonexistent:a'], 1, "^Error: Bad module 'nonexistent'") self.match_output( ['nonexistent:a'], 1, ( r"There was an exception \((ImportError|ModuleNotFoundError)\) " "importing your module.\n\nIt had these arguments: \n" "1. No module named '?nonexistent'?" ) ) def test_cwd_added_to_path(self): def null_serve(app, **kw): pass sys_path = sys.path current_dir = os.getcwd() try: os.chdir(os.path.dirname(__file__)) argv = [ 'waitress-serve', 'fixtureapps.runner:app', ] self.assertEqual(runner.run(argv=argv, _serve=null_serve), 0) finally: sys.path = sys_path os.chdir(current_dir) def test_bad_app_object(self): self.match_output( ['waitress.tests.fixtureapps.runner:a'], 1, "^Error: Bad object name 'a'") def test_simple_call(self): import waitress.tests.fixtureapps.runner as _apps def check_server(app, **kw): self.assertIs(app, _apps.app) self.assertDictEqual(kw, {'port': '80'}) argv = [ 'waitress-serve', '--port=80', 'waitress.tests.fixtureapps.runner:app', ] self.assertEqual(runner.run(argv=argv, _serve=check_server), 0) def test_returned_app(self): import waitress.tests.fixtureapps.runner as _apps def check_server(app, **kw): self.assertIs(app, _apps.app) self.assertDictEqual(kw, {'port': '80'}) argv = [ 'waitress-serve', '--port=80', '--call', 'waitress.tests.fixtureapps.runner:returns_app', ] self.assertEqual(runner.run(argv=argv, _serve=check_server), 0) class Test_helper(unittest.TestCase): def test_exception_logging(self): from waitress.runner import show_exception regex = ( r"There was an exception \(ImportError\) importing your module." r"\n\nIt had these arguments: \n1. My reason" ) with capture() as captured: try: raise ImportError("My reason") except ImportError: self.assertEqual(show_exception(sys.stderr), None) self.assertRegexpMatches( captured.getvalue(), regex ) captured.close() regex = ( r"There was an exception \(ImportError\) importing your module." r"\n\nIt had no arguments." ) with capture() as captured: try: raise ImportError except ImportError: self.assertEqual(show_exception(sys.stderr), None) self.assertRegexpMatches( captured.getvalue(), regex ) captured.close() @contextlib.contextmanager def capture(): from waitress.compat import NativeIO fd = NativeIO() sys.stdout = fd sys.stderr = fd yield fd sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__