From 6026876cdfd8ffb1bde3c98e97bb7ba05ff4e4ae Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Sat, 12 Sep 2020 17:08:25 +0200 Subject: Moved parenthesis and operation in flow, Added sandbox context, Replaced subprocess wait by communicate to avoid dead lock --- README.md | 2 +- preview.gif | Bin 0 -> 6275302 bytes recording.gif | Bin 6275302 -> 0 bytes src/config.py | 4 +- src/sandbox.py | 11 +++- src/suite/suite.py | 8 +-- src/suites/flow.py | 150 ++++++++++++++++++++++++++++++++++++++++++++++ src/suites/operation.py | 104 -------------------------------- src/suites/parenthesis.py | 54 ----------------- src/test/test.py | 72 +++++++++++----------- 10 files changed, 204 insertions(+), 201 deletions(-) create mode 100644 preview.gif delete mode 100644 recording.gif create mode 100644 src/suites/flow.py delete mode 100644 src/suites/operation.py delete mode 100644 src/suites/parenthesis.py diff --git a/README.md b/README.md index d4a19b8..f60673c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Test for the minishell project of school 42. -![screenshot](recording.gif) +![preview](preview.gif) ## Usage diff --git a/preview.gif b/preview.gif new file mode 100644 index 0000000..618bd36 Binary files /dev/null and b/preview.gif differ diff --git a/recording.gif b/recording.gif deleted file mode 100644 index 618bd36..0000000 Binary files a/recording.gif and /dev/null differ diff --git a/src/config.py b/src/config.py index a9a3b78..7092fea 100644 --- a/src/config.py +++ b/src/config.py @@ -6,7 +6,7 @@ # By: charles +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2020/07/15 18:24:19 by charles #+# #+# # -# Updated: 2020/09/12 01:33:18 by charles ### ########.fr # +# Updated: 2020/09/12 16:56:23 by charles ### ########.fr # # # # ############################################################################ # @@ -50,7 +50,7 @@ AVAILABLE_COMMANDS = ["rmdir", "env", "cat", "touch", "ls", "grep", "sh"] PATH_VARIABLE = os.path.abspath(EXECUTABLES_PATH) # default test timeout -TIMEOUT = 1 +TIMEOUT = 0.5 LOREM = """ Mollitia asperiores assumenda excepturi et ipsa. Nihil corporis facere aut a rem consequatur. diff --git a/src/sandbox.py b/src/sandbox.py index efad60c..8194556 100644 --- a/src/sandbox.py +++ b/src/sandbox.py @@ -6,7 +6,7 @@ # By: charles +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2020/09/11 13:48:07 by charles #+# #+# # -# Updated: 2020/09/11 20:25:38 by charles ### ########.fr # +# Updated: 2020/09/12 17:06:28 by charles ### ########.fr # # # # ############################################################################ # @@ -14,6 +14,7 @@ import os import glob import shutil import subprocess +from contextlib import contextmanager import config @@ -35,3 +36,11 @@ def remove(): except PermissionError: subprocess.run(["chmod", "777", *glob.glob(config.SANDBOX_PATH + "/*")], check=True) subprocess.run(["rm", "-rf", config.SANDBOX_PATH], check=True) + + +@contextmanager +def context(): + """Sandbox context manager""" + create() + yield + remove() diff --git a/src/suite/suite.py b/src/suite/suite.py index ee13268..63421f6 100644 --- a/src/suite/suite.py +++ b/src/suite/suite.py @@ -6,7 +6,7 @@ # By: charles +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2020/07/15 18:24:29 by charles #+# #+# # -# Updated: 2020/09/12 10:53:42 by charles ### ########.fr # +# Updated: 2020/09/12 17:07:00 by charles ### ########.fr # # # # ############################################################################ # @@ -40,8 +40,8 @@ class Suite: continue matches = [n for n in suite_names if n.find("/") != -1 - and n[n.find("/") + 1:].startswith(name) - or n.startswith(name)] + and n[n.find("/") + 1:].startswith(name) + or n.startswith(name)] if len(matches) == 1: names.append(matches[0]) elif len(matches) != 0 and all([n.startswith(name) for n in matches]): @@ -61,10 +61,10 @@ class Suite: [s for s in cls.available if s.name in names] + [s for s in cls.available if any([g for g in s.groups if g in names])] )) + cls.available.sort(key=lambda s: s.name) for s in cls.available: s.generator_func() - @classmethod def available_names(cls) -> [str]: """List of available suites names""" diff --git a/src/suites/flow.py b/src/suites/flow.py new file mode 100644 index 0000000..cf8ca61 --- /dev/null +++ b/src/suites/flow.py @@ -0,0 +1,150 @@ +# ############################################################################ # +# # +# ::: :::::::: # +# flow.py :+: :+: :+: # +# +:+ +:+ +:+ # +# By: charles +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2020/07/15 18:24:52 by charles #+# #+# # +# Updated: 2020/09/12 15:30:37 by charles ### ########.fr # +# # +# ############################################################################ # + +from suite import suite +import hooks + + +@suite() +def suite_end(test): + test("echo bonjour; echo je") + test("echo bonjour ;echo je") + test("echo bonjour ; echo je") + test("echo bonjour;") + test("echo; ") + test("echo ; ") + test("echo ;") + test("; echo", hook=hooks.error_line0) + test(" ;echo", hook=hooks.error_line0) + test(" ; echo", hook=hooks.error_line0) + test("echo a; echo b; echo c; echo d; echo e; echo f; echo g; echo h; echo i;" + "echo j; echo k; echo l; echo m; echo c; echo c; echo c; echo c; echo c;" + "echo c; echo c; echo c; echo v; echo w; echo x; echo y; echo z") + test("echo a ; echo b; echo c ;echo d ; echo e ;echo f; echo g ;echo h; echo i;" + "echo j ; echo k; echo l; echo m; echo c ; echo c; echo c ; echo c; echo c;" + "echo c; echo c ; echo c; echo v ; echo w; echo x; echo y ; echo z") + test("ls doesnotexists ; echo bonjour") + test("ls doesnotexists; echo bonjour") + test("echo bonjour; ls doesnotexists") + + +@suite() +def suite_pipe(test): + test("cat /etc/shells | head -c 10") + test("cat -e /etc/shells | head -c 10") + test("cat -e /etc/shells | cat -e | head -c 10") + test("cat -e /etc/shells | cat -e | cat -e | head -c 10") + test("echo bonjour | cat") + test("echo bonjour | cat -e") + test("echo bonjour | cat -e | cat -e | cat -e | cat -e | cat -e | cat -e | cat -e") + test("ls | cat -e", setup="touch a b c d; mkdir m1 m2 m3") + test("ls -l | cat -e", setup="touch a b c d; mkdir m1 m2 m3") + test("ls -l | cat -e | cat | cat | cat", setup="touch a b c d; mkdir m1 m2 m3") + test("ls -l | cat -e | cat -e | cat -e | cat -e", setup="touch a b c d; mkdir m1 m2 m3") + test("ls -l | cat -e < a", setup="touch a b c d; mkdir m1 m2 m3; echo bonjour > a") + test("echo|", hook=hooks.discard) + test("echo |", hook=hooks.discard) + test("echo | ", hook=hooks.discard) + test("|cat", hook=hooks.error_line0) + test("| cat", hook=hooks.error_line0) + test(" | cat", hook=hooks.error_line0) + test("echo a | export A=a; echo $A") + test("export A=a | cat; echo $A") + # test("echo a | A=a; echo $A") + # test("A=a | cat; echo $A") + + +@suite(bonus=True) +def suite_and(test): + test("echo bonjour&& echo je") + test("echo bonjour &&echo je") + test("echo bonjour && echo je") + test("echo bonjour&&", hook=hooks.discard) + test("echo&& ", hook=hooks.discard) + test("echo && ", hook=hooks.discard) + test("echo &&", hook=hooks.discard) + test("&&echo", hook=hooks.error_line0) + test("&& echo", hook=hooks.error_line0) + test(" && echo", hook=hooks.error_line0) + test("echo a&& echo b&& echo c&& echo d&& echo e&& echo f&& echo g&& echo h&& echo i&&" + "echo j&& echo k&& echo l&& echo m&& echo c&& echo c&& echo c&& echo c&& echo c&&" + "echo c&& echo c&& echo c&& echo v&& echo w&& echo x&& echo y&& echo z") + test("echo a && echo b&& echo c &&echo d && echo e &&echo f&& echo g &&echo h&& echo i&&" + "echo j && echo k&& echo l&& echo m&& echo c && echo c&& echo c && echo c&& echo c&&" + "echo c&& echo c && echo c&& echo v && echo w&& echo x&& echo y && echo z") + test("ls doesnotexists && echo bonjour") + test("ls doesnotexists&& echo bonjour") + test("echo bonjour&& ls doesnotexists") + + +@suite(bonus=True) +def suite_or(test): + test("echo bonjour|| echo je") + test("echo bonjour ||echo je") + test("echo bonjour || echo je") + test("echo bonjour||", hook=hooks.discard) + test("echo|| ", hook=hooks.discard) + test("echo || ", hook=hooks.discard) + test("echo ||", hook=hooks.discard) + test("||echo", hook=hooks.error_line0) + test("|| echo", hook=hooks.error_line0) + test(" || echo", hook=hooks.error_line0) + test("echo a|| echo b|| echo c|| echo d|| echo e|| echo f|| echo g|| echo h|| echo i||" + "echo j|| echo k|| echo l|| echo m|| echo c|| echo c|| echo c|| echo c|| echo c||" + "echo c|| echo c|| echo c|| echo v|| echo w|| echo x|| echo y|| echo z") + test("echo a || echo b|| echo c ||echo d || echo e ||echo f|| echo g ||echo h|| echo i||" + "echo j || echo k|| echo l|| echo m|| echo c || echo c|| echo c || echo c|| echo c||" + "echo c|| echo c || echo c|| echo v || echo w|| echo x|| echo y || echo z") + test("ls doesnotexists || echo bonjour") + test("ls doesnotexists|| echo bonjour") + test("echo bonjour|| ls doesnotexists") + + +@suite(bonus=True) +def suite_parenthesis(test): + test("(echo bonjour)") + test("(echo bonjour )") + test("( echo bonjour )") + test("(echo a && echo b) && echo c") + test("(echo a || echo b) || echo c") + test("(ls doesnotexist || echo b) || echo c") + test("(echo a || ls doesnotexist) || echo c") + test("echo aa && (echo b && echo c)") + test("ls doesnotexist || (echo b && echo c)") + test("(echo bonjour > f1)", files=["f1"]) + test("(echo bonjour > f1 > f2 > f3)", files=["f1", "f2", "f3"]) + test("(echo bonjour > f1 > f2 > f3 > f4 > f5 > f6 > f7 > f8 > f9)", + files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"]) + test("(echo bonjour) > f1", files=["f1"]) + test("(echo bonjour) > f1 > f2 > f3", files=["f1", "f2", "f3"]) + test("(echo bonjour) > f1 > f2 > f3 > f4 > f5 > f6 > f7 > f8 > f9", + files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"]) + test("(cat -e < f1)", setup="echo bonjour > f1") + test("(cat -e < f1 < f2 < f3)", setup="touch f1 f2 f3 f4; echo bonjour > f3") + test("(cat -e < f1 < f2 < f3 < f4 < f5 < f6 < f7 < f8 < f9)", + setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f9") + test("(cat -e) < f1", setup="echo bonjour > f1") + test("(cat -e) < f1 < f2 < f3", setup="touch f1 f2 f3 f4; echo bonjour > f3") + test("(cat -e) < f1 < f2 < f3 < f4 < f5 < f6 < f7 < f8 < f9", + setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f9") + test("(echo bonjour > f1 > f2 > f3 > f4) > f5 > f6 > f7 > f8 > f9", + files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"]) + test("(cat -e < f1 < f2 < f3 < f4) < f5 < f6 < f7 < f8 < f9", + setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f4") + test("(echo bonjour > f1) > f2", files=["f1", "f2"]) + test("(cat -e > f1) < f2", setup="ls -l / > f2", files=["f1"]) + test("(exit); echo bonjour") + test("(echo bonjour; exit; echo aurevoir)") + test("(ls && ls)") + test("(ls doesntexist || ls)") + test("(ls doesntexist && ls)") + test("(ls && ls) && echo $?") diff --git a/src/suites/operation.py b/src/suites/operation.py deleted file mode 100644 index 18ebd72..0000000 --- a/src/suites/operation.py +++ /dev/null @@ -1,104 +0,0 @@ -# ############################################################################ # -# # -# ::: :::::::: # -# operation.py :+: :+: :+: # -# +:+ +:+ +:+ # -# By: charles +#+ +:+ +#+ # -# +#+#+#+#+#+ +#+ # -# Created: 2020/07/15 18:24:52 by charles #+# #+# # -# Updated: 2020/09/11 20:12:54 by charles ### ########.fr # -# # -# ############################################################################ # - -from suite import suite -import hooks - - -@suite() -def suite_end(test): - test("echo bonjour; echo je") - test("echo bonjour ;echo je") - test("echo bonjour ; echo je") - test("echo bonjour;") - test("echo; ") - test("echo ; ") - test("echo ;") - test("; echo", hook=hooks.error_line0) - test(" ;echo", hook=hooks.error_line0) - test(" ; echo", hook=hooks.error_line0) - test("echo a; echo b; echo c; echo d; echo e; echo f; echo g; echo h; echo i;" - "echo j; echo k; echo l; echo m; echo c; echo c; echo c; echo c; echo c;" - "echo c; echo c; echo c; echo v; echo w; echo x; echo y; echo z") - test("echo a ; echo b; echo c ;echo d ; echo e ;echo f; echo g ;echo h; echo i;" - "echo j ; echo k; echo l; echo m; echo c ; echo c; echo c ; echo c; echo c;" - "echo c; echo c ; echo c; echo v ; echo w; echo x; echo y ; echo z") - test("ls doesnotexists ; echo bonjour") - test("ls doesnotexists; echo bonjour") - test("echo bonjour; ls doesnotexists") - - -@suite() -def suite_pipe(test): - test("echo bonjour | cat") - test("echo bonjour | cat -e") - test("ls | cat -e", setup="touch a b c d; mkdir m1 m2 m3") - test("ls -l | cat -e", setup="touch a b c d; mkdir m1 m2 m3") - test("ls -l | cat -e | cat | cat | cat", setup="touch a b c d; mkdir m1 m2 m3") - test("ls -l | cat -e | cat -e | cat -e | cat -e", setup="touch a b c d; mkdir m1 m2 m3") - test("ls -l | cat -e < a", setup="touch a b c d; mkdir m1 m2 m3; echo bonjour > a") - test("echo|", hook=hooks.discard) - test("echo |", hook=hooks.discard) - test("echo | ", hook=hooks.discard) - test("|cat", hook=hooks.error_line0) - test("| cat", hook=hooks.error_line0) - test(" | cat", hook=hooks.error_line0) - test("echo a | export A=a; echo $A") - test("export A=a | cat; echo $A") - # test("echo a | A=a; echo $A") - # test("A=a | cat; echo $A") - - -@suite(bonus=True) -def suite_and(test): - test("echo bonjour&& echo je") - test("echo bonjour &&echo je") - test("echo bonjour && echo je") - test("echo bonjour&&", hook=hooks.discard) - test("echo&& ", hook=hooks.discard) - test("echo && ", hook=hooks.discard) - test("echo &&", hook=hooks.discard) - test("&&echo", hook=hooks.error_line0) - test("&& echo", hook=hooks.error_line0) - test(" && echo", hook=hooks.error_line0) - test("echo a&& echo b&& echo c&& echo d&& echo e&& echo f&& echo g&& echo h&& echo i&&" - "echo j&& echo k&& echo l&& echo m&& echo c&& echo c&& echo c&& echo c&& echo c&&" - "echo c&& echo c&& echo c&& echo v&& echo w&& echo x&& echo y&& echo z") - test("echo a && echo b&& echo c &&echo d && echo e &&echo f&& echo g &&echo h&& echo i&&" - "echo j && echo k&& echo l&& echo m&& echo c && echo c&& echo c && echo c&& echo c&&" - "echo c&& echo c && echo c&& echo v && echo w&& echo x&& echo y && echo z") - test("ls doesnotexists && echo bonjour") - test("ls doesnotexists&& echo bonjour") - test("echo bonjour&& ls doesnotexists") - - -@suite(bonus=True) -def suite_or(test): - test("echo bonjour|| echo je") - test("echo bonjour ||echo je") - test("echo bonjour || echo je") - test("echo bonjour||", hook=hooks.discard) - test("echo|| ", hook=hooks.discard) - test("echo || ", hook=hooks.discard) - test("echo ||", hook=hooks.discard) - test("||echo", hook=hooks.error_line0) - test("|| echo", hook=hooks.error_line0) - test(" || echo", hook=hooks.error_line0) - test("echo a|| echo b|| echo c|| echo d|| echo e|| echo f|| echo g|| echo h|| echo i||" - "echo j|| echo k|| echo l|| echo m|| echo c|| echo c|| echo c|| echo c|| echo c||" - "echo c|| echo c|| echo c|| echo v|| echo w|| echo x|| echo y|| echo z") - test("echo a || echo b|| echo c ||echo d || echo e ||echo f|| echo g ||echo h|| echo i||" - "echo j || echo k|| echo l|| echo m|| echo c || echo c|| echo c || echo c|| echo c||" - "echo c|| echo c || echo c|| echo v || echo w|| echo x|| echo y || echo z") - test("ls doesnotexists || echo bonjour") - test("ls doesnotexists|| echo bonjour") - test("echo bonjour|| ls doesnotexists") diff --git a/src/suites/parenthesis.py b/src/suites/parenthesis.py deleted file mode 100644 index 6a1e7f1..0000000 --- a/src/suites/parenthesis.py +++ /dev/null @@ -1,54 +0,0 @@ -# ############################################################################ # -# # -# ::: :::::::: # -# parenthesis.py :+: :+: :+: # -# +:+ +:+ +:+ # -# By: charles +#+ +:+ +#+ # -# +#+#+#+#+#+ +#+ # -# Created: 2020/07/15 18:24:57 by charles #+# #+# # -# Updated: 2020/09/11 20:12:27 by charles ### ########.fr # -# # -# ############################################################################ # - -from suite import suite - - -@suite(bonus=True) -def suite_parenthesis(test): - test("(echo bonjour)") - test("(echo bonjour )") - test("( echo bonjour )") - test("(echo a && echo b) && echo c") - test("(echo a || echo b) || echo c") - test("(ls doesnotexist || echo b) || echo c") - test("(echo a || ls doesnotexist) || echo c") - test("echo aa && (echo b && echo c)") - test("ls doesnotexist || (echo b && echo c)") - test("(echo bonjour > f1)", files=["f1"]) - test("(echo bonjour > f1 > f2 > f3)", files=["f1", "f2", "f3"]) - test("(echo bonjour > f1 > f2 > f3 > f4 > f5 > f6 > f7 > f8 > f9)", - files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"]) - test("(echo bonjour) > f1", files=["f1"]) - test("(echo bonjour) > f1 > f2 > f3", files=["f1", "f2", "f3"]) - test("(echo bonjour) > f1 > f2 > f3 > f4 > f5 > f6 > f7 > f8 > f9", - files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"]) - test("(cat -e < f1)", setup="echo bonjour > f1") - test("(cat -e < f1 < f2 < f3)", setup="touch f1 f2 f3 f4; echo bonjour > f3") - test("(cat -e < f1 < f2 < f3 < f4 < f5 < f6 < f7 < f8 < f9)", - setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f9") - test("(cat -e) < f1", setup="echo bonjour > f1") - test("(cat -e) < f1 < f2 < f3", setup="touch f1 f2 f3 f4; echo bonjour > f3") - test("(cat -e) < f1 < f2 < f3 < f4 < f5 < f6 < f7 < f8 < f9", - setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f9") - test("(echo bonjour > f1 > f2 > f3 > f4) > f5 > f6 > f7 > f8 > f9", - files=["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9"]) - test("(cat -e < f1 < f2 < f3 < f4) < f5 < f6 < f7 < f8 < f9", - setup="touch f1 f2 f3 f4 f5 f6 f7 f8 f9; echo bonjour > f4") - test("(echo bonjour > f1) > f2", files=["f1", "f2"]) - test("(cat -e > f1) < f2", setup="ls -l / > f2", files=["f1"]) - test("(exit); echo bonjour") - test("(echo bonjour; exit; echo aurevoir)") - test("(ls && ls)") - test("(ls doesntexist || ls)") - test("(ls doesntexist && ls)") - test("(ls && ls) && echo $?") diff --git a/src/test/test.py b/src/test/test.py index b5abd85..00e5516 100644 --- a/src/test/test.py +++ b/src/test/test.py @@ -6,14 +6,14 @@ # By: charles +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2020/06/16 21:48:50 by charles #+# #+# # -# Updated: 2020/09/12 01:35:46 by charles ### ########.fr # +# Updated: 2020/09/12 17:07:22 by charles ### ########.fr # # # # ############################################################################ # import os import sys import subprocess -import time +# import time import config from test.captured import Captured @@ -62,30 +62,31 @@ class Test: self.result.put() def _run_sandboxed(self, shell_path: str, shell_options: str) -> Captured: - """ Run the command in a sandbox environment - Capture the output (stdout and stderr) + """ Run the command in a sandbox environment """ + with sandbox.context(): + if self.setup != "": + try: + subprocess.run( + self.setup, + shell=True, + cwd=config.SANDBOX_PATH, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, + check=True + ) + except subprocess.CalledProcessError as e: + print("Error: `{}` setup command failed for `{}`\n\twith '{}'" + .format(self.setup, + self.cmd, + "no stderr" if e.stdout is None + else e.stdout.decode().strip())) + sys.exit(1) + return self._run_capture(shell_path, shell_options) + + def _run_capture(self, shell_path: str, shell_options: str) -> Captured: + """ Capture the output (stdout and stderr) Capture the content of the watched files after the command is run """ - - # create and setup sandbox - sandbox.create() - if self.setup != "": - try: - subprocess.run( - self.setup, - shell=True, - cwd=config.SANDBOX_PATH, - stderr=subprocess.STDOUT, - stdout=subprocess.PIPE, - check=True - ) - except subprocess.CalledProcessError as e: - print("Error: `{}` setup command failed for `{}`\n\twith '{}'" - .format(self.setup, - self.cmd, - "no stderr" if e.stdout is None else e.stdout.decode().strip())) - sys.exit(1) - # run the command in the sandbox process = subprocess.Popen( [shell_path, *shell_options, self.cmd], @@ -98,18 +99,19 @@ class Test: **self.exports, }, ) - if self.signal is not None: - time.sleep(0.2) - process.send_signal(self.signal) - else: - try: - process.wait(timeout=self.timeout) - except subprocess.TimeoutExpired: - return Captured.timeout() + # if self.signal is not None: + # time.sleep(0.2) + # process.send_signal(self.signal) + # else: - # get command output + # https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate + try: + stdout, _ = process.communicate(timeout=self.timeout) + except subprocess.TimeoutExpired: + process.kill() + # _, _ = process.communicate(timeout=2) + return Captured.timeout() try: - stdout, _ = process.communicate() output = stdout.decode() except UnicodeDecodeError: output = "UNICODE ERROR: {}".format(process.stdout) @@ -123,7 +125,7 @@ class Test: except FileNotFoundError: files_content.append(None) - sandbox.remove() + # sandbox.remove() if self.hook is not None: output = self.hook(output) return Captured(output, process.returncode, files_content) -- cgit