mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-09 18:15:50 +00:00
Route mock alert cleanup through managed runtime
This commit is contained in:
@@ -199,6 +199,11 @@ Makefile targets, `scripts/toggle-mock.sh`, and `scripts/clean-mock-alerts.sh` m
|
||||
route through the managed runtime control plane when they are operating on the
|
||||
local dev stack, instead of resurrecting lane-local `hot-dev.sh` or raw Vite
|
||||
process management through separate shell folklore.
|
||||
When `scripts/clean-mock-alerts.sh` needs to quiesce a local dev runtime, it
|
||||
must stop the managed session through `hot-dev-bg` before touching legacy
|
||||
compatibility services, and its operator recovery guidance must point back to
|
||||
the canonical repo-root `npm run dev` and `npm run dev:foreground` controls
|
||||
instead of treating `pulse-hot-dev` service management as the primary dev path.
|
||||
That same rule now extends to the macOS auto-start surface. The launchd helper
|
||||
may not boot a separate legacy foreground runtime beside the managed dev stack:
|
||||
`scripts/dev-launchd-wrapper.sh`, `scripts/dev-launchd-setup.sh`, and the
|
||||
|
||||
@@ -9,7 +9,9 @@ GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
ALERT_HISTORY="/etc/pulse/alerts/alert-history.json"
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
HOT_DEV_BG_PATH="${HOT_DEV_BG_PATH:-${ROOT_DIR}/scripts/hot-dev-bg.sh}"
|
||||
ALERT_HISTORY="${ALERT_HISTORY:-/etc/pulse/alerts/alert-history.json}"
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo -e "${RED}Error: jq is required but not installed${NC}"
|
||||
@@ -33,6 +35,16 @@ run_privileged() {
|
||||
fi
|
||||
}
|
||||
|
||||
managed_runtime_running() {
|
||||
if [ ! -x "$HOT_DEV_BG_PATH" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local status_output
|
||||
status_output="$("$HOT_DEV_BG_PATH" status 2>/dev/null || true)"
|
||||
[[ "$status_output" == *"[hot-dev-bg] Running (pid:"* ]]
|
||||
}
|
||||
|
||||
if [ ! -f "$ALERT_HISTORY" ]; then
|
||||
echo -e "${RED}Error: Alert history file not found at $ALERT_HISTORY${NC}"
|
||||
exit 1
|
||||
@@ -57,7 +69,12 @@ echo -e "${GREEN}✓ Backup created: $BACKUP_FILE${NC}"
|
||||
|
||||
# Stop backend to prevent writes during cleanup
|
||||
echo "Stopping backend..."
|
||||
if managed_runtime_running; then
|
||||
echo "Stopping managed development runtime..."
|
||||
"$HOT_DEV_BG_PATH" stop
|
||||
fi
|
||||
pkill -x pulse 2>/dev/null || true
|
||||
# Legacy compatibility for service-based deployments that are not using the managed dev runtime.
|
||||
run_privileged systemctl stop pulse-hot-dev 2>/dev/null || true
|
||||
run_privileged systemctl stop pulse 2>/dev/null || true
|
||||
run_privileged systemctl stop pulse-backend 2>/dev/null || true
|
||||
@@ -84,7 +101,7 @@ run_privileged chown pulse:pulse "$ALERT_HISTORY"
|
||||
echo -e "${GREEN}✓ Mock alerts removed successfully${NC}"
|
||||
echo ""
|
||||
echo "To restart the backend, run:"
|
||||
echo " npm run dev (managed development runtime)"
|
||||
echo " ./scripts/hot-dev.sh (foreground development escape hatch)"
|
||||
echo " sudo systemctl start pulse (systemd)"
|
||||
echo " sudo systemctl start pulse-backend (legacy)"
|
||||
echo " (cd \"${ROOT_DIR}\" && npm run dev) (managed development runtime)"
|
||||
echo " (cd \"${ROOT_DIR}\" && npm run dev:foreground) (foreground development escape hatch)"
|
||||
echo " sudo systemctl start pulse (systemd)"
|
||||
echo " sudo systemctl start pulse-backend (legacy)"
|
||||
|
||||
@@ -6,6 +6,7 @@ set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
HOT_DEV_BG="${ROOT_DIR}/scripts/hot-dev-bg.sh"
|
||||
CLEAN_MOCK_ALERTS="${ROOT_DIR}/scripts/clean-mock-alerts.sh"
|
||||
PACKAGE_JSON="${ROOT_DIR}/package.json"
|
||||
FRONTEND_PACKAGE_JSON="${ROOT_DIR}/frontend-modern/package.json"
|
||||
DEV_LAUNCHD_WRAPPER="${ROOT_DIR}/scripts/dev-launchd-wrapper.sh"
|
||||
@@ -251,6 +252,119 @@ PY
|
||||
assert_contains "frontend package keeps explicit frontend-only escape hatch" "${output}" "dev:frontend-only=vite"
|
||||
}
|
||||
|
||||
test_clean_mock_alerts_prefers_managed_runtime() {
|
||||
local test_dir fake_bin alert_history fake_hot_dev_bg action_log output
|
||||
test_dir="$(mktemp -d)"
|
||||
temp_dirs+=("${test_dir}")
|
||||
fake_bin="${test_dir}/bin"
|
||||
mkdir -p "${fake_bin}"
|
||||
action_log="${test_dir}/actions.log"
|
||||
alert_history="${test_dir}/alert-history.json"
|
||||
fake_hot_dev_bg="${test_dir}/hot-dev-bg.sh"
|
||||
|
||||
cat > "${alert_history}" <<'EOF'
|
||||
[
|
||||
{
|
||||
"alert": {
|
||||
"resourceId": "mock-resource-1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"alert": {
|
||||
"resourceId": "real-resource-1"
|
||||
}
|
||||
}
|
||||
]
|
||||
EOF
|
||||
|
||||
cat > "${fake_hot_dev_bg}" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'hot-dev-bg %s\n' "$*" >> "${ACTION_LOG}"
|
||||
case "${1:-}" in
|
||||
status)
|
||||
echo "[hot-dev-bg] Running (pid: 12345)"
|
||||
;;
|
||||
stop)
|
||||
echo "[hot-dev-bg] Stopped"
|
||||
;;
|
||||
*)
|
||||
echo "unexpected hot-dev-bg command: $*" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
EOF
|
||||
chmod +x "${fake_hot_dev_bg}"
|
||||
|
||||
cat > "${fake_bin}/sudo" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'sudo %s\n' "$*" >> "${ACTION_LOG}"
|
||||
exec "$@"
|
||||
EOF
|
||||
chmod +x "${fake_bin}/sudo"
|
||||
|
||||
cat > "${fake_bin}/systemctl" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'systemctl %s\n' "$*" >> "${ACTION_LOG}"
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "${fake_bin}/systemctl"
|
||||
|
||||
cat > "${fake_bin}/chown" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'chown %s\n' "$*" >> "${ACTION_LOG}"
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "${fake_bin}/chown"
|
||||
|
||||
cat > "${fake_bin}/pkill" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'pkill %s\n' "$*" >> "${ACTION_LOG}"
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "${fake_bin}/pkill"
|
||||
|
||||
output="$(
|
||||
PATH="${fake_bin}:$PATH" \
|
||||
ACTION_LOG="${action_log}" \
|
||||
ALERT_HISTORY="${alert_history}" \
|
||||
HOT_DEV_BG_PATH="${fake_hot_dev_bg}" \
|
||||
"${CLEAN_MOCK_ALERTS}"
|
||||
)"
|
||||
|
||||
local actions
|
||||
actions="$(cat "${action_log}")"
|
||||
assert_contains "clean-mock-alerts checks managed runtime state" "${actions}" "hot-dev-bg status"
|
||||
assert_contains "clean-mock-alerts stops managed runtime first" "${actions}" "hot-dev-bg stop"
|
||||
assert_contains "clean-mock-alerts still stops compatibility services" "${actions}" "systemctl stop pulse-hot-dev"
|
||||
assert_contains "clean-mock-alerts advertises managed restart" "${output}" "npm run dev"
|
||||
assert_contains "clean-mock-alerts advertises foreground escape hatch" "${output}" "npm run dev:foreground"
|
||||
|
||||
local order_output
|
||||
order_output="$(
|
||||
ACTION_LOG_PATH="${action_log}" python3 - <<'PY'
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
lines = Path(os.environ["ACTION_LOG_PATH"]).read_text(encoding="utf-8").splitlines()
|
||||
stop_index = next(i for i, line in enumerate(lines) if line == "hot-dev-bg stop")
|
||||
systemctl_index = next(i for i, line in enumerate(lines) if line == "systemctl stop pulse-hot-dev")
|
||||
print(f"managed_before_systemctl={stop_index < systemctl_index}")
|
||||
PY
|
||||
)"
|
||||
assert_contains "managed runtime stop precedes legacy service stop" "${order_output}" "managed_before_systemctl=True"
|
||||
|
||||
local cleaned_count mock_count
|
||||
cleaned_count="$(jq 'length' "${alert_history}")"
|
||||
mock_count="$(jq '[.[] | select((.alert.resourceId // "" | contains("mock")))] | length' "${alert_history}")"
|
||||
assert_contains "clean-mock-alerts removes only mock alerts" "${cleaned_count}" "1"
|
||||
assert_contains "clean-mock-alerts leaves no mock alerts" "${mock_count}" "0"
|
||||
}
|
||||
|
||||
test_backend_restart_requires_managed_runtime() {
|
||||
local frontend_port backend_port output
|
||||
local state_dir
|
||||
@@ -330,6 +444,7 @@ main() {
|
||||
test_launchd_wrapper_uses_managed_supervisor
|
||||
test_root_package_exposes_managed_runtime_entrypoints
|
||||
test_frontend_package_exposes_managed_runtime_entrypoints
|
||||
test_clean_mock_alerts_prefers_managed_runtime
|
||||
test_backend_restart_requires_managed_runtime
|
||||
test_status_without_runtime
|
||||
test_detects_unmanaged_listeners
|
||||
|
||||
Reference in New Issue
Block a user