testsAndMisc/linux_configuration/scripts/periodic_background/lib/services_apps.sh
Krzysztof kuhy Rudnicki 0a69d18390 check_and_enable_services: 100% coverage via a redirectable path prefix
Follow-up to 9085a4e5, which recorded services_units.sh at 84.51% because
its remaining branches sit behind [[ -f /etc/systemd/system/*.service ]] --
absolute root-owned paths that exist on this machine, so the else-branch
never runs and no PATH shim can redirect it.

All 87 such paths across the seven check libs now go through $SYSROOT, read
from SERVICES_ROOT. The prefix is deliberately NOT defaulted. Three commands
in hosts_fix_resolved run outside `run` and so are not stopped by --dry-run
(chattr -i on resolved.conf.d, find -delete over its *.conf, and an append to
resolved.conf); with an empty default, a test that forgot to set SERVICES_ROOT
would really delete this machine's resolved.conf drop-ins. Unset is therefore
a hard error and only an explicitly empty value means the real filesystem.

The harness now owns PATH outright: $FAKE_BIN for shims and staged fake apps,
$REAL_BIN for a curated set of symlinks to genuine coreutils. The machine's
/usr/bin is deliberately absent -- a really-installed discord and chromium
otherwise make the "no target apps present" branches untestable, which is
exactly what happened until these tests caught it.

Coverage, measured against run_all.sh because two test files jointly cover
services_common.sh after the 250-cap split: common 55/55, report 27/27,
units 72/72 (was 84.51%), wrappers 100/100, apps 66/66, browser 79/79 --
seven libs at 100%. services_hosts.sh reads 86.05% and services_hosts_fix.sh
97.30%, and those 14 lines are a kcov attribution artifact rather than a gap.
Falsified rather than assumed: the suite prints "51 passed, 0 failed" when run
under kcov, so no group is skipped, and every supposedly-uncovered line is an
issues+=("...") whose string can only reach stdout through the print loop
below it -- with a passing assertion matching that exact string.

Two falsification checks, both re-run after the rewrite: `--status --dry-run`
as root stays byte-identical to rev 6691cb26 modulo the Date: line, and the
sha256sums of /etc/hosts, /etc/nsswitch.conf and /etc/systemd/resolved.conf
plus the contents of resolved.conf.d are unchanged across a full suite run.
The second one is what makes a missed prefix site detectable instead of a
matter of inspection: the repair paths really do write.

220 assertions across 8 test files. Also fixes a bug in the harness's own
lsattr shim, where printf with a leading-dash format string parsed the dashes
as options and silently produced nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3PzGc75gBcdxP3PkHXGcV
2026-08-21 14:08:11 +02:00

127 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# lib/services_apps.sh — per-application blocking checks (messaging-app launch
# wrappers, and the LeechBlock browser extension for the invoking user).
#
# Sourced by check_and_enable_services.sh.
# Absolute paths the checks below probe are prefixed with $SYSROOT, which is
# empty in production and a fixture tree under test. It is deliberately NOT
# defaulted here: several repairs in this family write outside `run` (chattr,
# find -delete, an append to resolved.conf), so a test that forgot to set it
# would edit the real /etc. Unset is a hard error; empty is the real filesystem.
SYSROOT="${SERVICES_ROOT?SERVICES_ROOT must be set (empty = the real filesystem)}"
check_compulsive_blocker() {
header "Compulsive Opening Blocker"
local status="ok"
local issues=()
# Check if main script is installed
if [[ -f "${SYSROOT}/usr/local/bin/block-compulsive-opening.sh" ]]; then
msg "Blocker script installed at ${SYSROOT}/usr/local/bin/block-compulsive-opening.sh"
else
issues+=("block-compulsive-opening.sh not found in ${SYSROOT}/usr/local/bin")
status="error"
fi
# Check if wrappers are installed for known apps
local checked_any=false
for app in beeper signal-desktop discord; do
local wrapper_path="${SYSROOT}/usr/bin/$app"
if [[ -f "${wrapper_path}.orig" ]] || [[ -L "$wrapper_path" ]]; then
if [[ -f "${wrapper_path}.orig" ]]; then
msg "$app wrapper installed (original backed up)"
checked_any=true
fi
elif command -v "$app" &>/dev/null; then
issues+=("$app is installed but wrapper not applied")
if [[ $status != "error" ]]; then status="warning"; fi
checked_any=true
fi
done
if [[ $checked_any == false && $status == "ok" ]]; then
note "No target apps (beeper, signal-desktop, discord) found on system"
fi
if [[ $status != "ok" ]]; then
for issue in "${issues[@]}"; do
if [[ $status == "error" ]]; then
err "$issue"
else
warn "$issue"
fi
done
((ISSUES_FOUND++)) || true
if [[ $STATUS_ONLY -eq 0 && $status == "error" ]]; then
note "Installing compulsive opening blocker..."
if [[ -f $COMPULSIVE_BLOCK_SCRIPT ]]; then
run bash "$COMPULSIVE_BLOCK_SCRIPT" install
((FIXES_APPLIED++)) || true
else
err_missing_script "Install script not found: $COMPULSIVE_BLOCK_SCRIPT"
fi
fi
fi
set_service_status "compulsive_blocker" "$status"
}
check_leechblock() {
header "LeechBlock Browser Extension"
local status="ok"
local issues=()
local user="${SUDO_USER:-$USER}"
local user_home
user_home="${SYSROOT}/home/$user"
# Check if LeechBlock is installed for any browser
local leechblock_dir="$user_home/.local/share/leechblockng"
if [[ -d $leechblock_dir ]]; then
msg "LeechBlock directory exists at $leechblock_dir"
else
issues+=("LeechBlock not found at $leechblock_dir")
status="error"
fi
# Check for browser wrappers with LeechBlock
local found_wrapper=false
for desktop_file in "$user_home/.local/share/applications/"*leechblock* "$user_home/.local/share/applications/"*LeechBlock*; do
if [[ -f $desktop_file ]]; then
msg "LeechBlock desktop entry found: $(basename "$desktop_file")"
found_wrapper=true
fi
done
if [[ $found_wrapper == false && -d $leechblock_dir ]]; then
issues+=("No LeechBlock desktop entries found")
if [[ $status != "error" ]]; then status="warning"; fi
fi
if [[ $status != "ok" ]]; then
for issue in "${issues[@]}"; do
if [[ $status == "error" ]]; then
err "$issue"
else
warn "$issue"
fi
done
((ISSUES_FOUND++)) || true
if [[ $STATUS_ONLY -eq 0 && $status == "error" ]]; then
note "Installing LeechBlock..."
if [[ -f $LEECHBLOCK_SCRIPT ]]; then
run sudo -u "$user" bash "$LEECHBLOCK_SCRIPT"
((FIXES_APPLIED++)) || true
else
err_missing_script "Install script not found: $LEECHBLOCK_SCRIPT"
fi
fi
fi
set_service_status "leechblock" "$status"
}