#!/usr/bin/env bash # # Regression tests for scripts/vc6-probe.sh. # # Covers the two failure modes that made the probe's exit status and # output untrustworthy: # 1. strip_prefix() must remove a literal Windows-style path prefix # (backslash-separated) from probe output. A naive sed/glob # pattern silently no-ops on this because `\h`, `\u`, etc. are # consumed as escapes instead of literal characters. # 2. The reported exit status must be cl.exe's real status even # though its output passes through `grep` and `strip_prefix` in a # pipeline. # # Part 2 additionally runs the real probe against a deliberately # broken translation unit when wine + MSVC600 are available, so the # check exercises the actual pipeline, not just the helper functions. # # Usage: scripts/vc6-probe.test.sh set -u REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PROBE="$REPO_ROOT/scripts/vc6-probe.sh" fail=0 pass() { echo "ok - $1"; } bad() { echo "not ok - $1"; fail=1; } # --- unit test: strip_prefix removes a literal backslash-heavy prefix --- # shellcheck source=scripts/vc6-probe.sh source "$PROBE" prefix='Z:\home\ubuntu\projects\python-win9x\' input="Z:\\home\\ubuntu\\projects\\python-win9x\\cpython\\Programs\\python.c(1) : error C2061" expected="cpython\\Programs\\python.c(1) : error C2061" actual="$(printf '%s\n' "$input" | strip_prefix "$prefix")" if [ "$actual" = "$expected" ]; then pass "strip_prefix removes literal backslash-separated prefix" else bad "strip_prefix removes literal backslash-separated prefix (got: [$actual], want: [$expected])" fi # A line that does not start with the prefix must be passed through # unchanged (no partial/garbled matches). input2="unrelated line with no prefix" actual2="$(printf '%s\n' "$input2" | strip_prefix "$prefix")" if [ "$actual2" = "$input2" ]; then pass "strip_prefix leaves non-matching lines untouched" else bad "strip_prefix leaves non-matching lines untouched (got: [$actual2])" fi # --- unit test: pipeline exit status reflects the first command, not # grep/sed-equivalent downstream stages --- fake_failure() { return 7; } fake_failure 2>&1 | grep -v '^nomatch' | strip_prefix "$prefix" >/dev/null status="${PIPESTATUS[0]}" if [ "$status" -eq 7 ]; then pass "PIPESTATUS[0] reports the producing command's exit status through the filter pipeline" else bad "PIPESTATUS[0] reports the producing command's exit status through the filter pipeline (got: $status)" fi # --- integration test: run the real probe against a broken translation # unit, when the toolchain is actually available. Skipped (not # failed) otherwise, since CI/dev boxes without wine+MSVC600 # cannot exercise this. --- MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}" if command -v wine >/dev/null 2>&1 && [ -e "$MSVC600_ROOT/VC98/Bin/CL.EXE" ]; then BAD_SRC="$REPO_ROOT/cpython/Programs/_vc6_probe_test_bad.c" printf 'this is not valid C !!! ###\n' > "$BAD_SRC" trap 'rm -f "$BAD_SRC"' EXIT out="$("$PROBE" cpython/Programs/_vc6_probe_test_bad.c 2>&1)" real_status=$? if [ "$real_status" -ne 0 ]; then pass "probe reports nonzero exit for a broken translation unit" else bad "probe reports nonzero exit for a broken translation unit (got: $real_status)" fi if printf '%s' "$out" | grep -q 'error C'; then pass "probe output surfaces the compiler diagnostic" else bad "probe output surfaces the compiler diagnostic" fi if printf '%s' "$out" | grep -q 'Z:\\home'; then bad "probe output leaks an unstripped absolute Wine path" else pass "probe output does not leak an unstripped absolute Wine path" fi else echo "skip - wine/MSVC600 not available; skipping live probe integration check" fi if [ "$fail" -ne 0 ]; then echo "FAILED" exit 1 fi echo "ALL TESTS PASSED"