summaryrefslogtreecommitdiff
path: root/tests/test_runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_runner.py')
-rw-r--r--tests/test_runner.py191
1 files changed, 191 insertions, 0 deletions
diff --git a/tests/test_runner.py b/tests/test_runner.py
new file mode 100644
index 0000000..e53018b
--- /dev/null
+++ b/tests/test_runner.py
@@ -0,0 +1,191 @@
+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(
+ ["tests.fixtureapps.runner:a"], 1, "^Error: Bad object name 'a'"
+ )
+
+ def test_simple_call(self):
+ import 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",
+ "tests.fixtureapps.runner:app",
+ ]
+ self.assertEqual(runner.run(argv=argv, _serve=check_server), 0)
+
+ def test_returned_app(self):
+ import 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",
+ "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__