diff --git a/pkg/rules/manager.go b/pkg/rules/manager.go index 4fb1acc1d3..d4552f23b9 100644 --- a/pkg/rules/manager.go +++ b/pkg/rules/manager.go @@ -313,6 +313,12 @@ func (m *Manager) Update(evalInterval time.Duration, files []string) error { ruleFiles = map[string]string{} ) + // Initialize filesByStrategy for existing managers' strategies to make + // sure that managers are updated when they have no rules configured. + for strategy := range m.mgrs { + filesByStrategy[strategy] = make([]string, 0) + } + if err := os.RemoveAll(m.workDir); err != nil { return errors.Wrapf(err, "remove %s", m.workDir) } diff --git a/pkg/rules/manager_test.go b/pkg/rules/manager_test.go index d0a75331db..0d35fbd0be 100644 --- a/pkg/rules/manager_test.go +++ b/pkg/rules/manager_test.go @@ -338,3 +338,50 @@ func TestManager_Rules(t *testing.T) { }() testRulesAgainstExamples(t, filepath.Join(curr, "../../examples/alerts"), thanosRuleMgr) } + +func TestManagerUpdateWithNoRules(t *testing.T) { + dir, err := ioutil.TempDir("", "test_rule_rule_groups") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, os.RemoveAll(dir)) }() + + testutil.Ok(t, ioutil.WriteFile(filepath.Join(dir, "no_strategy.yaml"), []byte(` +groups: +- name: "something1" + rules: + - alert: "some" + expr: "up" +`), os.ModePerm)) + + thanosRuleMgr := NewManager( + context.Background(), + nil, + dir, + rules.ManagerOptions{ + Logger: log.NewLogfmtLogger(os.Stderr), + Queryable: nopQueryable{}, + }, + func(partialResponseStrategy storepb.PartialResponseStrategy) rules.QueryFunc { + return func(ctx context.Context, q string, t time.Time) (promql.Vector, error) { + return nil, nil + } + }, + nil, + ) + + // We need to run the underlying rule managers to update them more than + // once (otherwise there's a deadlock). + thanosRuleMgr.Run() + defer func() { + thanosRuleMgr.Stop() + }() + + err = thanosRuleMgr.Update(1*time.Second, []string{ + filepath.Join(dir, "no_strategy.yaml"), + }) + testutil.Ok(t, err) + testutil.Equals(t, 1, len(thanosRuleMgr.RuleGroups())) + + err = thanosRuleMgr.Update(1*time.Second, []string{}) + testutil.Ok(t, err) + testutil.Equals(t, 0, len(thanosRuleMgr.RuleGroups())) +}