128 lines
3.7 KiB
Python
128 lines
3.7 KiB
Python
import re
|
|
import subprocess
|
|
|
|
BIN = "./lab3"
|
|
STAT_RE = re.compile(
|
|
r"STAT:.*size=(\d+).*depth=(\d+).*min_size=(\d+).*processes=(\d+).*valid=(\d+).*time=([\d.]+)"
|
|
)
|
|
|
|
|
|
def run(args):
|
|
p = subprocess.run([BIN, *args], text=True, capture_output=True)
|
|
if p.returncode != 0:
|
|
print("STDOUT:\n", p.stdout)
|
|
print("STDERR:\n", p.stderr)
|
|
raise AssertionError(f"command failed: {args}")
|
|
m = STAT_RE.search(p.stderr)
|
|
assert m and m.group(5) == "1", f"bad stat: {p.stderr}"
|
|
return p, m
|
|
|
|
|
|
def ints(s):
|
|
return [int(x) for x in s.split()] if s.strip() else []
|
|
|
|
|
|
def test_01_printed_small_random_array_sorted():
|
|
p, _ = run(["--size", "97", "--depth", "3", "--min-size", "8", "--print"])
|
|
a = ints(p.stdout)
|
|
assert len(a) == 97
|
|
assert a == sorted(a)
|
|
|
|
|
|
def test_02_seed_makes_random_input_reproducible():
|
|
a = run(
|
|
["--size", "128", "--depth", "2", "--min-size", "8", "--seed", "42", "--print"]
|
|
)[0].stdout
|
|
b = run(
|
|
["--size", "128", "--depth", "2", "--min-size", "8", "--seed", "42", "--print"]
|
|
)[0].stdout
|
|
c = run(
|
|
["--size", "128", "--depth", "2", "--min-size", "8", "--seed", "43", "--print"]
|
|
)[0].stdout
|
|
assert a == b
|
|
assert a != c
|
|
|
|
|
|
def test_03_zero_depth_sequential_fallback():
|
|
_, m = run(["--size", "1000", "--depth", "0", "--min-size", "1"])
|
|
assert m.group(4) == "1"
|
|
|
|
|
|
def test_04_depth_two_full_tree_process_count():
|
|
_, m = run(["--size", "4096", "--depth", "2", "--min-size", "16"])
|
|
assert m.group(4) == "7", m.group(0)
|
|
|
|
|
|
def test_05_depth_three_full_tree_process_count():
|
|
_, m = run(["--size", "8192", "--depth", "3", "--min-size", "16"])
|
|
assert m.group(4) == "15", m.group(0)
|
|
|
|
|
|
def test_06_min_size_stops_forking():
|
|
_, m = run(["--size", "1000", "--depth", "5", "--min-size", "1000"])
|
|
assert m.group(4) == "1", m.group(0)
|
|
|
|
|
|
def test_07_odd_size_sorted_correctly():
|
|
p, _ = run(
|
|
["--size", "999", "--depth", "4", "--min-size", "17", "--seed", "77", "--print"]
|
|
)
|
|
a = ints(p.stdout)
|
|
assert len(a) == 999
|
|
assert a == sorted(a)
|
|
|
|
|
|
def test_08_single_element_array():
|
|
p, m = run(["--size", "1", "--depth", "5", "--min-size", "1", "--print"])
|
|
a = ints(p.stdout)
|
|
assert len(a) == 1
|
|
assert m.group(4) == "1"
|
|
|
|
|
|
def test_09_empty_array():
|
|
p, m = run(["--size", "0", "--depth", "5", "--min-size", "1", "--print"])
|
|
assert p.stdout.strip() == ""
|
|
assert m.group(4) == "1"
|
|
|
|
|
|
def test_10_timeline_log_has_events_and_pid_fields():
|
|
p, _ = run(["--size", "128", "--depth", "2", "--min-size", "8", "--log"])
|
|
assert "START PID=" in p.stdout
|
|
assert "END PID=" in p.stdout
|
|
assert "PPID=" in p.stdout
|
|
assert "depth=" in p.stdout
|
|
|
|
|
|
def test_11_help_has_no_mode_argument():
|
|
p = subprocess.run([BIN, "--help"], text=True, capture_output=True)
|
|
assert p.returncode == 0
|
|
assert "--mode" not in p.stdout
|
|
assert "--seed" in p.stdout
|
|
|
|
|
|
def test_12_unknown_mode_is_rejected():
|
|
p = subprocess.run([BIN, "--mode", "random"], text=True, capture_output=True)
|
|
assert p.returncode != 0
|
|
assert "unknown argument" in p.stderr
|
|
|
|
|
|
if __name__ == "__main__":
|
|
tests = [
|
|
test_01_printed_small_random_array_sorted,
|
|
test_02_seed_makes_random_input_reproducible,
|
|
test_03_zero_depth_sequential_fallback,
|
|
test_04_depth_two_full_tree_process_count,
|
|
test_05_depth_three_full_tree_process_count,
|
|
test_06_min_size_stops_forking,
|
|
test_07_odd_size_sorted_correctly,
|
|
test_08_single_element_array,
|
|
test_09_empty_array,
|
|
test_10_timeline_log_has_events_and_pid_fields,
|
|
test_11_help_has_no_mode_argument,
|
|
test_12_unknown_mode_is_rejected,
|
|
]
|
|
|
|
for t in tests:
|
|
t()
|
|
print(f"OK {t.__name__}")
|