Skip to content

Commit 9e4fd0d

Browse files
dsabsayDaniel Sabsay
and
Daniel Sabsay
authored
Flaky rules test fix (#6549)
* Ignore evaluation-related fields in ruler API tests These tests were flaky: sometimes they get evaluated before the test issues the GET request, sometimes they do not. Signed-off-by: Daniel Sabsay <[email protected]> * fix comment Signed-off-by: Daniel Sabsay <[email protected]> --------- Signed-off-by: Daniel Sabsay <[email protected]> Co-authored-by: Daniel Sabsay <[email protected]>
1 parent c05fe0b commit 9e4fd0d

File tree

1 file changed

+154
-3
lines changed

1 file changed

+154
-3
lines changed

Diff for: pkg/ruler/api_test.go

+154-3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,147 @@ func TestAPIResponseSerialization(t *testing.T) {
106106
}
107107
}
108108

109+
func Test_stripEvaluationFields(t *testing.T) {
110+
input := `
111+
{
112+
"data": {
113+
"groups": [
114+
{
115+
"evaluationTime": 0.00119525,
116+
"file": ")(_+?/|namespace1+/?",
117+
"interval": 10,
118+
"lastEvaluation": "2025-01-24T12:04:26.440399-08:00",
119+
"limit": 0,
120+
"name": ")(_+?/|group1+/?",
121+
"rules": [
122+
{
123+
"evaluationTime": 0.000976083,
124+
"health": "ok",
125+
"labels": {},
126+
"lastError": "",
127+
"lastEvaluation": "2025-01-24T12:04:26.440437-08:00",
128+
"name": "UP_RULE",
129+
"query": "up",
130+
"type": "recording"
131+
},
132+
{
133+
"alerts": [],
134+
"annotations": {},
135+
"duration": 0,
136+
"evaluationTime": 0.000172375,
137+
"health": "ok",
138+
"keepFiringFor": 0,
139+
"labels": {},
140+
"lastError": "",
141+
"lastEvaluation": "2025-01-24T12:04:26.441418-08:00",
142+
"name": "UP_ALERT",
143+
"query": "up < 1",
144+
"state": "inactive",
145+
"type": "alerting"
146+
}
147+
]
148+
}
149+
]
150+
},
151+
"status": "success"
152+
}`
153+
inputResponse := util_api.Response{}
154+
err := json.Unmarshal([]byte(input), &inputResponse)
155+
require.NoError(t, err)
156+
stripEvaluationFields(t, inputResponse)
157+
output, err := json.Marshal(inputResponse)
158+
require.NoError(t, err)
159+
160+
expected := `
161+
{
162+
"data": {
163+
"groups": [
164+
{
165+
"evaluationTime": 0,
166+
"file": ")(_+?/|namespace1+/?",
167+
"interval": 10,
168+
"lastEvaluation": "0001-01-01T00:00:00Z",
169+
"limit": 0,
170+
"name": ")(_+?/|group1+/?",
171+
"rules": [
172+
{
173+
"evaluationTime": 0,
174+
"health": "unknown",
175+
"labels": {},
176+
"lastError": "",
177+
"lastEvaluation": "0001-01-01T00:00:00Z",
178+
"name": "UP_RULE",
179+
"query": "up",
180+
"type": "recording"
181+
},
182+
{
183+
"alerts": [],
184+
"annotations": {},
185+
"duration": 0,
186+
"evaluationTime": 0,
187+
"health": "unknown",
188+
"keepFiringFor": 0,
189+
"labels": {},
190+
"lastError": "",
191+
"lastEvaluation": "0001-01-01T00:00:00Z",
192+
"name": "UP_ALERT",
193+
"query": "up < 1",
194+
"state": "inactive",
195+
"type": "alerting"
196+
}
197+
]
198+
}
199+
]
200+
},
201+
"status": "success"
202+
}`
203+
204+
require.JSONEq(t, expected, string(output))
205+
}
206+
207+
// stripEvaluationFields sets evaluation-related fields of a rules API response to zero values.
208+
func stripEvaluationFields(t *testing.T, r util_api.Response) {
209+
dataMap, ok := r.Data.(map[string]interface{})
210+
if !ok {
211+
t.Fatalf("expected map[string]interface{} got %T", r.Data)
212+
}
213+
214+
groups, ok := dataMap["groups"].([]interface{})
215+
if !ok {
216+
t.Fatalf("expected []interface{} got %T", dataMap["groups"])
217+
}
218+
219+
for i := range groups {
220+
group, ok := groups[i].(map[string]interface{})
221+
if !ok {
222+
t.Fatalf("expected map[string]interface{} got %T", groups[i])
223+
}
224+
group["evaluationTime"] = 0
225+
group["lastEvaluation"] = "0001-01-01T00:00:00Z"
226+
227+
rules, ok := group["rules"].([]interface{})
228+
if !ok {
229+
t.Fatalf("expected []interface{} got %T", group["rules"])
230+
}
231+
232+
for i := range rules {
233+
rule, ok := rules[i].(map[string]interface{})
234+
if !ok {
235+
t.Fatalf("expected map[string]interface{} got %T", rules[i])
236+
}
237+
rule["health"] = "unknown"
238+
rule["evaluationTime"] = 0
239+
rule["lastEvaluation"] = "0001-01-01T00:00:00Z"
240+
rules[i] = rule
241+
}
242+
group["rules"] = rules
243+
groups[i] = group
244+
}
245+
246+
dataMap["groups"] = groups
247+
r.Data = dataMap
248+
}
249+
109250
func TestRuler_rules(t *testing.T) {
110251
store := newMockRuleStore(mockRules, nil)
111252
cfg := defaultRulerConfig(t)
@@ -128,6 +269,9 @@ func TestRuler_rules(t *testing.T) {
128269
require.NoError(t, err)
129270
require.Equal(t, http.StatusOK, resp.StatusCode)
130271
require.Equal(t, responseJSON.Status, "success")
272+
stripEvaluationFields(t, responseJSON)
273+
actual, err := json.Marshal(responseJSON)
274+
require.NoError(t, err)
131275

132276
// Testing the running rules for user1 in the mock store
133277
expectedResponse, _ := json.Marshal(util_api.Response{
@@ -159,7 +303,7 @@ func TestRuler_rules(t *testing.T) {
159303
},
160304
})
161305

162-
require.Equal(t, string(expectedResponse), string(body))
306+
require.JSONEq(t, string(expectedResponse), string(actual))
163307
}
164308

165309
func TestRuler_rules_special_characters(t *testing.T) {
@@ -184,6 +328,9 @@ func TestRuler_rules_special_characters(t *testing.T) {
184328
require.NoError(t, err)
185329
require.Equal(t, http.StatusOK, resp.StatusCode)
186330
require.Equal(t, responseJSON.Status, "success")
331+
stripEvaluationFields(t, responseJSON)
332+
actual, err := json.Marshal(responseJSON)
333+
require.NoError(t, err)
187334

188335
// Testing the running rules for user1 in the mock store
189336
expectedResponse, _ := json.Marshal(util_api.Response{
@@ -214,7 +361,7 @@ func TestRuler_rules_special_characters(t *testing.T) {
214361
},
215362
},
216363
})
217-
require.Equal(t, string(expectedResponse), string(body))
364+
require.JSONEq(t, string(expectedResponse), string(actual))
218365
}
219366

220367
func TestRuler_rules_limit(t *testing.T) {
@@ -238,6 +385,9 @@ func TestRuler_rules_limit(t *testing.T) {
238385
require.NoError(t, err)
239386
require.Equal(t, http.StatusOK, resp.StatusCode)
240387
require.Equal(t, responseJSON.Status, "success")
388+
stripEvaluationFields(t, responseJSON)
389+
actual, err := json.Marshal(responseJSON)
390+
require.NoError(t, err)
241391

242392
// Testing the running rules for user1 in the mock store
243393
expectedResponse, _ := json.Marshal(util_api.Response{
@@ -269,8 +419,9 @@ func TestRuler_rules_limit(t *testing.T) {
269419
},
270420
},
271421
})
272-
require.Equal(t, string(expectedResponse), string(body))
422+
require.JSONEq(t, string(expectedResponse), string(actual))
273423
}
424+
274425
func TestRuler_alerts(t *testing.T) {
275426
store := newMockRuleStore(mockRules, nil)
276427
cfg := defaultRulerConfig(t)

0 commit comments

Comments
 (0)