ssh_compose_pro/tests/run_tests.py

130 lines
3.3 KiB
Python
Raw Permalink Normal View History

2024-07-17 20:29:51 -06:00
import argparse
import datetime
import difflib
import subprocess
import sys
import tempfile
from pathlib import Path
parser = argparse.ArgumentParser(description="Process some integers.")
2024-07-17 20:58:50 -06:00
parser.add_argument(
"src", default="src", type=Path, help="src directory", nargs="?"
)
2024-07-17 20:29:51 -06:00
parser.add_argument(
"tests", default="tests", type=Path, help="tests directory", nargs="?"
)
args = parser.parse_args()
def make_log_file():
time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
return (args.tests / time).with_suffix(".log")
def log_new_test(in_path):
global LOG_FILE
with open(LOG_FILE, "a") as f:
f.write("# ======================================\n")
f.write(f"# Test: {in_path}\n")
f.write("# ======================================\n")
def log_message(message):
global LOG_FILE
with open(LOG_FILE, "a") as f:
f.write(message)
f.write("\n")
def log_return(ret):
if ret[0]:
log_message("Passed")
else:
log_message(f"Error: {ret[1]}")
log_message("# ======================================\n")
return ret
def attempt_decode(out):
try:
return out.decode("utf-8")
except UnicodeDecodeError:
return "Invalid utf-8 in output"
def diff_files(file1, file2):
with open(file1, "r") as f1, open(file2, "r") as f2:
diff = difflib.unified_diff(
f1.readlines(),
f2.readlines(),
fromfile=str(file1),
tofile=str(file2),
)
return "".join(diff)
def run_test(exe_path, in_path):
expected_file = in_path.with_suffix(".out")
log_new_test(in_path)
with tempfile.TemporaryDirectory() as tmp:
temp = Path(tmp)
out_path = temp / "output"
test = subprocess.Popen(
[sys.executable, str(exe_path), str(in_path), "--out", str(out_path)],
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
)
try:
_, stderr = test.communicate(1)
except subprocess.TimeoutExpired:
return [False, "Timed out"]
if test.returncode != 0:
log_message(attempt_decode(stderr))
return log_return(
[
False,
f"Expected returncode 0 got: {test.returncode}",
]
)
diff = diff_files(expected_file, out_path)
if diff != "":
log_message(diff)
return log_return([False, "Output did not match"])
return log_return([True])
if __name__ == "__main__":
LOG_FILE = make_log_file()
PASS_MESSAGE = "✅ Passed"
ERROR_MESSAGE = "❌ Error:"
tests = list(Path(args.tests).glob("**/*.in"))
max_len = max(len(str(t)) for t in tests)
for test in tests:
print(f"{test}...", end="")
res = run_test(args.src / "main.py", test)
if res[0]:
dots = 80 - len(str(test)) - 3 - len(PASS_MESSAGE)
if dots > 0:
print("." * dots, end="")
print(PASS_MESSAGE)
else:
dots = 80 - len(str(test)) - 3 - len(ERROR_MESSAGE) - len(res[1])
if dots > 0:
print("." * dots, end="")
print(f"{ERROR_MESSAGE} {res[1]}")
print(f"Log file at: {LOG_FILE}")