mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-01 14:47:38 +00:00
153 lines
3.8 KiB
Go
153 lines
3.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"math/rand"
|
||
|
"strings"
|
||
|
"sync"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func TestManagerUpdateError(t *testing.T) {
|
||
|
m := &manager{groups: make(map[uint64]*Group)}
|
||
|
path := []string{"foo/bar"}
|
||
|
err := m.update(context.Background(), path, true, false)
|
||
|
if err == nil {
|
||
|
t.Fatalf("expected to have err; got nil instead")
|
||
|
}
|
||
|
expErr := "no groups found"
|
||
|
if !strings.Contains(err.Error(), expErr) {
|
||
|
t.Fatalf("expected to got err %s; got %s", expErr, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TestManagerUpdateConcurrent supposed to test concurrent
|
||
|
// execution of configuration update.
|
||
|
// Should be executed with -race flag
|
||
|
func TestManagerUpdateConcurrent(t *testing.T) {
|
||
|
m := &manager{groups: make(map[uint64]*Group)}
|
||
|
paths := []string{
|
||
|
"testdata/dir/rules0-good.rules",
|
||
|
"testdata/dir/rules1-good.rules",
|
||
|
"testdata/rules0-good.rules",
|
||
|
}
|
||
|
|
||
|
const n = 500
|
||
|
wg := sync.WaitGroup{}
|
||
|
wg.Add(n)
|
||
|
for i := 0; i < n; i++ {
|
||
|
go func() {
|
||
|
defer wg.Done()
|
||
|
rnd := rand.Intn(len(paths))
|
||
|
path := []string{paths[rnd]}
|
||
|
err := m.update(context.Background(), path, true, false)
|
||
|
if err != nil {
|
||
|
t.Errorf("update error: %s", err)
|
||
|
}
|
||
|
}()
|
||
|
}
|
||
|
wg.Wait()
|
||
|
}
|
||
|
|
||
|
// TestManagerUpdate tests sequential configuration
|
||
|
// updates.
|
||
|
func TestManagerUpdate(t *testing.T) {
|
||
|
testCases := []struct {
|
||
|
name string
|
||
|
initPath string
|
||
|
updatePath string
|
||
|
want []*Group
|
||
|
}{
|
||
|
{
|
||
|
name: "update good rules",
|
||
|
initPath: "testdata/rules0-good.rules",
|
||
|
updatePath: "testdata/dir/rules1-good.rules",
|
||
|
want: []*Group{
|
||
|
{
|
||
|
File: "testdata/dir/rules1-good.rules",
|
||
|
Name: "duplicatedGroupDiffFiles",
|
||
|
Rules: []*Rule{newTestRule("VMRows", time.Second*10)},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "update good rules from 1 to 2 groups",
|
||
|
initPath: "testdata/dir/rules1-good.rules",
|
||
|
updatePath: "testdata/rules0-good.rules",
|
||
|
want: []*Group{
|
||
|
{
|
||
|
File: "testdata/rules0-good.rules",
|
||
|
Name: "groupGorSingleAlert", Rules: []*Rule{
|
||
|
newTestRule("VMRows", time.Second*10),
|
||
|
}},
|
||
|
{
|
||
|
File: "testdata/rules0-good.rules",
|
||
|
Name: "TestGroup", Rules: []*Rule{
|
||
|
newTestRule("Conns", time.Duration(0)),
|
||
|
newTestRule("ExampleAlertAlwaysFiring", time.Duration(0)),
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "update with one bad rule file",
|
||
|
initPath: "testdata/rules0-good.rules",
|
||
|
updatePath: "testdata/dir/rules2-bad.rules",
|
||
|
want: []*Group{
|
||
|
{
|
||
|
File: "testdata/rules0-good.rules",
|
||
|
Name: "groupGorSingleAlert", Rules: []*Rule{
|
||
|
newTestRule("VMRows", time.Second*10),
|
||
|
}},
|
||
|
{
|
||
|
File: "testdata/rules0-good.rules",
|
||
|
Name: "TestGroup", Rules: []*Rule{
|
||
|
newTestRule("Conns", time.Duration(0)),
|
||
|
newTestRule("ExampleAlertAlwaysFiring", time.Duration(0)),
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
for _, tc := range testCases {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
ctx, cancel := context.WithCancel(context.TODO())
|
||
|
m := &manager{groups: make(map[uint64]*Group)}
|
||
|
path := []string{tc.initPath}
|
||
|
if err := m.update(ctx, path, true, false); err != nil {
|
||
|
t.Fatalf("failed to complete initial rules update: %s", err)
|
||
|
}
|
||
|
|
||
|
path = []string{tc.updatePath}
|
||
|
_ = m.update(ctx, path, true, false)
|
||
|
if len(tc.want) != len(m.groups) {
|
||
|
t.Fatalf("\nwant number of groups: %d;\ngot: %d ", len(tc.want), len(m.groups))
|
||
|
}
|
||
|
|
||
|
for _, wantG := range tc.want {
|
||
|
gotG, ok := m.groups[wantG.ID()]
|
||
|
if !ok {
|
||
|
t.Fatalf("expected to have group %q", wantG.Name)
|
||
|
}
|
||
|
compareGroups(t, gotG, wantG)
|
||
|
}
|
||
|
|
||
|
cancel()
|
||
|
m.close()
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func compareGroups(t *testing.T, a, b *Group) {
|
||
|
t.Helper()
|
||
|
if len(a.Rules) != len(b.Rules) {
|
||
|
t.Fatalf("expected group %s to have %d rules; got: %d",
|
||
|
a.Name, len(a.Rules), len(b.Rules))
|
||
|
}
|
||
|
for i, r := range a.Rules {
|
||
|
got, want := r, b.Rules[i]
|
||
|
if got.Name != want.Name {
|
||
|
t.Fatalf("expected to have rule %q; got %q", want.Name, got.Name)
|
||
|
}
|
||
|
}
|
||
|
}
|