New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
testutil compareMetricFamilies: make less error-prone #1424
base: main
Are you sure you want to change the base?
testutil compareMetricFamilies: make less error-prone #1424
Conversation
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: prometheus#1351 Signed-off-by: leonnicolas <leonloechner@gmx.de>
0381a25
to
7163ac9
Compare
@@ -254,6 +254,9 @@ func compareMetricFamilies(got, expected []*dto.MetricFamily, metricNames ...str | |||
if metricNames != nil { | |||
got = filterMetrics(got, metricNames) | |||
expected = filterMetrics(expected, metricNames) | |||
if len(metricNames) > len(got) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking to use something like slices, to find the metricName that is not present in got
. Would the additional package (slices is not yet in the std lib in go 1.19) and extra complexity of this function be outweighed by the improved usability? You would be able to see the misspelled or missing metricName in the error text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I would either wait for older versions than 1.19 to be dropped from support or quickly write a small function finding those. I don't think at the end using std lib slices
extension is that needed. It might be just two loops. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a commit. Finding the difference in 2 slices seems so easy but always requires so much code.
I added the "resulting" slice to the error with %v
. I wonder if we should somehow allow callers of compareMetricFamilies
to extract the missing metric Names? I guess that would require an API change :(
It is just awkward to test if the "correct" metric names are in the error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any feedback @bwplotka ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why exact metric names would be useful? Isn't it enough to return error?
compareMetricFamilies
has a clear semantics - we are just ensuring the error is more readable and comparison true.
I think small code complexity is fine here - proposed below what can be done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why exact metric names would be useful? Isn't it enough to return error?
right, error should be enough
In to see which metric names are missing, we can add them to the error message. Signed-off-by: leonnicolas <leonloechner@gmx.de>
276aea0
to
d4090e9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, added suggestions, otherwise LGTM!
prometheus/testutil/testutil.go
Outdated
if len(metricNames) > len(got) { | ||
h := make(map[string]struct{}) | ||
for _, mf := range got { | ||
if mf == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got
element can be really nil here?
@@ -254,6 +254,9 @@ func compareMetricFamilies(got, expected []*dto.MetricFamily, metricNames ...str | |||
if metricNames != nil { | |||
got = filterMetrics(got, metricNames) | |||
expected = filterMetrics(expected, metricNames) | |||
if len(metricNames) > len(got) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why exact metric names would be useful? Isn't it enough to return error?
compareMetricFamilies
has a clear semantics - we are just ensuring the error is more readable and comparison true.
I think small code complexity is fine here - proposed below what can be done.
@@ -332,27 +332,46 @@ Diff: | |||
} | |||
|
|||
func TestScrapeAndCompare(t *testing.T) { | |||
const expected = ` | |||
scenarios := map[string]struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice!
6085d5d
to
847a7bb
Compare
- remove if nil check - use two nested loops instead of map - use new function `hasMetricByName` for readability Co-authored-by: Bartlomiej Plotka <bwplotka@gmail.com> Signed-off-by: leonnicolas <60091705+leonnicolas@users.noreply.github.com>
847a7bb
to
437f988
Compare
@bwplotka thanks for your review. I hope I addressed all you comments |
@bwplotka anything missing from my side to move on with this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looks nice, just one comment, otherwise LGTM
// expectedErrPrefix if empty, means no fail is expected for the comparison. | ||
expectedErrPrefix string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why prefix and not exact error? Would be nice to test that missing metric semantics.
The functions
GatherAndCompare
,ScrapeAndCompare
and others that usecompareMetricFamilies
under the hood can return no error ifmetricNames
includes none of the names found in the scraped/gatheredresults. 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 leonloechner@gmx.de