Skip to content
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

[chore] [reveiver/prometheusreceiver] Add unit tests around protobuf negotiation #29153

Merged
57 changes: 47 additions & 10 deletions receiver/prometheusreceiver/metrics_receiver_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
package prometheusreceiver

import (
"bytes"
"context"
"encoding/binary"
"fmt"
"log"
"math"
Expand All @@ -17,9 +19,11 @@ import (
"time"

gokitlog "github.com/go-kit/log"
"github.com/gogo/protobuf/proto"
promcfg "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/model/value"
dto "github.com/prometheus/prometheus/prompb/io/prometheus/client"
"github.com/prometheus/prometheus/scrape"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -37,6 +41,9 @@ type mockPrometheusResponse struct {
code int
data string
useOpenMetrics bool

useProtoBuf bool // This overrides data and useOpenMetrics above
buf []byte
}

type mockPrometheus struct {
Expand Down Expand Up @@ -82,11 +89,18 @@ func (mp *mockPrometheus) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(404)
return
}
if pages[index].useOpenMetrics {
switch {
case pages[index].useProtoBuf:
rw.Header().Set("Content-Type", "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited")
krajorama marked this conversation as resolved.
Show resolved Hide resolved
case pages[index].useOpenMetrics:
rw.Header().Set("Content-Type", "application/openmetrics-text")
}
rw.WriteHeader(pages[index].code)
_, _ = rw.Write([]byte(pages[index].data))
if pages[index].useProtoBuf {
_, _ = rw.Write(pages[index].buf)
} else {
_, _ = rw.Write([]byte(pages[index].data))
}
}

func (mp *mockPrometheus) Close() {
Expand Down Expand Up @@ -563,10 +577,11 @@ func assertNormalNan() numberPointComparator {
}
}

func compareHistogram(count uint64, sum float64, buckets []uint64) histogramPointComparator {
func compareHistogram(count uint64, sum float64, upperBounds []float64, buckets []uint64) histogramPointComparator {
return func(t *testing.T, histogramDataPoint pmetric.HistogramDataPoint) {
assert.Equal(t, count, histogramDataPoint.Count(), "Histogram count value does not match")
assert.Equal(t, sum, histogramDataPoint.Sum(), "Histogram sum value does not match")
assert.Equal(t, upperBounds, histogramDataPoint.ExplicitBounds().AsRaw(), "Histogram upper bounds values do not match")
assert.Equal(t, buckets, histogramDataPoint.BucketCounts().AsRaw(), "Histogram bucket count values do not match")
}
}
Expand All @@ -593,7 +608,7 @@ func compareSummary(count uint64, sum float64, quantiles [][]float64) summaryPoi
}

// starts prometheus receiver with custom config, retrieves metrics from MetricsSink
func testComponent(t *testing.T, targets []*testData, useStartTimeMetric bool, trimMetricSuffixes bool, startTimeMetricRegex string, cfgMuts ...func(*promcfg.Config)) {
func testComponent(t *testing.T, targets []*testData, alterConfig func(*Config), cfgMuts ...func(*promcfg.Config)) {
ctx := context.Background()
mp, cfg, err := setupMockPrometheus(targets...)
for _, cfgMut := range cfgMuts {
Expand All @@ -602,13 +617,16 @@ func testComponent(t *testing.T, targets []*testData, useStartTimeMetric bool, t
require.Nilf(t, err, "Failed to create Prometheus config: %v", err)
defer mp.Close()

cms := new(consumertest.MetricsSink)
receiver := newPrometheusReceiver(receivertest.NewNopCreateSettings(), &Config{
config := &Config{
PrometheusConfig: cfg,
UseStartTimeMetric: useStartTimeMetric,
StartTimeMetricRegex: startTimeMetricRegex,
TrimMetricSuffixes: trimMetricSuffixes,
}, cms)
StartTimeMetricRegex: "",
}
if alterConfig != nil {
alterConfig(config)
}

cms := new(consumertest.MetricsSink)
receiver := newPrometheusReceiver(receivertest.NewNopCreateSettings(), config, cms)

require.NoError(t, receiver.Start(ctx, componenttest.NewNopHost()))
// verify state after shutdown is called
Expand Down Expand Up @@ -695,3 +713,22 @@ func getTS(ms pmetric.MetricSlice) pcommon.Timestamp {
}
return 0
}

func prometheusMetricFamilyToProtoBuf(t *testing.T, buffer *bytes.Buffer, metricFamily *dto.MetricFamily) *bytes.Buffer {
if buffer == nil {
buffer = &bytes.Buffer{}
}

data, err := proto.Marshal(metricFamily)
require.NoError(t, err)

varintBuf := make([]byte, binary.MaxVarintLen32)
varintLength := binary.PutUvarint(varintBuf, uint64(len(data)))

_, err = buffer.Write(varintBuf[:varintLength])
require.NoError(t, err)
_, err = buffer.Write(data)
require.NoError(t, err)

return buffer
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func TestHonorTimeStampsWithTrue(t *testing.T) {
},
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

// TestHonorTimeStampsWithFalse validates that with honor_timestamp config set to false,
Expand All @@ -168,7 +168,7 @@ func TestHonorTimeStampsWithFalse(t *testing.T) {
},
}

testComponent(t, targets, false, false, "", func(cfg *promcfg.Config) {
testComponent(t, targets, nil, func(cfg *promcfg.Config) {
for _, scrapeConfig := range cfg.ScrapeConfigs {
scrapeConfig.HonorTimestamps = false
}
Expand Down Expand Up @@ -246,7 +246,7 @@ func verifyHonorTimeStampsTrue(t *testing.T, td *testData, resourceMetrics []pme
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts4))),
compareHistogramTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts4))),
compareHistogram(2500, 5000, []uint64{1000, 500, 500, 500}),
compareHistogram(2500, 5000, []float64{0.05, 0.5, 1}, []uint64{1000, 500, 500, 500}),
},
},
}),
Expand Down Expand Up @@ -310,7 +310,7 @@ func verifyHonorTimeStampsTrue(t *testing.T, td *testData, resourceMetrics []pme
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts9))),
compareHistogramTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts9))),
compareHistogram(2400, 4950, []uint64{900, 500, 500, 500}),
compareHistogram(2400, 4950, []float64{0.05, 0.5, 1}, []uint64{900, 500, 500, 500}),
},
},
}),
Expand Down Expand Up @@ -374,7 +374,7 @@ func verifyHonorTimeStampsTrue(t *testing.T, td *testData, resourceMetrics []pme
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts9))),
compareHistogramTimestamp(pcommon.NewTimestampFromTime(time.UnixMilli(ts14))),
compareHistogram(2500, 5000, []uint64{1000, 500, 500, 500}),
compareHistogram(2500, 5000, []float64{0.05, 0.5, 1}, []uint64{1000, 500, 500, 500}),
},
},
}),
Expand Down Expand Up @@ -446,7 +446,7 @@ func verifyHonorTimeStampsFalse(t *testing.T, td *testData, resourceMetrics []pm
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(ts1),
compareHistogramTimestamp(ts1),
compareHistogram(2500, 5000, []uint64{1000, 500, 500, 500}),
compareHistogram(2500, 5000, []float64{0.05, 0.5, 1}, []uint64{1000, 500, 500, 500}),
},
},
}),
Expand Down Expand Up @@ -512,7 +512,7 @@ func verifyHonorTimeStampsFalse(t *testing.T, td *testData, resourceMetrics []pm
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(ts2),
compareHistogramTimestamp(ts2),
compareHistogram(2400, 4950, []uint64{900, 500, 500, 500}),
compareHistogram(2400, 4950, []float64{0.05, 0.5, 1}, []uint64{900, 500, 500, 500}),
},
},
}),
Expand Down
26 changes: 13 additions & 13 deletions receiver/prometheusreceiver/metrics_receiver_labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestExternalLabels(t *testing.T) {
},
}

testComponent(t, targets, false, false, "", func(cfg *promcfg.Config) {
testComponent(t, targets, nil, func(cfg *promcfg.Config) {
cfg.GlobalConfig.ExternalLabels = labels.FromStrings("key", "value")
})
}
Expand Down Expand Up @@ -121,7 +121,7 @@ func TestLabelLimitConfig(t *testing.T) {
},
}

testComponent(t, targets, false, false, "", func(cfg *promcfg.Config) {
testComponent(t, targets, nil, func(cfg *promcfg.Config) {
// set label limit in scrape_config
for _, scrapeCfg := range cfg.ScrapeConfigs {
scrapeCfg.LabelLimit = 5
Expand Down Expand Up @@ -198,7 +198,7 @@ func verifyLabelConfigTarget1(t *testing.T, td *testData, rms []pmetric.Resource
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(ts1),
compareHistogramTimestamp(ts1),
compareHistogram(2500, 5000, []uint64{1000, 500, 500, 500}),
compareHistogram(2500, 5000, []float64{0.1, 0.5, 1}, []uint64{1000, 500, 500, 500}),
compareHistogramAttributes(map[string]string{"label1": "value1", "label2": "value2"}),
},
},
Expand Down Expand Up @@ -248,7 +248,7 @@ func TestLabelNameLimitConfig(t *testing.T) {
},
}

testComponent(t, targets, false, false, "", func(cfg *promcfg.Config) {
testComponent(t, targets, nil, func(cfg *promcfg.Config) {
// set label limit in scrape_config
for _, scrapeCfg := range cfg.ScrapeConfigs {
scrapeCfg.LabelNameLengthLimit = 20
Expand Down Expand Up @@ -284,7 +284,7 @@ func TestLabelValueLimitConfig(t *testing.T) {
},
}

testComponent(t, targets, false, false, "", func(cfg *promcfg.Config) {
testComponent(t, targets, nil, func(cfg *promcfg.Config) {
// set label name limit in scrape_config
for _, scrapeCfg := range cfg.ScrapeConfigs {
scrapeCfg.LabelValueLengthLimit = 25
Expand Down Expand Up @@ -360,7 +360,7 @@ func verifyEmptyLabelValuesTarget1(t *testing.T, td *testData, rms []pmetric.Res
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(ts1),
compareHistogramTimestamp(ts1),
compareHistogram(2500, 5000, []uint64{1000, 500, 500, 500}),
compareHistogram(2500, 5000, []float64{0.1, 0.5, 1}, []uint64{1000, 500, 500, 500}),
compareHistogramAttributes(map[string]string{"id": "1"}),
},
},
Expand Down Expand Up @@ -462,7 +462,7 @@ func TestEmptyLabelValues(t *testing.T) {
validateFunc: verifyEmptyLabelValuesTarget2,
},
}
testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

const honorLabelsTarget = `
Expand Down Expand Up @@ -556,7 +556,7 @@ func TestEmptyLabels(t *testing.T) {
validateFunc: verifyEmptyLabelsTarget1,
},
}
testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func TestHonorLabelsFalseConfig(t *testing.T) {
Expand All @@ -570,7 +570,7 @@ func TestHonorLabelsFalseConfig(t *testing.T) {
},
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyHonorLabelsTrue(t *testing.T, td *testData, rms []pmetric.ResourceMetrics) {
Expand Down Expand Up @@ -613,7 +613,7 @@ func TestHonorLabelsTrueConfig(t *testing.T) {
},
}

testComponent(t, targets, false, false, "", func(cfg *promcfg.Config) {
testComponent(t, targets, nil, func(cfg *promcfg.Config) {
// set label name limit in scrape_config
for _, scrapeCfg := range cfg.ScrapeConfigs {
scrapeCfg.HonorLabels = true
Expand All @@ -639,7 +639,7 @@ func TestRelabelJobInstance(t *testing.T) {
},
}

testComponent(t, targets, false, false, "", func(cfg *promcfg.Config) {
testComponent(t, targets, nil, func(cfg *promcfg.Config) {
for _, scrapeConfig := range cfg.ScrapeConfigs {
scrapeConfig.MetricRelabelConfigs = []*relabel.Config{
{
Expand Down Expand Up @@ -709,7 +709,7 @@ func TestTargetInfoResourceAttributes(t *testing.T) {
},
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyTargetInfoResourceAttributes(t *testing.T, td *testData, rms []pmetric.ResourceMetrics) {
Expand Down Expand Up @@ -759,7 +759,7 @@ func TestScopeInfoScopeAttributes(t *testing.T) {
},
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyMultipleScopes(t *testing.T, td *testData, rms []pmetric.ResourceMetrics) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ func TestMetricNormalize(t *testing.T) {
},
}

testComponent(t, targets, false, true, "")
testComponent(t, targets, func(c *Config) {
c.TrimMetricSuffixes = true
})
}

func verifyNormalizeMetric(t *testing.T, td *testData, resourceMetrics []pmetric.ResourceMetrics) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestStaleNaNs(t *testing.T) {
validateScrapes: true,
},
}
testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyStaleNaNs(t *testing.T, td *testData, resourceMetrics []pmetric.ResourceMetrics) {
Expand Down Expand Up @@ -133,7 +133,7 @@ func verifyStaleNaNsSuccessfulScrape(t *testing.T, td *testData, resourceMetric
histogramPointComparator: []histogramPointComparator{
compareHistogramStartTimestamp(startTimestamp),
compareHistogramTimestamp(ts1),
compareHistogram(2500, 5000, []uint64{1000, 500, 500, 500}),
compareHistogram(2500, 5000, []float64{0.05, 0.5, 1}, []uint64{1000, 500, 500, 500}),
},
},
}),
Expand Down Expand Up @@ -252,7 +252,7 @@ func TestNormalNaNs(t *testing.T) {
validateFunc: verifyNormalNaNs,
},
}
testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyNormalNaNs(t *testing.T, td *testData, resourceMetrics []pmetric.ResourceMetrics) {
Expand Down Expand Up @@ -339,7 +339,7 @@ func TestInfValues(t *testing.T) {
validateFunc: verifyInfValues,
},
}
testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyInfValues(t *testing.T, td *testData, resourceMetrics []pmetric.ResourceMetrics) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func TestOpenMetricsPositive(t *testing.T) {
targets = append(targets, testData)
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyFailTarget(t *testing.T, td *testData, mds []pmetric.ResourceMetrics) {
Expand Down Expand Up @@ -107,7 +107,7 @@ func TestOpenMetricsFail(t *testing.T) {
targets = append(targets, testData)
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

func verifyInvalidTarget(t *testing.T, td *testData, mds []pmetric.ResourceMetrics) {
Expand Down Expand Up @@ -142,7 +142,7 @@ func TestOpenMetricsInvalid(t *testing.T) {
targets = append(targets, testData)
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)
}

// reads test data from testdata/openmetrics directory
Expand Down Expand Up @@ -228,7 +228,7 @@ func TestInfoStatesetMetrics(t *testing.T) {
},
}

testComponent(t, targets, false, false, "")
testComponent(t, targets, nil)

}

Expand Down
Loading