run_errors.sh (3155B)
1 #!/usr/bin/env bash 2 # test/parse/run_errors.sh — file-driven negative C-parser runner, on the 3 # shared corpus harness (test/lib/kit_corpus.sh). Single negative lane. 4 # 5 # For each test/parse/cases_err/*.c, runs `parse-runner --emit FILE.c /dev/null` 6 # and expects a nonzero exit (the parser must diagnose the constraint violation 7 # / syntax error). Kept as a separate runner from the positive parser harness 8 # (test-parse-err vs test-parse-ok); reuses parse-runner, which test-parse-ok 9 # builds. 10 # 11 # Oracle (lane P): parse-runner must exit nonzero. Optional sidecar: 12 # <name>.errpat — first line is a substring of stderr that must be present 13 # (grep -qF). When absent, only exit status is checked. 14 # 15 # No opt axis. Filtering: 16 # ./run_errors.sh [name_filter] (or KIT_TEST_FILTER); substring match 17 # against case basename. 18 # 19 # Parallelism: parallel by default; KIT_TEST_JOBS=N caps concurrency; 20 # KIT_PARSE_PARALLEL=0 forces serial. The lane hook keeps all output under 21 # $KIT_WORK, so the summary is identical serial or parallel. 22 23 set -u 24 25 ROOT="$(cd "$(dirname "$0")/../.." && pwd)" 26 export KIT_LIB_DIR="$ROOT/test/lib" 27 # shellcheck source=../lib/kit_corpus.sh 28 . "$ROOT/test/lib/kit_corpus.sh" 29 30 TEST_DIR="$ROOT/test/parse" 31 BUILD_DIR="$ROOT/build/test" 32 CASES_DIR="$TEST_DIR/cases_err" 33 34 FILTER="${1:-${KIT_TEST_FILTER:-}}" 35 export KIT_TEST_FILTER="$FILTER" 36 37 PARSE_RUNNER="$BUILD_DIR/parse-runner" 38 39 if [ ! -x "$PARSE_RUNNER" ]; then 40 echo "parse-err: parse-runner not built at $PARSE_RUNNER (run test-parse-ok once first)" >&2 41 exit 2 42 fi 43 44 # No cases_err directory -> nothing to test (graceful, like the original). 45 if [ ! -d "$CASES_DIR" ]; then 46 echo "parse-err: no cases_err directory; nothing to test" 47 exit 0 48 fi 49 50 # ----- negative lane P: parse-runner --emit must fail (+ optional errpat) ---- 51 # parse-runner emits to /dev/null (we only care about exit status + stderr). 52 # All logs stay under $KIT_WORK for parallel safety. When <name>.errpat exists, 53 # stderr must contain its first line (grep -qF), else only exit status checks. 54 kit_lane_P() { 55 local name="$KIT_BASE" 56 local err_log="$KIT_WORK/parse.err" 57 58 if "$PARSE_RUNNER" --emit "$KIT_SRC" /dev/null \ 59 >"$KIT_WORK/parse.out" 2>"$err_log"; then 60 kit_fail "$name" "expected nonzero exit, got success" 61 return 62 fi 63 64 local pat_file="$KIT_SIDECAR_DIR/$KIT_BASE.errpat" 65 if [ -e "$pat_file" ]; then 66 local pat 67 pat=$(head -n1 "$pat_file") 68 if ! grep -qF -- "$pat" "$err_log"; then 69 kit_fail "$name" "stderr missing pattern: $pat" 70 sed 's/^/ | /' "$err_log" 71 return 72 fi 73 fi 74 75 kit_pass "$name" 76 } 77 78 # ----- drive the corpus ----------------------------------------------------- 79 80 PAR="${KIT_PARSE_PARALLEL:-1}" 81 82 KIT_LABEL=test-parse-err KIT_BUILD_DIR="$BUILD_DIR/parse-err" \ 83 KIT_CORPUS_GLOBS="$CASES_DIR/*.c" KIT_CORPUS_EXT=c KIT_SIDECAR_DIR="$CASES_DIR" \ 84 KIT_LANES="P" KIT_OPT_LEVELS="" KIT_TUPLES="none-none" KIT_TARGETS_EXT="" \ 85 KIT_PARALLELIZABLE="$PAR" kit_corpus_run 86 87 kit_summary test-parse-err 88 kit_exit