You've already forked opentelemetry-go
							
							
				mirror of
				https://github.com/open-telemetry/opentelemetry-go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	Use https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize to update code to new style. --------- Co-authored-by: Flc゛ <four_leaf_clover@foxmail.com> Co-authored-by: Damien Mathieu <42@dmathieu.com>
		
			
				
	
	
		
			271 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright The OpenTelemetry Authors
 | |
| // SPDX-License-Identifier: Apache-2.0
 | |
| 
 | |
| // Package metricdatatest provides testing functionality for use with the
 | |
| // metricdata package.
 | |
| package metricdatatest // import "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest"
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"go.opentelemetry.io/otel/attribute"
 | |
| 	"go.opentelemetry.io/otel/sdk/metric/metricdata"
 | |
| )
 | |
| 
 | |
| // Datatypes are the concrete data-types the metricdata package provides.
 | |
| type Datatypes interface {
 | |
| 	metricdata.DataPoint[float64] |
 | |
| 		metricdata.DataPoint[int64] |
 | |
| 		metricdata.Gauge[float64] |
 | |
| 		metricdata.Gauge[int64] |
 | |
| 		metricdata.Histogram[float64] |
 | |
| 		metricdata.Histogram[int64] |
 | |
| 		metricdata.HistogramDataPoint[float64] |
 | |
| 		metricdata.HistogramDataPoint[int64] |
 | |
| 		metricdata.Extrema[int64] |
 | |
| 		metricdata.Extrema[float64] |
 | |
| 		metricdata.Metrics |
 | |
| 		metricdata.ResourceMetrics |
 | |
| 		metricdata.ScopeMetrics |
 | |
| 		metricdata.Sum[float64] |
 | |
| 		metricdata.Sum[int64] |
 | |
| 		metricdata.Exemplar[float64] |
 | |
| 		metricdata.Exemplar[int64] |
 | |
| 		metricdata.ExponentialHistogram[float64] |
 | |
| 		metricdata.ExponentialHistogram[int64] |
 | |
| 		metricdata.ExponentialHistogramDataPoint[float64] |
 | |
| 		metricdata.ExponentialHistogramDataPoint[int64] |
 | |
| 		metricdata.ExponentialBucket |
 | |
| 		metricdata.Summary |
 | |
| 		metricdata.SummaryDataPoint |
 | |
| 		metricdata.QuantileValue
 | |
| 
 | |
| 	// Interface types are not allowed in union types, therefore the
 | |
| 	// Aggregation and Value type from metricdata are not included here.
 | |
| }
 | |
| 
 | |
| // TestingT is an interface that implements [testing.T], but without the
 | |
| // private method of [testing.TB], so other testing packages can rely on it as
 | |
| // well.
 | |
| // The methods in this interface must match the [testing.TB] interface.
 | |
| type TestingT interface {
 | |
| 	Helper()
 | |
| 	// DO NOT CHANGE: any modification will not be backwards compatible and
 | |
| 	// must never be done outside of a new major release.
 | |
| 
 | |
| 	Error(...any)
 | |
| 	// DO NOT CHANGE: any modification will not be backwards compatible and
 | |
| 	// must never be done outside of a new major release.
 | |
| }
 | |
| 
 | |
| type config struct {
 | |
| 	ignoreTimestamp bool
 | |
| 	ignoreExemplars bool
 | |
| 	ignoreValue     bool
 | |
| }
 | |
| 
 | |
| func newConfig(opts []Option) config {
 | |
| 	var cfg config
 | |
| 	for _, opt := range opts {
 | |
| 		cfg = opt.apply(cfg)
 | |
| 	}
 | |
| 	return cfg
 | |
| }
 | |
| 
 | |
| // 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
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // IgnoreExemplars disables checking if Exemplars are different.
 | |
| func IgnoreExemplars() Option {
 | |
| 	return fnOption(func(cfg config) config {
 | |
| 		cfg.ignoreExemplars = true
 | |
| 		return cfg
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // IgnoreValue disables checking if values are different. This can be
 | |
| // useful for non-deterministic values, like measured durations.
 | |
| //
 | |
| // This will ignore the value and trace information for Exemplars;
 | |
| // the buckets, zero count, scale, sum, max, min, and counts of
 | |
| // ExponentialHistogramDataPoints; the buckets, sum, count, max,
 | |
| // and min of HistogramDataPoints; the value of DataPoints.
 | |
| func IgnoreValue() Option {
 | |
| 	return fnOption(func(cfg config) config {
 | |
| 		cfg.ignoreValue = true
 | |
| 		return cfg
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // AssertEqual asserts that the two concrete data-types from the metricdata
 | |
| // package are equal.
 | |
| func AssertEqual[T Datatypes](t TestingT, expected, actual T, opts ...Option) bool {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	cfg := newConfig(opts)
 | |
| 
 | |
| 	// Generic types cannot be type asserted. Use an interface instead.
 | |
| 	aIface := any(actual)
 | |
| 
 | |
| 	var r []string
 | |
| 	switch e := any(expected).(type) {
 | |
| 	case metricdata.Exemplar[int64]:
 | |
| 		r = equalExemplars(e, aIface.(metricdata.Exemplar[int64]), cfg)
 | |
| 	case metricdata.Exemplar[float64]:
 | |
| 		r = equalExemplars(e, aIface.(metricdata.Exemplar[float64]), cfg)
 | |
| 	case metricdata.DataPoint[int64]:
 | |
| 		r = equalDataPoints(e, aIface.(metricdata.DataPoint[int64]), cfg)
 | |
| 	case metricdata.DataPoint[float64]:
 | |
| 		r = equalDataPoints(e, aIface.(metricdata.DataPoint[float64]), cfg)
 | |
| 	case metricdata.Gauge[int64]:
 | |
| 		r = equalGauges(e, aIface.(metricdata.Gauge[int64]), cfg)
 | |
| 	case metricdata.Gauge[float64]:
 | |
| 		r = equalGauges(e, aIface.(metricdata.Gauge[float64]), cfg)
 | |
| 	case metricdata.Histogram[float64]:
 | |
| 		r = equalHistograms(e, aIface.(metricdata.Histogram[float64]), cfg)
 | |
| 	case metricdata.Histogram[int64]:
 | |
| 		r = equalHistograms(e, aIface.(metricdata.Histogram[int64]), cfg)
 | |
| 	case metricdata.HistogramDataPoint[float64]:
 | |
| 		r = equalHistogramDataPoints(e, aIface.(metricdata.HistogramDataPoint[float64]), cfg)
 | |
| 	case metricdata.HistogramDataPoint[int64]:
 | |
| 		r = equalHistogramDataPoints(e, aIface.(metricdata.HistogramDataPoint[int64]), cfg)
 | |
| 	case metricdata.Extrema[int64]:
 | |
| 		r = equalExtrema(e, aIface.(metricdata.Extrema[int64]), cfg)
 | |
| 	case metricdata.Extrema[float64]:
 | |
| 		r = equalExtrema(e, aIface.(metricdata.Extrema[float64]), cfg)
 | |
| 	case metricdata.Metrics:
 | |
| 		r = equalMetrics(e, aIface.(metricdata.Metrics), cfg)
 | |
| 	case metricdata.ResourceMetrics:
 | |
| 		r = equalResourceMetrics(e, aIface.(metricdata.ResourceMetrics), cfg)
 | |
| 	case metricdata.ScopeMetrics:
 | |
| 		r = equalScopeMetrics(e, aIface.(metricdata.ScopeMetrics), cfg)
 | |
| 	case metricdata.Sum[int64]:
 | |
| 		r = equalSums(e, aIface.(metricdata.Sum[int64]), cfg)
 | |
| 	case metricdata.Sum[float64]:
 | |
| 		r = equalSums(e, aIface.(metricdata.Sum[float64]), cfg)
 | |
| 	case metricdata.ExponentialHistogram[float64]:
 | |
| 		r = equalExponentialHistograms(e, aIface.(metricdata.ExponentialHistogram[float64]), cfg)
 | |
| 	case metricdata.ExponentialHistogram[int64]:
 | |
| 		r = equalExponentialHistograms(e, aIface.(metricdata.ExponentialHistogram[int64]), cfg)
 | |
| 	case metricdata.ExponentialHistogramDataPoint[float64]:
 | |
| 		r = equalExponentialHistogramDataPoints(e, aIface.(metricdata.ExponentialHistogramDataPoint[float64]), cfg)
 | |
| 	case metricdata.ExponentialHistogramDataPoint[int64]:
 | |
| 		r = equalExponentialHistogramDataPoints(e, aIface.(metricdata.ExponentialHistogramDataPoint[int64]), cfg)
 | |
| 	case metricdata.ExponentialBucket:
 | |
| 		r = equalExponentialBuckets(e, aIface.(metricdata.ExponentialBucket), cfg)
 | |
| 	case metricdata.Summary:
 | |
| 		r = equalSummary(e, aIface.(metricdata.Summary), cfg)
 | |
| 	case metricdata.SummaryDataPoint:
 | |
| 		r = equalSummaryDataPoint(e, aIface.(metricdata.SummaryDataPoint), cfg)
 | |
| 	case metricdata.QuantileValue:
 | |
| 		r = equalQuantileValue(e, aIface.(metricdata.QuantileValue), cfg)
 | |
| 	default:
 | |
| 		// We control all types passed to this, panic to signal developers
 | |
| 		// early they changed things in an incompatible way.
 | |
| 		panic(fmt.Sprintf("unknown types: %T", expected))
 | |
| 	}
 | |
| 
 | |
| 	if len(r) > 0 {
 | |
| 		t.Error(r)
 | |
| 		return false
 | |
| 	}
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| // AssertAggregationsEqual asserts that two Aggregations are equal.
 | |
| func AssertAggregationsEqual(t TestingT, expected, actual metricdata.Aggregation, opts ...Option) bool {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	cfg := newConfig(opts)
 | |
| 	if r := equalAggregations(expected, actual, cfg); len(r) > 0 {
 | |
| 		t.Error(r)
 | |
| 		return false
 | |
| 	}
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| // AssertHasAttributes asserts that all Datapoints or HistogramDataPoints have all passed attrs.
 | |
| func AssertHasAttributes[T Datatypes](t TestingT, actual T, attrs ...attribute.KeyValue) bool {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	var reasons []string
 | |
| 
 | |
| 	switch e := any(actual).(type) {
 | |
| 	case metricdata.Exemplar[int64]:
 | |
| 		reasons = hasAttributesExemplars(e, attrs...)
 | |
| 	case metricdata.Exemplar[float64]:
 | |
| 		reasons = hasAttributesExemplars(e, attrs...)
 | |
| 	case metricdata.DataPoint[int64]:
 | |
| 		reasons = hasAttributesDataPoints(e, attrs...)
 | |
| 	case metricdata.DataPoint[float64]:
 | |
| 		reasons = hasAttributesDataPoints(e, attrs...)
 | |
| 	case metricdata.Gauge[int64]:
 | |
| 		reasons = hasAttributesGauge(e, attrs...)
 | |
| 	case metricdata.Gauge[float64]:
 | |
| 		reasons = hasAttributesGauge(e, attrs...)
 | |
| 	case metricdata.Sum[int64]:
 | |
| 		reasons = hasAttributesSum(e, attrs...)
 | |
| 	case metricdata.Sum[float64]:
 | |
| 		reasons = hasAttributesSum(e, attrs...)
 | |
| 	case metricdata.HistogramDataPoint[int64]:
 | |
| 		reasons = hasAttributesHistogramDataPoints(e, attrs...)
 | |
| 	case metricdata.HistogramDataPoint[float64]:
 | |
| 		reasons = hasAttributesHistogramDataPoints(e, attrs...)
 | |
| 	case metricdata.Extrema[int64], metricdata.Extrema[float64]:
 | |
| 		// Nothing to check.
 | |
| 	case metricdata.Histogram[int64]:
 | |
| 		reasons = hasAttributesHistogram(e, attrs...)
 | |
| 	case metricdata.Histogram[float64]:
 | |
| 		reasons = hasAttributesHistogram(e, attrs...)
 | |
| 	case metricdata.Metrics:
 | |
| 		reasons = hasAttributesMetrics(e, attrs...)
 | |
| 	case metricdata.ScopeMetrics:
 | |
| 		reasons = hasAttributesScopeMetrics(e, attrs...)
 | |
| 	case metricdata.ResourceMetrics:
 | |
| 		reasons = hasAttributesResourceMetrics(e, attrs...)
 | |
| 	case metricdata.ExponentialHistogram[int64]:
 | |
| 		reasons = hasAttributesExponentialHistogram(e, attrs...)
 | |
| 	case metricdata.ExponentialHistogram[float64]:
 | |
| 		reasons = hasAttributesExponentialHistogram(e, attrs...)
 | |
| 	case metricdata.ExponentialHistogramDataPoint[int64]:
 | |
| 		reasons = hasAttributesExponentialHistogramDataPoints(e, attrs...)
 | |
| 	case metricdata.ExponentialHistogramDataPoint[float64]:
 | |
| 		reasons = hasAttributesExponentialHistogramDataPoints(e, attrs...)
 | |
| 	case metricdata.ExponentialBucket:
 | |
| 		// Nothing to check.
 | |
| 	case metricdata.Summary:
 | |
| 		reasons = hasAttributesSummary(e, attrs...)
 | |
| 	case metricdata.SummaryDataPoint:
 | |
| 		reasons = hasAttributesSummaryDataPoint(e, attrs...)
 | |
| 	case metricdata.QuantileValue:
 | |
| 		// Nothing to check.
 | |
| 	default:
 | |
| 		// We control all types passed to this, panic to signal developers
 | |
| 		// early they changed things in an incompatible way.
 | |
| 		panic(fmt.Sprintf("unknown types: %T", actual))
 | |
| 	}
 | |
| 
 | |
| 	if len(reasons) > 0 {
 | |
| 		t.Error(reasons)
 | |
| 		return false
 | |
| 	}
 | |
| 
 | |
| 	return true
 | |
| }
 |