Repository: VictoriaMetrics/VictoriaMetrics
Pull request #3975 (2023-03-17 12:43:58)

Vmalert tests
See commits description

codecov[bot]: ## [Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3975?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) Report
Patch coverage: **`100.00`**% and project coverage change: **`+0.43`** :tada:
> Comparison is base [(`d3608be`)](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/commit/d3608be313b49cc2217b07325a155b810119aada?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) 58.13% compared to head [(`03b6127`)](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3975?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) 58.57%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #3975      +/-   ##
==========================================
+ Coverage   58.13%   58.57%   +0.43%     
==========================================
  Files         313      313              
  Lines       52851    52844       -7     
==========================================
+ Hits        30725    30951     +226     
+ Misses      20180    19931     -249     
- Partials     1946     1962      +16     
```


| [Impacted Files](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3975?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) | Coverage Δ | |
|---|---|---|
| [app/vmalert/notifier/init.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3975?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvbm90aWZpZXIvaW5pdC5nbw==) | `66.66% <ø> (+56.32%)` | :arrow_up: |
| [app/vmalert/notifier/alert.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3975?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvbm90aWZpZXIvYWxlcnQuZ28=) | `68.29% <100.00%> (+17.12%)` | :arrow_up: |

... and [14 files with indirect coverage changes](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3975/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)

</details>

[:umbrella: View full report in Codecov by Sentry](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/3975?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).

f41gh7:  See failing test for i386
```
?   	github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/tpl	[no test files]
Error: app/vmalert/templates/template_test.go:86:33: cannot use 1679055557691 (untyped int constant) as int value in argument to formatting (overflows)
```
hagen1778: > See failing test for i386

that's old failing test. should have been addressed in https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3975/commits/c01ac4f19df08ae94c72f68ebd81e104333987e0

Patch:
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/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)


Test patch:
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_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)