77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Verification test for lwc_counter.py.
|
|
|
|
Q62 leg (b): this file used to read its input from an untracked copy of the
|
|
fixture under the spark wizard-outputs directory, and to accept the counter's
|
|
output by substring ("Words: 24" is a substring of "Words: 240"). It now
|
|
resolves both the counter and the fixture from this directory, pins the
|
|
fixture's digest, and compares the whole output exactly.
|
|
|
|
Checks are explicit rather than bare `assert`s, so they still grade under
|
|
`python3 -O` (the Q63 class).
|
|
"""
|
|
|
|
import hashlib
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
COUNTER = HERE / "lwc_counter.py"
|
|
INPUT = HERE / "test_input.txt"
|
|
|
|
# The tracked fixture, byte for byte: "The quick brown fox ... and clever."
|
|
EXPECTED_SHA256 = "3127d0f89b3e87760130ee60e68eb9d9bf213ee83019062119361f1529cfd777"
|
|
EXPECTED_STDOUT = "Lines: 1\nWords: 24\nChars: 125"
|
|
|
|
|
|
def _check(ok, message):
|
|
"""Fail loudly, under -O as well."""
|
|
if not ok:
|
|
print(f"FAIL: {message}")
|
|
sys.exit(1)
|
|
|
|
|
|
def main():
|
|
_check(COUNTER.is_file(), f"counter is not a file: {COUNTER}")
|
|
_check(INPUT.is_file(), f"fixture is not a file: {INPUT}")
|
|
|
|
# Both paths must resolve inside this directory. Catches a symlink to a
|
|
# host copy as well as a literal path elsewhere.
|
|
for path in (COUNTER, INPUT):
|
|
_check(
|
|
path.resolve().parent == HERE,
|
|
f"{path.name} resolves outside this directory: {path.resolve()}",
|
|
)
|
|
|
|
digest = hashlib.sha256(INPUT.read_bytes()).hexdigest()
|
|
_check(
|
|
digest == EXPECTED_SHA256,
|
|
f"fixture {INPUT.name} changed: sha256 {digest}, pinned {EXPECTED_SHA256}",
|
|
)
|
|
|
|
result = subprocess.run(
|
|
[sys.executable, str(COUNTER), str(INPUT)],
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
_check(
|
|
result.returncode == 0,
|
|
f"counter exited {result.returncode}: {result.stderr.strip()}",
|
|
)
|
|
_check(result.stderr == "", f"counter wrote to stderr: {result.stderr!r}")
|
|
|
|
got = result.stdout.rstrip("\n")
|
|
_check(
|
|
got == EXPECTED_STDOUT,
|
|
f"counts differ: expected {EXPECTED_STDOUT!r}, got {got!r}",
|
|
)
|
|
|
|
print("PASS: lwc_counter.py on the in-repo fixture: 1 line, 24 words, 125 chars")
|
|
print(f" input {INPUT} sha256 {EXPECTED_SHA256[:16]}...")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|