diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/api/__init__.py | 5 | ||||
-rw-r--r-- | tests/api/test_eval.py | 10 | ||||
-rw-r--r-- | tests/gunicorn_utils.py | 4 | ||||
-rw-r--r-- | tests/test_integration.py | 1 | ||||
-rw-r--r-- | tests/test_main.py | 18 | ||||
-rw-r--r-- | tests/test_nsjail.py | 90 |
6 files changed, 65 insertions, 63 deletions
diff --git a/tests/api/__init__.py b/tests/api/__init__.py index a900316..3f7d250 100644 --- a/tests/api/__init__.py +++ b/tests/api/__init__.py @@ -14,10 +14,7 @@ class SnekAPITestCase(testing.TestCase): self.patcher = mock.patch("snekbox.api.resources.eval.NsJail", autospec=True) self.mock_nsjail = self.patcher.start() self.mock_nsjail.return_value.python3.return_value = CompletedProcess( - args=[], - returncode=0, - stdout="output", - stderr="error" + args=[], returncode=0, stdout="output", stderr="error" ) self.addCleanup(self.patcher.stop) diff --git a/tests/api/test_eval.py b/tests/api/test_eval.py index 24e673a..976970e 100644 --- a/tests/api/test_eval.py +++ b/tests/api/test_eval.py @@ -20,15 +20,13 @@ class TestEvalResource(SnekAPITestCase): expected = { "title": "Request data failed validation", - "description": "'input' is a required property" + "description": "'input' is a required property", } self.assertEqual(expected, result.json) def test_post_invalid_data_400(self): - bodies = ( - {"input": 400}, {"input": "", "args": [400]} - ) + bodies = ({"input": 400}, {"input": "", "args": [400]}) for body in bodies: with self.subTest(): @@ -38,7 +36,7 @@ class TestEvalResource(SnekAPITestCase): expected = { "title": "Request data failed validation", - "description": "400 is not of type 'string'" + "description": "400 is not of type 'string'", } self.assertEqual(expected, result.json) @@ -52,7 +50,7 @@ class TestEvalResource(SnekAPITestCase): expected = { "title": "415 Unsupported Media Type", - "description": "application/xml is an unsupported media type." + "description": "application/xml is an unsupported media type.", } self.assertEqual(expected, result.json) diff --git a/tests/gunicorn_utils.py b/tests/gunicorn_utils.py index f5dae7a..5c077aa 100644 --- a/tests/gunicorn_utils.py +++ b/tests/gunicorn_utils.py @@ -29,12 +29,14 @@ class _StandaloneApplication(WSGIApplication): def _proc_target(config_path: str, event: multiprocessing.Event, **kwargs) -> None: """Run a Gunicorn app with the given config and set `event` when Gunicorn is ready.""" + def when_ready(_): event.set() app = _StandaloneApplication(config_path, when_ready=when_ready, **kwargs) import logging + logging.disable(logging.INFO) app.run() @@ -62,7 +64,7 @@ def run_gunicorn(config_path: str = "config/gunicorn.conf.py", **kwargs) -> Iter concurrent.futures.wait( [executor.submit(proc.join), executor.submit(event.wait)], timeout=60, - return_when=concurrent.futures.FIRST_COMPLETED + return_when=concurrent.futures.FIRST_COMPLETED, ) # Can't use the context manager cause wait=False needs to be set. executor.shutdown(wait=False, cancel_futures=True) diff --git a/tests/test_integration.py b/tests/test_integration.py index b76b005..7c5db2b 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -21,7 +21,6 @@ def run_code_in_snekbox(code: str) -> tuple[str, int]: class IntegrationTests(unittest.TestCase): - def test_memory_limit_separate_per_process(self): """ Each NsJail process should have its own memory limit. diff --git a/tests/test_main.py b/tests/test_main.py index 5b5bfcb..77b3130 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -12,30 +12,24 @@ import snekbox.__main__ as snekbox_main class ArgParseTests(unittest.TestCase): def test_parse_args(self): subtests = ( - ( - ["", "code"], - Namespace(code="code", nsjail_args=[], py_args=["-c"]) - ), + (["", "code"], Namespace(code="code", nsjail_args=[], py_args=["-c"])), ( ["", "code", "--time_limit", "0"], - Namespace(code="code", nsjail_args=["--time_limit", "0"], py_args=["-c"]) + Namespace(code="code", nsjail_args=["--time_limit", "0"], py_args=["-c"]), ), ( ["", "code", "---", "-m", "timeit"], - Namespace(code="code", nsjail_args=[], py_args=["-m", "timeit"]) + Namespace(code="code", nsjail_args=[], py_args=["-m", "timeit"]), ), ( ["", "code", "--time_limit", "0", "---", "-m", "timeit"], - Namespace(code="code", nsjail_args=["--time_limit", "0"], py_args=["-m", "timeit"]) + Namespace(code="code", nsjail_args=["--time_limit", "0"], py_args=["-m", "timeit"]), ), ( ["", "code", "--time_limit", "0", "---"], - Namespace(code="code", nsjail_args=["--time_limit", "0"], py_args=[]) + Namespace(code="code", nsjail_args=["--time_limit", "0"], py_args=[]), ), - ( - ["", "code", "---"], - Namespace(code="code", nsjail_args=[], py_args=[]) - ) + (["", "code", "---"], Namespace(code="code", nsjail_args=[], py_args=[])), ) for argv, expected in subtests: diff --git a/tests/test_nsjail.py b/tests/test_nsjail.py index 989cc31..a3632e6 100644 --- a/tests/test_nsjail.py +++ b/tests/test_nsjail.py @@ -5,7 +5,7 @@ import unittest import unittest.mock from textwrap import dedent -from snekbox.nsjail import NsJail, OUTPUT_MAX, READ_CHUNK_SIZE +from snekbox.nsjail import OUTPUT_MAX, READ_CHUNK_SIZE, NsJail class NsJailTests(unittest.TestCase): @@ -23,10 +23,7 @@ class NsJailTests(unittest.TestCase): self.assertEqual(result.stderr, None) def test_timeout_returns_137(self): - code = dedent(""" - while True: - pass - """).strip() + code = "while True: pass" with self.assertLogs(self.logger) as log: result = self.nsjail.python3(code) @@ -38,9 +35,7 @@ class NsJailTests(unittest.TestCase): def test_memory_returns_137(self): # Add a kilobyte just to be safe. - code = dedent(f""" - x = ' ' * {self.nsjail.config.cgroup_mem_max + 1000} - """).strip() + code = f"x = ' ' * {self.nsjail.config.cgroup_mem_max + 1000}" result = self.nsjail.python3(code) self.assertEqual(result.returncode, 137) @@ -48,7 +43,8 @@ class NsJailTests(unittest.TestCase): self.assertEqual(result.stderr, None) def test_subprocess_resource_unavailable(self): - code = dedent(""" + code = dedent( + """ import subprocess # Max PIDs is 5. @@ -60,7 +56,8 @@ class NsJailTests(unittest.TestCase): 'import time; time.sleep(1)' ], ).pid) - """).strip() + """ + ).strip() result = self.nsjail.python3(code) self.assertEqual(result.returncode, 1) @@ -68,7 +65,8 @@ class NsJailTests(unittest.TestCase): self.assertEqual(result.stderr, None) def test_multiprocess_resource_limits(self): - code = dedent(""" + code = dedent( + """ import time from multiprocessing import Process @@ -87,7 +85,8 @@ class NsJailTests(unittest.TestCase): proc_2.join() print(proc_1.exitcode, proc_2.exitcode) - """) + """ + ) result = self.nsjail.python3(code) @@ -98,10 +97,12 @@ class NsJailTests(unittest.TestCase): def test_read_only_file_system(self): for path in ("/", "/etc", "/lib", "/lib64", "/snekbox", "/usr"): with self.subTest(path=path): - code = dedent(f""" + code = dedent( + f""" with open('{path}/hello', 'w') as f: f.write('world') - """).strip() + """ + ).strip() result = self.nsjail.python3(code) self.assertEqual(result.returncode, 1) @@ -109,11 +110,13 @@ class NsJailTests(unittest.TestCase): self.assertEqual(result.stderr, None) def test_forkbomb_resource_unavailable(self): - code = dedent(""" + code = dedent( + """ import os while 1: os.fork() - """).strip() + """ + ).strip() result = self.nsjail.python3(code) self.assertEqual(result.returncode, 1) @@ -121,10 +124,12 @@ class NsJailTests(unittest.TestCase): self.assertEqual(result.stderr, None) def test_sigsegv_returns_139(self): # In honour of Juan. - code = dedent(""" + code = dedent( + """ import ctypes ctypes.string_at(0) - """).strip() + """ + ).strip() result = self.nsjail.python3(code) self.assertEqual(result.returncode, 139) @@ -144,12 +149,16 @@ class NsJailTests(unittest.TestCase): self.assertEqual(result.stderr, None) def test_unicode_env_erase_escape_fails(self): - result = self.nsjail.python3(dedent(""" - import os - import sys - os.unsetenv('PYTHONIOENCODING') - os.execl(sys.executable, 'python', '-c', 'print(chr(56550))') - """).strip()) + result = self.nsjail.python3( + dedent( + """ + import os + import sys + os.unsetenv('PYTHONIOENCODING') + os.execl(sys.executable, 'python', '-c', 'print(chr(56550))') + """ + ).strip() + ) self.assertEqual(result.returncode, None) self.assertEqual(result.stdout, "UnicodeDecodeError: invalid Unicode in output pipe") self.assertEqual(result.stderr, None) @@ -168,7 +177,7 @@ class NsJailTests(unittest.TestCase): "cmdline::setupArgv(nsjconf_t*, int, char**, int)():316 No command-line provided", "[F][2019-06-22T20:07:00+0000][16] int main(int, char**)():204 " "Couldn't parse cmdline options", - "Invalid Line" + "Invalid Line", ) with self.assertLogs(self.logger, logging.DEBUG) as log: @@ -181,16 +190,18 @@ class NsJailTests(unittest.TestCase): self.assertIn("WARNING:snekbox.nsjail:This is a warning!", log.output) self.assertIn( "INFO:snekbox.nsjail:pid=20 ([STANDALONE MODE]) exited with status: 2, (PIDs left: 0)", - log.output + log.output, ) def test_shm_and_tmp_not_mounted(self): for path in ("/dev/shm", "/run/shm", "/tmp"): with self.subTest(path=path): - code = dedent(f""" + code = dedent( + f""" with open('{path}/test', 'wb') as file: file.write(bytes([255])) - """).strip() + """ + ).strip() result = self.nsjail.python3(code) self.assertEqual(result.returncode, 1) @@ -198,13 +209,15 @@ class NsJailTests(unittest.TestCase): self.assertEqual(result.stderr, None) def test_multiprocessing_shared_memory_disabled(self): - code = dedent(""" + code = dedent( + """ from multiprocessing.shared_memory import SharedMemory try: SharedMemory('test', create=True, size=16) except FileExistsError: pass - """).strip() + """ + ).strip() result = self.nsjail.python3(code) self.assertEqual(result.returncode, 1) @@ -220,26 +233,25 @@ class NsJailTests(unittest.TestCase): def test_output_order(self): stdout_msg = "greetings from stdout!" stderr_msg = "hello from stderr!" - code = dedent(f""" + code = dedent( + f""" print({stdout_msg!r}) raise ValueError({stderr_msg!r}) - """).strip() + """ + ).strip() result = self.nsjail.python3(code) self.assertLess( result.stdout.find(stdout_msg), result.stdout.find(stderr_msg), - msg="stdout does not come before stderr" + msg="stdout does not come before stderr", ) self.assertEqual(result.stderr, None) def test_stdout_flood_results_in_graceful_sigterm(self): - stdout_flood = dedent(""" - while True: - print('abcdefghij') - """).strip() + code = "while True: print('abcdefghij')" - result = self.nsjail.python3(stdout_flood) + result = self.nsjail.python3(code) self.assertEqual(result.returncode, 143) def test_large_output_is_truncated(self): @@ -260,7 +272,7 @@ class NsJailTests(unittest.TestCase): result = self.nsjail.python3("", nsjail_args=args) end = result.args.index("--") - self.assertEqual(result.args[end - len(args):end], args) + self.assertEqual(result.args[end - len(args) : end], args) def test_py_args(self): args = ("-m", "timeit") |