Testing — System Health Monitor¶
Testing a monitoring script requires both verifying normal operation and simulating alert conditions.
Basic Smoke Test¶
Run the script manually and check its exit code:
Expected output:
[2024-01-15 09:30:00] [INFO ] === Health check started on my-server ===
[2024-01-15 09:30:00] [INFO ] Disk / OK: 45% (threshold: 85%)
[2024-01-15 09:30:00] [INFO ] Memory OK: 62% (threshold: 80%)
[2024-01-15 09:30:00] [INFO ] CPU load OK: 0.42 (threshold: 4.0)
[2024-01-15 09:30:00] [INFO ] === All systems normal ===
Exit code: 0
Test Alert Triggering¶
Temporarily lower a threshold to force an alert:
Expected output:
[2024-01-15 09:30:05] [INFO ] === Health check started on my-server ===
[2024-01-15 09:30:05] [ALERT] Disk / at 45% — threshold 1% exceeded
[2024-01-15 09:30:05] [INFO ] Memory OK: 62% (threshold: 80%)
[2024-01-15 09:30:05] [INFO ] CPU load OK: 0.42 (threshold: 4.0)
[2024-01-15 09:30:05] [WARN ] === 1 alert(s) triggered ===
Test Each Function Independently¶
# Source the script without running main
# (requires main to be guarded: [[ "${BASH_SOURCE[0]}" == "$0" ]] && main "$@")
source health_check.sh
# Now test individual functions
get_disk_pct # should print a number
get_mem_pct # should print a number
get_cpu_load # should print a decimal
check_metric "Disk" "45" "85" "%" # should log INFO and return 0
check_metric "Disk" "95" "85" "%" # should log ALERT and return 1
echo "Return code: $?"
To support source testing, add this guard at the bottom of your script:
Test Log Rotation¶
# Fill the log beyond LOG_MAX_LINES
for i in $(seq 1 1100); do
echo "[test] line $i" >> ~/projects/health-monitor/logs/health_check.log
done
wc -l ~/projects/health-monitor/logs/health_check.log
# Should show: 1100 ...
# Run the script — rotation should trim it
bash health_check.sh
wc -l ~/projects/health-monitor/logs/health_check.log
# Should show <= 1000 ...
Test the Cron Environment¶
The most common failure mode is the script working on the command line but failing in cron because $PATH is different. Test this explicitly:
If this fails while the normal run succeeds, you have a $PATH dependency. Fix it by using absolute paths for all commands (/usr/bin/awk, /bin/df, etc.) or adding this to the top of your script:
Test Error Cases¶
# What happens if the log directory doesn't exist?
LOGFILE=/nonexistent/path/test.log bash health_check.sh
# What happens if the config file has a syntax error?
echo "THRESHOLD_DISK=bad value" >> health_check.conf
bash health_check.sh
# Restore config afterwards
Checklist¶
□ Script runs without errors
□ Low threshold triggers ALERT log line
□ All metrics appear in log
□ Log rotation trims file correctly
□ Script works with cron's minimal $PATH
□ Missing config file uses sensible defaults
□ Interrupted with Ctrl+C leaves no temp files
□ shellcheck health_check.sh returns 0 warnings