Skip to content

Commit 7284bc8

Browse files
krajoramaFiery-Fenix
authored andcommitted
[chore](prometheusreceiver): use type and unit as identifier in tests (open-telemetry#38645)
I'd like to fix a technical dept from open-telemetry#28663 where the Prometheus receiver didn't allow receiving both classic and native histogram for the same metric name. To test the implementation, the assertions must not assume that the metric name alone is identifying in OpenTelemetry. No new tests added, I just refactored to make name+type+unit the identifier. Also I made it implicit that `doCompare` fails on metrics that were not expected - excluding the 5 scrape metrics. This means that `assertMetricAbsent` is not needed anymore. Signed-off-by: György Krajcsovits <[email protected]>
1 parent 90dd575 commit 7284bc8

11 files changed

+1137
-645
lines changed

receiver/prometheusreceiver/metrics_receiver_helper_test.go

Lines changed: 131 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"net/http"
1414
"net/http/httptest"
1515
"net/url"
16+
"strings"
1617
"sync"
1718
"sync/atomic"
1819
"testing"
@@ -396,7 +397,6 @@ func isExtraScrapeMetrics(m pmetric.Metric) bool {
396397
}
397398

398399
type (
399-
metricTypeComparator func(*testing.T, pmetric.Metric)
400400
numberPointComparator func(*testing.T, pmetric.NumberDataPoint)
401401
histogramPointComparator func(*testing.T, pmetric.HistogramDataPoint)
402402
summaryPointComparator func(*testing.T, pmetric.SummaryDataPoint)
@@ -410,19 +410,30 @@ type dataPointExpectation struct {
410410
exponentialHistogramComparator []exponentialHistogramComparator
411411
}
412412

413-
type testExpectation func(*testing.T, pmetric.ResourceMetrics)
413+
type metricChecker func(*testing.T, pmetric.Metric)
414414

415-
func doCompare(t *testing.T, name string, want pcommon.Map, got pmetric.ResourceMetrics, expectations []testExpectation) {
416-
doCompareNormalized(t, name, want, got, expectations, false)
415+
type metricExpectation struct {
416+
name string
417+
mtype pmetric.MetricType
418+
munit string
419+
dataPointExpectations []dataPointExpectation
420+
extraExpectation metricChecker
417421
}
418422

419-
func doCompareNormalized(t *testing.T, name string, want pcommon.Map, got pmetric.ResourceMetrics, expectations []testExpectation, normalizedNames bool) {
423+
// doCompare is a helper function to compare the expected metrics with the actual metrics
424+
// name is the test name
425+
// want is the map of expected attributes
426+
// got is the actual metrics
427+
// metricExpections is the list of expected metrics, exluding the internal scrape metrics
428+
func doCompare(t *testing.T, name string, want pcommon.Map, got pmetric.ResourceMetrics, metricExpectations []metricExpectation) {
429+
doCompareNormalized(t, name, want, got, metricExpectations, false)
430+
}
431+
432+
func doCompareNormalized(t *testing.T, name string, want pcommon.Map, got pmetric.ResourceMetrics, metricExpectations []metricExpectation, normalizedNames bool) {
420433
t.Run(name, func(t *testing.T) {
421434
assert.Equal(t, expectedScrapeMetricCount, countScrapeMetricsRM(got, normalizedNames))
422435
assertExpectedAttributes(t, want, got)
423-
for _, e := range expectations {
424-
e(t, got)
425-
}
436+
assertExpectedMetrics(t, metricExpectations, got, normalizedNames, false)
426437
})
427438
}
428439

@@ -437,75 +448,154 @@ func assertExpectedAttributes(t *testing.T, want pcommon.Map, got pmetric.Resour
437448
}
438449
}
439450

440-
func assertMetricPresent(name string, metricTypeExpectations metricTypeComparator, metricUnitExpectations metricTypeComparator, dataPointExpectations []dataPointExpectation) testExpectation {
441-
return func(t *testing.T, rm pmetric.ResourceMetrics) {
442-
allMetrics := getMetrics(rm)
443-
var present bool
444-
for _, m := range allMetrics {
445-
if name != m.Name() {
451+
func assertExpectedMetrics(t *testing.T, metricExpectations []metricExpectation, got pmetric.ResourceMetrics, normalizedNames bool, existsOnly bool) {
452+
var defaultExpectations []metricExpectation
453+
switch {
454+
case existsOnly:
455+
case normalizedNames:
456+
defaultExpectations = []metricExpectation{
457+
{
458+
"scrape_duration",
459+
pmetric.MetricTypeGauge,
460+
"s",
461+
nil,
462+
nil,
463+
},
464+
{
465+
"scrape_samples_post_metric_relabeling",
466+
pmetric.MetricTypeGauge,
467+
"",
468+
nil,
469+
nil,
470+
},
471+
{
472+
"scrape_samples_scraped",
473+
pmetric.MetricTypeGauge,
474+
"",
475+
nil,
476+
nil,
477+
},
478+
{
479+
"scrape_series_added",
480+
pmetric.MetricTypeGauge,
481+
"",
482+
nil,
483+
nil,
484+
},
485+
{
486+
"up",
487+
pmetric.MetricTypeGauge,
488+
"",
489+
nil,
490+
nil,
491+
},
492+
}
493+
case !normalizedNames:
494+
defaultExpectations = []metricExpectation{
495+
{
496+
"scrape_duration_seconds",
497+
pmetric.MetricTypeGauge,
498+
"s",
499+
nil,
500+
nil,
501+
},
502+
{
503+
"scrape_samples_post_metric_relabeling",
504+
pmetric.MetricTypeGauge,
505+
"",
506+
nil,
507+
nil,
508+
},
509+
{
510+
"scrape_samples_scraped",
511+
pmetric.MetricTypeGauge,
512+
"",
513+
nil,
514+
nil,
515+
},
516+
{
517+
"scrape_series_added",
518+
pmetric.MetricTypeGauge,
519+
"",
520+
nil,
521+
nil,
522+
},
523+
{
524+
"up",
525+
pmetric.MetricTypeGauge,
526+
"",
527+
nil,
528+
nil,
529+
},
530+
}
531+
}
532+
533+
metricExpectations = append(defaultExpectations, metricExpectations...)
534+
535+
allMetrics := getMetrics(got)
536+
for _, me := range metricExpectations {
537+
id := fmt.Sprintf("name '%s' type '%s' unit '%s'", me.name, me.mtype.String(), me.munit)
538+
pos := -1
539+
for k, m := range allMetrics {
540+
if me.name != m.Name() || me.mtype != m.Type() || me.munit != m.Unit() {
446541
continue
447542
}
448543

449-
present = true
450-
metricTypeExpectations(t, m)
451-
metricUnitExpectations(t, m)
452-
for i, de := range dataPointExpectations {
544+
require.Equal(t, -1, pos, "metric %s is not unique", id)
545+
pos = k
546+
547+
for i, de := range me.dataPointExpectations {
453548
switch m.Type() {
454549
case pmetric.MetricTypeGauge:
455550
for _, npc := range de.numberPointComparator {
456-
require.Len(t, dataPointExpectations, m.Gauge().DataPoints().Len(), "Expected number of data-points in Gauge metric '%s' does not match to testdata", name)
551+
require.Len(t, me.dataPointExpectations, m.Gauge().DataPoints().Len(), "Expected number of data-points in Gauge metric '%s' does not match to testdata", id)
457552
npc(t, m.Gauge().DataPoints().At(i))
458553
}
459554
case pmetric.MetricTypeSum:
460555
for _, npc := range de.numberPointComparator {
461-
require.Len(t, dataPointExpectations, m.Sum().DataPoints().Len(), "Expected number of data-points in Sum metric '%s' does not match to testdata", name)
556+
require.Len(t, me.dataPointExpectations, m.Sum().DataPoints().Len(), "Expected number of data-points in Sum metric '%s' does not match to testdata", id)
462557
npc(t, m.Sum().DataPoints().At(i))
463558
}
464559
case pmetric.MetricTypeHistogram:
465560
for _, hpc := range de.histogramPointComparator {
466-
require.Len(t, dataPointExpectations, m.Histogram().DataPoints().Len(), "Expected number of data-points in Histogram metric '%s' does not match to testdata", name)
561+
require.Len(t, me.dataPointExpectations, m.Histogram().DataPoints().Len(), "Expected number of data-points in Histogram metric '%s' does not match to testdata", id)
467562
hpc(t, m.Histogram().DataPoints().At(i))
468563
}
469564
case pmetric.MetricTypeSummary:
470565
for _, spc := range de.summaryPointComparator {
471-
require.Len(t, dataPointExpectations, m.Summary().DataPoints().Len(), "Expected number of data-points in Summary metric '%s' does not match to testdata", name)
566+
require.Len(t, me.dataPointExpectations, m.Summary().DataPoints().Len(), "Expected number of data-points in Summary metric '%s' does not match to testdata", id)
472567
spc(t, m.Summary().DataPoints().At(i))
473568
}
474569
case pmetric.MetricTypeExponentialHistogram:
475570
for _, ehc := range de.exponentialHistogramComparator {
476-
require.Len(t, dataPointExpectations, m.ExponentialHistogram().DataPoints().Len(), "Expected number of data-points in Exponential Histogram metric '%s' does not match to testdata", name)
571+
require.Len(t, me.dataPointExpectations, m.ExponentialHistogram().DataPoints().Len(), "Expected number of data-points in Exponential Histogram metric '%s' does not match to testdata", id)
477572
ehc(t, m.ExponentialHistogram().DataPoints().At(i))
478573
}
479574
case pmetric.MetricTypeEmpty:
480575
}
481576
}
482-
}
483-
require.True(t, present, "expected metric '%s' is not present", name)
484-
}
485-
}
486577

487-
func assertMetricAbsent(name string) testExpectation {
488-
return func(t *testing.T, rm pmetric.ResourceMetrics) {
489-
allMetrics := getMetrics(rm)
490-
for _, m := range allMetrics {
491-
assert.NotEqual(t, name, m.Name(), "Metric is present, but was expected absent")
578+
if me.extraExpectation != nil {
579+
me.extraExpectation(t, m)
580+
}
492581
}
582+
require.GreaterOrEqual(t, pos, 0, "expected metric %s is not present", id)
583+
allMetrics = append(allMetrics[:pos], allMetrics[pos+1:]...)
493584
}
494-
}
495585

496-
func compareMetricType(typ pmetric.MetricType) metricTypeComparator {
497-
return func(t *testing.T, metric pmetric.Metric) {
498-
assert.Equal(t, typ.String(), metric.Type().String(), "Metric type does not match")
586+
if existsOnly {
587+
return
499588
}
500-
}
501589

502-
func compareMetricUnit(unit string) metricTypeComparator {
503-
return func(t *testing.T, metric pmetric.Metric) {
504-
assert.Equal(t, unit, metric.Unit(), "Metric unit does not match")
590+
remainingMetrics := []string{}
591+
for _, m := range allMetrics {
592+
remainingMetrics = append(remainingMetrics, fmt.Sprintf("%s(%s,%s)", m.Name(), m.Type().String(), m.Unit()))
505593
}
594+
595+
require.Empty(t, allMetrics, "not all metrics were validated: %v", strings.Join(remainingMetrics, ", "))
506596
}
507597

508-
func compareMetricIsMonotonic(isMonotonic bool) metricTypeComparator {
598+
func compareMetricIsMonotonic(isMonotonic bool) metricChecker {
509599
return func(t *testing.T, metric pmetric.Metric) {
510600
assert.Equal(t, pmetric.MetricTypeSum.String(), metric.Type().String(), "IsMonotonic only exists for sums")
511601
assert.Equal(t, isMonotonic, metric.Sum().IsMonotonic(), "IsMonotonic does not match")

0 commit comments

Comments
 (0)