Take the fixes/lib suite from 110s to 37s, same 645 assertions
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Python tests / test (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run

Three changes, none of which touch what a single test asserts:

thorium_repairs.sh's `sleep 4` becomes `sleep ${THORIUM_STARTUP_WAIT:-4}`
and the harness sets 0.2s. Three cases were each paying four real
seconds to watch a stubbed browser stay up; the stub sleeps 30s, so the
`kill -0` check is unchanged. That file: 17.0s -> 5.6s.

_t_hide was the rest of it. It walks PATH and creates a symlink per
executable -- ~13.5k here, 4.6s a build -- and the suite has ~16
distinct tool sets. Now the full farm is built ONCE and `cp -al`
hard-links it per set, with only the hidden names deleted from the copy.
The cache also moved out of $TEST_TMPDIR, which is per-file, into a
run-scoped dir run_all.sh creates and removes, so it survives between
files.

110s -> 98s (sleep) -> 85s (shared cache) -> 37s (hard-linked farm).

645 OK, 0 FAIL throughout. The cases that only pass when a tool is
genuinely unfindable -- install_pyroveil's missing-dependency arms,
fix_aggressive without sqlite3 -- still pass, which is what proves the
farm is still hiding rather than quietly returning a full PATH.

lib_test_core.sh hit exactly 250 lines, so _t_hide and the farm move to
lib_test_path.sh (194 + 67).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Krzysztof Rudnicki 2026-08-23 14:00:13 +02:00
parent cf4077712a
commit b399fab56d
7 changed files with 153 additions and 50 deletions

View File

@ -0,0 +1,17 @@
{
"title": "Make the fixes/lib suite fast without weakening it",
"objective": "Cut the suite from 110s to well under a minute so pre-push stops being dominated by it, changing only how long things wait and how the PATH shim farm is built.",
"acceptance_criteria": [
"run_all.sh completes in under 60s and exits 0.",
"The assertion count is unchanged at 645 OK with 0 FAIL; no test is deleted, skipped or weakened.",
"The cases that depend on a tool being genuinely unfindable still pass, so the shim farm is still doing its job.",
"Every touched file stays under the 250-line cap and shellcheck-clean with zero suppressions.",
"thorium_repairs.sh's production wait is unchanged by default: THORIUM_STARTUP_WAIT defaults to the original 4."
],
"out_of_scope": [
"Changing what any test asserts.",
"The coverage jail's own runtime, which is dominated by kcov and runs two passes by design.",
"The pacman_hook_stall harness, which predates lib_test_core.sh."
],
"verifier": "time bash linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh (expects exit 0 in under 60s), plus `bash run_all.sh | grep -c '^ OK'` returning 645 and `grep -c '^ FAIL'` returning 0."
}

View File

@ -0,0 +1,51 @@
{
"intent": "Cut the fixes/lib test suite's runtime from 110s to 37s so the commit/push cycle stops being dominated by it, without weakening a single assertion.",
"scope": [
"linux_configuration/scripts/single_use/fixes/lib/tests/lib_test_core.sh and the new lib_test_path.sh",
"linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh",
"linux_configuration/scripts/single_use/fixes/lib/thorium_repairs.sh (one timing seam)",
"linux_configuration/scripts/single_use/fixes/lib/tests/thorium_harness.sh"
],
"changes": [
"thorium_repairs.sh's hardcoded `sleep 4` is now `sleep ${THORIUM_STARTUP_WAIT:-4}`; the harness sets 0.2s. Three cases paid four real seconds each.",
"_t_hide now builds ONE farm of every executable on PATH and hard-links it per tool set with `cp -al`, instead of walking PATH and creating ~13.5k symlinks for each distinct set",
"The farm cache moved out of $TEST_TMPDIR into a run-scoped dir exported by run_all.sh, because each test file gets a fresh tmpdir and the cache never survived between files",
"Split _t_hide and the farm into lib_test_path.sh; lib_test_core.sh had reached exactly 250 lines"
],
"verification": [
{
"command": "time bash linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh",
"result": "pass",
"evidence": "110.0s at session start -> 98.5s after the sleep seam -> 84.6s after the run-scoped cache -> 36.7s after the hard-linked farm. Exit 0 throughout."
},
{
"command": "Per-file timing of the slowest files",
"result": "pass",
"evidence": "test_thorium_repairs_deep.sh 17041ms -> 5563ms. A single _t_hide farm build measured 4645ms, with ~16 distinct tool sets per run."
},
{
"command": "bash run_all.sh | grep -c '^ OK' and '^ FAIL'",
"result": "pass",
"evidence": "645 OK, 0 FAIL. No assertion was deleted, skipped or weakened."
},
{
"command": "Targeted re-check that the 'not installed' branches still hide",
"result": "pass",
"evidence": "install_pyroveil's missing-dependency cases and fix_aggressive's sqlite3-absent case all still pass; they assert on behaviour only reachable when the tool is genuinely unfindable, so a broken farm would fail them loudly."
},
{
"command": "shellcheck + wc -l on both split files",
"result": "pass",
"evidence": "lib_test_core.sh 194 lines, lib_test_path.sh 67 lines, both clean with zero suppressions."
}
],
"risks": [
"`cp -al` hard-links symlinks; if a future _t_hide caller mutated the farm in place it would corrupt the shared copy. Callers only ever read it and the per-set copy is what gets the deletions.",
"The shared farm assumes PATH does not change mid-run. _t_full_path restores the same original PATH, so the assumption holds for this suite.",
"THORIUM_STARTUP_WAIT shortens a real timing check to 0.2s in tests; the stubbed browser sleeps 30s, so the process is still comfortably alive when kill -0 runs."
],
"rollback": [
"git revert the commit; the suite returns to ~110s with identical assertions",
"Re-run run_all.sh and confirm 645 OK / 0 FAIL is unchanged"
]
}

View File

@ -147,55 +147,9 @@ _t_unstub() {
hash -r
}
# _t_hide TOOL... — make TOOL genuinely unfindable, so has_cmd/command -v
# report it absent.
#
# A prepended stub dir cannot do this: every tool these libs probe for
# (usbreset, pactl, wpctl) really exists on an Arch desktop, so PATH has to
# stop resolving it. Dropping PATH to $FAKE_BIN alone is NOT the answer
# either -- that also hides grep, head, awk and sort, which these libs use
# on the very branch under test, turning a "not installed" case into a
# cascade of "command not found".
#
# Instead a shim dir is built containing a symlink to every real executable
# on PATH EXCEPT the hidden ones, and PATH is pointed at it.
_t_hide() {
# Keyed by the tool list and reused: the farm holds a symlink per
# executable on PATH (~13.5k on this host), so rebuilding it on every
# call dominated the suite's runtime and pushed a jail case past its
# 120s timeout. The same hidden set always yields the same farm, so the
# second and later calls are a PATH assignment.
local key="${*}"
local hide_dir="${TEST_TMPDIR}/hidden_path/${key// /_}"
if [[ -d "$hide_dir" ]]; then
PATH="${FAKE_BIN}:${hide_dir}"
hash -r
return 0
fi
mkdir -p "$hide_dir"
local -A hidden=()
local tool
for tool in "$@"; do
hidden["$tool"]=1
done
local dir entry name
local IFS=':'
for dir in ${LIB_TEST_ORIG_PATH}; do
[[ -d "$dir" ]] || continue
for entry in "$dir"/*; do
name="${entry##*/}"
[[ -n "${hidden[$name]:-}" ]] && continue
[[ -x "$entry" && ! -d "$entry" ]] || continue
[[ -e "${hide_dir}/${name}" ]] && continue
ln -s "$entry" "${hide_dir}/${name}" 2>/dev/null || true
done
done
PATH="${FAKE_BIN}:${hide_dir}"
hash -r
}
# _t_hide and its shim farm live in lib_test_path.sh (250-line cap).
# shellcheck source=lib_test_path.sh
. "$(dirname "${BASH_SOURCE[0]}")/lib_test_path.sh"
# _t_full_path — restore the prepended-stub PATH set up by lib_test_core.sh.
_t_full_path() {

View File

@ -0,0 +1,66 @@
#!/usr/bin/env bash
# lib/tests/lib_test_path.sh — _t_hide and the shim farm it builds.
#
# Split out of lib_test_core.sh on 2026-08-23 to hold both files under the
# repo's 250-line cap. Sourced by lib_test_core.sh, not directly by tests.
set -uo pipefail
# _t_hide TOOL... — make TOOL genuinely unfindable, so has_cmd/command -v
# report it absent.
#
# A prepended stub dir cannot do this: every tool these libs probe for
# (usbreset, pactl, wpctl) really exists on an Arch desktop, so PATH has to
# stop resolving it. Dropping PATH to $FAKE_BIN alone is NOT the answer
# either -- that also hides grep, head, awk and sort, which these libs use
# on the very branch under test, turning a "not installed" case into a
# cascade of "command not found".
#
# Instead a shim dir is built containing a symlink to every real executable
# on PATH EXCEPT the hidden ones, and PATH is pointed at it.
_t_hide() {
# Keyed by the tool list and reused, and deliberately cached OUTSIDE
# $TEST_TMPDIR so the farm survives across test files: each file gets a
# fresh tmpdir, so a per-file cache rebuilt the farm ~16 times per run.
# The farm holds a symlink per executable on PATH (~13.5k on this host)
# and costs ~4.6s to build, which was the single largest cost in the
# suite. Its contents are a pure function of the tool list and
# $LIB_TEST_ORIG_PATH, so sharing it changes no behaviour.
#
# $LIB_TEST_HIDE_CACHE is set by run_all.sh for a whole-suite run and
# falls back to the per-file tmpdir when a test file is run on its own.
local key="${*}"
local hide_dir="${LIB_TEST_HIDE_CACHE:-${TEST_TMPDIR}/hidden_path}/${key// /_}"
if [[ -d "$hide_dir" ]]; then
PATH="${FAKE_BIN}:${hide_dir}"
hash -r
return 0
fi
# Build the FULL farm once, then copy it per tool set and delete just the
# hidden names. Walking PATH and creating ~13.5k symlinks is the whole
# cost; `cp -al` hard-links the symlinks instead of recreating them, which
# turns each additional tool set from seconds into milliseconds.
local full="${LIB_TEST_HIDE_CACHE:-${TEST_TMPDIR}/hidden_path}/__all"
if [[ ! -d "$full" ]]; then
mkdir -p "$full"
local dir entry name
local IFS=':'
for dir in ${LIB_TEST_ORIG_PATH}; do
[[ -d "$dir" ]] || continue
for entry in "$dir"/*; do
name="${entry##*/}"
[[ -x "$entry" && ! -d "$entry" ]] || continue
[[ -e "${full}/${name}" ]] && continue
ln -s "$entry" "${full}/${name}" 2>/dev/null || true
done
done
fi
cp -al "$full" "$hide_dir"
local tool
for tool in "$@"; do
rm -f "${hide_dir}/${tool}"
done
PATH="${FAKE_BIN}:${hide_dir}"
hash -r
}

View File

@ -16,6 +16,15 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# One _t_hide shim farm for the whole run. Each test file gets its own
# $TEST_TMPDIR, so without this the farm -- a symlink per executable on PATH,
# ~13.5k of them and ~4.6s to build -- was rebuilt once per distinct tool set,
# roughly sixteen times a run. Its contents depend only on the tool list and
# the original PATH, so sharing it across files changes nothing but the clock.
LIB_TEST_HIDE_CACHE="$(mktemp -d)"
export LIB_TEST_HIDE_CACHE
trap 'rm -rf "${LIB_TEST_HIDE_CACHE}"' EXIT
failed=0
for test_script in "${SCRIPT_DIR}"/test_*.sh; do
printf '\n### %s\n' "$(basename "$test_script")"

View File

@ -37,6 +37,10 @@ export BACKUP_SUFFIX=".bak.20260822_120000"
export DRY_RUN=false
export AGGRESSIVE=false
export TEST_AFTER=false
# test_thorium sleeps to see whether the browser stayed up. Four real
# seconds per case dominated this file's runtime (17s of a 110s suite);
# the stub browser sleeps far longer than this, so the check is unchanged.
export THORIUM_STARTUP_WAIT=0.2
# The lib echoes these directly; fix_thorium.sh defines them for a terminal.
# Empty here so assertions match on text rather than escape sequences.

View File

@ -146,7 +146,9 @@ test_thorium() {
local pid=$!
# Wait a few seconds and check if it's still running
sleep 4
# How long to let the browser prove it stays up. Overridable so the
# tests do not pay four real seconds per case; production never sets it.
sleep "${THORIUM_STARTUP_WAIT:-4}"
if kill -0 "$pid" 2>/dev/null; then
log_ok "Thorium started successfully! (PID: $pid)"