package alert_test
import (
"os"
"strings"
"testing"
"github.com/wangjia/pangolin/server/internal/alert"
)
// allEventTypes lists every EventType constant for completeness checks.
var allEventTypes = []alert.EventType{
alert.EventTypeBlockConfirmed,
alert.EventTypeReplenishFailed,
alert.EventTypeWatermarkLow,
alert.EventTypeBreakerTripped,
alert.EventTypeProbeAgentLost,
alert.EventTypeHeartbeatMissing,
alert.EventTypeFault,
}
// expectedAnchors maps each EventType to the expected in the runbook.
var expectedAnchors = map[alert.EventType]string{
alert.EventTypeBlockConfirmed: "block-confirmed",
alert.EventTypeReplenishFailed: "replenish-failed",
alert.EventTypeWatermarkLow: "watermark-low",
alert.EventTypeBreakerTripped: "breaker-tripped",
alert.EventTypeProbeAgentLost: "probe-agent-lost",
alert.EventTypeHeartbeatMissing: "heartbeat-missing",
alert.EventTypeFault: "node-fault",
}
// TestRunbookAnchorsInCode verifies that every EventType produces an Event
// whose RunbookAnchor matches the expected anchor.
func TestRunbookAnchorsInCode(t *testing.T) {
for _, et := range allEventTypes {
e := alert.NewEvent(et, "node-x", nil)
wantAnchor := "#" + expectedAnchors[et]
if e.RunbookAnchor != wantAnchor {
t.Errorf("EventType %q: RunbookAnchor = %q; want %q",
et, e.RunbookAnchor, wantAnchor)
}
}
}
// TestRunbookFileContainsAllAnchors verifies that docs/runbook-scheduler.md
// contains an tag for every event type.
//
// The test is skipped when the file does not exist yet (so it never blocks CI
// while the runbook is being drafted) and fails once the file is present but
// an anchor is missing.
func TestRunbookFileContainsAllAnchors(t *testing.T) {
// Navigate up from server/internal/alert to the repo root, then to docs/.
// Go test sets cwd to the package directory (server/internal/alert/),
// so three levels up reaches the worktree root (where docs/ lives).
runbookPath := "../../../docs/runbook-scheduler.md"
data, err := os.ReadFile(runbookPath)
if os.IsNotExist(err) {
t.Skip("docs/runbook-scheduler.md not found; skipping anchor check")
}
if err != nil {
t.Fatalf("read runbook: %v", err)
}
content := string(data)
for et, anchor := range expectedAnchors {
tag := `id="` + anchor + `"`
if !strings.Contains(content, tag) {
t.Errorf("runbook missing anchor for EventType %q: expected ", et, tag)
}
}
}