Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/component/mimir/rules/kubernetes/diff_test.go
4096 views
1
package rules
2
3
import (
4
"fmt"
5
"testing"
6
7
"github.com/prometheus/prometheus/model/rulefmt"
8
"github.com/stretchr/testify/require"
9
)
10
11
func parseRuleGroups(t *testing.T, buf []byte) []rulefmt.RuleGroup {
12
t.Helper()
13
14
groups, errs := rulefmt.Parse(buf)
15
require.Empty(t, errs)
16
17
return groups.Groups
18
}
19
20
func TestDiffRuleState(t *testing.T) {
21
ruleGroupsA := parseRuleGroups(t, []byte(`
22
groups:
23
- name: rule-group-a
24
interval: 1m
25
rules:
26
- record: rule_a
27
expr: 1
28
`))
29
30
ruleGroupsAModified := parseRuleGroups(t, []byte(`
31
groups:
32
- name: rule-group-a
33
interval: 1m
34
rules:
35
- record: rule_a
36
expr: 3
37
`))
38
39
managedNamespace := "agent/namespace/name/12345678-1234-1234-1234-123456789012"
40
41
type testCase struct {
42
name string
43
desired map[string][]rulefmt.RuleGroup
44
actual map[string][]rulefmt.RuleGroup
45
expected map[string][]ruleGroupDiff
46
}
47
48
testCases := []testCase{
49
{
50
name: "empty sets",
51
desired: map[string][]rulefmt.RuleGroup{},
52
actual: map[string][]rulefmt.RuleGroup{},
53
expected: map[string][]ruleGroupDiff{},
54
},
55
{
56
name: "add rule group",
57
desired: map[string][]rulefmt.RuleGroup{
58
managedNamespace: ruleGroupsA,
59
},
60
actual: map[string][]rulefmt.RuleGroup{},
61
expected: map[string][]ruleGroupDiff{
62
managedNamespace: {
63
{
64
Kind: ruleGroupDiffKindAdd,
65
Desired: ruleGroupsA[0],
66
},
67
},
68
},
69
},
70
{
71
name: "remove rule group",
72
desired: map[string][]rulefmt.RuleGroup{},
73
actual: map[string][]rulefmt.RuleGroup{
74
managedNamespace: ruleGroupsA,
75
},
76
expected: map[string][]ruleGroupDiff{
77
managedNamespace: {
78
{
79
Kind: ruleGroupDiffKindRemove,
80
Actual: ruleGroupsA[0],
81
},
82
},
83
},
84
},
85
{
86
name: "update rule group",
87
desired: map[string][]rulefmt.RuleGroup{
88
managedNamespace: ruleGroupsA,
89
},
90
actual: map[string][]rulefmt.RuleGroup{
91
managedNamespace: ruleGroupsAModified,
92
},
93
expected: map[string][]ruleGroupDiff{
94
managedNamespace: {
95
{
96
Kind: ruleGroupDiffKindUpdate,
97
Desired: ruleGroupsA[0],
98
Actual: ruleGroupsAModified[0],
99
},
100
},
101
},
102
},
103
{
104
name: "unchanged rule groups",
105
desired: map[string][]rulefmt.RuleGroup{
106
managedNamespace: ruleGroupsA,
107
},
108
actual: map[string][]rulefmt.RuleGroup{
109
managedNamespace: ruleGroupsA,
110
},
111
expected: map[string][]ruleGroupDiff{},
112
},
113
}
114
115
for _, tc := range testCases {
116
t.Run(tc.name, func(t *testing.T) {
117
actual := diffRuleState(tc.desired, tc.actual)
118
requireEqualRuleDiffs(t, tc.expected, actual)
119
})
120
}
121
}
122
123
func requireEqualRuleDiffs(t *testing.T, expected, actual map[string][]ruleGroupDiff) {
124
require.Equal(t, len(expected), len(actual))
125
126
var summarizeDiff = func(diff ruleGroupDiff) string {
127
switch diff.Kind {
128
case ruleGroupDiffKindAdd:
129
return fmt.Sprintf("add: %s", diff.Desired.Name)
130
case ruleGroupDiffKindRemove:
131
return fmt.Sprintf("remove: %s", diff.Actual.Name)
132
case ruleGroupDiffKindUpdate:
133
return fmt.Sprintf("update: %s", diff.Desired.Name)
134
}
135
panic("unreachable")
136
}
137
138
for namespace, expectedDiffs := range expected {
139
actualDiffs, ok := actual[namespace]
140
require.True(t, ok)
141
142
require.Equal(t, len(expectedDiffs), len(actualDiffs))
143
144
for i, expectedDiff := range expectedDiffs {
145
actualDiff := actualDiffs[i]
146
147
if expectedDiff.Kind != actualDiff.Kind ||
148
!equalRuleGroups(expectedDiff.Desired, actualDiff.Desired) ||
149
!equalRuleGroups(expectedDiff.Actual, actualDiff.Actual) {
150
151
t.Logf("expected diff: %s", summarizeDiff(expectedDiff))
152
t.Logf("actual diff: %s", summarizeDiff(actualDiff))
153
t.Fail()
154
}
155
}
156
}
157
}
158
159