Commit Graph

14 Commits

Author SHA1 Message Date
b4b6908d69 Test arch_cpu.sh to 100% and take it off the allowlist (91 -> 90)
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
57/57 lines, measured through run_all.sh and confirmed a second time at
--min 100 so a shortfall would exit non-zero. check_shell_coverage.sh
passes with the exemption removed.

28 assertions over 14 cases: no cpufreq at all, every core already
tuned, the mixed case where only some cores lag, cpupower absent /
unconfigured / already configured, and all three I/O scheduler targets
(none for NVMe, mq-deadline for SATA SSD, bfq for spinning disks).

The sysfs reads and the two /etc write targets are now behind overrides
defaulting to the real paths, so the tests can present hardware this
host does not have -- a rotational disk -- without touching anything.

One assertion initially passed for the wrong reason: _t_hide keeps
$FAKE_BIN on PATH by design, so the harness's own cpupower stub still
satisfied has_cmd and the "not installed" branch never ran. Unstubbing
before hiding is now explicit, and the case fails if that is lost.

This also settles arch_sysctl.sh's diagnosis: it uses this same
harness, so the harness is not why it cannot be measured.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 21:14:57 +02:00
28f2925c30 Instrument: multi-line array elements are not statements; clear arch_perf_fixes
Fourth flavour of defect (a) found this session, after multi-line quotes,
`} |` and the backslash-continued assignment. bash reports a multi-line array
assignment at its OPENING line and never emits the element lines or the
closing paren, so kcov instrumenting them inflates the denominator:

    +L3 items=('one' 'two')      # opened line 3, closed line 6
                                 # lines 4, 5, 6: never emitted

The rule is therefore symmetric with the existing multi-line-quote case: the
opening line is the statement, everything up to the closing paren is data.
_closes_array() finds that paren by recomputing quote state per candidate, so
an element like "a(b)" does not end the literal early.

Measured effect through fixes/lib/tests/run_all.sh:

  arch_perf_fixes.sh  93.48% -> 100.00%  (43/43)
  bt_audio.sh        100.00% -> 100.00%  (127/127)
  arch_perf_report.sh 100.00% -> 100.00% (59/59)
  arch_perf_probes.sh 100.00% -> 100.00% (93/93)
  ubuntu_perf_more.sh 100.00% -> 100.00% (32/32)
  bt_report.sh       100.00% -> 100.00%  (37/37)
  bt_pairing.sh      100.00% -> 100.00%  (65/65)

One gained, six held, none went DOWN. Acceptance test unchanged:
dot_resolver_install.sh 39/39 and rpi_nc_ca.sh 73/73. arch_perf_fixes.sh
therefore comes off the allowlist in the same commit, confirmed by the real
gate with no exemption.

The fail-open check, since over-detection INFLATES coverage: the old and new
predicates were diffed over every allowlisted lib plus the six cleared ones,
printing each newly excluded line WITH its text. All 91 across 10 libs are
array elements or closing parens -- common.sh's tool tables, packages.sh's
associative arrays, arch_sysctl.sh's sysctl maps, thorium_repairs.sh's four
path lists, ubuntu_perf_fixes.sh's sssd units, and so on. No statement caught.

Tests cover both directions, including three negatives: a single-line
`x=(a b)`, an element containing a parenthesis, and `x=$(echo hi)` which is a
command substitution rather than an array. Module stays at 100% branch
coverage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 20:13:45 +02:00
99a9804d75 Test ubuntu_perf_more.sh to 100%: allowlist 93 -> 92
Seventh of the 16 untested fixes/lib libs and the first of the ubuntu-perf
pair, which gets its own harness here. 24 assertions; 32/32 = 100.00%
through run_all.sh on the first measurement, confirmed at --min 100 (exit 0),
then cleared with the real gate and no exemption.

Two absolute paths had to move behind env overrides, defaulting to the real
ones: fix_journal writes /etc/systemd/journald.conf.d/size-limit.conf and
run_undo globs /root for undo scripts. Binding those in the jail was rejected
for the same reason as bt_pairing.sh's udev rule -- run_all.sh runs UN-jailed
in ci_mirror.sh and in CI, so a bind mount protects the coverage run and
nothing else. JOURNALD_CONF_DIR and UNDO_DIR follow the UDEV_RULES_DIR
precedent.

Proof the suite is safe where it runs un-jailed: after a bare run_all.sh the
real /etc/systemd/journald.conf.d/size-limit.conf still carries its 2026-03-02
mtime, a genuine artifact of a past production run, and no
undo_ubuntu_performance_*.sh exists in /root.

Worth noting for the rest of the family: run_undo ends in `exit`, so its cases
run inside an explicit subshell. A command substitution already provides one,
so the exit ends only that subshell rather than the whole test file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 19:25:21 +02:00
fa7b05da74 Test arch_perf_probes.sh to 100%: allowlist 93 -> 92
Sixth of the 16 untested fixes/lib libs, and the first with no dead branch to
fix -- the whole job was test-writing. 43 assertions across two files;
93/93 = 100.00% through run_all.sh, twice, the second at --min 100 (exit 0),
then cleared with the real gate confirming and no exemption.

The one genuine gap was check_memory_pressure's high-swap branch (lines
158-159), which fires only when swap is heavily used WHILE RAM is still
available -- a state this host does not happen to be in. The lib reads the
absolute /proc/meminfo, but every read goes through `awk`, so stubbing awk
supplies controlled figures without touching /proc: the stub answers on the
pattern being matched and execs the real awk for anything else. Both
directions are covered, including RAM genuinely exhausted, which must NOT be
flagged because it is not the stutter signature.

Everything else here is branch coverage of probes whose inputs are external
commands: failed systemd units, ACPI error counts, a CPU-hungry Xorg,
governors all-performance vs one-powersave vs unsupported, thermal
throttling excerpts, the TLP/power-profiles-daemon conflict in all three
combinations, and storage health with and without fstrim/smartctl.

lib_test_core.sh gains _t_stub_cat. "Print this fixture file" is by far the
commonest stub shape, and writing it inline forces every call site to embed
a literal ${LIB_TEST_DEV} that must not expand at write time -- SC2016 on
every use. Passing the fixture NAME as data removes the class outright, and
two earlier bluetooth test files are simplified onto it. All 21 test files
and three harnesses now lint clean with no suppression anywhere.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 19:04:50 +02:00
c309c95f5a Clear bt_audio.sh and arch_perf_report.sh: allowlist 95 -> 93
Both were already tested to their reachable ceiling earlier in this session
(a5b6663c, ffcf99f1) and held below 100% only by the closing-brace artifact
that d989cd7e removed. With the instrument corrected they measure:

  bt_audio.sh          127/127 = 100.00%
  arch_perf_report.sh   59/59  = 100.00%

both at --min 100 with exit 0, and check_shell_coverage.sh returns
"every checked shell library meets the coverage bar" with their allowlist
lines already gone, i.e. with no exemption. bt_report.sh and bt_pairing.sh
were gated in the same run to confirm the two libs cleared earlier did not
regress.

Note that the closing-brace exclusion is now load-bearing: reverting
d989cd7e without also restoring these two lines would turn every subsequent
commit red.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 18:40:05 +02:00
0e9cc0ce95 Test bt_pairing.sh to 100%: allowlist 97 -> 96
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Second of the 16 untested fixes/lib libs. 65/65 = 100.00% through
run_all.sh, twice, the second at --min 100 (exit 0), then cleared from the
allowlist and confirmed by the real gate with no exemption.

Two findings worth keeping:

- udevadm was NOT in the harness's stub list, so `udevadm control
  --reload-rules` was reaching the REAL binary during the suite. A
  prepended stub dir cannot hide a tool the host actually has. Caught by
  asserting on the recorded call rather than by reading the code, which is
  the argument for asserting on calls at all.

- _disable_usb_autosuspend writes /etc/udev/rules.d/50-bluetooth-no-
  autosuspend.rules. Binding /etc in the jail would have covered it, and
  was rejected: run_all.sh runs UN-jailed in ci_mirror.sh and in the
  shell-tests workflow, as its own header says, so a bind mount protects
  the coverage run and leaves every bare run writing to a real root-owned
  file. Instead the lib gained a UDEV_RULES_DIR override, defaulting to the
  real path -- the same env-override seam pacman_hook_stall_harness.sh uses
  for PACMAN_LOG/CACHE_DIR/PACMAN_LOCK.

Proof the suite is safe where it runs un-jailed: after a bare run_all.sh,
the real rule file still has its 2026-02-21 mtime (it is a genuine artifact
of a production run six months ago) and the probed power/control values are
unchanged. The jail cannot give that check.

fix_usb_autosuspend globs the real /sys/bus/usb/devices/*/ with no override,
so its branches are driven through stubbed lsusb output: ffff:ffff matches
nothing on any machine and reaches the not-found arm, while 046d:c077
(control=on) and 046d:0825 (control=auto) are read-only probes, each guarded
so the case self-skips with a note if the host state changes rather than
silently asserting nothing.

Split across two test files to stay under the 250-line cap; run_all.sh globs
test_*.sh, so splitting costs nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 16:47:40 +02:00
4cfc3fdde1 Test bt_report.sh to 100%: allowlist 98 -> 97
First of the 16 untested fixes/lib libs. Measured 37/37 = 100.00% through
lib/tests/run_all.sh, twice, the second run at --min 100 (exit 0), then
removed from the allowlist and confirmed with the real gate and no
exemption.

Adds two reusable pieces rather than a per-family harness clone:

- lib_test_core.sh -- PASS/FAIL tally, _t_eq/_t_contains/_t_lacks, a
  mktemp -d sandbox wiped on EXIT, a FAKE_BIN stub dir on PATH, and
  _t_stub/_t_unstub. _t_unstub runs `hash -r`: deleting a stub file alone
  does not drop bash's cached executable path, so the real binary would
  never be reached again.
- bt_harness.sh -- sources the core, sources the real scripts/lib/common.sh
  for the production log_*/has_cmd helpers (verified inert at source time),
  and redefines _btctl and apply_fix verbatim from fix_bluetooth.sh, since
  those live in the entry script rather than in any lib. Same trade-off
  pacman_hook_stall_harness.sh already makes with log_size.

pacman_hook_stall_harness.sh is deliberately left alone: its six libs are
already off the allowlist, i.e. gated at 100% with no exemption, so
refactoring it onto the new core would risk banked work for no gain. jscpd
reads 1.6% against the hook's own flags, and **/lib/tests/** is excluded
from that scan anyway, so the duplication budget is not at stake.

_t_only_path exists because every tool these libs call (usbreset, pactl,
lsusb, ...) genuinely exists on an Arch desktop: a prepended stub dir
cannot exercise a "not installed" branch, so those cases drop PATH to
FAKE_BIN alone.

The three coverage runs were made in a detached worktree: a second session
was writing to this repo concurrently, and the jail aborts on any
working-tree delta during a run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 16:33:33 +02:00
83de41f470 Clear five pacman_hook_stall libs: allowlist 103 -> 98
Each measured 100.00% through fixes/lib/tests/run_all.sh, twice, with the
second run gating at --min 100 so a shortfall would exit non-zero rather than
print a number I might misread:

  pacman_hook_stall_capture.sh   59/59
  pacman_hook_stall_load.sh      25/25
  pacman_hook_stall_summary.sh   18/18
  pacman_hook_stall_watch.sh     24/24
  pacman_hook_stall_usage.sh       1/1

Two matching runs was the bar because this directory's suites drive
watch_forever timing loops, and a timing-dependent suite can vary its line
set between runs -- dwm_config.sh was observed doing exactly that. These five
did not vary.

pacman_hook_stall_setup.sh stays: 26/27 = 96.30%, uncovered line 7.

usage.sh's denominator of 1 is honest rather than broken. The lib is a single
usage() whose body is one `cat <<EOF` heredoc plus `exit 0`, and heredoc
content is data, not statements. Its tests assert on the rendered text, so
the behaviour is exercised even though only one line is instrumentable.

summary.sh has one off-set line (36). That cannot inflate the figure -- an
off-set line is by construction one the trace SAW EXECUTE -- but it does mean
the lib is measured over a subset of its statements.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 14:57:01 +02:00
154b416617 Clear transcribe_venv.sh: 100%, off the allowlist, 104 -> 103
A 29-assertion suite covering all six functions. transcribe_venv.sh measures
53/53 = 100.00% through the directory runner, and check_shell_coverage.sh
passes it with the exemption deleted.

Assertions are on recorded ARGV because which index a pip install points at
IS the behaviour: the OpenNMT cu12 wheel index on the NVIDIA path, the
CPU-only torch index for diarization (forced to avoid mismatched CUDA
builds). "pip was called" cannot see either.

generate_test_audio's four-deep fallback chain is covered by failing each
generator in turn. Every stub materialises the wav, because the chain
advances on `[[ ! -s $tmpwav ]]` -- a record-only stub would silently
exercise the branch after the one under test.

One assertion was wrong and got corrected rather than forced: I claimed a
wholly-failing pip still returns 0, but the final `python "$PY_HELPERS"
deps-installed` carries no `|| log`, so it does not. The suite now asserts
what the subject actually guarantees -- all four warnings emitted, no earlier
failure aborting the run.

SC2016 fixed at the source with a quoted heredoc, not suppressed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016sxxsDHWgdRhmdmzNMA6XM
2026-08-22 13:24:28 +02:00
b91be3099d Clear unity_handler.sh: 100%, off the allowlist, 105 -> 104
The first allowlist removal of the campaign this session. unity_handler.sh
measures 32/32 = 100.00% through its directory's runner, and
check_shell_coverage.sh passes it with the exemption DELETED -- the real
gate, not just the measurement.

HARNESS BUG found getting there: bash caches executable locations in a hash
table, so `command -v foo` keeps succeeding after foo is removed from the
stub dir. Every "tool is missing" test was therefore running as a "tool is
present" test, asserting the opposite of its own name while looking
plausible. Reproduced minimally: after rm, STILL FOUND; after `hash -r`,
gone.

A _t_unstub helper now removes the stub and clears the table. The two suites
committed an hour ago had the same defect and are corrected here --
test_transcribe_pkgmgr.sh goes from 15 to 18 passing assertions, so three of
its checks had been vacuous. This is exactly the failure the campaign exists
to catch, found in its own test code.

`basename` joins the restricted PATH because the SUBJECT calls it; the suite
avoids needing `tail` via a parameter expansion instead, since every binary
in that PATH is one more thing a stub's shebang can trip over.

transcribe_deps.sh (92.31%) and transcribe_pkgmgr.sh (98.00%) re-measured
unchanged and stay on the allowlist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016sxxsDHWgdRhmdmzNMA6XM
2026-08-22 13:20:54 +02:00
bca70b67b5 Shell coverage: convert the ratchet to a measured 100% bar
The gate was a presence check -- 'a run_all.sh exists beside this lib' --
which an empty suite that asserts nothing satisfies. It now measures.

100% is reachable with no suppressions and no production source changes:
run the suite inside a user+mount namespace and the sudo-writes, systemd
units and nftables rules execute for real against a throwaway /etc.

- meta/scripts/shell_coverage_jail.sh: the runner, promoted out of a
  session scratchpad. Two fixes it needed on the way: bind targets mirror
  the real directory tree (an empty bind makes writes fail with ENOENT,
  which reads as unreachable code), and sudo gets a pass-through stub
  because real sudo cannot setresuid inside a userns.
- It fingerprints git status before and after and fails the run if a
  write escapes the jail. Verified with a deliberate escapee.
- dot_resolver_install.sh: 39/39 = 100.00%, 28 assertions. Picked by
  scoring every allowlisted lib on root ops, system writes and
  destructive calls -- it scored highest in the repo. Allowlist 106 -> 105.
- jscpd was already over its own threshold at 2.45% and would have
  rejected every commit staging a .sh file. Excluding vendored .venv/
  shell alone gives 1.67%; also excluding lib/tests/ gives 1.47%.

The gate is deliberately NOT wired into the hook chain yet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbD4nco3EgL1UFoZKmKsLE
2026-08-22 11:20:58 +02:00
d42d8ff20d Shrink the shell-coverage allowlist 115 -> 106: cover scripts/lib
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Gives linux_configuration/scripts/lib a real test suite, which takes all
nine of its libraries off meta/shell-coverage-allowlist.txt at once —
coverage is per-directory, so this is the highest-ratio first batch.

139 assertions across four suites, all offline: the mtk toolkit is driven
through its existing MTK_ROOT_FIXTURE seam, and adb is shimmed onto a
narrowed PATH. Nothing reads the wall clock, this host's udev rules, or a
real device, because the suite runs in shell-tests.yml and again on every
pre-push via ci-mirror — a host-dependent assertion would be a flake that
blocks unrelated pushes.

The gate only checks that tests/run_all.sh EXISTS, so an empty one would
mark all nine libraries covered while testing nothing. Each of the four
load-bearing rules was therefore mutation-tested and the suite required to
go red: classify_device's && -> ||, discover_partitions' init_boot/boot
ordering, mtk_select_device's refusal to guess between two phones, and
is_hour_in_range's 10#$ octal guard.

That last one initially SURVIVED. Dropping 10#$ makes bash abort with
"value too great for base", a non-zero exit indistinguishable from an
honest out-of-range result, so the status-only assertion passed either
way. It now asserts stderr is empty.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 23:52:09 +02:00
53e80462c5 Phase 3: prove 100% shell coverage is reachable via a namespace jail
Measurement-only. No production file changed.

The gating question was whether the campaign's constraints are jointly
satisfiable: 100% line coverage over ALL .sh files with no suppressions.
Phase 1 measured effecting code at 0% under PATH shims, which implied
either forbidden suppressions or source seams in 17+46 files.

They are satisfiable. A user+mount namespace reaches 100% with zero
source changes: --map-root-user makes require_root fall through, and
bind-mounting each write target makes installer writes land in the jail.
setup_night_lockdown.sh went 81.58% (PATH shims) -> 86.84% (userns) ->
100.00% (38/38, all mounts).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3PzGc75gBcdxP3PkHXGcV
2026-08-21 17:08:05 +02:00
3278bebd03 Phase 3: ratchet shell libraries onto test suites
A shell library under a lib/ directory must now sit beside a
tests/run_all.sh. This is a presence gate, not a coverage percentage:
Phase 1 measured these libs' decision logic at ~90% under test but
their effecting code at 0%, because it sudo-writes, pkills and installs.
A numeric bar would only be reachable by shimming every external for
every installer, or by the suppressions this repo forbids.

Seeded at 125 exempt libraries out of 208 tracked; the other 83 already
have a suite. The allowlist shrinks only — a modified library loses its
exemption and must bring tests.

Verified standalone: blocks a new untested lib (exit 1), and does NOT
block covered libs, exempt libs, or unrelated entry scripts. That last
case is the point of a ratchet over the repo-wide gate.

The .pre-commit-config.yaml entry is deliberately NOT included — the
edit was denied as a sensitive file, so the gate is runnable but not
yet enforced.
2026-08-21 17:00:26 +02:00