kit

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

commit c562293046d7bf431615d75bb41393db83b99197
parent 5cb0213fcda79c07c71fe59fa9aa10e792d32c67
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sat,  9 May 2026 12:18:43 -0700

test-link: add filters, per-path timing; fix slow podman exec path

- ./run.sh [name_filter] [paths] (or CFREE_TEST_FILTER/CFREE_TEST_PATHS)
  to scope a run to one case and/or a subset of R/E/J.
- Per-case ms timings on PASS/FAIL lines plus a totals line.
- Drop --platform linux/arm64 from podman run on arm64 hosts: the flag
  triggers a registry manifest lookup (~30s) even when the local image
  is already arm64. Cuts path E from ~32s to ~0.5s per case.

Diffstat:
Mtest/link/run.sh | 65++++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 48 insertions(+), 17 deletions(-)

diff --git a/test/link/run.sh b/test/link/run.sh @@ -26,6 +26,12 @@ # gc_absent — one symbol per line; jit-runner verifies each is absent # after --gc-sections (implies linker_flags contains that flag) # archive_b — package b.o into b.a; content "demand" or "whole" +# +# Filtering: +# ./run.sh [name_filter] [paths] +# name_filter substring match against case name (e.g. "02", "rodata") +# paths subset of "REJ" (default "REJ") +# Equivalent env vars: CFREE_TEST_FILTER, CFREE_TEST_PATHS. set -u @@ -44,6 +50,17 @@ CC="${CC:-cc}" CFREE_CFLAGS="-I$ROOT/include" ALLOW_SKIP="${CFREE_TEST_ALLOW_SKIP:-0}" +# Filters (env vars or positional args; args win): +# $1 / CFREE_TEST_FILTER — substring match against case name (e.g. "02" or "rodata") +# $2 / CFREE_TEST_PATHS — subset of "REJ" (default "REJ"); selects which paths run +FILTER="${1:-${CFREE_TEST_FILTER:-}}" +PATHS="${2:-${CFREE_TEST_PATHS:-REJ}}" +case "$PATHS" in *R*) RUN_R=1;; *) RUN_R=0;; esac +case "$PATHS" in *E*) RUN_E=1;; *) RUN_E=0;; esac +case "$PATHS" in *J*) RUN_J=1;; *) RUN_J=0;; esac +T_R=0; T_E=0; T_J=0 # accumulated wall-clock seconds per path +now_ms() { python3 -c 'import time;print(int(time.time()*1000))'; } + mkdir -p "$BUILD_DIR" mkdir -p "$BUILD_DIR/link" @@ -96,9 +113,13 @@ run_aarch64() { "$QEMU_BIN" "$exe" >"$out" 2>"$err"; RUN_RC=$?; return fi if [ $have_podman -eq 1 ]; then - local dir base + local dir base platform_flag=() dir="$(cd "$(dirname "$exe")" && pwd)"; base="$(basename "$exe")" - podman run --rm --platform linux/arm64 --net=none \ + # `--platform linux/arm64` triggers a registry manifest lookup (~30s) + # even when the local image is already arm64. Only pass it on hosts + # where the podman machine isn't natively arm64. + [ $is_aarch64 -eq 0 ] && platform_flag=(--platform linux/arm64) + podman run --rm "${platform_flag[@]}" --net=none \ -v "$dir":/work:Z -w /work "$RUN_AARCH64_IMAGE" "./$base" >"$out" 2>"$err" RUN_RC=$?; return fi @@ -145,6 +166,7 @@ printf 'Running cases...\n' for case_dir in "$TEST_DIR/cases"/*/; do [ -d "$case_dir" ] || continue name="$(basename "$case_dir")" + [ -n "$FILTER" ] && [[ "$name" != *"$FILTER"* ]] && continue work="$BUILD_DIR/link/$name" mkdir -p "$work" @@ -231,8 +253,9 @@ for case_dir in "$TEST_DIR/cases"/*/; do done # ---- Path R: roundtrip -------------------------------------------------- - if [ $jit_only -eq 0 ]; then + if [ $jit_only -eq 0 ] && [ $RUN_R -eq 1 ]; then if [ $have_roundtrip -eq 1 ] && [ $have_readelf -eq 1 ] && [ $have_python3 -eq 1 ]; then + t0=$(now_ms) r_ok=1 for obj in "${rt_obj_files[@]}"; do base="$(basename "$obj" .o)" @@ -250,7 +273,8 @@ for case_dir in "$TEST_DIR/cases"/*/; do r_ok=0; break fi done - if [ $r_ok -eq 1 ]; then note_pass "$name/R" + dt=$(( $(now_ms) - t0 )); T_R=$(( T_R + dt )) + if [ $r_ok -eq 1 ]; then note_pass "$name/R (${dt}ms)" else note_fail "$name/R"; fi else note_skip "$name/R" "missing roundtrip/readelf/python3" @@ -258,7 +282,8 @@ for case_dir in "$TEST_DIR/cases"/*/; do fi # ---- Path E: exec ------------------------------------------------------- - if [ $jit_only -eq 0 ] && [ $have_exe_runner -eq 1 ]; then + if [ $jit_only -eq 0 ] && [ $RUN_E -eq 1 ] && [ $have_exe_runner -eq 1 ]; then + t0=$(now_ms) # Compile start.o start_obj="$work/start.o" clang $CLANG_TARGET -O1 -ffreestanding -fno-stack-protector \ @@ -270,22 +295,25 @@ for case_dir in "$TEST_DIR/cases"/*/; do "${link_obj_files[@]}" "$start_obj" "${link_arc_flags[@]}") if ! "${link_cmd[@]}" >"$work/exec_link.out" 2>"$work/exec_link.err"; then - note_fail "$name/E (link failed)" + dt=$(( $(now_ms) - t0 )); T_E=$(( T_E + dt )) + note_fail "$name/E (link failed, ${dt}ms)" elif [ $have_runner -eq 1 ]; then run_aarch64 "$exe" "$work/exec.out" "$work/exec.err" - if [ "$RUN_RC" -eq "$expected" ]; then note_pass "$name/E" - else note_fail "$name/E (expected $expected, got $RUN_RC)"; fi + dt=$(( $(now_ms) - t0 )); T_E=$(( T_E + dt )) + if [ "$RUN_RC" -eq "$expected" ]; then note_pass "$name/E (${dt}ms)" + else note_fail "$name/E (expected $expected, got $RUN_RC, ${dt}ms)"; fi else note_skip "$name/E" "no runner (qemu/podman)" fi else - if [ $jit_only -eq 0 ]; then + if [ $jit_only -eq 0 ] && [ $RUN_E -eq 1 ]; then note_skip "$name/E" "no link-exe-runner" fi fi # ---- Path J: JIT -------------------------------------------------------- - if [ $have_jit_runner -eq 1 ]; then + if [ $RUN_J -eq 1 ] && [ $have_jit_runner -eq 1 ]; then + t0=$(now_ms) jit_cmd=("$JIT_RUNNER" "${extra_flags[@]}") [ $use_resolver -eq 1 ] && jit_cmd+=(--use-resolver) jit_cmd+=("${link_obj_files[@]}" "${link_arc_flags[@]}") @@ -309,9 +337,10 @@ for case_dir in "$TEST_DIR/cases"/*/; do fi done - if [ "$j_rc" -eq "$expected" ]; then note_pass "$name/J" - else note_fail "$name/J (expected $expected, got $j_rc)"; fi - else + dt=$(( $(now_ms) - t0 )); T_J=$(( T_J + dt )) + if [ "$j_rc" -eq "$expected" ]; then note_pass "$name/J (${dt}ms)" + else note_fail "$name/J (expected $expected, got $j_rc, ${dt}ms)"; fi + elif [ $RUN_J -eq 1 ]; then note_skip "$name/J" "no jit-runner (not aarch64 host or build failed)" fi @@ -326,6 +355,7 @@ done for case_dir in "$TEST_DIR/bad"/*/; do [ -d "$case_dir" ] || continue name="bad/$(basename "$case_dir")" + [ -n "$FILTER" ] && [[ "$name" != *"$FILTER"* ]] && continue work="$BUILD_DIR/link/$name" mkdir -p "$work" @@ -359,7 +389,7 @@ for case_dir in "$TEST_DIR/bad"/*/; do fi # Path E - if [ $have_exe_runner -eq 1 ]; then + if [ $RUN_E -eq 1 ] && [ $have_exe_runner -eq 1 ]; then start_obj="$work/start.o" clang $CLANG_TARGET -O1 -ffreestanding -fno-stack-protector \ -fno-PIC -fno-pie \ @@ -379,12 +409,12 @@ for case_dir in "$TEST_DIR/bad"/*/; do note_pass "$name/E" fi fi - else + elif [ $RUN_E -eq 1 ]; then note_skip "$name/E" "no link-exe-runner" fi # Path J - if [ $have_jit_runner -eq 1 ]; then + if [ $RUN_J -eq 1 ] && [ $have_jit_runner -eq 1 ]; then if "$JIT_RUNNER" "${obj_files[@]}" >"$work/jit.out" 2>"$work/jit.err"; then note_fail "$name/J (jit-runner succeeded; expected non-zero exit)" else @@ -398,7 +428,7 @@ for case_dir in "$TEST_DIR/bad"/*/; do note_pass "$name/J" fi fi - else + elif [ $RUN_J -eq 1 ]; then note_skip "$name/J" "no jit-runner (not aarch64 host or build failed)" fi done @@ -407,6 +437,7 @@ done printf '\n' printf 'Results: %s pass, %s fail, %s skip\n' "$PASS" "$FAIL" "$SKIP" +printf 'Time: R=%dms E=%dms J=%dms\n' "$T_R" "$T_E" "$T_J" if [ ${#FAIL_NAMES[@]} -gt 0 ]; then printf 'Failed:\n'