From 4cfc3fdde117ccd56d0a7ef4769b5df87625b0fd Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sat, 22 Aug 2026 16:33:33 +0200 Subject: [PATCH] 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) --- .../bt-report-coverage-2026-08-22.json | 53 +++++++ .../single_use/fixes/lib/tests/bt_harness.sh | 137 ++++++++++++++++++ .../fixes/lib/tests/lib_test_core.sh | 112 ++++++++++++++ .../fixes/lib/tests/test_bt_report.sh | 118 +++++++++++++++ meta/shell-coverage-allowlist.txt | 1 - 5 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 docs/superpowers/evidence/bt-report-coverage-2026-08-22.json create mode 100755 linux_configuration/scripts/single_use/fixes/lib/tests/bt_harness.sh create mode 100755 linux_configuration/scripts/single_use/fixes/lib/tests/lib_test_core.sh create mode 100755 linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_report.sh diff --git a/docs/superpowers/evidence/bt-report-coverage-2026-08-22.json b/docs/superpowers/evidence/bt-report-coverage-2026-08-22.json new file mode 100644 index 00000000..aa3ddf70 --- /dev/null +++ b/docs/superpowers/evidence/bt-report-coverage-2026-08-22.json @@ -0,0 +1,53 @@ +{ + "intent": "Test linux_configuration/scripts/single_use/fixes/lib/bt_report.sh to 100% line coverage and take it off the shell-coverage allowlist, continuing the fixes/lib coverage campaign.", + "scope": [ + "linux_configuration/scripts/single_use/fixes/lib/tests/lib_test_core.sh (new shared assertion/sandbox primitives)", + "linux_configuration/scripts/single_use/fixes/lib/tests/bt_harness.sh (new fix_bluetooth.sh family harness)", + "linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_report.sh (new, 24 assertions)", + "meta/shell-coverage-allowlist.txt (one line removed)", + "Non-goal: refactoring pacman_hook_stall_harness.sh, whose six libs are already gated at 100% with no exemption", + "Non-goal: the remaining 15 untested fixes/lib libs, handled in later commits" + ], + "changes": [ + "Added lib_test_core.sh: PASS/FAIL tally, _t_eq/_t_contains/_t_lacks assertions, a mktemp -d sandbox wiped on EXIT, a FAKE_BIN stub dir on PATH, and _t_stub/_t_unstub. _t_unstub runs `hash -r`, because removing a stub file alone does not drop bash's cached executable path.", + "Added bt_harness.sh: sources lib_test_core.sh, 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.", + "Added _t_only_path, which drops PATH to FAKE_BIN alone: every tool these libs call (usbreset, pactl, lsusb, ...) genuinely exists on this host, so a prepended stub dir cannot exercise a 'not installed' branch.", + "Added test_bt_report.sh covering show_instructions (both the known-MAC and -placeholder branches) and dump_diagnostics (populated output, the (none loaded)/(rfkill not available) fallbacks, the empty-TARGET_MAC skip, and the (device not known) arm).", + "Removed linux_configuration/scripts/single_use/fixes/lib/bt_report.sh from meta/shell-coverage-allowlist.txt." + ], + "verification": [ + { + "command": "bash linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh", + "result": "pass", + "evidence": "test_bt_report.sh: 24 passed, 0 failed. All fixes lib test files passed -- the eight pre-existing pacman_hook_stall suites stay green alongside the new file." + }, + { + "command": "bash meta/scripts/shell_coverage_jail.sh --subject linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh --measure bt_report.sh --min 1 --fail-on-case-error -- \"\"", + "result": "pass", + "evidence": "bt_report.sh: 37/37 lines = 100.00%. Measured through run_all.sh, the subject is_covered() builds. No 'outside kcov's line set' lines were reported, so the figure covers every statement kcov instrumented." + }, + { + "command": "bash meta/scripts/shell_coverage_jail.sh --subject linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh --measure bt_report.sh --min 100 --fail-on-case-error -- \"\"", + "result": "pass", + "evidence": "bt_report.sh: 37/37 lines = 100.00%, exit code 0. Second matching run at the --min 100 bar, so a shortfall would have been a non-zero exit rather than a number to misread." + }, + { + "command": "bash meta/scripts/check_shell_coverage.sh linux_configuration/scripts/single_use/fixes/lib/bt_report.sh", + "result": "pass", + "evidence": "'check_shell_coverage.sh: every checked shell library meets the coverage bar', exit 0, run with the allowlist line already removed so the lib had no exemption." + }, + { + "command": "jscpd --pattern '**/*.sh' --min-lines 14 --min-tokens 25 --threshold 2 (the pre-commit hook's exact flags)", + "result": "pass", + "evidence": "444 files, 27 clones, 933 duplicated lines = 1.6%, under the 2% threshold. The hook already excludes **/lib/tests/** and **/tests/**, so the shared-core harness design carries no duplication risk." + } + ], + "risks": [ + "bt_harness.sh copies _btctl and apply_fix from fix_bluetooth.sh, so a change to either in the entry script would leave the harness stale. This is the same trade-off pacman_hook_stall_harness.sh already makes with log_size, and is preferable to moving those helpers into a lib, which would reintroduce a cross-file-global seam.", + "The three coverage runs were executed in a detached git worktree under the scratchpad, because a second Claude session was concurrently writing to this repo (phone_focus_mode/config.sh, focus_owner/) and the jail aborts on any working-tree delta during a run. The measurement subject and libs were identical to HEAD; only the tree's isolation differed." + ], + "rollback": [ + "git revert the commit; that restores the bt_report.sh line in meta/shell-coverage-allowlist.txt and deletes the three new test files together.", + "After rollback, run bash linux_configuration/scripts/single_use/fixes/lib/tests/run_all.sh and confirm the eight pacman_hook_stall suites still pass, then bash meta/scripts/check_shell_coverage.sh to confirm the gate is green with bt_report.sh exempt again." + ] +} diff --git a/linux_configuration/scripts/single_use/fixes/lib/tests/bt_harness.sh b/linux_configuration/scripts/single_use/fixes/lib/tests/bt_harness.sh new file mode 100755 index 00000000..dc2c9adf --- /dev/null +++ b/linux_configuration/scripts/single_use/fixes/lib/tests/bt_harness.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +# lib/tests/bt_harness.sh — shared setup for the fix_bluetooth.sh lib tests +# (bt_report.sh, bt_adapter.sh, bt_pairing.sh, bt_audio.sh). +# +# Sourced, not executed. Builds on lib_test_core.sh (tmpdir, $FAKE_BIN on +# PATH, the _t_* assertions) and adds the three things the bt libs need: +# +# 1. the real log_*/has_cmd helpers, by sourcing scripts/lib/common.sh -- +# it is inert at source time (a load guard, two exports and three +# sub-sources), so the libs get the exact helpers they see in production +# rather than reimplementations that could drift; +# 2. _btctl and apply_fix, which live in fix_bluetooth.sh itself rather +# than in any lib. Redefined here verbatim from the entry script so the +# libs resolve them exactly as they do when sourced for real -- the same +# approach pacman_hook_stall_harness.sh takes with log_size; +# 3. stubs for the external tools the bt libs shell out to. +# +# Every tool these libs call (dmesg, wget, lsusb, modprobe, pactl, usbreset, +# bluetoothctl, rfkill...) genuinely exists on an Arch desktop, so a +# PREPENDED stub dir cannot exercise a "not installed" branch. _t_only_path +# below drops PATH to $FAKE_BIN alone for exactly those cases. +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +FIXES_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" +REPO_ROOT="$(cd "${FIXES_DIR}/../../../.." && pwd)" + +# shellcheck source=lib_test_core.sh +. "${SCRIPT_DIR}/lib_test_core.sh" + +# Real logging/has_cmd/ask_yes_no helpers, as the entry script gets them. +# shellcheck source=../../../../lib/common.sh +. "${REPO_ROOT}/linux_configuration/scripts/lib/common.sh" + +# --- pieces that live in fix_bluetooth.sh, not in a lib --------------------- + +# Verbatim from fix_bluetooth.sh: bluetoothctl returns empty when driven with +# `-- `, so the real script pipes the command in on stdin. +_btctl() { + echo "$*" | bluetoothctl 2>/dev/null +} + +FIXES_APPLIED=0 +FIXES_SKIPPED=0 +INTERACTIVE_MODE="false" + +# Verbatim from fix_bluetooth.sh. The libs call apply_fix for every mutating +# action, so it is the seam most assertions read: $DEV/fixes records the +# description of each fix that actually ran. +apply_fix() { + local description="$1" + shift + + echo "" + log_info "$description" + printf '%s\n' "$description" >>"${DEV}/fixes" + + if [[ $INTERACTIVE_MODE == "true" ]]; then + if ! ask_yes_no " Apply this fix?"; then + log_warn "Skipped." + ((FIXES_SKIPPED++)) || true + return 0 + fi + fi + + if "$@"; then + log_ok "Done." + ((FIXES_APPLIED++)) || true + else + log_error "Failed (non-fatal, continuing)." + fi +} + +# --- external tool stubs ---------------------------------------------------- + +# Default every tool the bt libs touch to a quiet success. Individual tests +# re-stub the one tool they care about via _t_stub. +_bt_default_stubs() { + local tool + for tool in dmesg wget curl lsusb modprobe dbus-send pactl wpctl \ + bluetoothctl rfkill lsmod usbreset systemctl journalctl sudo id; do + _t_stub "$tool" 'exit 0' + done + # `id -u ` feeds _run_as_user's XDG_RUNTIME_DIR path. + _t_stub id 'echo 1000' + # sudo -u VAR=... ... -- drop sudo's own arguments and exec + # the wrapped command, so _run_as_user reaches the stubbed tool. Held in + # a quoted heredoc: every $ in here belongs to the stub, not to us. + local sudo_body + sudo_body="$( + cat <<'SUDO_BODY' +shift 2 2>/dev/null || true +while [[ "${1:-}" == *=* ]]; do shift; done +[[ $# -gt 0 ]] || exit 0 +exec "$@" +SUDO_BODY + )" + _t_stub sudo "$sudo_body" +} + +# _t_only_path — restrict PATH to $FAKE_BIN plus coreutils, so a tool absent +# from $FAKE_BIN is genuinely "not installed" as far as has_cmd/command -v is +# concerned. Used for the has_cmd false branches. +_t_only_path() { + PATH="${FAKE_BIN}" + hash -r +} + +# _t_full_path — restore the prepended-stub PATH set up by lib_test_core.sh. +_t_full_path() { + PATH="${FAKE_BIN}:${LIB_TEST_ORIG_PATH}" + hash -r +} + +export LIB_TEST_ORIG_PATH="${PATH#"${FAKE_BIN}:"}" + +# bt_reset — start a test group from "nothing has happened yet". +bt_reset() { + _t_reset_calls + : >"${DEV}/fixes" + FIXES_APPLIED=0 + FIXES_SKIPPED=0 + INTERACTIVE_MODE="false" + TARGET_MAC="F8:5C:7E:0E:50:6B" + _t_full_path + _bt_default_stubs +} + +# _t_fixes — the descriptions of the fixes apply_fix ran this round. +_t_fixes() { + cat "${DEV}/fixes" 2>/dev/null || true +} + +# TARGET_MAC is read by the bt libs under test, never by this harness, so +# static analysis cannot see the use. export makes the intent explicit. +export TARGET_MAC="F8:5C:7E:0E:50:6B" +bt_reset diff --git a/linux_configuration/scripts/single_use/fixes/lib/tests/lib_test_core.sh b/linux_configuration/scripts/single_use/fixes/lib/tests/lib_test_core.sh new file mode 100755 index 00000000..a03e798e --- /dev/null +++ b/linux_configuration/scripts/single_use/fixes/lib/tests/lib_test_core.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# lib/tests/lib_test_core.sh — assertion + sandbox primitives shared by the +# per-family harnesses in this directory. +# +# Sourced, not executed. Provides exactly the pieces every family needs and +# nothing family-specific: a PASS/FAIL tally, the _t_* assertions, a +# throwaway $TEST_TMPDIR wiped on EXIT, and a $FAKE_BIN stub directory +# prepended to PATH. +# +# Deliberately does NOT touch pacman_hook_stall_harness.sh, which predates it +# and whose six libs are already off the coverage allowlist -- i.e. gated at +# 100% with no exemption. Refactoring that harness to sit on top of this one +# would put banked work at risk for no coverage gain. +set -uo pipefail + +PASS=0 +FAIL=0 + +_t_pass() { + PASS=$((PASS + 1)) + printf ' OK: %s\n' "$1" +} + +_t_fail() { + FAIL=$((FAIL + 1)) + printf ' FAIL: %s\n' "$1" +} + +_t_eq() { + local want="$1" got="$2" what="$3" + if [[ "$got" == "$want" ]]; then + _t_pass "$what" + else + _t_fail "$what (want '${want}', got '${got}')" + fi +} + +# _t_contains HAYSTACK NEEDLE WHAT — substring assertion. +_t_contains() { + local haystack="$1" needle="$2" what="$3" + if [[ "$haystack" == *"$needle"* ]]; then + _t_pass "$what" + else + _t_fail "$what (expected to contain '${needle}', got: ${haystack})" + fi +} + +# _t_lacks HAYSTACK NEEDLE WHAT — negative substring assertion. +_t_lacks() { + local haystack="$1" needle="$2" what="$3" + if [[ "$haystack" != *"$needle"* ]]; then + _t_pass "$what" + else + _t_fail "$what (expected NOT to contain '${needle}', got: ${haystack})" + fi +} + +TEST_TMPDIR="$(mktemp -d)" +trap 'rm -rf "${TEST_TMPDIR}"' EXIT + +readonly DEV="${TEST_TMPDIR}/device" +readonly FAKE_BIN="${TEST_TMPDIR}/fake_bin" +mkdir -p "${DEV}" "${FAKE_BIN}" +: >"${DEV}/calls" + +export PATH="${FAKE_BIN}:${PATH}" + +# _t_stub NAME BODY — write an executable stub NAME into $FAKE_BIN whose body +# is BODY, then drop bash's cached path for NAME. +# +# Every stub records its own invocation into $DEV/calls before running BODY, +# so _t_calls works uniformly without each stub repeating the boilerplate. +_t_stub() { + local name="$1" body="$2" + # The recording preamble is written with a quoted heredoc so $0 and $@ + # reach the stub file unexpanded and expand when the STUB runs. Using + # $0/$@ rather than the stub's literal name is what keeps this a plain + # heredoc with nothing for the writer to interpolate. + cat >"${FAKE_BIN}/${name}" <<'STUB_PREAMBLE' +#!/usr/bin/env bash +printf '%s %s\n' "${0##*/}" "$*" >>"${LIB_TEST_DEV}/calls" +STUB_PREAMBLE + printf '%s\n' "$body" >>"${FAKE_BIN}/${name}" + chmod +x "${FAKE_BIN}/${name}" + hash -r +} + +# _t_unstub NAME... — remove stubs and drop bash's cached executable paths. +# +# `rm` alone does NOT hide a stub: bash caches the resolved location of every +# command it has run, so a later call re-executes the deleted file's path and +# fails with "No such file or directory" instead of falling through to the +# real binary. `hash -r` is the part that matters. +_t_unstub() { + local name + for name in "$@"; do + rm -f "${FAKE_BIN}/${name}" + done + hash -r +} + +# _t_calls — print everything the stubs recorded this round. +_t_calls() { + cat "${DEV}/calls" 2>/dev/null || true +} + +# _t_reset_calls — start a fresh recording window. +_t_reset_calls() { + : >"${DEV}/calls" +} + +export LIB_TEST_DEV="${DEV}" diff --git a/linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_report.sh b/linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_report.sh new file mode 100755 index 00000000..21aba591 --- /dev/null +++ b/linux_configuration/scripts/single_use/fixes/lib/tests/test_bt_report.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +# Tests for lib/bt_report.sh: show_instructions and dump_diagnostics. +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=bt_harness.sh +. "${SCRIPT_DIR}/bt_harness.sh" + +# shellcheck source=../bt_report.sh +. "${FIXES_DIR}/lib/bt_report.sh" + +# --- show_instructions ------------------------------------------------------ + +bt_reset +TARGET_MAC="AA:BB:CC:DD:EE:FF" +out="$(show_instructions)" +_t_contains "$out" "Next Steps" "show_instructions: prints the Next Steps header" +_t_contains "$out" "PAIRING mode" "show_instructions: tells the user to enter pairing mode" +_t_contains "$out" "pair AA:BB:CC:DD:EE:FF" \ + "show_instructions: interpolates TARGET_MAC into the pair command" +_t_contains "$out" "trust AA:BB:CC:DD:EE:FF" \ + "show_instructions: interpolates TARGET_MAC into the trust command" +_t_contains "$out" "connect AA:BB:CC:DD:EE:FF" \ + "show_instructions: interpolates TARGET_MAC into the connect command" +_t_lacks "$out" "pair " \ + "show_instructions: omits the placeholder form when a MAC is known" +_t_contains "$out" "journalctl -u bluetooth -f" \ + "show_instructions: points at the bluetooth journal on failure" + +# With no MAC known, the placeholder branch runs instead. +bt_reset +TARGET_MAC="" +out="$(show_instructions)" +_t_contains "$out" "pair " \ + "show_instructions: falls back to the placeholder when TARGET_MAC is empty" +_t_contains "$out" "note its MAC address" \ + "show_instructions: tells the user to note the MAC when none is known" +_t_lacks "$out" "trust AA:BB" \ + "show_instructions: does not emit a concrete MAC when TARGET_MAC is empty" + +# --- dump_diagnostics ------------------------------------------------------- + +bt_reset +TARGET_MAC="AA:BB:CC:DD:EE:FF" +# _btctl pipes the command in on stdin, so the stub dispatches on what it +# reads there. Quoted heredoc: the $ belong to the stub, not to this file. +btctl_body="$( + cat <<'BTCTL_BODY' +read -r cmd rest +case "$cmd" in +show) echo "Controller AA:11 [bluetoothctl]"; echo " Powered: yes" ;; +devices) echo "Device AA:BB:CC:DD:EE:FF JBL Charge 5" ;; +info) echo " Connected: yes" ;; +esac +exit 0 +BTCTL_BODY +)" +_t_stub bluetoothctl "$btctl_body" +# `lsmod | grep -i bluetooth` matches on the module NAME, so the fixture has +# to carry a row whose text actually contains "bluetooth" -- bare "btusb" is +# filtered out by the lib's own grep, exactly as it would be in production. +_t_stub lsmod ' +echo "btusb 73728 0" +echo "bluetooth 995328 9 btrtl,btmtk,btintel,btbcm,btusb" +' +_t_stub rfkill 'echo "0 bluetooth hci0 unblocked unblocked"' +_t_stub journalctl 'echo "bluetoothd[1]: Bluetooth daemon"' + +out="$(dump_diagnostics)" +_t_contains "$out" "=== Diagnostic Summary ===" "dump_diagnostics: prints the summary header" +_t_contains "$out" "--- Bluetooth adapter ---" "dump_diagnostics: prints the adapter section" +_t_contains "$out" "Powered: yes" "dump_diagnostics: includes bluetoothctl show output" +_t_lacks "$out" "[bluetoothctl]" \ + "dump_diagnostics: filters the [bluetoothctl] prompt noise out of show output" +_t_contains "$out" "Device AA:BB:CC:DD:EE:FF" "dump_diagnostics: lists known devices" +_t_contains "$out" "bluetooth 995328" \ + "dump_diagnostics: reports loaded bluetooth kernel modules" +_t_lacks "$out" "(none loaded)" \ + "dump_diagnostics: omits the '(none loaded)' fallback when a module matches" +_t_contains "$out" "--- rfkill status ---" "dump_diagnostics: prints the rfkill section" +_t_contains "$out" "--- Device info: AA:BB:CC:DD:EE:FF ---" \ + "dump_diagnostics: dumps info for the target device when a MAC is set" +_t_contains "$out" "Bluetooth daemon" "dump_diagnostics: includes recent journal entries" + +# Empty results still print their section, via the `|| echo`/`|| true` arms. +bt_reset +TARGET_MAC="" +_t_stub bluetoothctl 'exit 0' +_t_stub lsmod 'echo "ext4 1000 0"' +_t_stub rfkill 'exit 1' +_t_stub journalctl 'exit 1' + +out="$(dump_diagnostics)" +_t_contains "$out" "(none loaded)" \ + "dump_diagnostics: reports '(none loaded)' when no bluetooth module matches" +_t_contains "$out" "(rfkill not available)" \ + "dump_diagnostics: reports rfkill unavailable when the command fails" +_t_lacks "$out" "--- Device info:" \ + "dump_diagnostics: skips the device-info section when TARGET_MAC is empty" + +# A device the adapter does not know about takes the `|| echo` arm. +bt_reset +TARGET_MAC="11:22:33:44:55:66" +btctl_body="$( + cat <<'BTCTL_INFO_FAILS' +read -r cmd rest +[[ "$cmd" == "info" ]] && exit 1 +exit 0 +BTCTL_INFO_FAILS +)" +_t_stub bluetoothctl "$btctl_body" +out="$(dump_diagnostics)" +_t_contains "$out" "(device not known)" \ + "dump_diagnostics: reports an unknown device when bluetoothctl info fails" + +echo +echo "bt_report: ${PASS} passed, ${FAIL} failed" +((FAIL == 0)) diff --git a/meta/shell-coverage-allowlist.txt b/meta/shell-coverage-allowlist.txt index 5f9ed198..776ba1b8 100644 --- a/meta/shell-coverage-allowlist.txt +++ b/meta/shell-coverage-allowlist.txt @@ -82,7 +82,6 @@ linux_configuration/scripts/single_use/fixes/lib/arch_sysctl.sh linux_configuration/scripts/single_use/fixes/lib/bt_adapter.sh linux_configuration/scripts/single_use/fixes/lib/bt_audio.sh linux_configuration/scripts/single_use/fixes/lib/bt_pairing.sh -linux_configuration/scripts/single_use/fixes/lib/bt_report.sh linux_configuration/scripts/single_use/fixes/lib/hosts_guard_migrate.sh linux_configuration/scripts/single_use/fixes/lib/hosts_guard_rollback.sh linux_configuration/scripts/single_use/fixes/lib/nvidia_config.sh