changed vmalert behaviour (#738)

* VMAlert start with empty rules dir

There are some applications (operator for instance), that generates alerts configuration at runtime
and vmalert must start correctly without rules to support this behaviour.
Later application will add rules files and send SIGHUP to vmalert,
which will trigger reading rules files and start rules exectuion.

Removing rules files with SIGHUP signal must stop rules execution and
vmalert will wait for new rules.

* imports sorted

* added test cases for empty rules, removed blank line

* fixed imports conflict

* updated tests
This commit is contained in:
Nikolay Khramchikhin 2020-09-03 11:04:42 +03:00 committed by Aliaksandr Valialkin
parent 4388c6cad1
commit 80a9dc79fe
3 changed files with 29 additions and 13 deletions

View file

@ -11,6 +11,7 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier" "github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/envtemplate" "github.com/VictoriaMetrics/VictoriaMetrics/lib/envtemplate"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
"github.com/VictoriaMetrics/metricsql" "github.com/VictoriaMetrics/metricsql"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
@ -170,7 +171,7 @@ func Parse(pathPatterns []string, validateAnnotations, validateExpressions bool)
} }
} }
if len(groups) < 1 { if len(groups) < 1 {
return nil, fmt.Errorf("no groups found in %s", strings.Join(pathPatterns, ";")) logger.Warnf("no groups found in %s", strings.Join(pathPatterns, ";"))
} }
return groups, nil return groups, nil
} }

View file

@ -51,10 +51,6 @@ func TestParseBad(t *testing.T) {
[]string{"testdata/dir/rules4-bad.rules"}, []string{"testdata/dir/rules4-bad.rules"},
"either `record` or `alert` must be set", "either `record` or `alert` must be set",
}, },
{
[]string{"testdata/*.yaml"},
"no groups found",
},
} }
for _, tc := range testCases { for _, tc := range testCases {
_, err := Parse(tc.path, true, true) _, err := Parse(tc.path, true, true)

View file

@ -5,7 +5,6 @@ import (
"math/rand" "math/rand"
"net/url" "net/url"
"os" "os"
"strings"
"sync" "sync"
"testing" "testing"
"time" "time"
@ -19,16 +18,15 @@ func TestMain(m *testing.M) {
os.Exit(m.Run()) os.Exit(m.Run())
} }
func TestManagerUpdateError(t *testing.T) { // TestManagerEmptyRulesDir tests
// successful cases of
// starting with empty rules folder
func TestManagerEmptyRulesDir(t *testing.T) {
m := &manager{groups: make(map[uint64]*Group)} m := &manager{groups: make(map[uint64]*Group)}
path := []string{"foo/bar"} path := []string{"foo/bar"}
err := m.update(context.Background(), path, true, true, false) err := m.update(context.Background(), path, true, true, false)
if err == nil { if err != nil {
t.Fatalf("expected to have err; got nil instead") t.Fatalf("expected to load succesfully with empty rules dir; got err instead: %v", err)
}
expErr := "no groups found"
if !strings.Contains(err.Error(), expErr) {
t.Fatalf("expected to got err %s; got %s", expErr, err)
} }
} }
@ -180,6 +178,27 @@ func TestManagerUpdate(t *testing.T) {
}}, }},
}, },
}, },
{
name: "update empty dir rules from 0 to 2 groups",
initPath: "config/testdata/empty/*",
updatePath: "config/testdata/rules0-good.rules",
want: []*Group{
{
File: "config/testdata/rules0-good.rules",
Name: "groupGorSingleAlert",
Interval: defaultEvalInterval,
Rules: []Rule{VMRows},
},
{
File: "config/testdata/rules0-good.rules",
Interval: defaultEvalInterval,
Name: "TestGroup", Rules: []Rule{
Conns,
ExampleAlertAlwaysFiring,
},
},
},
},
} }
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {