aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorGravatar Chris Goes <[email protected]>2019-06-29 15:54:28 -0600
committerGravatar GitHub <[email protected]>2019-06-29 15:54:28 -0600
commitd07e6c9a98192bd47684352633d3a18e8db2552d (patch)
tree20c732b8e952fdae9d40110715ac8e2d50dc9d88 /tests
parentMerge pull request #29 from python-discord/api-adjustments (diff)
parentUse write_text() and fix codec names (diff)
Merge pull request #31 from python-discord/testing
NsJail Tests
Diffstat (limited to 'tests')
-rw-r--r--tests/test_nsjail.py124
-rw-r--r--tests/test_snekbox.py56
2 files changed, 124 insertions, 56 deletions
diff --git a/tests/test_nsjail.py b/tests/test_nsjail.py
new file mode 100644
index 0000000..bb176d9
--- /dev/null
+++ b/tests/test_nsjail.py
@@ -0,0 +1,124 @@
+import logging
+import unittest
+from textwrap import dedent
+
+from snekbox.nsjail import MEM_MAX, NsJail
+
+
+class NsJailTests(unittest.TestCase):
+ def setUp(self):
+ super().setUp()
+
+ self.nsjail = NsJail()
+ self.nsjail.DEBUG = False
+ self.logger = logging.getLogger("snekbox.nsjail")
+
+ def test_print_returns_0(self):
+ result = self.nsjail.python3("print('test')")
+ self.assertEqual(result.returncode, 0)
+ self.assertEqual(result.stdout, "test\n")
+ self.assertEqual(result.stderr, None)
+
+ def test_timeout_returns_137(self):
+ code = dedent("""
+ while True:
+ pass
+ """).strip()
+
+ with self.assertLogs(self.logger) as log:
+ result = self.nsjail.python3(code)
+
+ self.assertEqual(result.returncode, 137)
+ self.assertEqual(result.stdout, "")
+ self.assertEqual(result.stderr, None)
+ self.assertIn("run time >= time limit", "\n".join(log.output))
+
+ def test_memory_returns_137(self):
+ # Add a kilobyte just to be safe.
+ code = dedent(f"""
+ x = ' ' * {MEM_MAX + 1000}
+ """).strip()
+
+ result = self.nsjail.python3(code)
+ self.assertEqual(result.returncode, 137)
+ self.assertEqual(result.stdout, "")
+ self.assertEqual(result.stderr, None)
+
+ def test_subprocess_resource_unavailable(self):
+ code = dedent("""
+ import subprocess
+ print(subprocess.check_output('kill -9 6', shell=True).decode())
+ """).strip()
+
+ result = self.nsjail.python3(code)
+ self.assertEqual(result.returncode, 1)
+ self.assertIn("Resource temporarily unavailable", result.stdout)
+ self.assertEqual(result.stderr, None)
+
+ def test_read_only_file_system(self):
+ code = dedent("""
+ open('hello', 'w').write('world')
+ """).strip()
+
+ result = self.nsjail.python3(code)
+ self.assertEqual(result.returncode, 1)
+ self.assertIn("Read-only file system", result.stdout)
+ self.assertEqual(result.stderr, None)
+
+ def test_forkbomb_resource_unavailable(self):
+ code = dedent("""
+ import os
+ while 1:
+ os.fork()
+ """).strip()
+
+ result = self.nsjail.python3(code)
+ self.assertEqual(result.returncode, 1)
+ self.assertIn("Resource temporarily unavailable", result.stdout)
+ self.assertEqual(result.stderr, None)
+
+ def test_sigsegv_returns_139(self): # In honour of Juan.
+ code = dedent("""
+ import ctypes
+ ctypes.string_at(0)
+ """).strip()
+
+ result = self.nsjail.python3(code)
+ self.assertEqual(result.returncode, 139)
+ self.assertEqual(result.stdout, "")
+ self.assertEqual(result.stderr, None)
+
+ def test_null_byte_value_error(self):
+ result = self.nsjail.python3("\0")
+ self.assertEqual(result.returncode, None)
+ self.assertEqual(result.stdout, "ValueError: embedded null byte")
+ self.assertEqual(result.stderr, None)
+
+ def test_log_parser(self):
+ log_lines = (
+ "[D][2019-06-22T20:07:00+0000][16] void foo::bar()():100 This is a debug message.",
+ "[I][2019-06-22T20:07:48+0000] pid=20 ([STANDALONE MODE]) "
+ "exited with status: 2, (PIDs left: 0)",
+ "[W][2019-06-22T20:06:04+0000][14] void cmdline::logParams(nsjconf_t*)():250 "
+ "Process will be UID/EUID=0 in the global user namespace, and will have user "
+ "root-level access to files",
+ "[W][2019-06-22T20:07:00+0000][16] void foo::bar()():100 This is a warning!",
+ "[E][2019-06-22T20:07:00+0000][16] bool "
+ "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"
+ )
+
+ with self.assertLogs(self.logger, logging.DEBUG) as log:
+ self.nsjail._parse_log(log_lines)
+
+ self.assertIn("DEBUG:snekbox.nsjail:This is a debug message.", log.output)
+ self.assertIn("ERROR:snekbox.nsjail:Couldn't parse cmdline options", log.output)
+ self.assertIn("ERROR:snekbox.nsjail:No command-line provided", log.output)
+ self.assertIn("WARNING:snekbox.nsjail:Failed to parse log line 'Invalid Line'", log.output)
+ 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
+ )
diff --git a/tests/test_snekbox.py b/tests/test_snekbox.py
deleted file mode 100644
index 46319d6..0000000
--- a/tests/test_snekbox.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import unittest
-
-from snekbox.nsjail import NsJail
-
-nsjail = NsJail()
-
-
-class SnekTests(unittest.TestCase):
- def test_nsjail(self):
- result = nsjail.python3("print('test')")
- self.assertEquals(result.strip(), "test")
-
- # def test_memory_error(self):
- # code = ("x = "*"\n"
- # "while True:\n"
- # " x = x * 99\n")
- # result = nsjail.python3(code)
- # self.assertEquals(result.strip(), "timed out or memory limit exceeded")
-
- def test_timeout(self):
- code = (
- "x = '*'\n"
- "while True:\n"
- " try:\n"
- " x = x * 99\n"
- " except:\n"
- " continue\n"
- )
-
- result = nsjail.python3(code)
- self.assertEquals(result.strip(), "timed out or memory limit exceeded")
-
- def test_kill(self):
- code = ("import subprocess\n"
- "print(subprocess.check_output('kill -9 6', shell=True).decode())")
- result = nsjail.python3(code)
- if "ModuleNotFoundError" in result.strip():
- self.assertIn("ModuleNotFoundError", result.strip())
- else:
- self.assertIn("(PIDs left: 0)", result.strip())
-
- def test_forkbomb(self):
- code = ("import os\n"
- "while 1:\n"
- " os.fork()")
- result = nsjail.python3(code)
- self.assertIn("Resource temporarily unavailable", result.strip())
-
- def test_juan_golf(self): # in honour of Juan
- code = ("func = lambda: None\n"
- "CodeType = type(func.__code__)\n"
- "bytecode = CodeType(0,1,0,0,0,b'',(),(),(),'','',1,b'')\n"
- "exec(bytecode)")
-
- result = nsjail.python3(code)
- self.assertEquals("unknown error, code: 111", result.strip())