Skip to content

Commit 7163ac9

Browse files
committed
testutil compareMetricFamilies: make less error-prone
The functions `GatherAndCompare`, `ScrapeAndCompare` and others that use `compareMetricFamilies` under the hood can return no error if `metricNames` includes none of the names found in the scraped/gathered results. To avoid false Positves (an error being the negative case), we can return an error if there is is at least one name in `metricNames` that is not in the filtered results. Fixes: #1351 Signed-off-by: leonnicolas <[email protected]>
1 parent 046e320 commit 7163ac9

File tree

2 files changed

+95
-46
lines changed

2 files changed

+95
-46
lines changed

prometheus/testutil/testutil.go

+3
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ func compareMetricFamilies(got, expected []*dto.MetricFamily, metricNames ...str
254254
if metricNames != nil {
255255
got = filterMetrics(got, metricNames)
256256
expected = filterMetrics(expected, metricNames)
257+
if len(metricNames) > len(got) {
258+
return fmt.Errorf("expected metrics name not found")
259+
}
257260
}
258261

259262
return compare(got, expected)

prometheus/testutil/testutil_test.go

+92-46
Original file line numberDiff line numberDiff line change
@@ -332,27 +332,46 @@ Diff:
332332
}
333333

334334
func TestScrapeAndCompare(t *testing.T) {
335-
const expected = `
335+
scenarios := map[string]struct {
336+
want string
337+
metricNames []string
338+
errPrefix string
339+
fail bool
340+
}{
341+
"empty metric Names": {
342+
want: `
336343
# HELP some_total A value that represents a counter.
337344
# TYPE some_total counter
338345
339346
some_total{ label1 = "value1" } 1
340-
`
347+
`,
348+
metricNames: []string{},
349+
},
350+
"one metric": {
351+
want: `
352+
# HELP some_total A value that represents a counter.
353+
# TYPE some_total counter
341354
342-
expectedReader := strings.NewReader(expected)
355+
some_total{ label1 = "value1" } 1
356+
`,
357+
metricNames: []string{"some_total"},
358+
},
359+
"multiple expected": {
360+
want: `
361+
# HELP some_total A value that represents a counter.
362+
# TYPE some_total counter
343363
344-
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
345-
fmt.Fprintln(w, expected)
346-
}))
347-
defer ts.Close()
364+
some_total{ label1 = "value1" } 1
348365
349-
if err := ScrapeAndCompare(ts.URL, expectedReader, "some_total"); err != nil {
350-
t.Errorf("unexpected scraping result:\n%s", err)
351-
}
352-
}
366+
# HELP some_total2 A value that represents a counter.
367+
# TYPE some_total2 counter
353368
354-
func TestScrapeAndCompareWithMultipleExpected(t *testing.T) {
355-
const expected = `
369+
some_total2{ label2 = "value2" } 1
370+
`,
371+
metricNames: []string{"some_total2"},
372+
},
373+
"expected metric name is not scraped": {
374+
want: `
356375
# HELP some_total A value that represents a counter.
357376
# TYPE some_total counter
358377
@@ -362,53 +381,80 @@ func TestScrapeAndCompareWithMultipleExpected(t *testing.T) {
362381
# TYPE some_total2 counter
363382
364383
some_total2{ label2 = "value2" } 1
365-
`
366-
367-
expectedReader := strings.NewReader(expected)
384+
`,
385+
metricNames: []string{"some_total3"},
386+
errPrefix: "expected metrics name not found",
387+
fail: true,
388+
},
389+
"one of multiple expected metric names is not scraped": {
390+
want: `
391+
# HELP some_total A value that represents a counter.
392+
# TYPE some_total counter
368393
369-
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
370-
fmt.Fprintln(w, expected)
371-
}))
372-
defer ts.Close()
394+
some_total{ label1 = "value1" } 1
373395
374-
if err := ScrapeAndCompare(ts.URL, expectedReader, "some_total2"); err != nil {
375-
t.Errorf("unexpected scraping result:\n%s", err)
376-
}
377-
}
396+
# HELP some_total2 A value that represents a counter.
397+
# TYPE some_total2 counter
378398
379-
func TestScrapeAndCompareFetchingFail(t *testing.T) {
380-
err := ScrapeAndCompare("some_url", strings.NewReader("some expectation"), "some_total")
381-
if err == nil {
382-
t.Errorf("expected an error but got nil")
399+
some_total2{ label2 = "value2" } 1
400+
`,
401+
metricNames: []string{"some_total1", "some_total3"},
402+
errPrefix: "expected metrics name not found",
403+
fail: true,
404+
},
383405
}
384-
if !strings.HasPrefix(err.Error(), "scraping metrics failed") {
385-
t.Errorf("unexpected error happened: %s", err)
406+
for name, scenario := range scenarios {
407+
t.Run(name, func(t *testing.T) {
408+
expectedReader := strings.NewReader(scenario.want)
409+
410+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
411+
fmt.Fprintln(w, scenario.want)
412+
}))
413+
defer ts.Close()
414+
if err := ScrapeAndCompare(ts.URL, expectedReader, scenario.metricNames...); err != nil {
415+
if !scenario.fail || !strings.HasPrefix(err.Error(), scenario.errPrefix) {
416+
t.Errorf("unexpected error happened: %s", err)
417+
}
418+
} else if scenario.fail {
419+
t.Errorf("expected an error but got nil")
420+
}
421+
})
386422
}
387-
}
388423

389-
func TestScrapeAndCompareBadStatusCode(t *testing.T) {
390-
const expected = `
424+
t.Run("fetching fail", func(t *testing.T) {
425+
err := ScrapeAndCompare("some_url", strings.NewReader("some expectation"), "some_total")
426+
if err == nil {
427+
t.Errorf("expected an error but got nil")
428+
}
429+
if !strings.HasPrefix(err.Error(), "scraping metrics failed") {
430+
t.Errorf("unexpected error happened: %s", err)
431+
}
432+
})
433+
434+
t.Run("bad status code", func(t *testing.T) {
435+
const expected = `
391436
# HELP some_total A value that represents a counter.
392437
# TYPE some_total counter
393438
394439
some_total{ label1 = "value1" } 1
395440
`
396441

397-
expectedReader := strings.NewReader(expected)
442+
expectedReader := strings.NewReader(expected)
398443

399-
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
400-
w.WriteHeader(http.StatusBadGateway)
401-
fmt.Fprintln(w, expected)
402-
}))
403-
defer ts.Close()
444+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
445+
w.WriteHeader(http.StatusBadGateway)
446+
fmt.Fprintln(w, expected)
447+
}))
448+
defer ts.Close()
404449

405-
err := ScrapeAndCompare(ts.URL, expectedReader, "some_total")
406-
if err == nil {
407-
t.Errorf("expected an error but got nil")
408-
}
409-
if !strings.HasPrefix(err.Error(), "the scraping target returned a status code other than 200") {
410-
t.Errorf("unexpected error happened: %s", err)
411-
}
450+
err := ScrapeAndCompare(ts.URL, expectedReader, "some_total")
451+
if err == nil {
452+
t.Errorf("expected an error but got nil")
453+
}
454+
if !strings.HasPrefix(err.Error(), "the scraping target returned a status code other than 200") {
455+
t.Errorf("unexpected error happened: %s", err)
456+
}
457+
})
412458
}
413459

414460
func TestCollectAndCount(t *testing.T) {

0 commit comments

Comments
 (0)