| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | // Copyright 2019, OpenTelemetry Authors | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License. | 
					
						
							|  |  |  | // You may obtain a copy of the License at | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and | 
					
						
							|  |  |  | // limitations under the License. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package gauge | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"math/rand" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 11:40:29 -07:00
										 |  |  | 	"go.opentelemetry.io/otel/api/core" | 
					
						
							| 
									
										
										
										
											2019-11-05 13:08:55 -08:00
										 |  |  | 	export "go.opentelemetry.io/otel/sdk/export/metric" | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 	"go.opentelemetry.io/otel/sdk/export/metric/aggregator" | 
					
						
							| 
									
										
										
										
											2019-11-01 11:40:29 -07:00
										 |  |  | 	"go.opentelemetry.io/otel/sdk/metric/aggregator/test" | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const count = 100 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 13:08:55 -08:00
										 |  |  | var _ export.Aggregator = &Aggregator{} | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestGaugeNonMonotonic(t *testing.T) { | 
					
						
							|  |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	test.RunProfiles(t, func(t *testing.T, profile test.Profile) { | 
					
						
							|  |  |  | 		agg := New() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		record := test.NewAggregatorTest(export.GaugeKind, profile.NumberKind, false) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var last core.Number | 
					
						
							|  |  |  | 		for i := 0; i < count; i++ { | 
					
						
							|  |  |  | 			x := profile.Random(rand.Intn(1)*2 - 1) | 
					
						
							|  |  |  | 			last = x | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 			test.CheckedUpdate(t, agg, x, record) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		agg.Checkpoint(ctx, record) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		lv, _, err := agg.LastValue() | 
					
						
							|  |  |  | 		require.Equal(t, last, lv, "Same last value - non-monotonic") | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestGaugeMonotonic(t *testing.T) { | 
					
						
							|  |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	test.RunProfiles(t, func(t *testing.T, profile test.Profile) { | 
					
						
							|  |  |  | 		agg := New() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		record := test.NewAggregatorTest(export.GaugeKind, profile.NumberKind, true) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		small := profile.Random(+1) | 
					
						
							|  |  |  | 		last := small | 
					
						
							|  |  |  | 		for i := 0; i < count; i++ { | 
					
						
							|  |  |  | 			x := profile.Random(+1) | 
					
						
							|  |  |  | 			last.AddNumber(profile.NumberKind, x) | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 			test.CheckedUpdate(t, agg, last, record) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		agg.Checkpoint(ctx, record) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		lv, _, err := agg.LastValue() | 
					
						
							|  |  |  | 		require.Equal(t, last, lv, "Same last value - monotonic") | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestGaugeMonotonicDescending(t *testing.T) { | 
					
						
							|  |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	test.RunProfiles(t, func(t *testing.T, profile test.Profile) { | 
					
						
							|  |  |  | 		agg := New() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		record := test.NewAggregatorTest(export.GaugeKind, profile.NumberKind, true) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		first := profile.Random(+1) | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		test.CheckedUpdate(t, agg, first, record) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for i := 0; i < count; i++ { | 
					
						
							|  |  |  | 			x := profile.Random(-1) | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			err := agg.Update(ctx, x, record) | 
					
						
							|  |  |  | 			if err != aggregator.ErrNonMonotoneInput { | 
					
						
							|  |  |  | 				t.Error("Expected ErrNonMonotoneInput", err) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		agg.Checkpoint(ctx, record) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		lv, _, err := agg.LastValue() | 
					
						
							|  |  |  | 		require.Equal(t, first, lv, "Same last value - monotonic") | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							| 
									
										
										
										
											2019-10-29 13:27:22 -07:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestGaugeNormalMerge(t *testing.T) { | 
					
						
							|  |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	test.RunProfiles(t, func(t *testing.T, profile test.Profile) { | 
					
						
							|  |  |  | 		agg1 := New() | 
					
						
							|  |  |  | 		agg2 := New() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		descriptor := test.NewAggregatorTest(export.GaugeKind, profile.NumberKind, false) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		first1 := profile.Random(+1) | 
					
						
							|  |  |  | 		first2 := profile.Random(+1) | 
					
						
							|  |  |  | 		first1.AddNumber(profile.NumberKind, first2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		test.CheckedUpdate(t, agg1, first1, descriptor) | 
					
						
							|  |  |  | 		test.CheckedUpdate(t, agg2, first2, descriptor) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		agg1.Checkpoint(ctx, descriptor) | 
					
						
							|  |  |  | 		agg2.Checkpoint(ctx, descriptor) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		_, t1, err := agg1.LastValue() | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		_, t2, err := agg2.LastValue() | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 		require.True(t, t1.Before(t2)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		test.CheckedMerge(t, agg1, agg2, descriptor) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		lv, ts, err := agg1.LastValue() | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		require.Equal(t, t2, ts, "Merged timestamp - non-monotonic") | 
					
						
							|  |  |  | 		require.Equal(t, first2, lv, "Merged value - non-monotonic") | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestGaugeMonotonicMerge(t *testing.T) { | 
					
						
							|  |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	test.RunProfiles(t, func(t *testing.T, profile test.Profile) { | 
					
						
							|  |  |  | 		agg1 := New() | 
					
						
							|  |  |  | 		agg2 := New() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		descriptor := test.NewAggregatorTest(export.GaugeKind, profile.NumberKind, true) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		first1 := profile.Random(+1) | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		test.CheckedUpdate(t, agg1, first1, descriptor) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		first2 := profile.Random(+1) | 
					
						
							|  |  |  | 		first2.AddNumber(profile.NumberKind, first1) | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		test.CheckedUpdate(t, agg2, first2, descriptor) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		agg1.Checkpoint(ctx, descriptor) | 
					
						
							|  |  |  | 		agg2.Checkpoint(ctx, descriptor) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		test.CheckedMerge(t, agg1, agg2, descriptor) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		_, ts2, err := agg1.LastValue() | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 		lv, ts1, err := agg1.LastValue() | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		require.Equal(t, first2, lv, "Merged value - monotonic") | 
					
						
							|  |  |  | 		require.Equal(t, ts2, ts1, "Merged timestamp - monotonic") | 
					
						
							| 
									
										
										
										
											2019-10-30 22:15:27 -07:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-11-15 13:01:20 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestGaugeNotSet(t *testing.T) { | 
					
						
							|  |  |  | 	descriptor := test.NewAggregatorTest(export.GaugeKind, core.Int64NumberKind, true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	g := New() | 
					
						
							|  |  |  | 	g.Checkpoint(context.Background(), descriptor) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	value, timestamp, err := g.LastValue() | 
					
						
							|  |  |  | 	require.Equal(t, aggregator.ErrNoLastValue, err) | 
					
						
							|  |  |  | 	require.True(t, timestamp.IsZero()) | 
					
						
							|  |  |  | 	require.Equal(t, core.Number(0), value) | 
					
						
							|  |  |  | } |