1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-07-15 01:04:25 +02:00

Single-state Aggregator and test refactor (#812)

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
Joshua MacDonald
2020-06-13 00:55:01 -07:00
committed by GitHub
parent 288a3dd435
commit 9925ebe517
34 changed files with 1058 additions and 849 deletions

View File

@ -15,43 +15,55 @@
package array
import (
"errors"
"fmt"
"math"
"os"
"testing"
"unsafe"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
ottest "go.opentelemetry.io/otel/internal/testing"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator/test"
)
// Ensure struct alignment prior to running tests.
func TestMain(m *testing.M) {
fields := []ottest.FieldOffset{
{
Name: "Aggregator.ckptSum",
Offset: unsafe.Offsetof(Aggregator{}.ckptSum),
},
}
if !ottest.Aligned8Byte(fields, os.Stderr) {
os.Exit(1)
}
os.Exit(m.Run())
}
type updateTest struct {
count int
}
func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) {
kind := desc.NumberKind()
sum, err := agg.Sum()
require.NoError(t, err)
require.Equal(t, kind.Zero(), sum)
count, err := agg.Count()
require.NoError(t, err)
require.Equal(t, int64(0), count)
max, err := agg.Max()
require.True(t, errors.Is(err, aggregation.ErrNoData))
require.Equal(t, kind.Zero(), max)
min, err := agg.Min()
require.True(t, errors.Is(err, aggregation.ErrNoData))
require.Equal(t, kind.Zero(), min)
}
func new2() (_, _ *Aggregator) {
alloc := New(2)
return &alloc[0], &alloc[1]
}
func new4() (_, _, _, _ *Aggregator) {
alloc := New(4)
return &alloc[0], &alloc[1], &alloc[2], &alloc[3]
}
func (ut *updateTest) run(t *testing.T, profile test.Profile) {
descriptor := test.NewAggregatorTest(metric.ValueRecorderKind, profile.NumberKind)
agg := New()
agg, ckpt := new2()
all := test.NewNumbers(profile.NumberKind)
@ -65,11 +77,14 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
test.CheckedUpdate(t, agg, y, descriptor)
}
agg.Checkpoint(descriptor)
err := agg.SynchronizedCopy(ckpt, descriptor)
require.NoError(t, err)
checkZero(t, agg, descriptor)
all.Sort()
sum, err := agg.Sum()
sum, err := ckpt.Sum()
require.Nil(t, err)
allSum := all.Sum()
require.InEpsilon(t,
@ -77,19 +92,19 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
sum.CoerceToFloat64(profile.NumberKind),
0.0000001,
"Same sum")
count, err := agg.Count()
count, err := ckpt.Count()
require.Nil(t, err)
require.Equal(t, all.Count(), count, "Same count")
min, err := agg.Min()
min, err := ckpt.Min()
require.Nil(t, err)
require.Equal(t, all.Min(), min, "Same min")
max, err := agg.Max()
max, err := ckpt.Max()
require.Nil(t, err)
require.Equal(t, all.Max(), max, "Same max")
qx, err := agg.Quantile(0.5)
qx, err := ckpt.Quantile(0.5)
require.Nil(t, err)
require.Equal(t, all.Median(), qx, "Same median")
}
@ -115,9 +130,7 @@ type mergeTest struct {
func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
descriptor := test.NewAggregatorTest(metric.ValueRecorderKind, profile.NumberKind)
agg1 := New()
agg2 := New()
agg1, agg2, ckpt1, ckpt2 := new4()
all := test.NewNumbers(profile.NumberKind)
@ -141,14 +154,17 @@ func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
}
}
agg1.Checkpoint(descriptor)
agg2.Checkpoint(descriptor)
require.NoError(t, agg1.SynchronizedCopy(ckpt1, descriptor))
require.NoError(t, agg2.SynchronizedCopy(ckpt2, descriptor))
test.CheckedMerge(t, agg1, agg2, descriptor)
checkZero(t, agg1, descriptor)
checkZero(t, agg2, descriptor)
test.CheckedMerge(t, ckpt1, ckpt2, descriptor)
all.Sort()
sum, err := agg1.Sum()
sum, err := ckpt1.Sum()
require.Nil(t, err)
allSum := all.Sum()
require.InEpsilon(t,
@ -156,19 +172,19 @@ func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
sum.CoerceToFloat64(profile.NumberKind),
0.0000001,
"Same sum - absolute")
count, err := agg1.Count()
count, err := ckpt1.Count()
require.Nil(t, err)
require.Equal(t, all.Count(), count, "Same count - absolute")
min, err := agg1.Min()
min, err := ckpt1.Min()
require.Nil(t, err)
require.Equal(t, all.Min(), min, "Same min - absolute")
max, err := agg1.Max()
max, err := ckpt1.Max()
require.Nil(t, err)
require.Equal(t, all.Max(), max, "Same max - absolute")
qx, err := agg1.Quantile(0.5)
qx, err := ckpt1.Quantile(0.5)
require.Nil(t, err)
require.Equal(t, all.Median(), qx, "Same median - absolute")
}
@ -195,17 +211,17 @@ func TestArrayMerge(t *testing.T) {
func TestArrayErrors(t *testing.T) {
test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
agg := New()
agg, ckpt := new2()
_, err := agg.Max()
_, err := ckpt.Max()
require.Error(t, err)
require.Equal(t, err, aggregation.ErrNoData)
_, err = agg.Min()
_, err = ckpt.Min()
require.Error(t, err)
require.Equal(t, err, aggregation.ErrNoData)
_, err = agg.Quantile(0.1)
_, err = ckpt.Quantile(0.1)
require.Error(t, err)
require.Equal(t, err, aggregation.ErrNoData)
@ -216,23 +232,23 @@ func TestArrayErrors(t *testing.T) {
if profile.NumberKind == metric.Float64NumberKind {
test.CheckedUpdate(t, agg, metric.NewFloat64Number(math.NaN()), descriptor)
}
agg.Checkpoint(descriptor)
require.NoError(t, agg.SynchronizedCopy(ckpt, descriptor))
count, err := agg.Count()
count, err := ckpt.Count()
require.Equal(t, int64(1), count, "NaN value was not counted")
require.Nil(t, err)
num, err := agg.Quantile(0)
num, err := ckpt.Quantile(0)
require.Nil(t, err)
require.Equal(t, num, metric.Number(0))
_, err = agg.Quantile(-0.0001)
_, err = ckpt.Quantile(-0.0001)
require.Error(t, err)
require.Equal(t, err, aggregation.ErrInvalidQuantile)
require.True(t, errors.Is(err, aggregation.ErrInvalidQuantile))
_, err = agg.Quantile(1.0001)
require.Error(t, err)
require.Equal(t, err, aggregation.ErrInvalidQuantile)
require.True(t, errors.Is(err, aggregation.ErrNoData))
})
}
@ -269,7 +285,7 @@ func TestArrayFloat64(t *testing.T) {
all := test.NewNumbers(metric.Float64NumberKind)
agg := New()
agg, ckpt := new2()
for _, f := range fpsf(1) {
all.Append(metric.NewFloat64Number(f))
@ -281,32 +297,32 @@ func TestArrayFloat64(t *testing.T) {
test.CheckedUpdate(t, agg, metric.NewFloat64Number(f), descriptor)
}
agg.Checkpoint(descriptor)
require.NoError(t, agg.SynchronizedCopy(ckpt, descriptor))
all.Sort()
sum, err := agg.Sum()
sum, err := ckpt.Sum()
require.Nil(t, err)
allSum := all.Sum()
require.InEpsilon(t, (&allSum).AsFloat64(), sum.AsFloat64(), 0.0000001, "Same sum")
count, err := agg.Count()
count, err := ckpt.Count()
require.Equal(t, all.Count(), count, "Same count")
require.Nil(t, err)
min, err := agg.Min()
min, err := ckpt.Min()
require.Nil(t, err)
require.Equal(t, all.Min(), min, "Same min")
max, err := agg.Max()
max, err := ckpt.Max()
require.Nil(t, err)
require.Equal(t, all.Max(), max, "Same max")
qx, err := agg.Quantile(0.5)
qx, err := ckpt.Quantile(0.5)
require.Nil(t, err)
require.Equal(t, all.Median(), qx, "Same median")
po, err := agg.Points()
po, err := ckpt.Points()
require.Nil(t, err)
require.Equal(t, all.Len(), len(po), "Points() must have same length of updates")
for i := 0; i < len(po); i++ {