kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

kit_sh_kit.sh (3630B)


      1 # test/lib/kit_sh_kit.sh — the Type-K (scripted-shell) test kit.
      2 #
      3 # ONE source point for hand-written tool/driver tests. A K harness sources this
      4 # file and renders verdicts via ONE OF TWO oracle modes, both recording through
      5 # the single report layer (kit_sh_report.sh):
      6 #
      7 #   mode G (golden transcript): loop cases/<name>.sh and call
      8 #           kit_scenario_case NAME SH EXPECTED  — runs the case in a sandbox and
      9 #           diffs stdout+stderr vs <name>.expected. (ar/strip/objcopy/strings/
     10 #           objdump/dbg.) kit_scenario_case lives in kit_sh_report.sh.
     11 #   mode P (procedural asserts): set up $work and call ok / run_ok / run_fail /
     12 #           contains / same_file / is_executable / assert_file_exists /
     13 #           check_mode. (cas/pkg/driver/windows-smokes.) These come from
     14 #           kit_sh_assert.sh and route through kit_pass/kit_fail/kit_skip.
     15 #
     16 # Either way: kit_report_init at the top, kit_summary LABEL + kit_exit at the end.
     17 # No harness reimplements counters/summary. Mode-P suites are SERIAL by design
     18 # (cas/pkg/driver share one $work and mutate fixtures), so the assert verbs do
     19 # NOT participate in the corpus engine's parallel event-replay.
     20 
     21 # The caller sets KIT_KIT_DIR to the test/lib directory before sourcing. (This
     22 # kit is sourced by /bin/sh harnesses, where BASH_SOURCE is unavailable, so we
     23 # do not self-resolve.)
     24 : "${KIT_KIT_DIR:?kit_sh_kit.sh: caller must set KIT_KIT_DIR=<repo>/test/lib}"
     25 . "$KIT_KIT_DIR/kit_sh_report.sh"   # counters + verbs + kit_summary/kit_exit
     26 . "$KIT_KIT_DIR/kit_sh_assert.sh"   # mode-P procedural verbs (route through kit_*)
     27 
     28 # check_mode NAME FILE EXPECTED_OCTAL : assert FILE's permission bits, portably
     29 # (Darwin stat -f vs GNU stat -c). The stat invocation is the one host-specific
     30 # bit; the verdict goes through kit_pass/kit_fail.
     31 check_mode() {
     32   kit_km_got=
     33   if [ "$(uname -s 2>/dev/null)" = "Darwin" ]; then
     34     kit_km_got=$(stat -f '%Lp' "$2" 2>/dev/null)
     35   else
     36     kit_km_got=$(stat -c '%a' "$2" 2>/dev/null)
     37   fi
     38   if [ "$kit_km_got" = "$3" ]; then kit_pass "$1"
     39   else kit_fail "$1" "mode $kit_km_got want $3"; fi
     40 }
     41 
     42 # kit_scenario_case NAME SH EXPECTED [KEEP_DIR] : mode-G oracle. Run scenario
     43 # script SH in a sandbox under $KIT_WORK and diff stdout+stderr against the
     44 # golden EXPECTED. Records exactly one pass/fail/skip; honors a leading "SKIP"
     45 # line when KIT_SCENARIO_SKIP=1. (ar/strip/objcopy/strings/objdump; dbg extends
     46 # it with stdin/normalizer/xfail in its own migration.)
     47 kit_scenario_case() {
     48   kit_sc_name=$1
     49   kit_sc_sh=$2
     50   kit_sc_exp=$3
     51   kit_sc_keep=${4:-}
     52   kit_sc_tag=$(printf '%s' "$kit_sc_name" | tr / -)
     53   kit_sc_actual="$KIT_WORK/$kit_sc_tag.actual"
     54 
     55   if [ ! -e "$kit_sc_exp" ]; then
     56     kit_fail "$kit_sc_name" "missing $(basename "$kit_sc_exp")"
     57     return
     58   fi
     59 
     60   kit_sc_box="$KIT_WORK/$kit_sc_tag"
     61   mkdir -p "$kit_sc_box"
     62   ( cd "$kit_sc_box" && sh "$kit_sc_sh" ) > "$kit_sc_actual" 2>&1
     63   kit_sc_rc=$?
     64 
     65   if [ "${KIT_SCENARIO_SKIP:-0}" = "1" ] && [ "$kit_sc_rc" -eq 0 ] &&
     66      head -n1 "$kit_sc_actual" 2>/dev/null | grep -q '^SKIP'; then
     67     kit_skip "$kit_sc_name" "$(head -n1 "$kit_sc_actual" | sed 's/^SKIP[: ]*//')"
     68     return
     69   fi
     70 
     71   if [ "$kit_sc_rc" -ne 0 ]; then
     72     kit_fail "$kit_sc_name" "script exit=$kit_sc_rc"
     73     diff -u "$kit_sc_exp" "$kit_sc_actual" || true
     74     return
     75   fi
     76 
     77   if diff -u "$kit_sc_exp" "$kit_sc_actual" >/dev/null 2>&1; then
     78     kit_pass "$kit_sc_name"
     79   else
     80     kit_fail "$kit_sc_name"
     81     diff -u "$kit_sc_exp" "$kit_sc_actual" || true
     82     if [ -n "$kit_sc_keep" ]; then
     83       cp "$kit_sc_actual" "$kit_sc_keep/$kit_sc_name.actual" 2>/dev/null || true
     84     fi
     85   fi
     86 }