Skip to content

Commit

Permalink
Merge branch 'new_sdk/main' into rm-view-agg-todo
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAlias authored Aug 11, 2022
2 parents d748269 + 258bb2d commit cd88304
Show file tree
Hide file tree
Showing 7 changed files with 968 additions and 58 deletions.
4 changes: 2 additions & 2 deletions sdk/metric/manual_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ type manualReader struct {
aggregationSelector AggregationSelector
}

// Compile time check the manualReader implements Reader.
var _ Reader = &manualReader{}
// Compile time check the manualReader implements Reader and is comparable.
var _ = map[Reader]struct{}{&manualReader{}: {}}

// NewManualReader returns a Reader which is directly called to collect metrics.
func NewManualReader(opts ...ManualReaderOption) Reader {
Expand Down
62 changes: 48 additions & 14 deletions sdk/metric/metricdata/metricdatatest/assertion.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,38 +44,66 @@ type Datatypes interface {
// Aggregation and Value type from metricdata are not included here.
}

type config struct {
ignoreTimestamp bool
}

// Option allows for fine grain control over how AssertEqual operates.
type Option interface {
apply(cfg config) config
}

type fnOption func(cfg config) config

func (fn fnOption) apply(cfg config) config {
return fn(cfg)
}

// IgnoreTimestamp disables checking if timestamps are different.
func IgnoreTimestamp() Option {
return fnOption(func(cfg config) config {
cfg.ignoreTimestamp = true
return cfg
})
}

// AssertEqual asserts that the two concrete data-types from the metricdata
// package are equal.
func AssertEqual[T Datatypes](t *testing.T, expected, actual T) bool {
func AssertEqual[T Datatypes](t *testing.T, expected, actual T, opts ...Option) bool {
t.Helper()

cfg := config{}
for _, opt := range opts {
cfg = opt.apply(cfg)
}

// Generic types cannot be type asserted. Use an interface instead.
aIface := interface{}(actual)

var r []string
switch e := interface{}(expected).(type) {
case metricdata.DataPoint[int64]:
r = equalDataPoints(e, aIface.(metricdata.DataPoint[int64]))
r = equalDataPoints(e, aIface.(metricdata.DataPoint[int64]), cfg)
case metricdata.DataPoint[float64]:
r = equalDataPoints(e, aIface.(metricdata.DataPoint[float64]))
r = equalDataPoints(e, aIface.(metricdata.DataPoint[float64]), cfg)
case metricdata.Gauge[int64]:
r = equalGauges(e, aIface.(metricdata.Gauge[int64]))
r = equalGauges(e, aIface.(metricdata.Gauge[int64]), cfg)
case metricdata.Gauge[float64]:
r = equalGauges(e, aIface.(metricdata.Gauge[float64]))
r = equalGauges(e, aIface.(metricdata.Gauge[float64]), cfg)
case metricdata.Histogram:
r = equalHistograms(e, aIface.(metricdata.Histogram))
r = equalHistograms(e, aIface.(metricdata.Histogram), cfg)
case metricdata.HistogramDataPoint:
r = equalHistogramDataPoints(e, aIface.(metricdata.HistogramDataPoint))
r = equalHistogramDataPoints(e, aIface.(metricdata.HistogramDataPoint), cfg)
case metricdata.Metrics:
r = equalMetrics(e, aIface.(metricdata.Metrics))
r = equalMetrics(e, aIface.(metricdata.Metrics), cfg)
case metricdata.ResourceMetrics:
r = equalResourceMetrics(e, aIface.(metricdata.ResourceMetrics))
r = equalResourceMetrics(e, aIface.(metricdata.ResourceMetrics), cfg)
case metricdata.ScopeMetrics:
r = equalScopeMetrics(e, aIface.(metricdata.ScopeMetrics))
r = equalScopeMetrics(e, aIface.(metricdata.ScopeMetrics), cfg)
case metricdata.Sum[int64]:
r = equalSums(e, aIface.(metricdata.Sum[int64]))
r = equalSums(e, aIface.(metricdata.Sum[int64]), cfg)
case metricdata.Sum[float64]:
r = equalSums(e, aIface.(metricdata.Sum[float64]))
r = equalSums(e, aIface.(metricdata.Sum[float64]), cfg)
default:
// We control all types passed to this, panic to signal developers
// early they changed things in an incompatible way.
Expand All @@ -90,9 +118,15 @@ func AssertEqual[T Datatypes](t *testing.T, expected, actual T) bool {
}

// AssertAggregationsEqual asserts that two Aggregations are equal.
func AssertAggregationsEqual(t *testing.T, expected, actual metricdata.Aggregation) bool {
func AssertAggregationsEqual(t *testing.T, expected, actual metricdata.Aggregation, opts ...Option) bool {
t.Helper()
if r := equalAggregations(expected, actual); len(r) > 0 {

cfg := config{}
for _, opt := range opts {
cfg = opt.apply(cfg)
}

if r := equalAggregations(expected, actual, cfg); len(r) > 0 {
t.Error(r)
return false
}
Expand Down
114 changes: 104 additions & 10 deletions sdk/metric/metricdata/metricdatatest/assertion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ var (
Time: endB,
Value: 2.0,
}
dataPointInt64C = metricdata.DataPoint[int64]{
Attributes: attrA,
StartTime: startB,
Time: endB,
Value: -1,
}
dataPointFloat64C = metricdata.DataPoint[float64]{
Attributes: attrA,
StartTime: startB,
Time: endB,
Value: -1.0,
}

max, min = 99.0, 3.
histogramDataPointA = metricdata.HistogramDataPoint{
Expand All @@ -85,6 +97,15 @@ var (
Min: &min,
Sum: 3,
}
histogramDataPointC = metricdata.HistogramDataPoint{
Attributes: attrA,
StartTime: startB,
Time: endB,
Count: 2,
Bounds: []float64{0, 10},
BucketCounts: []uint64{1, 1},
Sum: 2,
}

gaugeInt64A = metricdata.Gauge[int64]{
DataPoints: []metricdata.DataPoint[int64]{dataPointInt64A},
Expand All @@ -98,6 +119,12 @@ var (
gaugeFloat64B = metricdata.Gauge[float64]{
DataPoints: []metricdata.DataPoint[float64]{dataPointFloat64B},
}
gaugeInt64C = metricdata.Gauge[int64]{
DataPoints: []metricdata.DataPoint[int64]{dataPointInt64C},
}
gaugeFloat64C = metricdata.Gauge[float64]{
DataPoints: []metricdata.DataPoint[float64]{dataPointFloat64C},
}

sumInt64A = metricdata.Sum[int64]{
Temporality: metricdata.CumulativeTemporality,
Expand All @@ -119,6 +146,16 @@ var (
IsMonotonic: true,
DataPoints: []metricdata.DataPoint[float64]{dataPointFloat64B},
}
sumInt64C = metricdata.Sum[int64]{
Temporality: metricdata.CumulativeTemporality,
IsMonotonic: true,
DataPoints: []metricdata.DataPoint[int64]{dataPointInt64C},
}
sumFloat64C = metricdata.Sum[float64]{
Temporality: metricdata.CumulativeTemporality,
IsMonotonic: true,
DataPoints: []metricdata.DataPoint[float64]{dataPointFloat64C},
}

histogramA = metricdata.Histogram{
Temporality: metricdata.CumulativeTemporality,
Expand All @@ -128,6 +165,10 @@ var (
Temporality: metricdata.DeltaTemporality,
DataPoints: []metricdata.HistogramDataPoint{histogramDataPointB},
}
histogramC = metricdata.Histogram{
Temporality: metricdata.CumulativeTemporality,
DataPoints: []metricdata.HistogramDataPoint{histogramDataPointC},
}

metricsA = metricdata.Metrics{
Name: "A",
Expand All @@ -141,6 +182,12 @@ var (
Unit: unit.Bytes,
Data: gaugeFloat64B,
}
metricsC = metricdata.Metrics{
Name: "A",
Description: "A desc",
Unit: unit.Dimensionless,
Data: sumInt64C,
}

scopeMetricsA = metricdata.ScopeMetrics{
Scope: instrumentation.Scope{Name: "A"},
Expand All @@ -150,6 +197,10 @@ var (
Scope: instrumentation.Scope{Name: "B"},
Metrics: []metricdata.Metrics{metricsB},
}
scopeMetricsC = metricdata.ScopeMetrics{
Scope: instrumentation.Scope{Name: "A"},
Metrics: []metricdata.Metrics{metricsC},
}

resourceMetricsA = metricdata.ResourceMetrics{
Resource: resource.NewSchemaless(attribute.String("resource", "A")),
Expand All @@ -159,20 +210,34 @@ var (
Resource: resource.NewSchemaless(attribute.String("resource", "B")),
ScopeMetrics: []metricdata.ScopeMetrics{scopeMetricsB},
}
resourceMetricsC = metricdata.ResourceMetrics{
Resource: resource.NewSchemaless(attribute.String("resource", "A")),
ScopeMetrics: []metricdata.ScopeMetrics{scopeMetricsC},
}
)

type equalFunc[T Datatypes] func(T, T) []string
type equalFunc[T Datatypes] func(T, T, config) []string

func testDatatype[T Datatypes](a, b T, f equalFunc[T]) func(*testing.T) {
return func(t *testing.T) {
AssertEqual(t, a, a)
AssertEqual(t, b, b)

r := f(a, b)
r := f(a, b, config{})
assert.Greaterf(t, len(r), 0, "%v == %v", a, b)
}
}

func testDatatypeIgnoreTime[T Datatypes](a, b T, f equalFunc[T]) func(*testing.T) {
return func(t *testing.T) {
AssertEqual(t, a, a)
AssertEqual(t, b, b)

r := f(a, b, config{ignoreTimestamp: true})
assert.Equalf(t, len(r), 0, "%v == %v", a, b)
}
}

func TestAssertEqual(t *testing.T) {
t.Run("ResourceMetrics", testDatatype(resourceMetricsA, resourceMetricsB, equalResourceMetrics))
t.Run("ScopeMetrics", testDatatype(scopeMetricsA, scopeMetricsB, equalScopeMetrics))
Expand All @@ -187,6 +252,20 @@ func TestAssertEqual(t *testing.T) {
t.Run("DataPointFloat64", testDatatype(dataPointFloat64A, dataPointFloat64B, equalDataPoints[float64]))
}

func TestAssertEqualIgnoreTime(t *testing.T) {
t.Run("ResourceMetrics", testDatatypeIgnoreTime(resourceMetricsA, resourceMetricsC, equalResourceMetrics))
t.Run("ScopeMetrics", testDatatypeIgnoreTime(scopeMetricsA, scopeMetricsC, equalScopeMetrics))
t.Run("Metrics", testDatatypeIgnoreTime(metricsA, metricsC, equalMetrics))
t.Run("Histogram", testDatatypeIgnoreTime(histogramA, histogramC, equalHistograms))
t.Run("SumInt64", testDatatypeIgnoreTime(sumInt64A, sumInt64C, equalSums[int64]))
t.Run("SumFloat64", testDatatypeIgnoreTime(sumFloat64A, sumFloat64C, equalSums[float64]))
t.Run("GaugeInt64", testDatatypeIgnoreTime(gaugeInt64A, gaugeInt64C, equalGauges[int64]))
t.Run("GaugeFloat64", testDatatypeIgnoreTime(gaugeFloat64A, gaugeFloat64C, equalGauges[float64]))
t.Run("HistogramDataPoint", testDatatypeIgnoreTime(histogramDataPointA, histogramDataPointC, equalHistogramDataPoints))
t.Run("DataPointInt64", testDatatypeIgnoreTime(dataPointInt64A, dataPointInt64C, equalDataPoints[int64]))
t.Run("DataPointFloat64", testDatatypeIgnoreTime(dataPointFloat64A, dataPointFloat64C, equalDataPoints[float64]))
}

type unknownAggregation struct {
metricdata.Aggregation
}
Expand All @@ -199,27 +278,42 @@ func TestAssertAggregationsEqual(t *testing.T) {
AssertAggregationsEqual(t, gaugeFloat64A, gaugeFloat64A)
AssertAggregationsEqual(t, histogramA, histogramA)

r := equalAggregations(sumInt64A, nil)
r := equalAggregations(sumInt64A, nil, config{})
assert.Len(t, r, 1, "should return nil comparison mismatch only")

r = equalAggregations(sumInt64A, gaugeInt64A)
r = equalAggregations(sumInt64A, gaugeInt64A, config{})
assert.Len(t, r, 1, "should return with type mismatch only")

r = equalAggregations(unknownAggregation{}, unknownAggregation{})
r = equalAggregations(unknownAggregation{}, unknownAggregation{}, config{})
assert.Len(t, r, 1, "should return with unknown aggregation only")

r = equalAggregations(sumInt64A, sumInt64B)
r = equalAggregations(sumInt64A, sumInt64B, config{})
assert.Greaterf(t, len(r), 0, "%v == %v", sumInt64A, sumInt64B)

r = equalAggregations(sumFloat64A, sumFloat64B)
r = equalAggregations(sumInt64A, sumInt64C, config{ignoreTimestamp: true})
assert.Equalf(t, len(r), 0, "%v == %v", sumInt64A, sumInt64C)

r = equalAggregations(sumFloat64A, sumFloat64B, config{})
assert.Greaterf(t, len(r), 0, "%v == %v", sumFloat64A, sumFloat64B)

r = equalAggregations(gaugeInt64A, gaugeInt64B)
r = equalAggregations(sumFloat64A, sumFloat64C, config{ignoreTimestamp: true})
assert.Equalf(t, len(r), 0, "%v == %v", sumFloat64A, sumFloat64C)

r = equalAggregations(gaugeInt64A, gaugeInt64B, config{})
assert.Greaterf(t, len(r), 0, "%v == %v", gaugeInt64A, gaugeInt64B)

r = equalAggregations(gaugeFloat64A, gaugeFloat64B)
r = equalAggregations(gaugeInt64A, gaugeInt64C, config{ignoreTimestamp: true})
assert.Equalf(t, len(r), 0, "%v == %v", gaugeInt64A, gaugeInt64C)

r = equalAggregations(gaugeFloat64A, gaugeFloat64B, config{})
assert.Greaterf(t, len(r), 0, "%v == %v", gaugeFloat64A, gaugeFloat64B)

r = equalAggregations(histogramA, histogramB)
r = equalAggregations(gaugeFloat64A, gaugeFloat64C, config{ignoreTimestamp: true})
assert.Equalf(t, len(r), 0, "%v == %v", gaugeFloat64A, gaugeFloat64C)

r = equalAggregations(histogramA, histogramB, config{})
assert.Greaterf(t, len(r), 0, "%v == %v", histogramA, histogramB)

r = equalAggregations(histogramA, histogramC, config{ignoreTimestamp: true})
assert.Equalf(t, len(r), 0, "%v == %v", histogramA, histogramC)
}
Loading

0 comments on commit cd88304

Please sign in to comment.