Read the load average through LOADAVG_FILE so the probe tests are host-independent
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
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

The "flags nothing on a quiet machine" case read the real /proc/loadavg and
went red whenever a game was running on the host (22/16 during a BeamNG
session), and the "flags a load at/above thread count" case had to SKIP
whenever the host was idle. Same override pattern as JOURNALD_CONF_DIR: the
harness writes a fixture, both cases now assert deterministically, and a
missing file degrades to 0 as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SS8M5wk88nJTXxDWz61KKk
This commit is contained in:
Krzysztof Rudnicki 2026-09-14 21:53:54 +02:00
parent ccb7d7f7d3
commit 2d54765f6f
4 changed files with 50 additions and 10 deletions

View File

@ -0,0 +1,29 @@
{
"intent": "Make the arch_perf_probes lib tests independent of the host's real load average so the pre-push ci-mirror gate is not red whenever a game is running.",
"scope": [
"linux_configuration/fixes/lib/arch_perf_probes.sh (LOADAVG_FILE override, default /proc/loadavg)",
"linux_configuration/fixes/lib/tests/arch_perf_harness.sh (fixture written by arch_reset)",
"linux_configuration/fixes/lib/tests/test_arch_perf_probes.sh (deterministic load cases)"
],
"changes": [
"collect_basics reads the 1-minute load from ${LOADAVG_FILE:-/proc/loadavg}; behaviour on the host is unchanged",
"The harness exports LOADAVG_FILE into TEST_TMPDIR and arch_reset writes a quiet fixture (0.10)",
"The load test now asserts the (16/16) finding from a 16.50 fixture instead of SKIPping when the host is idle; a missing file case asserts no finding"
],
"verification": [
{
"command": "./linux_configuration/fixes/lib/tests/test_arch_perf_probes.sh",
"result": "pass",
"evidence": "arch_perf_probes (basics/governor): 17 passed, 0 failed (was 16 with one SKIP, and 1 failed at host load 22/16)"
},
{
"command": "./linux_configuration/fixes/lib/tests/run_all.sh (host load ~19/16, BeamNG running)",
"result": "pass",
"evidence": "All fixes lib test files passed."
}
],
"risks": ["None on the host: the default path is the real /proc/loadavg"],
"rollback": [
"git revert the commit; the tests return to reading the real load and go red under host load"
]
}

View File

@ -19,7 +19,9 @@ collect_basics() {
local cpu_count
cpu_count=$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)
local load1
load1=$(awk '{print int($1)}' /proc/loadavg 2>/dev/null || echo 0)
# Overridable so the tests do not depend on the host being idle: the
# "quiet machine" case went red whenever a game was running on the host.
load1=$(awk '{print int($1)}' "${LOADAVG_FILE:-/proc/loadavg}" 2>/dev/null || echo 0)
if [[ ${load1:-0} -ge ${cpu_count:-1} ]]; then
add_finding "1-minute load average is at/above CPU thread count (${load1}/${cpu_count}); background tasks may be saturating the system."
fi

View File

@ -37,6 +37,9 @@ export REPORT_FILE="${TEST_TMPDIR}/report.log"
export JOURNALD_CONF_DIR="${TEST_TMPDIR}/journald.conf.d"
export SYSTEMD_UNIT_DIR="${TEST_TMPDIR}/systemd_units"
export ORGANIZE_SCRIPT_CANDIDATES="${TEST_TMPDIR}/organize_downloads.sh"
# collect_basics reads the 1-minute load from here; a fixture, not the real
# /proc/loadavg, or the "quiet machine" case depends on nothing else running.
export LOADAVG_FILE="${TEST_TMPDIR}/loadavg"
export APPLY_SAFE_FIXES="false"
export INSTALL_TOOLS="false"
declare -a FINDINGS=()
@ -85,6 +88,7 @@ arch_reset() {
rm -rf "${JOURNALD_CONF_DIR}" "${SYSTEMD_UNIT_DIR}"
mkdir -p "${JOURNALD_CONF_DIR}" "${SYSTEMD_UNIT_DIR}"
rm -f "${ORGANIZE_SCRIPT_CANDIDATES}"
echo "0.10 0.20 0.30 1/100 1" >"${LOADAVG_FILE}"
_t_full_path
_arch_default_stubs
}

View File

@ -67,20 +67,25 @@ _t_contains "$findings" "ACPI errors detected" \
_t_contains "$findings" "Xorg is using high CPU (45%)" \
"collect_basics: flags a CPU-hungry Xorg"
# A load average at or above the thread count is flagged. /proc/loadavg is
# read directly by the lib, so the case is driven by a low CPU count instead.
# A load average at or above the thread count is flagged.
arch_reset
_t_stub getconf 'echo 1'
_t_stub getconf 'echo 16'
_t_stub systemctl 'exit 0'
_t_stub journalctl 'exit 0'
_t_stub ps 'echo none'
echo "16.50 12.00 9.00 3/900 1" >"${LOADAVG_FILE}"
collect_basics
if [[ $(awk '{print int($1)}' /proc/loadavg) -ge 1 ]]; then
_t_contains "$(_t_findings)" "load average is at/above CPU thread count" \
"collect_basics: flags a load average at or above the thread count"
else
_t_pass "collect_basics: SKIP load case (this host's 1-minute load is below 1)"
fi
_t_contains "$(_t_findings)" "load average is at/above CPU thread count (16/16)" \
"collect_basics: flags a load average at or above the thread count"
# An unreadable load file degrades to 0 rather than aborting the probe.
arch_reset
_t_stub systemctl 'exit 0'
_t_stub journalctl 'exit 0'
_t_stub ps 'echo none'
rm -f "${LOADAVG_FILE}"
collect_basics
_t_eq "" "$(_t_findings)" "collect_basics: missing load file is not a finding"
# --- check_cpu_governor -----------------------------------------------------