| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package alert
- import (
- "strings"
- "testing"
- )
- func goodAlert() *Alert {
- return &Alert{
- CompanyID: "acme-001",
- SourceID: "prom-prod",
- Severity: SeverityCritical,
- Category: "storage",
- Title: "Disk full on db-prod-03",
- Body: "92% used",
- Data: map[string]string{"host": "db-prod-03", "used_pct": "92"},
- DedupeKey: "disk:db-prod-03:full",
- }
- }
- func TestValidate_OK(t *testing.T) {
- if err := goodAlert().Validate(); err != nil {
- t.Fatalf("expected nil, got %v", err)
- }
- }
- func TestValidate_BadCompanyID(t *testing.T) {
- a := goodAlert()
- a.CompanyID = "ACME-001" // uppercase not allowed
- if err := a.Validate(); err == nil {
- t.Fatal("expected error for uppercase company_id")
- }
- }
- func TestValidate_UnknownSeverity(t *testing.T) {
- a := goodAlert()
- a.Severity = "emergency"
- err := a.Validate()
- if err == nil {
- t.Fatal("expected error for unknown severity")
- }
- if !IsInvalid(err) {
- t.Fatalf("expected *ErrInvalid, got %T", err)
- }
- if !strings.Contains(err.Error(), "severity") {
- t.Fatalf("expected severity reason, got %v", err)
- }
- }
- func TestValidate_DedupeKeyTooLong(t *testing.T) {
- a := goodAlert()
- a.DedupeKey = strings.Repeat("a", 129)
- if err := a.Validate(); err == nil {
- t.Fatal("expected error for long dedupe_key")
- }
- }
- func TestValidate_DataKeyTooLong(t *testing.T) {
- a := goodAlert()
- a.Data = map[string]string{strings.Repeat("k", 65): "v"}
- if err := a.Validate(); err == nil {
- t.Fatal("expected error for long data key")
- }
- }
- func TestValidate_TooManyDataKeys(t *testing.T) {
- a := goodAlert()
- a.Data = make(map[string]string, MaxDataKeys+1)
- for i := 0; i < MaxDataKeys+1; i++ {
- a.Data[shortKey(i)] = "v"
- }
- if err := a.Validate(); err == nil {
- t.Fatal("expected error for too many data keys")
- }
- }
- func TestInminentColapseBypass(t *testing.T) {
- if !SeverityInminentColapse.InminentColapseBypass() {
- t.Fatal("inminent_colapse must bypass quiet hours")
- }
- if SeverityCritical.InminentColapseBypass() {
- t.Fatal("critical must NOT bypass quiet hours")
- }
- }
- func TestNewID_UniqueAndSortable(t *testing.T) {
- a := NewID()
- b := NewID()
- if a == b {
- t.Fatalf("ids collided: %s", a)
- }
- if len(a) != 26 {
- t.Fatalf("id length expected 26, got %d (%q)", len(a), a)
- }
- }
- func shortKey(i int) string {
- const alphabet = "abcdefghijklmnopqrstuvwxyz"
- if i < len(alphabet) {
- return string(alphabet[i])
- }
- return shortKey(i/len(alphabet)) + string(alphabet[i%len(alphabet)])
- }
- func TestSeverityRank(t *testing.T) {
- cases := []struct {
- sev Severity
- want int
- }{
- {SeverityInfo, 0},
- {SeverityWarning, 1},
- {SeverityCritical, 2},
- {SeverityInminentColapse, 3},
- {Severity("bogus"), -1},
- }
- for _, tc := range cases {
- if got := tc.sev.Rank(); got != tc.want {
- t.Errorf("Severity(%q).Rank() = %d, want %d", tc.sev, got, tc.want)
- }
- }
- }
- func TestMinSeverityRank(t *testing.T) {
- if MinSeverityRank("") != 0 {
- t.Error("empty min_severity should default to rank 0 (info and above)")
- }
- if MinSeverityRank("critical") != 2 {
- t.Error("critical should be rank 2")
- }
- if MinSeverityRank("inminent_colapse") != 3 {
- t.Error("inminent_colapse should be rank 3")
- }
- }
|