aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--preview.gif (renamed from recording.gif)bin6275302 -> 6275302 bytes
-rw-r--r--src/config.py4
-rw-r--r--src/sandbox.py11
-rw-r--r--src/suite/suite.py8
-rw-r--r--src/suites/flow.py (renamed from src/suites/operation.py)50
-rw-r--r--src/suites/parenthesis.py54
-rw-r--r--src/test/test.py72
8 files changed, 102 insertions, 99 deletions
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/recording.gif b/preview.gif
index 618bd36..618bd36 100644
--- a/recording.gif
+++ b/preview.gif
Binary files 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# 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 <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# 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/operation.py b/src/suites/flow.py
index 18ebd72..cf8ca61 100644
--- a/src/suites/operation.py
+++ b/src/suites/flow.py
@@ -1,12 +1,12 @@
# ############################################################################ #
# #
# ::: :::::::: #
-# operation.py :+: :+: :+: #
+# flow.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/07/15 18:24:52 by charles #+# #+# #
-# Updated: 2020/09/11 20:12:54 by charles ### ########.fr #
+# Updated: 2020/09/12 15:30:37 by charles ### ########.fr #
# #
# ############################################################################ #
@@ -39,8 +39,13 @@ def suite_end(test):
@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")
@@ -102,3 +107,44 @@ def suite_or(test):
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/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 <charles.cabergs@gmail.com> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# 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 <charles.cabergs@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# 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)