testsAndMisc/docs/superpowers/evidence/bt-audio-coverage-2026-08-22.json
Krzysztof kuhy Rudnicki a5b6663c02 Test bt_audio.sh to 96.97% and fix its wpctl health check
Fourth of the 16 untested fixes/lib libs, the largest at 214 lines, and the
last of the bluetooth family. 47 assertions across three files. The lib
STAYS on the allowlist: 128/132 = 96.97%, twice with the same line set.

The bug the tests found, fixed here. Line 21 read:

    if timeout 3 _run_as_user wpctl status &>/dev/null; then

`timeout` is a binary and `_run_as_user` is a shell function that is never
exported, so this always failed with rc=127 -- "timeout: failed to run
command '_run_as_user'". check_pipewire_health therefore reported PipeWire
hung on EVERY run and restarted a healthy audio stack every time
fix_bluetooth.sh ran. The healthy branch was unreachable, which is why the
test for it could not be written without first noticing. Now
`_run_as_user timeout 3 wpctl status`: same bound, inside the sudo'd command.

Why 96.97% and not 100%. An earlier run of this suite read 99/99 = 100.00%,
and that number was wrong -- it measured the file before pre-commit's
`shfmt -w` reformatted it. shfmt rewrites the `{ ...; } \` + `| bluetoothctl`
one-liners into multi-line blocks ending in `} |`, which raises the
denominator 99 -> 132. Confirmed unavoidable by running shfmt against HEAD's
own copy: it rewrites there too, so reverting the reformat is not stable.

The four uncovered lines (90, 113, 137, 157) are each that `} |` -- the pipe
operator joining a block to bluetoothctl, not a statement. They do execute:
a `{ echo a; echo b; } | consumer` block writes every marker to a file even
though bash's xtrace never reports the left-hand side, because a pipe's LHS
runs in a subshell whose xtrace is not captured. kcov instruments them and
cannot attribute them; defect (a) in docs/kcov-under-report.md, third flavour.

Scope, measured: the continuation-pipe form appears ONLY in bt_adapter.sh
(pre-format) and bt_audio.sh (post-shfmt). None of the remaining twelve
untested libs carries either, so this does not block the campaign and the
detector fix stays off the critical path.

Also worth 90.91% -> 96.97% on its own: the bluetoothctl stubs now drain
stdin before exiting. Real bluetoothctl consumes its whole input; a stub
that read one line and exited closed the pipe early, so the writing block
took SIGPIPE partway through and its later lines never ran.

NOTE for whoever edits this file next: bt_audio.sh is now exactly 250 lines,
at the cap. The next change to it needs a split, not a comment trim.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 17:52:24 +02:00

68 lines
7.4 KiB
JSON

{
"intent": "Test linux_configuration/scripts/single_use/fixes/lib/bt_audio.sh, fourth of the 16 untested fixes/lib libs, and fix a production bug the tests exposed: check_pipewire_health could never see a healthy PipeWire. The lib reaches 96.97% and STAYS on the allowlist -- the four remaining lines are unreachable by construction, for the instrument reason recorded below.",
"scope": [
"linux_configuration/scripts/single_use/fixes/lib/bt_audio.sh (one-line behaviour fix at the timeout call)",
"linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_audio.sh (new, 20 assertions)",
"linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_audio_connect.sh (new, 15 assertions)",
"linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_audio_health.sh (new, 12 assertions)",
"linux_configuration/scripts/single_use/fixes/lib/tests/lib_test_core.sh (new _t_stub_stdin helper)",
"Non-goal: the remaining twelve untested fixes/lib libs",
"meta/shell-coverage-allowlist.txt is deliberately UNCHANGED: bt_audio.sh does not meet the 100% bar"
],
"changes": [
"Fixed lib/bt_audio.sh:21. It read `if timeout 3 _run_as_user wpctl status`, but `timeout` is a binary and cannot invoke a shell function, so the call always failed with rc=127 ('timeout: failed to run command _run_as_user'). check_pipewire_health therefore reported PipeWire hung on EVERY run and restarted a healthy audio stack every time. Now `_run_as_user timeout 3 wpctl status`, which keeps the 3-second bound but puts it inside the sudo'd command where it can actually run. Confirmed _run_as_user is never exported, so no caller relied on the old shape.",
"Added test_bt_audio.sh covering check_pipewire_health (wpctl absent, responsive, and hung), _run_as_user (SUDO_USER set and the USER fallback), _restart_pipewire_stack, and set_audio_profile (empty TARGET_MAC, pactl absent, no matching card, the SBC-XQ switch, and a healthy profile left alone).",
"Added test_bt_audio_connect.sh covering connect_device: empty TARGET_MAC, already connected, paired with a successful direct connect, a failed direct connect that falls through to scan-and-fail, a full scan/pair/trust/connect for an unpaired device, and a device found by the scan whose connection never becomes healthy.",
"Added test_bt_audio_health.sh covering _check_connection_health: not connected, services resolved on the first probe, services resolving only after the full adapter reset (driven by a counting dbus-send stub), and services that never resolve at all.",
"Added _t_stub_stdin to lib_test_core.sh. Stub bodies are data containing $1 and ${VAR} that must survive verbatim, and writing them as single-quoted strings tripped SC2016 on every use; reading the body from stdin via a quoted heredoc keeps it literal with no suppression.",
"Made the bluetoothctl stubs drain their stdin (`cat >/dev/null`) before exiting. The real tool consumes its whole input; a stub that read one line and exited closed the pipe early, so the writing `{ ...; } |` block took SIGPIPE partway through and its later lines never ran. That alone was worth 90.91% -> 96.97%."
],
"verification": [
{
"command": "bash linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh",
"result": "pass",
"evidence": "bt_audio (pipewire): 20 passed; bt_audio (connect): 15 passed; bt_audio (health): 12 passed; all 0 failed. All fixes lib test files passed, so bt_report, bt_pairing, bt_adapter and the eight pacman_hook_stall suites stay green."
},
{
"command": "bash meta/scripts/shell_coverage_jail.sh --subject linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh --measure bt_audio.sh --min 1 --fail-on-case-error -- \"\"",
"result": "pass",
"evidence": "bt_audio.sh: 128/132 lines = 96.97%, uncovered 90, 113, 137, 157."
},
{
"command": "bash meta/scripts/shell_coverage_jail.sh --subject linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh --measure bt_audio.sh --min 1 --fail-on-case-error -- \"\"",
"result": "pass",
"evidence": "bt_audio.sh: 128/132 lines = 96.97%, identical to the first run. Two matching runs, so the figure is not timing-dependent."
},
{
"command": "Read the uncovered lines before deciding whether the lib could be cleared",
"result": "pass",
"evidence": "Lines 90, 113, 137 and 157 are each the `} |` that closes a piped block -- the pipe OPERATOR joining the block to `bluetoothctl`, not a statement. Proven executable with a marker file: a `{ echo a; echo b; } | consumer` block writes every marker even though bash's xtrace never reports the left-hand side, because a pipe's LHS runs in a subshell whose xtrace is not captured. So the lines run; kcov cannot attribute them."
},
{
"command": "bash -c 'timeout 3 _run_as_user wpctl status'",
"result": "pass",
"evidence": "Reproduced the bug directly before fixing: \"timeout: failed to run command '_run_as_user': No such file or directory\", rc=127. After the fix the healthy branch is reachable and its test ('PipeWire is responsive') passes."
},
{
"command": "shfmt -w on HEAD's bt_audio.sh, then diff against HEAD",
"result": "pass",
"evidence": "shfmt REWRITES HEAD's `{ ...; } \\` + `| bluetoothctl` one-liners into multi-line blocks ending in `} |`. The pre-commit hook runs `shfmt -w` on every staged shell file, so this reformat is unavoidable on any commit touching the file and reverting it is not stable. That is why 96.97% is accepted rather than restored to the pre-format 100%."
},
{
"command": "grep -lnE '^[[:space:]]*\\|' and grep -lE '\\}[[:space:]]*\\|[[:space:]]*$' over all 22 fixes/lib libs",
"result": "pass",
"evidence": "The continuation-pipe form is confined to the bluetooth family: bt_adapter.sh carries the pre-format flavour and bt_audio.sh the post-shfmt one. None of the remaining twelve untested libs has either, so this artifact does not block the rest of the campaign."
}
],
"risks": [
"bt_audio.sh stays on the allowlist at 96.97%. The four uncovered lines are `} |` pipe operators that kcov instruments but bash never attributes a statement to -- the same defect (a) class as bt_adapter.sh line 97, in a third flavour. Clearing either lib needs meta/scripts/lib/shell_coverage_lines.py to exclude these forms, which changes the denominator for every measured lib and must land on its own.",
"An earlier measurement of this lib read 99/99 = 100.00%. That number measured the file BEFORE pre-commit's shfmt reformatted it, and is superseded by 128/132 = 96.97% here. The reformat raised the denominator from 99 to 132 by splitting six one-line blocks into their constituent statements.",
"The bt_audio.sh fix changes runtime behaviour: fix_bluetooth.sh will now SKIP the PipeWire/WirePlumber restart when wpctl answers within 3 seconds, where before it restarted the audio stack on every run. That is the intended behaviour of the function as written.",
"bt_audio.sh is now exactly 250 lines, i.e. AT the repo cap. The next edit to it must split the file; a comment trim will not buy room twice."
],
"rollback": [
"git revert the commit; it adds three test files, one core helper and a one-line behaviour fix, and touches no allowlist entry.",
"After rollback, run bash linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh and confirm the remaining suites pass. No coverage gate changes, since bt_audio.sh stays exempt either way."
]
}