1// Copyright The OpenTelemetry Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package aggregator_test // import "go.opentelemetry.io/otel/sdk/metric/aggregator" 16 17import ( 18 "errors" 19 "math" 20 "testing" 21 22 "github.com/stretchr/testify/require" 23 24 "go.opentelemetry.io/otel/metric" 25 "go.opentelemetry.io/otel/metric/number" 26 "go.opentelemetry.io/otel/sdk/export/metric/aggregation" 27 "go.opentelemetry.io/otel/sdk/metric/aggregator" 28 "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" 29 "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" 30) 31 32func TestInconsistentAggregatorErr(t *testing.T) { 33 err := aggregator.NewInconsistentAggregatorError(&sum.New(1)[0], &lastvalue.New(1)[0]) 34 require.Equal( 35 t, 36 "inconsistent aggregator types: *sum.Aggregator and *lastvalue.Aggregator", 37 err.Error(), 38 ) 39 require.True(t, errors.Is(err, aggregation.ErrInconsistentType)) 40} 41 42func testRangeNaN(t *testing.T, desc *metric.Descriptor) { 43 // If the descriptor uses int64 numbers, this won't register as NaN 44 nan := number.NewFloat64Number(math.NaN()) 45 err := aggregator.RangeTest(nan, desc) 46 47 if desc.NumberKind() == number.Float64Kind { 48 require.Equal(t, aggregation.ErrNaNInput, err) 49 } else { 50 require.Nil(t, err) 51 } 52} 53 54func testRangeNegative(t *testing.T, desc *metric.Descriptor) { 55 var neg, pos number.Number 56 57 if desc.NumberKind() == number.Float64Kind { 58 pos = number.NewFloat64Number(+1) 59 neg = number.NewFloat64Number(-1) 60 } else { 61 pos = number.NewInt64Number(+1) 62 neg = number.NewInt64Number(-1) 63 } 64 65 posErr := aggregator.RangeTest(pos, desc) 66 negErr := aggregator.RangeTest(neg, desc) 67 68 require.Nil(t, posErr) 69 require.Equal(t, negErr, aggregation.ErrNegativeInput) 70} 71 72func TestRangeTest(t *testing.T) { 73 // Only Counters implement a range test. 74 for _, nkind := range []number.Kind{number.Float64Kind, number.Int64Kind} { 75 t.Run(nkind.String(), func(t *testing.T) { 76 desc := metric.NewDescriptor( 77 "name", 78 metric.CounterInstrumentKind, 79 nkind, 80 ) 81 testRangeNegative(t, &desc) 82 }) 83 } 84} 85 86func TestNaNTest(t *testing.T) { 87 for _, nkind := range []number.Kind{number.Float64Kind, number.Int64Kind} { 88 t.Run(nkind.String(), func(t *testing.T) { 89 for _, mkind := range []metric.InstrumentKind{ 90 metric.CounterInstrumentKind, 91 metric.ValueRecorderInstrumentKind, 92 metric.ValueObserverInstrumentKind, 93 } { 94 desc := metric.NewDescriptor( 95 "name", 96 mkind, 97 nkind, 98 ) 99 testRangeNaN(t, &desc) 100 } 101 }) 102 } 103} 104