mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:07:04 +01:00
i3 config was filed under periodic_background, which it never was. It is now linux_configuration/i3/ (config + installer) and linux_configuration/i3blocks/ (the status scripts), both at depth 2. misc/testsAndMisc-bash/ was a directory named after the repo it already lived in, so its contents moved up to misc/. Its stray .gitignore came along, keeping the media rules working from the new location; its .vscode/tasks.json did not, because it invoked Bash/transcribe.sh, a path this repo dropped long ago. Most of this commit is the references the previous flatten missed. Its regex skipped anything with a variable prefix, which left 16 files -- including check_and_enable_services.sh and install_core_system.sh, the orchestrators -- still naming $CONFIG_DIR/scripts/periodic_background/... It had also rewritten three i3 paths into scripts/i3blocks/, a directory that has never existed; the i3blocks suites caught that by failing. 13 more symlinks broke on the i3 move. Repointed, and cpu_monitor/volume/ disk were run again to confirm the bar still reports. Depth 139 -> 104. Roughly 47 of the remainder sit in digital_wellbeing and hosts, still deferred. The rest encode real structure -- a C project, Python package directories, artgate's routes/styles, systemd unit dirs -- so flattening them further would destroy information rather than taxonomy. Verified: 1798 tests at 100%, both i3blocks suites pass, the shell coverage gate is clean, and the relocated media rules still ignore what they should while test_fw.srt stays tracked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
223 lines
7.8 KiB
Bash
Executable File
223 lines
7.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Regression tests for shutdown-timer-monitor.sh dispatcher behavior.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
|
REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
|
# shutdown-timer-monitor.sh moved to github.com/kuhyx/system-maintenance with
|
|
# the rest of that subsystem, but this suite is the pair test: it checks that
|
|
# digital_wellbeing's installer and the monitor it installs still agree. Prefer
|
|
# a sibling checkout, fall back to the installed copy, and skip rather than
|
|
# fail when neither is present -- a missing checkout is not a regression.
|
|
TARGET_SCRIPT="${SYSTEM_MAINTENANCE_DIR:-$HOME/system-maintenance}/bin/shutdown-timer-monitor.sh"
|
|
# Deliberately NOT falling back to /usr/local/bin: the installed copy can be
|
|
# older than the source (it is, on this machine), and testing the installer
|
|
# template against a stale binary compares two things that were never meant to
|
|
# match. Skip instead -- a missing checkout is not a regression.
|
|
if [[ ! -f $TARGET_SCRIPT ]]; then
|
|
printf 'SKIP: shutdown-timer-monitor.sh not found (set SYSTEM_MAINTENANCE_DIR)\n'
|
|
exit 0
|
|
fi
|
|
SETUP_SCRIPT="$REPO_DIR/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh"
|
|
# The installer was split into lib/ms_*.sh under the 250-line cap, so these
|
|
# template checks search the entry script AND its libs: the monitor template
|
|
# now lives in lib/ms_monitor.sh, it did not disappear.
|
|
SETUP_SOURCES=("$SETUP_SCRIPT")
|
|
for _ms_lib in "$(dirname "$SETUP_SCRIPT")"/lib/ms_*.sh; do
|
|
[[ -f "$_ms_lib" ]] && SETUP_SOURCES+=("$_ms_lib")
|
|
done
|
|
|
|
fail() {
|
|
printf 'FAIL: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
assert_equals() {
|
|
local expected="$1"
|
|
local actual="$2"
|
|
local context="$3"
|
|
if [[ "$expected" != "$actual" ]]; then
|
|
fail "$context (expected: '$expected', actual: '$actual')"
|
|
fi
|
|
}
|
|
|
|
TMP_DIR=$(mktemp -d)
|
|
cleanup() {
|
|
rm -rf "$TMP_DIR"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
WORKTREE="$TMP_DIR/worktree"
|
|
BIN_DIR="$TMP_DIR/bin"
|
|
mkdir -p "$WORKTREE/system-maintenance/bin" "$BIN_DIR"
|
|
cp "$TARGET_SCRIPT" "$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh"
|
|
|
|
cat >"$BIN_DIR/busctl" <<'EOF'
|
|
#!/bin/bash
|
|
if [[ $1 == monitor ]]; then
|
|
payload=${MOCK_BUSCTL_LINES:-${MOCK_BUSCTL_LINE:-no relevant event}}
|
|
printf '%b\n' "$payload" | while read -r line; do
|
|
printf '%s\n' "$line"
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
printf 'unexpected busctl args: %s\n' "$*" >&2
|
|
exit 1
|
|
EOF
|
|
chmod +x "$BIN_DIR/busctl"
|
|
|
|
cat >"$BIN_DIR/systemctl" <<'EOF'
|
|
#!/bin/bash
|
|
case "$*" in
|
|
'is-enabled day-specific-shutdown.timer'|'is-active day-specific-shutdown.timer')
|
|
exit 0
|
|
;;
|
|
'daemon-reload'|'enable day-specific-shutdown.timer'|'start day-specific-shutdown.timer')
|
|
exit 0
|
|
;;
|
|
*)
|
|
printf 'unexpected systemctl args: %s\n' "$*" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x "$BIN_DIR/systemctl"
|
|
|
|
cat >"$BIN_DIR/sleep" <<'EOF'
|
|
#!/bin/bash
|
|
printf '%s\n' "$1" >> "${SLEEP_LOG:?}"
|
|
exit 99
|
|
EOF
|
|
chmod +x "$BIN_DIR/sleep"
|
|
|
|
cat >"$BIN_DIR/tee" <<'EOF'
|
|
#!/bin/bash
|
|
while IFS= read -r _; do
|
|
:
|
|
done
|
|
EOF
|
|
chmod +x "$BIN_DIR/tee"
|
|
|
|
run_case() {
|
|
local expected_mode="$1"
|
|
local busctl_present="$2"
|
|
local sleep_log="$TMP_DIR/sleep.log"
|
|
local mode_file="$TMP_DIR/mode.log"
|
|
|
|
: >"$sleep_log"
|
|
: >"$mode_file"
|
|
if [[ $busctl_present -eq 0 ]]; then
|
|
mv "$BIN_DIR/busctl" "$BIN_DIR/busctl.off"
|
|
fi
|
|
|
|
mode=$(env -i PATH="$BIN_DIR" SLEEP_LOG="$sleep_log" SHUTDOWN_TIMER_MONITOR_SKIP_MAIN=1 /bin/bash -c \
|
|
"source '$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh'; \
|
|
timer_needs_restoration() { return 1; }; \
|
|
restore_timer() { :; }; \
|
|
monitor_with_dbus() { printf 'dbus'; }; \
|
|
monitor_with_polling() { printf 'polling'; }; \
|
|
start_monitoring")
|
|
|
|
assert_equals "$expected_mode" "$mode" 'shutdown timer monitor should choose the expected dispatcher'
|
|
|
|
if [[ -f "$BIN_DIR/busctl.off" ]]; then
|
|
mv "$BIN_DIR/busctl.off" "$BIN_DIR/busctl"
|
|
fi
|
|
}
|
|
|
|
run_dbus_throttle_case() {
|
|
local ts_sequence="$1"
|
|
local expected_calls="$2"
|
|
local check_interval="${3:-30}"
|
|
local calls
|
|
local counter_file="$TMP_DIR/timer_checks.log"
|
|
|
|
: >"$counter_file"
|
|
|
|
# The `bash -c` body below is a script for a CHILD shell - $1,
|
|
# $TEST_CHECK_INTERVAL, $COUNTER_FILE and ${mock_ts[...]} must reach it
|
|
# UNEXPANDED and be evaluated there. Single quotes are load-bearing.
|
|
# shellcheck disable=SC2016
|
|
calls=$(env -i PATH="$BIN_DIR" SHUTDOWN_TIMER_MONITOR_SKIP_MAIN=1 MOCK_BUSCTL_LINES="day-specific-shutdown.timer\nday-specific-shutdown.timer\nday-specific-shutdown.timer" MOCK_TS_SEQUENCE="$ts_sequence" COUNTER_FILE="$counter_file" TEST_CHECK_INTERVAL="$check_interval" /bin/bash -c '
|
|
source "$1"
|
|
CHECK_INTERVAL="$TEST_CHECK_INTERVAL"
|
|
timer_needs_restoration() { printf "x\n" >> "$COUNTER_FILE"; return 1; }
|
|
restore_timer() { :; }
|
|
mock_idx=0
|
|
IFS=" " read -r -a mock_ts <<< "$MOCK_TS_SEQUENCE"
|
|
current_epoch() {
|
|
local out_var="${1:-}"
|
|
local ts_value="${mock_ts[$mock_idx]:-0}"
|
|
mock_idx=$((mock_idx + 1))
|
|
|
|
if [[ -n $out_var ]]; then
|
|
printf -v "$out_var" '%s' "$ts_value"
|
|
else
|
|
printf "%s\n" "$ts_value"
|
|
fi
|
|
}
|
|
monitor_with_dbus >/dev/null 2>&1 || true
|
|
timer_checks=0
|
|
while IFS= read -r _; do
|
|
timer_checks=$((timer_checks + 1))
|
|
done < "$COUNTER_FILE"
|
|
printf "%s" "$timer_checks"
|
|
' _ "$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh")
|
|
|
|
assert_equals "$expected_calls" "$calls" 'monitor_with_dbus should throttle repeated relevant events'
|
|
}
|
|
|
|
printf 'Checking D-Bus path is preferred when busctl exists...\n'
|
|
run_case dbus 1
|
|
|
|
printf 'Checking polling fallback is used when busctl is absent...\n'
|
|
run_case polling 0
|
|
|
|
printf 'Checking D-Bus monitor throttles repeated events within interval...\n'
|
|
run_dbus_throttle_case '100 105 109' '1'
|
|
|
|
printf 'Checking D-Bus monitor can process all events when interval is zero...\n'
|
|
run_dbus_throttle_case '100 101 102' '3' '0'
|
|
|
|
printf 'Checking wait helper enforces delay even with /dev/null stdin...\n'
|
|
wait_elapsed=$(env -i PATH="/usr/bin:/bin" SHUTDOWN_TIMER_MONITOR_SKIP_MAIN=1 /bin/bash -c \
|
|
"source '$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh'; \
|
|
start=\$(printf '%(%s)T' -1); \
|
|
wait_seconds 1; \
|
|
end=\$(printf '%(%s)T' -1); \
|
|
printf '%s' \$((end-start))" </dev/null)
|
|
assert_equals '1' "$wait_elapsed" 'wait_seconds should not return immediately on /dev/null stdin'
|
|
|
|
printf 'Checking installer template stays in sync with the event-driven monitor...\n'
|
|
grep -Fq 'monitor_with_dbus()' "${SETUP_SOURCES[@]}" ||
|
|
fail 'setup_midnight_shutdown.sh should install the D-Bus monitor helper'
|
|
grep -Fq 'start_monitoring()' "${SETUP_SOURCES[@]}" ||
|
|
fail 'setup_midnight_shutdown.sh should install the start_monitoring dispatcher'
|
|
grep -Fq 'if command -v busctl &>/dev/null; then' "${SETUP_SOURCES[@]}" ||
|
|
fail 'setup_midnight_shutdown.sh should prefer busctl when available'
|
|
grep -Fq 'current_epoch now_ts' "${SETUP_SOURCES[@]}" ||
|
|
fail 'setup_midnight_shutdown.sh should use out-var epoch helper in D-Bus throttling path'
|
|
# Searching for this literal source text; expanding it would run
|
|
# current_epoch and grep for its output instead.
|
|
# shellcheck disable=SC2016
|
|
if grep -Fq 'now_ts=$(current_epoch)' "${SETUP_SOURCES[@]}"; then
|
|
fail 'setup_midnight_shutdown.sh should avoid subshell epoch capture in D-Bus path'
|
|
fi
|
|
# Literal source text, as above.
|
|
# shellcheck disable=SC2016
|
|
if grep -Fq 'now_ts=$(current_epoch)' "$TARGET_SCRIPT"; then
|
|
fail 'runtime shutdown monitor should avoid subshell epoch capture in D-Bus path'
|
|
fi
|
|
grep -Fq 'OnUnitActiveSec=300' "${SETUP_SOURCES[@]}" ||
|
|
fail 'setup_midnight_shutdown.sh should run watchdog timer at 300s cadence'
|
|
grep -Fq 'wait_seconds()' "${SETUP_SOURCES[@]}" ||
|
|
fail 'setup_midnight_shutdown.sh should install builtin wait helper in polling fallback'
|
|
# Literal source text, as above.
|
|
# shellcheck disable=SC2016
|
|
grep -Fq 'wait_seconds "$CHECK_INTERVAL"' "$TARGET_SCRIPT" ||
|
|
fail 'runtime shutdown monitor polling fallback should use builtin wait helper'
|
|
|
|
printf 'shutdown-timer-monitor.sh regression checks passed.\n'
|