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) } } }