Files
Python3-Win9x/scripts/generate-getpath-frozen.test.sh

120 lines
4.2 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Regression tests for reproducible getpath.py frozen-header generation.
set -u
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
GENERATOR="$REPO_ROOT/scripts/generate-getpath-frozen.sh"
TMP_ROOT="$REPO_ROOT/build/test-getpath-frozen"
OUT_HEADER="$TMP_ROOT/cpython/Python/frozen_modules/getpath.h"
DIRECT_HEADER="$TMP_ROOT/direct/getpath.h"
fail=0
pass() { echo "ok - $1"; }
bad() { echo "not ok - $1"; fail=1; }
rm -rf "$TMP_ROOT"
out="$($GENERATOR "$TMP_ROOT" 2>&1)"
status=$?
if [ "$status" -eq 0 ]; then
pass "generator exits 0"
else
bad "generator exits 0 (got exit $status)"
echo "$out"
fi
if [ "$out" = "build/test-getpath-frozen/cpython/Python/frozen_modules/getpath.h" ]; then
pass "generator reports the project-local build-relative output path"
else
bad "generator reports the project-local build-relative output path (got: $out)"
fi
if [ -s "$OUT_HEADER" ]; then
pass "generator writes a nonempty getpath.h under build/"
else
bad "generator writes a nonempty getpath.h under build/"
fi
first_line="$(sed -n '1p' "$OUT_HEADER" 2>/dev/null)"
if [ "$first_line" = '/* Auto-generated by Programs/_freeze_module.py */' ]; then
pass "generated header records the host-Python _freeze_module.py path"
else
bad "generated header records the host-Python _freeze_module.py path (got: $first_line)"
fi
second_line="$(sed -n '2p' "$OUT_HEADER" 2>/dev/null)"
if [ "$second_line" = 'const unsigned char _Py_M__getpath[] = {' ]; then
pass "generated header declares the expected getpath frozen symbol"
else
bad "generated header declares the expected getpath frozen symbol (got: $second_line)"
fi
python3 - "$OUT_HEADER" <<'PY'
import marshal
import re
import sys
from pathlib import Path
path = Path(sys.argv[1])
text = path.read_text()
if not text.endswith('};\n'):
raise SystemExit('header does not end with closing array marker')
match = re.search(r'const unsigned char _Py_M__getpath\[\] = \{\n(?P<body>.*?)\};\n\Z', text, re.S)
if not match:
raise SystemExit('array body not found')
lines = match.group('body').splitlines()
values = []
for index, line in enumerate(lines, 1):
if not line.startswith(' '):
raise SystemExit(f'line {index} is not four-space indented')
payload = line.strip()
if not payload.endswith(','):
raise SystemExit(f'line {index} is missing trailing comma')
nums = [part for part in payload[:-1].split(',') if part]
if len(nums) > 16:
raise SystemExit(f'line {index} has more than 16 bytes')
if index < len(lines) and len(nums) != 16:
raise SystemExit(f'non-final line {index} has {len(nums)} bytes, expected 16')
for num in nums:
value = int(num)
if not 0 <= value <= 255:
raise SystemExit(f'byte out of range: {value}')
values.append(value)
code = marshal.loads(bytes(values))
if code.co_filename != '<frozen getpath>':
raise SystemExit(f'unexpected code filename: {code.co_filename!r}')
if code.co_name != '<module>':
raise SystemExit(f'unexpected code name: {code.co_name!r}')
print('format-ok')
PY
format_status=$?
if [ "$format_status" -eq 0 ]; then
pass "generated byte array unmarshals as frozen getpath code with CPython format"
else
bad "generated byte array unmarshals as frozen getpath code with CPython format"
fi
mkdir -p "$(dirname "$DIRECT_HEADER")"
python3 "$REPO_ROOT/cpython/Programs/_freeze_module.py" getpath \
"$REPO_ROOT/cpython/Modules/getpath.py" "$DIRECT_HEADER"
if cmp -s "$OUT_HEADER" "$DIRECT_HEADER"; then
pass "generator output matches direct Programs/_freeze_module.py invocation exactly"
else
bad "generator output matches direct Programs/_freeze_module.py invocation exactly"
fi
frontier_out="$(bash "$REPO_ROOT/scripts/vc6-probe-pythoncore-frontier.sh" --list-only 2>&1)"
frontier_status=$?
if [ "$frontier_status" -eq 0 ] && printf '%s\n' "$frontier_out" | grep -q $'^compile\tcpython/Modules/getpath.c\t'; then
pass "frontier list still starts from Modules/getpath.c without requiring generated output"
else
bad "frontier list still starts from Modules/getpath.c without requiring generated output"
echo "$frontier_out"
fi
if [ "$fail" -ne 0 ]; then
echo "FAILED"
exit 1
fi
echo "ALL TESTS PASSED"