Skip to content

Commit

Permalink
Test metric aggregate times (#5323)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAlias committed May 9, 2024
1 parent d0068d0 commit 9e7d744
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 117 deletions.
40 changes: 32 additions & 8 deletions sdk/metric/internal/aggregate/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggreg
import (
"context"
"strconv"
"sync/atomic"
"testing"
"time"

Expand Down Expand Up @@ -39,16 +40,39 @@ var (
fltrBob = attribute.NewSet(userBob)

// Sat Jan 01 2000 00:00:00 GMT+0000.
staticTime = time.Unix(946684800, 0)
staticNowFunc = func() time.Time { return staticTime }
// Pass to t.Cleanup to override the now function with staticNowFunc and
// revert once the test completes. E.g. t.Cleanup(mockTime(now)).
mockTime = func(orig func() time.Time) (cleanup func()) {
now = staticNowFunc
return func() { now = orig }
}
y2k = time.Unix(946684800, 0)
)

// y2kPlus returns the timestamp at n seconds past Sat Jan 01 2000 00:00:00 GMT+0000.
func y2kPlus(n int64) time.Time {
d := time.Duration(n) * time.Second
return y2k.Add(d)
}

// clock is a test clock. It provides a predictable value for now() that can be
// reset.
type clock struct {
ticks atomic.Int64
}

// Now returns the mocked time starting at y2kPlus(0). Each call to Now will
// increment the returned value by one second.
func (c *clock) Now() time.Time {
old := c.ticks.Add(1) - 1
return y2kPlus(old)
}

// Reset resets the clock c to tick from y2kPlus(0).
func (c *clock) Reset() { c.ticks.Store(0) }

// Register registers clock c's Now method as the now var. It returns an
// unregister func that should be called to restore the original now value.
func (c *clock) Register() (unregister func()) {
orig := now
now = c.Now
return func() { now = orig }
}

func dropExemplars[N int64 | float64]() exemplar.Reservoir {
return exemplar.Drop()
}
Expand Down
41 changes: 24 additions & 17 deletions sdk/metric/internal/aggregate/exponential_histogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,11 +727,18 @@ func TestSubNormal(t *testing.T) {
}

func TestExponentialHistogramAggregation(t *testing.T) {
t.Cleanup(mockTime(now))
c := new(clock)
t.Cleanup(c.Register())

t.Run("Int64/Delta", testDeltaExpoHist[int64]())
c.Reset()

t.Run("Float64/Delta", testDeltaExpoHist[float64]())
c.Reset()

t.Run("Int64/Cumulative", testCumulativeExpoHist[int64]())
c.Reset()

t.Run("Float64/Cumulative", testCumulativeExpoHist[float64]())
}

Expand Down Expand Up @@ -770,8 +777,8 @@ func testDeltaExpoHist[N int64 | float64]() func(t *testing.T) {
DataPoints: []metricdata.ExponentialHistogramDataPoint[N]{
{
Attributes: fltrAlice,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(1),
Time: y2kPlus(9),
Count: 7,
Min: metricdata.NewExtrema[N](-1),
Max: metricdata.NewExtrema[N](16),
Expand Down Expand Up @@ -825,8 +832,8 @@ func testDeltaExpoHist[N int64 | float64]() func(t *testing.T) {
DataPoints: []metricdata.ExponentialHistogramDataPoint[N]{
{
Attributes: fltrAlice,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(10),
Time: y2kPlus(24),
Count: 7,
Min: metricdata.NewExtrema[N](-1),
Max: metricdata.NewExtrema[N](16),
Expand All @@ -843,8 +850,8 @@ func testDeltaExpoHist[N int64 | float64]() func(t *testing.T) {
},
{
Attributes: overflowSet,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(10),
Time: y2kPlus(24),
Count: 6,
Min: metricdata.NewExtrema[N](1),
Max: metricdata.NewExtrema[N](16),
Expand Down Expand Up @@ -897,8 +904,8 @@ func testCumulativeExpoHist[N int64 | float64]() func(t *testing.T) {
DataPoints: []metricdata.ExponentialHistogramDataPoint[N]{
{
Attributes: fltrAlice,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(0),
Time: y2kPlus(9),
Count: 7,
Min: metricdata.NewExtrema[N](-1),
Max: metricdata.NewExtrema[N](16),
Expand Down Expand Up @@ -930,8 +937,8 @@ func testCumulativeExpoHist[N int64 | float64]() func(t *testing.T) {
DataPoints: []metricdata.ExponentialHistogramDataPoint[N]{
{
Attributes: fltrAlice,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(0),
Time: y2kPlus(13),
Count: 10,
Min: metricdata.NewExtrema[N](-1),
Max: metricdata.NewExtrema[N](16),
Expand Down Expand Up @@ -959,8 +966,8 @@ func testCumulativeExpoHist[N int64 | float64]() func(t *testing.T) {
DataPoints: []metricdata.ExponentialHistogramDataPoint[N]{
{
Attributes: fltrAlice,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(0),
Time: y2kPlus(14),
Count: 10,
Min: metricdata.NewExtrema[N](-1),
Max: metricdata.NewExtrema[N](16),
Expand Down Expand Up @@ -996,8 +1003,8 @@ func testCumulativeExpoHist[N int64 | float64]() func(t *testing.T) {
DataPoints: []metricdata.ExponentialHistogramDataPoint[N]{
{
Attributes: fltrAlice,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(0),
Time: y2kPlus(21),
Count: 10,
Min: metricdata.NewExtrema[N](-1),
Max: metricdata.NewExtrema[N](16),
Expand All @@ -1014,8 +1021,8 @@ func testCumulativeExpoHist[N int64 | float64]() func(t *testing.T) {
},
{
Attributes: overflowSet,
StartTime: staticTime,
Time: staticTime,
StartTime: y2kPlus(0),
Time: y2kPlus(21),
Count: 6,
Min: metricdata.NewExtrema[N](1),
Max: metricdata.NewExtrema[N](16),
Expand Down
65 changes: 38 additions & 27 deletions sdk/metric/internal/aggregate/histogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"sort"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -22,22 +23,30 @@ var (
)

func TestHistogram(t *testing.T) {
t.Cleanup(mockTime(now))
c := new(clock)
t.Cleanup(c.Register())

t.Run("Int64/Delta/Sum", testDeltaHist[int64](conf[int64]{hPt: hPointSummed[int64]}))
c.Reset()
t.Run("Int64/Delta/NoSum", testDeltaHist[int64](conf[int64]{noSum: true, hPt: hPoint[int64]}))
c.Reset()
t.Run("Float64/Delta/Sum", testDeltaHist[float64](conf[float64]{hPt: hPointSummed[float64]}))
c.Reset()
t.Run("Float64/Delta/NoSum", testDeltaHist[float64](conf[float64]{noSum: true, hPt: hPoint[float64]}))
c.Reset()

t.Run("Int64/Cumulative/Sum", testCumulativeHist[int64](conf[int64]{hPt: hPointSummed[int64]}))
c.Reset()
t.Run("Int64/Cumulative/NoSum", testCumulativeHist[int64](conf[int64]{noSum: true, hPt: hPoint[int64]}))
c.Reset()
t.Run("Float64/Cumulative/Sum", testCumulativeHist[float64](conf[float64]{hPt: hPointSummed[float64]}))
c.Reset()
t.Run("Float64/Cumulative/NoSum", testCumulativeHist[float64](conf[float64]{noSum: true, hPt: hPoint[float64]}))
}

type conf[N int64 | float64] struct {
noSum bool
hPt func(attribute.Set, N, uint64) metricdata.HistogramDataPoint[N]
hPt func(attribute.Set, N, uint64, time.Time, time.Time) metricdata.HistogramDataPoint[N]
}

func testDeltaHist[N int64 | float64](c conf[N]) func(t *testing.T) {
Expand Down Expand Up @@ -71,8 +80,8 @@ func testDeltaHist[N int64 | float64](c conf[N]) func(t *testing.T) {
agg: metricdata.Histogram[N]{
Temporality: metricdata.DeltaTemporality,
DataPoints: []metricdata.HistogramDataPoint[N]{
c.hPt(fltrAlice, 2, 3),
c.hPt(fltrBob, 10, 2),
c.hPt(fltrAlice, 2, 3, y2kPlus(1), y2kPlus(7)),
c.hPt(fltrBob, 10, 2, y2kPlus(1), y2kPlus(7)),
},
},
},
Expand All @@ -87,8 +96,8 @@ func testDeltaHist[N int64 | float64](c conf[N]) func(t *testing.T) {
agg: metricdata.Histogram[N]{
Temporality: metricdata.DeltaTemporality,
DataPoints: []metricdata.HistogramDataPoint[N]{
c.hPt(fltrAlice, 10, 1),
c.hPt(fltrBob, 3, 1),
c.hPt(fltrAlice, 10, 1, y2kPlus(7), y2kPlus(10)),
c.hPt(fltrBob, 3, 1, y2kPlus(7), y2kPlus(10)),
},
},
},
Expand Down Expand Up @@ -117,9 +126,9 @@ func testDeltaHist[N int64 | float64](c conf[N]) func(t *testing.T) {
agg: metricdata.Histogram[N]{
Temporality: metricdata.DeltaTemporality,
DataPoints: []metricdata.HistogramDataPoint[N]{
c.hPt(fltrAlice, 1, 1),
c.hPt(fltrBob, 1, 1),
c.hPt(overflowSet, 1, 2),
c.hPt(fltrAlice, 1, 1, y2kPlus(11), y2kPlus(16)),
c.hPt(fltrBob, 1, 1, y2kPlus(11), y2kPlus(16)),
c.hPt(overflowSet, 1, 2, y2kPlus(11), y2kPlus(16)),
},
},
},
Expand Down Expand Up @@ -158,8 +167,8 @@ func testCumulativeHist[N int64 | float64](c conf[N]) func(t *testing.T) {
agg: metricdata.Histogram[N]{
Temporality: metricdata.CumulativeTemporality,
DataPoints: []metricdata.HistogramDataPoint[N]{
c.hPt(fltrAlice, 2, 3),
c.hPt(fltrBob, 10, 2),
c.hPt(fltrAlice, 2, 3, y2kPlus(0), y2kPlus(7)),
c.hPt(fltrBob, 10, 2, y2kPlus(0), y2kPlus(7)),
},
},
},
Expand All @@ -174,8 +183,8 @@ func testCumulativeHist[N int64 | float64](c conf[N]) func(t *testing.T) {
agg: metricdata.Histogram[N]{
Temporality: metricdata.CumulativeTemporality,
DataPoints: []metricdata.HistogramDataPoint[N]{
c.hPt(fltrAlice, 2, 4),
c.hPt(fltrBob, 10, 3),
c.hPt(fltrAlice, 2, 4, y2kPlus(0), y2kPlus(10)),
c.hPt(fltrBob, 10, 3, y2kPlus(0), y2kPlus(10)),
},
},
},
Expand All @@ -187,8 +196,8 @@ func testCumulativeHist[N int64 | float64](c conf[N]) func(t *testing.T) {
agg: metricdata.Histogram[N]{
Temporality: metricdata.CumulativeTemporality,
DataPoints: []metricdata.HistogramDataPoint[N]{
c.hPt(fltrAlice, 2, 4),
c.hPt(fltrBob, 10, 3),
c.hPt(fltrAlice, 2, 4, y2kPlus(0), y2kPlus(11)),
c.hPt(fltrBob, 10, 3, y2kPlus(0), y2kPlus(11)),
},
},
},
Expand All @@ -204,9 +213,9 @@ func testCumulativeHist[N int64 | float64](c conf[N]) func(t *testing.T) {
agg: metricdata.Histogram[N]{
Temporality: metricdata.CumulativeTemporality,
DataPoints: []metricdata.HistogramDataPoint[N]{
c.hPt(fltrAlice, 2, 4),
c.hPt(fltrBob, 10, 3),
c.hPt(overflowSet, 1, 2),
c.hPt(fltrAlice, 2, 4, y2kPlus(0), y2kPlus(14)),
c.hPt(fltrBob, 10, 3, y2kPlus(0), y2kPlus(14)),
c.hPt(overflowSet, 1, 2, y2kPlus(0), y2kPlus(14)),
},
},
},
Expand All @@ -216,14 +225,14 @@ func testCumulativeHist[N int64 | float64](c conf[N]) func(t *testing.T) {

// hPointSummed returns an HistogramDataPoint that started and ended now with
// multi number of measurements values v. It includes a min and max (set to v).
func hPointSummed[N int64 | float64](a attribute.Set, v N, multi uint64) metricdata.HistogramDataPoint[N] {
func hPointSummed[N int64 | float64](a attribute.Set, v N, multi uint64, start, t time.Time) metricdata.HistogramDataPoint[N] {
idx := sort.SearchFloat64s(bounds, float64(v))
counts := make([]uint64, len(bounds)+1)
counts[idx] += multi
return metricdata.HistogramDataPoint[N]{
Attributes: a,
StartTime: now(),
Time: now(),
StartTime: start,
Time: t,
Count: multi,
Bounds: bounds,
BucketCounts: counts,
Expand All @@ -235,14 +244,14 @@ func hPointSummed[N int64 | float64](a attribute.Set, v N, multi uint64) metricd

// hPoint returns an HistogramDataPoint that started and ended now with multi
// number of measurements values v. It includes a min and max (set to v).
func hPoint[N int64 | float64](a attribute.Set, v N, multi uint64) metricdata.HistogramDataPoint[N] {
func hPoint[N int64 | float64](a attribute.Set, v N, multi uint64, start, t time.Time) metricdata.HistogramDataPoint[N] {
idx := sort.SearchFloat64s(bounds, float64(v))
counts := make([]uint64, len(bounds)+1)
counts[idx] += multi
return metricdata.HistogramDataPoint[N]{
Attributes: a,
StartTime: now(),
Time: now(),
StartTime: start,
Time: t,
Count: multi,
Bounds: bounds,
BucketCounts: counts,
Expand Down Expand Up @@ -334,7 +343,9 @@ func TestCumulativeHistogramImutableCounts(t *testing.T) {
}

func TestDeltaHistogramReset(t *testing.T) {
t.Cleanup(mockTime(now))
orig := now
now = func() time.Time { return y2k }
t.Cleanup(func() { now = orig })

h := newHistogram[int64](bounds, noMinMax, false, 0, dropExemplars[int64])

Expand All @@ -345,7 +356,7 @@ func TestDeltaHistogramReset(t *testing.T) {
h.measure(context.Background(), 1, alice, nil)

expect := metricdata.Histogram[int64]{Temporality: metricdata.DeltaTemporality}
expect.DataPoints = []metricdata.HistogramDataPoint[int64]{hPointSummed[int64](alice, 1, 1)}
expect.DataPoints = []metricdata.HistogramDataPoint[int64]{hPointSummed[int64](alice, 1, 1, now(), now())}
h.delta(&data)
metricdatatest.AssertAggregationsEqual(t, expect, data)

Expand All @@ -356,7 +367,7 @@ func TestDeltaHistogramReset(t *testing.T) {

// Aggregating another set should not affect the original (alice).
h.measure(context.Background(), 1, bob, nil)
expect.DataPoints = []metricdata.HistogramDataPoint[int64]{hPointSummed[int64](bob, 1, 1)}
expect.DataPoints = []metricdata.HistogramDataPoint[int64]{hPointSummed[int64](bob, 1, 1, now(), now())}
h.delta(&data)
metricdatatest.AssertAggregationsEqual(t, expect, data)
}
Expand Down
Loading

0 comments on commit 9e7d744

Please sign in to comment.