All checks were successful
Auto-merge docs-only PRs / auto-merge-docs (pull_request) Successful in 2s
Reduce VM 115 (docker-sba) from 16 vCPUs (2×8) to 8 vCPUs (1×8) to match actual workload (0.06 load/core). Add --hosts flag to homelab-audit.sh for targeted post-change audits. Closes #18 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
127 lines
3.7 KiB
Bash
127 lines
3.7 KiB
Bash
#!/usr/bin/env bash
|
|
# test-audit-collectors.sh — validates homelab-audit.sh collector output format
|
|
#
|
|
# Re-implements each collector function inline and runs it locally, checking
|
|
# that output matches the expected format. Exits non-zero on any failure.
|
|
|
|
set -euo pipefail
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
pass() {
|
|
((PASS++)) || true
|
|
echo " PASS: $1"
|
|
}
|
|
fail() {
|
|
((FAIL++)) || true
|
|
echo " FAIL: $1 — $2"
|
|
}
|
|
|
|
echo "=== Collector output format tests ==="
|
|
|
|
# Run each collector function locally and validate output format
|
|
# These functions are designed to work on any Linux host
|
|
|
|
# --- cpu_load ---
|
|
result=$(uptime | awk -F'load average:' '{print $2}' | awk -F'[, ]+' '{print $2}')
|
|
if [[ "$result" =~ ^[0-9]+\.?[0-9]*$ ]]; then
|
|
pass "cpu_load returns numeric value: $result"
|
|
else
|
|
fail "cpu_load" "expected numeric, got: '$result'"
|
|
fi
|
|
|
|
# --- mem_pct ---
|
|
result=$(free | awk '/^Mem:/ {printf "%.0f", $3/$2*100}')
|
|
if [[ "$result" =~ ^[0-9]+$ ]] && ((result >= 0 && result <= 100)); then
|
|
pass "mem_pct returns percentage: $result"
|
|
else
|
|
fail "mem_pct" "expected 0-100, got: '$result'"
|
|
fi
|
|
|
|
# --- zombie_count ---
|
|
result=$(ps -eo stat= | grep -c "^Z" || true)
|
|
if [[ "$result" =~ ^[0-9]+$ ]]; then
|
|
pass "zombie_count returns integer: $result"
|
|
else
|
|
fail "zombie_count" "expected integer, got: '$result'"
|
|
fi
|
|
|
|
# --- zombie_parents ---
|
|
# May be empty if no zombies — that's valid
|
|
result=$(ps -eo pid=,ppid=,stat= | awk '$3 ~ /^Z/ {print $2}' | sort -u |
|
|
xargs -I{} ps -o comm= -p {} 2>/dev/null | paste -sd, || true)
|
|
if [[ -z "$result" || "$result" =~ ^[a-zA-Z0-9_.,/-]+$ ]]; then
|
|
pass "zombie_parents returns csv or empty: '${result:-<empty>}'"
|
|
else
|
|
fail "zombie_parents" "unexpected format: '$result'"
|
|
fi
|
|
|
|
# --- swap_mb ---
|
|
result=$(free | awk '/^Swap:/ {printf "%.0f", $3/1024}')
|
|
if [[ "$result" =~ ^[0-9]+$ ]]; then
|
|
pass "swap_mb returns integer MB: $result"
|
|
else
|
|
fail "swap_mb" "expected integer, got: '$result'"
|
|
fi
|
|
|
|
# --- oom_events ---
|
|
result=$(journalctl -k --since "7 days ago" 2>/dev/null | grep -ci "out of memory") || true
|
|
result="${result:-0}"
|
|
if [[ "$result" =~ ^[0-9]+$ ]]; then
|
|
pass "oom_events returns integer: $result"
|
|
else
|
|
fail "oom_events" "expected integer, got: '$result'"
|
|
fi
|
|
|
|
# --- stuck_procs ---
|
|
# May be empty — that's valid
|
|
result=$(ps -eo stat=,pcpu=,comm= |
|
|
awk '$1 ~ /^D/ && $2+0 >= 10 {print $3}' | paste -sd, || true)
|
|
if [[ -z "$result" || "$result" =~ ^[a-zA-Z0-9_.,/-]+$ ]]; then
|
|
pass "stuck_procs returns csv or empty: '${result:-<empty>}'"
|
|
else
|
|
fail "stuck_procs" "unexpected format: '$result'"
|
|
fi
|
|
|
|
# --- disk_usage format ---
|
|
result=$(df --output=pcent,target -x tmpfs -x devtmpfs 2>/dev/null | tail -n +2 | head -1 |
|
|
while read -r pct mnt; do echo "${pct%%%} $mnt"; done)
|
|
if [[ "$result" =~ ^[0-9]+\ / ]]; then
|
|
pass "disk_usage returns 'pct mount' format: $result"
|
|
else
|
|
fail "disk_usage" "expected 'N /path', got: '$result'"
|
|
fi
|
|
|
|
# --- --hosts flag parsing ---
|
|
echo ""
|
|
echo "=== --hosts argument parsing tests ==="
|
|
|
|
# Single host
|
|
input="vm-115:10.10.0.88"
|
|
IFS=',' read -ra entries <<<"$input"
|
|
label="${entries[0]%%:*}"
|
|
addr="${entries[0]#*:}"
|
|
if [[ "$label" == "vm-115" && "$addr" == "10.10.0.88" ]]; then
|
|
pass "--hosts single entry parsed: $label $addr"
|
|
else
|
|
fail "--hosts single" "expected 'vm-115 10.10.0.88', got: '$label $addr'"
|
|
fi
|
|
|
|
# Multiple hosts
|
|
input="vm-115:10.10.0.88,lxc-225:10.10.0.225"
|
|
IFS=',' read -ra entries <<<"$input"
|
|
label1="${entries[0]%%:*}"
|
|
addr1="${entries[0]#*:}"
|
|
label2="${entries[1]%%:*}"
|
|
addr2="${entries[1]#*:}"
|
|
if [[ "$label1" == "vm-115" && "$addr1" == "10.10.0.88" && "$label2" == "lxc-225" && "$addr2" == "10.10.0.225" ]]; then
|
|
pass "--hosts multi entry parsed: $label1 $addr1, $label2 $addr2"
|
|
else
|
|
fail "--hosts multi" "unexpected parse result"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
((FAIL == 0))
|