ci / lint (push) Successful in 1m31s
Three live-fire defects: unconditional 30-min watchdog page, tsys6 flap false-positive, Tripp Lite runtime-low gap. TDD: 4 new regression tests. On-box ha core check passed before commit. Meat + verification: https://projects.knownelement.com/issues/344#note-4966
70 lines
2.9 KiB
Bash
70 lines
2.9 KiB
Bash
#!/bin/bash
|
|
# SDLC regression tests (#778) — run in CI (see .gitea/workflows/ci.yml).
|
|
# Each test guards a rule that exists because of a real incident or ruling.
|
|
set -uo pipefail
|
|
cd "$(dirname "$0")/.." || exit 1
|
|
|
|
FAIL=0
|
|
t() {
|
|
# $1 = label, $2 = shell command string
|
|
if eval "$2"; then
|
|
echo " OK $1"
|
|
else
|
|
echo " FAIL $1"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
}
|
|
|
|
echo "=== alert twins (every alert ships a recovery twin) ==="
|
|
t "utility power restored twin" \
|
|
"grep -q 'id: pfv_plant_ups_power_restored' automations.yaml"
|
|
t "temperature recovered twin" \
|
|
"grep -q 'id: pfv_plant_temperature_recovered' automations.yaml"
|
|
|
|
echo "=== alert deep links (taps land on dashboards, #344) ==="
|
|
ALERTS="POWER OUTAGE|UPS BATTERY LOW|UPS COMMS LOST|UPS RUNTIME LOW|Power restored|HIGH TEMPERATURE|SENSOR WATCHDOG|TEMP RISING FAST|TEMPERATURE RECOVERED"
|
|
DL_OK=1
|
|
IFS='|' read -ra ALERT_ARR <<< "$ALERTS"
|
|
for a in "${ALERT_ARR[@]}"; do
|
|
if ! grep -A2 "title: $a$" automations.yaml | grep -q " url: "; then
|
|
echo " (missing deep link: $a)"
|
|
DL_OK=0
|
|
fi
|
|
done
|
|
t "all alerts deep-linked" "[ \"$DL_OK\" -eq 1 ]"
|
|
|
|
echo "=== watchdog coverage (#789) ==="
|
|
t "watchdog watches the deploy sensor" \
|
|
"grep -q 'sensor.pfv_deploy_gitea_release_head, 30' automations.yaml"
|
|
t "watchdog automation exists" \
|
|
"grep -q 'id: pfv_watchdog_stale_entities' automations.yaml"
|
|
|
|
echo "=== ghost entities (dead references never return) ==="
|
|
t "no tsys9_ups ghost refs" \
|
|
"! grep -rq 'tsys9_ups' automations.yaml packages/ dashboards/"
|
|
|
|
echo "=== secrets ==="
|
|
t "no private keys in tree" \
|
|
"! grep -rInE 'BEGIN (RSA |OPENSSH |EC |DSA )?PRIVATE KEY' --exclude-dir=.git --exclude-dir=docs ."
|
|
|
|
echo "=== alert hygiene: push only when something is wrong (2026-09-06 live-fire) ==="
|
|
# The 30-min sweep used to page every cycle even when the fleet was all-OK
|
|
# (48 pages/day of noise). Notify must sit behind the dead>0 + 4h-cooldown gate.
|
|
t "plant watchdog notify gated (dead-only + cooldown input)" \
|
|
"grep -q 'pfv_plant_watchdog_last_notify' configuration.yaml && grep -q 'notify_gate' automations.yaml"
|
|
|
|
# tsys6 DRAC ambient quantizes to whole degrees C and flaps ~2F; the raw-fed
|
|
# trend sensor tripped TEMP RISING FAST with zero real climb (2026-09-06 05:02 CDT).
|
|
t "trend sensors fed from smoothed sources" \
|
|
"grep -q 'time_simple_moving_average' packages/plant_snmp.yaml && sed -n '/^binary_sensor:/,/^utility_meter:/p' packages/plant_snmp.yaml | grep -q 'entity_id: sensor.pfv_tsys6_drac_ambient_smoothed'"
|
|
|
|
# Tripp Lite had runtime sensors but no runtime-low alert — half the plant's
|
|
# shutdown window was unmonitored.
|
|
t "runtime-low covers Tripp Lite" \
|
|
"sed -n '/id: pfv_plant_ups_runtime_low/,/^ mode:/p' automations.yaml | grep -q 'sensor.pfv_tripp_lite_runtime_minutes'"
|
|
t "runtime-low status check maps per-UPS" \
|
|
"sed -n '/id: pfv_plant_ups_runtime_low/,/^ mode:/p' automations.yaml | grep -q 'status_map'"
|
|
|
|
echo "=== SDLC SUITE: $FAIL failures ==="
|
|
exit "$FAIL"
|