From c8e3dce8be7d75d41952296d70085c44bfb3e137 Mon Sep 17 00:00:00 2001 From: Federico Torres Date: Thu, 6 Jun 2024 13:40:34 -0300 Subject: [PATCH] datadog-receiver: improve/add unit tests (#59) * Add output verification to TestDatadogMetricsV1_EndToEnd Signed-off-by: Federico Torres * Add output verification to TestDatadogMetricsV2_EndToEnd Signed-off-by: Federico Torres * Add output verification to TestDatadogSketches_EndToEnd Signed-off-by: Federico Torres * Add output verification to TestDatadogServices_EndToEnd Signed-off-by: Federico Torres * fmt Signed-off-by: Federico Torres * Refactor output verifications in E2E receiver tests Signed-off-by: Federico Torres * Add TestConvertBucketLayout Signed-off-by: Federico Torres * Add TestMapSketchBucketsToHistogramBuckets Signed-off-by: Federico Torres --------- Signed-off-by: Federico Torres --- .../internal/translator/sketches_test.go | 125 ++++++++++++++++++ receiver/datadogreceiver/receiver_test.go | 26 +++- 2 files changed, 149 insertions(+), 2 deletions(-) diff --git a/receiver/datadogreceiver/internal/translator/sketches_test.go b/receiver/datadogreceiver/internal/translator/sketches_test.go index 3e68cd7465ca..0f0af1d5efdd 100644 --- a/receiver/datadogreceiver/internal/translator/sketches_test.go +++ b/receiver/datadogreceiver/internal/translator/sketches_test.go @@ -455,3 +455,128 @@ func TestSketchTemporality(t *testing.T) { }) } } + +func TestConvertBucketLayout(t *testing.T) { + tests := []struct { + name string + inputBuckets map[int]uint64 + expectedOffset int32 + expectedBucketCountsLen int + expectedBucketCounts map[int]uint64 + }{ + { + name: "Empty input buckets", + inputBuckets: map[int]uint64{}, + expectedOffset: 0, + expectedBucketCountsLen: 0, + expectedBucketCounts: map[int]uint64{}, + }, + { + name: "Non-empty input buckets and no offset", + inputBuckets: map[int]uint64{5: 75, 64: 33, 83: 239, 0: 152, 32: 231, 50: 24, 51: 73, 63: 22, 74: 79, 75: 22, 90: 66}, + expectedOffset: 0, + expectedBucketCountsLen: 91, + expectedBucketCounts: map[int]uint64{0: 152, 5: 75, 32: 231, 50: 24, 51: 73, 63: 22, 64: 33, 74: 79, 75: 22, 83: 239, 90: 66}, + }, + { + name: "Non-empty input buckets with offset", + inputBuckets: map[int]uint64{5: 75, 64: 33, 83: 239, 32: 231, 50: 24, 51: 73, 63: 22, 74: 79, 75: 22, 90: 66}, + expectedOffset: 5, + expectedBucketCountsLen: 86, + expectedBucketCounts: map[int]uint64{0: 75, 27: 231, 45: 24, 46: 73, 58: 22, 59: 33, 69: 79, 70: 22, 78: 239, 85: 66}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + outputBuckets := pmetric.NewExponentialHistogramDataPointBuckets() + + convertBucketLayout(tt.inputBuckets, outputBuckets) + + require.Equal(t, tt.expectedOffset, outputBuckets.Offset()) + require.Equal(t, tt.expectedBucketCountsLen, outputBuckets.BucketCounts().Len()) + + for k, v := range outputBuckets.BucketCounts().AsRaw() { + require.Equal(t, tt.expectedBucketCounts[k], v) + } + }) + } +} + +func TestMapSketchBucketsToHistogramBuckets(t *testing.T) { + tests := []struct { + name string + sketchKeys []int32 + sketchCounts []uint32 + expectedNegativeBuckets map[int]uint64 + expectedPositiveBuckets map[int]uint64 + expectedZeroCount uint64 + }{ + { + name: "Empty sketch buckets", + sketchKeys: []int32{}, + sketchCounts: []uint32{}, + expectedNegativeBuckets: map[int]uint64{}, + expectedPositiveBuckets: map[int]uint64{}, + expectedZeroCount: 0, + }, + { + name: "Only positive buckets and no zero bucket", + sketchKeys: []int32{1338, 1345, 1383, 1409, 1427, 1442, 1454, 1464}, + sketchCounts: []uint32{152, 75, 231, 97, 55, 101, 239, 66}, + expectedNegativeBuckets: map[int]uint64{}, + expectedPositiveBuckets: map[int]uint64{0: 152, 5: 75, 32: 231, 50: 24, 51: 73, 63: 22, 64: 33, 74: 79, 75: 22, 83: 239, 90: 66}, + expectedZeroCount: 0, + }, + { + name: "Only negative buckets and no zero bucket", + sketchKeys: []int32{-1464, -1454, -1442, -1427, -1409, -1383, -1338}, + sketchCounts: []uint32{152, 231, 97, 55, 101, 239, 66}, + expectedNegativeBuckets: map[int]uint64{0: 66, 32: 239, 50: 25, 51: 76, 63: 22, 64: 33, 74: 76, 75: 21, 83: 231, 90: 152}, + expectedPositiveBuckets: map[int]uint64{}, + expectedZeroCount: 0, + }, + { + name: "Negative and positive buckets and no zero bucket", + sketchKeys: []int32{-1464, -1454, -1442, -1427, -1409, -1383, -1338, 1338, 1383, 1409, 1427, 1442, 1454, 1464}, + sketchCounts: []uint32{152, 231, 97, 55, 101, 239, 66, 43, 99, 123, 62, 194, 251, 239}, + expectedNegativeBuckets: map[int]uint64{0: 66, 32: 239, 50: 25, 51: 76, 63: 22, 64: 33, 74: 76, 75: 21, 83: 231, 90: 152}, + expectedPositiveBuckets: map[int]uint64{0: 43, 32: 99, 50: 30, 51: 93, 63: 25, 64: 37, 74: 152, 75: 42, 83: 251, 90: 239}, + expectedZeroCount: 0, + }, + { + name: "Only positive buckets and zero bucket", + sketchKeys: []int32{0, 1338, 1383, 1409, 1427, 1442, 1454, 1464}, + sketchCounts: []uint32{13, 152, 231, 97, 55, 101, 239, 66}, + expectedNegativeBuckets: map[int]uint64{}, + expectedPositiveBuckets: map[int]uint64{0: 152, 32: 231, 50: 24, 51: 73, 63: 22, 64: 33, 74: 79, 75: 22, 83: 239, 90: 66}, + expectedZeroCount: 13, + }, + { + name: "Only negative buckets and zero bucket", + sketchKeys: []int32{-1464, -1454, -1442, -1427, -1409, -1383, -1338, 0}, + sketchCounts: []uint32{152, 231, 97, 55, 101, 239, 66, 13}, + expectedNegativeBuckets: map[int]uint64{0: 66, 32: 239, 50: 25, 51: 76, 63: 22, 64: 33, 74: 76, 75: 21, 83: 231, 90: 152}, + expectedPositiveBuckets: map[int]uint64{}, + expectedZeroCount: 13, + }, + { + name: "Negative and positive buckets and zero bucket", + sketchKeys: []int32{-1464, -1454, -1442, -1427, -1409, -1383, -1338, 0, 1338, 1383, 1409, 1427, 1442, 1454, 1464}, + sketchCounts: []uint32{152, 231, 97, 55, 101, 239, 66, 12, 43, 99, 123, 62, 194, 251, 239}, + expectedNegativeBuckets: map[int]uint64{0: 66, 32: 239, 50: 25, 51: 76, 63: 22, 64: 33, 74: 76, 75: 21, 83: 231, 90: 152}, + expectedPositiveBuckets: map[int]uint64{0: 43, 32: 99, 50: 30, 51: 93, 63: 25, 64: 37, 74: 152, 75: 42, 83: 251, 90: 239}, + expectedZeroCount: 12, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + negativeBuckets, positiveBuckets, zeroCount := mapSketchBucketsToHistogramBuckets(tt.sketchKeys, tt.sketchCounts) + + require.Equal(t, tt.expectedNegativeBuckets, negativeBuckets) + require.Equal(t, tt.expectedPositiveBuckets, positiveBuckets) + require.Equal(t, tt.expectedZeroCount, zeroCount) + }) + } +} diff --git a/receiver/datadogreceiver/receiver_test.go b/receiver/datadogreceiver/receiver_test.go index c124ef2253b0..b1e960c5bcae 100644 --- a/receiver/datadogreceiver/receiver_test.go +++ b/receiver/datadogreceiver/receiver_test.go @@ -13,6 +13,8 @@ import ( "strings" "testing" + "go.opentelemetry.io/collector/pdata/pcommon" + "github.com/DataDog/agent-payload/v5/gogen" pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" "github.com/stretchr/testify/assert" @@ -20,7 +22,6 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/consumer/consumertest" - "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver/receivertest" "go.uber.org/multierr" @@ -448,8 +449,10 @@ func TestDatadogSketches_EndToEnd(t *testing.T) { resp, err := http.DefaultClient.Do(req) require.NoError(t, err, "Must not error performing request") - _, err = io.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, multierr.Combine(err, resp.Body.Close()), "Must not error when reading body") + require.Equal(t, string(body), "OK", "Expected response to be 'OK', got %s", string(body)) + require.Equal(t, http.StatusAccepted, resp.StatusCode) mds := sink.AllMetrics() require.Len(t, mds, 1) @@ -459,6 +462,25 @@ func TestDatadogSketches_EndToEnd(t *testing.T) { assert.Equal(t, 1, metrics.Len()) metric := metrics.At(0) assert.Equal(t, pmetric.MetricTypeExponentialHistogram, metric.Type()) + assert.Equal(t, "Test1", metric.Name()) + assert.Equal(t, pmetric.AggregationTemporalityDelta, metric.ExponentialHistogram().AggregationTemporality()) + assert.Equal(t, pcommon.Timestamp(400*1_000_000_000), metric.ExponentialHistogram().DataPoints().At(0).Timestamp()) + assert.Equal(t, uint64(13), metric.ExponentialHistogram().DataPoints().At(0).Count()) + assert.Equal(t, 11.0, metric.ExponentialHistogram().DataPoints().At(0).Sum()) + assert.Equal(t, -6.0, metric.ExponentialHistogram().DataPoints().At(0).Min()) + assert.Equal(t, 6.0, metric.ExponentialHistogram().DataPoints().At(0).Max()) + assert.Equal(t, int32(5), metric.ExponentialHistogram().DataPoints().At(0).Scale()) + assert.Equal(t, uint64(55), metric.ExponentialHistogram().DataPoints().At(0).ZeroCount()) + assert.Equal(t, 91, metric.ExponentialHistogram().DataPoints().At(0).Positive().BucketCounts().Len()) + expectedPositiveInputBuckets := map[int]uint64{64: 26, 74: 131, 75: 36, 0: 101, 32: 239, 50: 16, 51: 50, 63: 17, 83: 209, 90: 154} + for k, v := range metric.ExponentialHistogram().DataPoints().At(0).Positive().BucketCounts().AsRaw() { + assert.Equal(t, expectedPositiveInputBuckets[k], v) + } + assert.Equal(t, 76, metric.ExponentialHistogram().DataPoints().At(0).Negative().BucketCounts().Len()) + expectedNegativeInputBuckets := map[int]uint64{74: 119, 75: 33, 63: 51, 64: 73, 50: 17, 51: 51, 32: 231, 0: 97} + for k, v := range metric.ExponentialHistogram().DataPoints().At(0).Negative().BucketCounts().AsRaw() { + assert.Equal(t, expectedNegativeInputBuckets[k], v) + } } func TestStats_EndToEnd(t *testing.T) {