diff --git a/app/vmalert/notifier/alert.go b/app/vmalert/notifier/alert.go index f26cfcfa3..89dca7e17 100644 --- a/app/vmalert/notifier/alert.go +++ b/app/vmalert/notifier/alert.go @@ -111,11 +111,7 @@ func (a *Alert) ExecTemplate(q templates.QueryFn, labels, annotations map[string ActiveAt: a.ActiveAt, For: a.For, } - tmpl, err := templates.GetWithFuncs(templates.FuncsWithQuery(q)) - if err != nil { - return nil, fmt.Errorf("error getting a template: %w", err) - } - return templateAnnotations(annotations, tplData, tmpl, true) + return ExecTemplate(q, annotations, tplData) } // ExecTemplate executes the given template for given annotations map. diff --git a/app/vmalert/notifier/alert_test.go b/app/vmalert/notifier/alert_test.go index 9999f6f42..bff535996 100644 --- a/app/vmalert/notifier/alert_test.go +++ b/app/vmalert/notifier/alert_test.go @@ -200,6 +200,9 @@ func TestAlert_ExecTemplate(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + if err := ValidateTemplates(tc.annotations); err != nil { + t.Fatal(err) + } tpl, err := tc.alert.ExecTemplate(qFn, tc.alert.Labels, tc.annotations) if err != nil { t.Fatal(err) diff --git a/app/vmalert/notifier/init.go b/app/vmalert/notifier/init.go index e85bc47f1..4ec773fbf 100644 --- a/app/vmalert/notifier/init.go +++ b/app/vmalert/notifier/init.go @@ -81,10 +81,6 @@ var ( // // Init returns an error if both mods are used. func Init(gen AlertURLGenerator, extLabels map[string]string, extURL string) (func() []Notifier, error) { - if externalLabels != nil || externalURL != "" { - return nil, fmt.Errorf("BUG: notifier.Init was called multiple times") - } - externalURL = extURL externalLabels = extLabels eu, err := url.Parse(externalURL) diff --git a/app/vmalert/notifier/init_test.go b/app/vmalert/notifier/init_test.go new file mode 100644 index 000000000..c7ab2527f --- /dev/null +++ b/app/vmalert/notifier/init_test.go @@ -0,0 +1,37 @@ +package notifier + +import ( + "github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil" + "testing" +) + +func TestInit(t *testing.T) { + oldAddrs := *addrs + defer func() { *addrs = oldAddrs }() + + *addrs = flagutil.ArrayString{"127.0.0.1", "127.0.0.2"} + + fn, err := Init(nil, nil, "") + if err != nil { + t.Fatalf("%s", err) + } + + nfs := fn() + if len(nfs) != 2 { + t.Fatalf("expected to get 2 notifiers; got %d", len(nfs)) + } + + targets := GetTargets() + if targets == nil || targets[TargetStatic] == nil { + t.Fatalf("expected to get static targets in response") + } + + nf1 := targets[TargetStatic][0] + if nf1.Addr() != "127.0.0.1/api/v2/alerts" { + t.Fatalf("expected to get \"127.0.0.1/api/v2/alerts\"; got %q instead", nf1.Addr()) + } + nf2 := targets[TargetStatic][1] + if nf2.Addr() != "127.0.0.2/api/v2/alerts" { + t.Fatalf("expected to get \"127.0.0.2/api/v2/alerts\"; got %q instead", nf2.Addr()) + } +} diff --git a/app/vmalert/remotewrite/init_test.go b/app/vmalert/remotewrite/init_test.go new file mode 100644 index 000000000..330fef0f3 --- /dev/null +++ b/app/vmalert/remotewrite/init_test.go @@ -0,0 +1,20 @@ +package remotewrite + +import ( + "context" + "testing" +) + +func TestInit(t *testing.T) { + oldAddr := *addr + defer func() { *addr = oldAddr }() + + *addr = "http://localhost:8428" + cl, err := Init(context.Background()) + if err != nil { + t.Fatal(err) + } + if err := cl.Close(); err != nil { + t.Fatal(err) + } +} diff --git a/app/vmalert/templates/template_test.go b/app/vmalert/templates/template_test.go index d5378a434..30bf1e975 100644 --- a/app/vmalert/templates/template_test.go +++ b/app/vmalert/templates/template_test.go @@ -76,6 +76,20 @@ func TestTemplateFuncs(t *testing.T) { formatting("humanize1024", float64(146521335255970361638912), "124.1Zi") formatting("humanize1024", float64(150037847302113650318245888), "124.1Yi") formatting("humanize1024", float64(153638755637364377925883789312), "1.271e+05Yi") + + formatting("humanize", float64(127087), "127.1k") + formatting("humanize", float64(136458627186688), "136.5T") + + formatting("humanizeDuration", 1, "1s") + formatting("humanizeDuration", 0.2, "200ms") + formatting("humanizeDuration", 42000, "11h 40m 0s") + formatting("humanizeDuration", 16790555, "194d 8h 2m 35s") + + formatting("humanizePercentage", 1, "100%") + formatting("humanizePercentage", 0.8, "80%") + formatting("humanizePercentage", 0.015, "1.5%") + + formatting("humanizeTimestamp", 1679055557, "2023-03-17 12:19:17 +0000 UTC") } func mkTemplate(current, replacement interface{}) textTemplate { diff --git a/app/vmalert/web_test.go b/app/vmalert/web_test.go index 5648087c6..600010527 100644 --- a/app/vmalert/web_test.go +++ b/app/vmalert/web_test.go @@ -7,6 +7,7 @@ import ( "net/http/httptest" "reflect" "testing" + "time" "github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier" ) @@ -19,9 +20,18 @@ func TestHandler(t *testing.T) { }, state: newRuleState(10), } + ar.state.add(ruleStateEntry{ + time: time.Now(), + at: time.Now(), + samples: 10, + }) + rr := &RecordingRule{ + Name: "record", + state: newRuleState(10), + } g := &Group{ Name: "group", - Rules: []Rule{ar}, + Rules: []Rule{ar, rr}, } m := &manager{groups: make(map[uint64]*Group)} m.groups[0] = g @@ -62,6 +72,14 @@ func TestHandler(t *testing.T) { t.Run("/vmalert/rule", func(t *testing.T) { a := ar.ToAPI() getResp(ts.URL+"/vmalert/"+a.WebLink(), nil, 200) + r := rr.ToAPI() + getResp(ts.URL+"/vmalert/"+r.WebLink(), nil, 200) + }) + t.Run("/vmalert/alert", func(t *testing.T) { + alerts := ar.AlertsToAPI() + for _, a := range alerts { + getResp(ts.URL+"/vmalert/"+a.WebLink(), nil, 200) + } }) t.Run("/vmalert/rule?badParam", func(t *testing.T) { params := fmt.Sprintf("?%s=0&%s=1", paramGroupID, paramRuleID)