Skip to content

Commit 84828f3

Browse files
committed
integration: add test asserting that certain metrics have certain values
1 parent 6eb9826 commit 84828f3

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

integration/integration_test.go

+146
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,150 @@ func TestSMK6(t *testing.T) {
173173
}
174174
}
175175
})
176+
177+
t.Run("metrics have expected values", func(t *testing.T) {
178+
t.Parallel()
179+
180+
type testCase struct {
181+
name string
182+
metricName string // Metric name to assert.
183+
metricLabels map[string]string
184+
assertValue func(float64) bool
185+
}
186+
187+
for _, tc := range []testCase{
188+
// Some global metrics.
189+
{
190+
name: "Script duration seconds",
191+
metricName: "probe_script_duration_seconds",
192+
assertValue: nonZero,
193+
},
194+
{
195+
name: "Sent bytes",
196+
metricName: "probe_data_sent_bytes",
197+
assertValue: nonZero,
198+
},
199+
{
200+
name: "Received bytes",
201+
metricName: "probe_data_received_bytes",
202+
assertValue: nonZero,
203+
},
204+
// Check-related metrics.
205+
{
206+
name: "Passed checks metric",
207+
metricName: "probe_checks_total",
208+
metricLabels: map[string]string{"result": "pass"},
209+
assertValue: equals(1),
210+
},
211+
{
212+
name: "Failed checks metric",
213+
metricName: "probe_checks_total",
214+
metricLabels: map[string]string{"result": "fail"},
215+
assertValue: equals(2),
216+
},
217+
// Misc http metrics.
218+
{
219+
name: "HTTP duration second has a duration-ish value",
220+
metricName: "probe_http_duration_seconds",
221+
metricLabels: map[string]string{"phase": "processing", "url": "https://test-api.k6.io/public/crocodiles/"},
222+
assertValue: nonZero,
223+
},
224+
{
225+
name: "HTTP duration seconds has custom 'resolve' phase",
226+
metricName: "probe_http_duration_seconds",
227+
metricLabels: map[string]string{"phase": "resolve", "url": "https://test-api.k6.io/public/crocodiles/"},
228+
assertValue: any, // Just fail if not present.
229+
},
230+
{
231+
name: "Error code for request that should succeed",
232+
metricName: "probe_http_error_code",
233+
metricLabels: map[string]string{"url": "https://test-api.k6.io/public/crocodiles/"},
234+
assertValue: equals(0),
235+
},
236+
{
237+
name: "Error code for request that should fail",
238+
metricName: "probe_http_error_code",
239+
metricLabels: map[string]string{"url": "http://fail.internal/public/crocodiles4/"},
240+
assertValue: equals(1101),
241+
},
242+
{
243+
name: "HTTP status code for a request that should succeed",
244+
metricName: "probe_http_status_code",
245+
metricLabels: map[string]string{"url": "https://test-api.k6.io/public/crocodiles/"},
246+
assertValue: equals(200),
247+
},
248+
{
249+
name: "Expected response for a request that should succeed",
250+
metricName: "probe_http_got_expected_response",
251+
metricLabels: map[string]string{"url": "https://test-api.k6.io/public/crocodiles/"},
252+
assertValue: equals(1),
253+
},
254+
{
255+
name: "Expected response for a request that should fail",
256+
metricName: "probe_http_got_expected_response",
257+
metricLabels: map[string]string{"url": "https://test-api.k6.io/public/crocodiles2/"},
258+
assertValue: equals(0),
259+
},
260+
{
261+
name: "Total requests for each url",
262+
metricName: "probe_http_requests_total",
263+
assertValue: equals(1),
264+
},
265+
{
266+
name: "HTTP version",
267+
metricName: "probe_http_version",
268+
metricLabels: map[string]string{"url": "https://test-api.k6.io/public/crocodiles/"},
269+
assertValue: func(f float64) bool { return f >= 1.1 },
270+
},
271+
} {
272+
tc := tc
273+
t.Run(tc.name, func(t *testing.T) {
274+
matchedMetrics := 0
275+
for _, mf := range mfs {
276+
if *mf.Name != tc.metricName {
277+
// This is not the metric we are asserting on
278+
continue
279+
}
280+
281+
metric:
282+
for _, m := range mf.Metric {
283+
for _, labelPair := range m.Label {
284+
// Check each label of this particular metric against the test case labels.
285+
// If the metric has a label we're not matching for, that's okay, but it we are matching
286+
// it then the value should match as well.
287+
if actual, present := tc.metricLabels[*labelPair.Name]; present && actual != *labelPair.Value {
288+
continue metric
289+
}
290+
}
291+
292+
matchedMetrics++
293+
// Hack. Instead of check which type this metric has, and then use that one, rely on GetValue
294+
// that does this check for us and return 0 if the type is not correct.
295+
metricValue := m.Gauge.GetValue() + m.Counter.GetValue() + m.Untyped.GetValue()
296+
if !tc.assertValue(metricValue) {
297+
t.Fatalf("Metric value for %q got unexpected value %v (did not satisfy assert function)", *mf.Name, metricValue)
298+
}
299+
}
300+
}
301+
302+
if matchedMetrics == 0 {
303+
t.Fatalf("Test case for %q with specified labels matched no metric in extension output", tc.metricName)
304+
}
305+
})
306+
}
307+
})
308+
}
309+
310+
func equals(expected float64) func(float64) bool {
311+
return func(v float64) bool {
312+
return v == expected
313+
}
314+
}
315+
316+
func nonZero(v float64) bool {
317+
return v > 0
318+
}
319+
320+
func any(float64) bool {
321+
return true
176322
}

0 commit comments

Comments
 (0)