knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/observability/metrics/k8s/instruments_test.go (about)

     1  /*
     2  Copyright 2025 The Knative Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package k8s
    18  
    19  import (
    20  	"testing"
    21  
    22  	"go.opentelemetry.io/otel/attribute"
    23  	"go.opentelemetry.io/otel/metric"
    24  	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
    25  	"go.opentelemetry.io/otel/sdk/metric/metricdata"
    26  
    27  	"knative.dev/pkg/observability/metrics/metricstest"
    28  )
    29  
    30  func TestGauge(t *testing.T) {
    31  	r := sdkmetric.NewManualReader()
    32  	provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(r))
    33  	m := must(provider.Meter("meter").Int64UpDownCounter("instrument"))
    34  	g := gauge{m, attribute.NewSet(attribute.String("key", "val"))}
    35  
    36  	g.Inc()
    37  
    38  	metricstest.AssertMetrics(t, r,
    39  		metricstest.MetricsEqual("meter", metricdata.Metrics{
    40  			Name: "instrument",
    41  			Data: metricdata.Sum[int64]{
    42  				Temporality: metricdata.CumulativeTemporality,
    43  				DataPoints: []metricdata.DataPoint[int64]{{
    44  					Attributes: attribute.NewSet(attribute.String("key", "val")),
    45  					Value:      1,
    46  				}},
    47  			},
    48  		}),
    49  	)
    50  
    51  	g.Dec()
    52  
    53  	metricstest.AssertMetrics(t, r,
    54  		metricstest.MetricsEqual("meter", metricdata.Metrics{
    55  			Name: "instrument",
    56  			Data: metricdata.Sum[int64]{
    57  				Temporality: metricdata.CumulativeTemporality,
    58  				DataPoints: []metricdata.DataPoint[int64]{{
    59  					Attributes: attribute.NewSet(attribute.String("key", "val")),
    60  					Value:      0,
    61  				}},
    62  			},
    63  		}),
    64  	)
    65  }
    66  
    67  func TestCounter(t *testing.T) {
    68  	r := sdkmetric.NewManualReader()
    69  	provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(r))
    70  	m := must(provider.Meter("meter").Int64Counter("instrument"))
    71  	c := counter{m, attribute.NewSet(attribute.String("key", "val"))}
    72  
    73  	c.Inc()
    74  
    75  	metricstest.AssertMetrics(t, r,
    76  		metricstest.MetricsEqual("meter", metricdata.Metrics{
    77  			Name: "instrument",
    78  			Data: metricdata.Sum[int64]{
    79  				Temporality: metricdata.CumulativeTemporality,
    80  				IsMonotonic: true,
    81  				DataPoints: []metricdata.DataPoint[int64]{{
    82  					Attributes: attribute.NewSet(attribute.String("key", "val")),
    83  					Value:      1,
    84  				}},
    85  			},
    86  		}),
    87  	)
    88  
    89  	c.Inc()
    90  
    91  	metricstest.AssertMetrics(t, r,
    92  		metricstest.MetricsEqual("meter", metricdata.Metrics{
    93  			Name: "instrument",
    94  			Data: metricdata.Sum[int64]{
    95  				Temporality: metricdata.CumulativeTemporality,
    96  				IsMonotonic: true,
    97  				DataPoints: []metricdata.DataPoint[int64]{{
    98  					Attributes: attribute.NewSet(attribute.String("key", "val")),
    99  					Value:      2,
   100  				}},
   101  			},
   102  		}),
   103  	)
   104  }
   105  
   106  func TestHistogram(t *testing.T) {
   107  	r := sdkmetric.NewManualReader()
   108  	provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(r))
   109  	m := must(provider.Meter("meter").Float64Histogram("instrument",
   110  		metric.WithExplicitBucketBoundaries(0.01, 1, 2),
   111  	))
   112  	c := histogram{m, attribute.NewSet(attribute.String("key", "val"))}
   113  
   114  	c.Observe(1)
   115  
   116  	metricstest.AssertMetrics(t, r,
   117  		metricstest.MetricsEqual("meter", metricdata.Metrics{
   118  			Name: "instrument",
   119  			Data: metricdata.Histogram[float64]{
   120  				Temporality: metricdata.CumulativeTemporality,
   121  				DataPoints: []metricdata.HistogramDataPoint[float64]{{
   122  					Attributes:   attribute.NewSet(attribute.String("key", "val")),
   123  					Bounds:       []float64{0.01, 1, 2},
   124  					BucketCounts: []uint64{0, 1, 0, 0},
   125  					Count:        1,
   126  					Max:          metricdata.NewExtrema[float64](1),
   127  					Min:          metricdata.NewExtrema[float64](1),
   128  					Sum:          1,
   129  				}},
   130  			},
   131  		}),
   132  	)
   133  
   134  	c.Observe(2)
   135  
   136  	metricstest.AssertMetrics(t, r,
   137  		metricstest.MetricsEqual("meter", metricdata.Metrics{
   138  			Name: "instrument",
   139  			Data: metricdata.Histogram[float64]{
   140  				Temporality: metricdata.CumulativeTemporality,
   141  				DataPoints: []metricdata.HistogramDataPoint[float64]{{
   142  					Attributes:   attribute.NewSet(attribute.String("key", "val")),
   143  					Bounds:       []float64{0.01, 1, 2},
   144  					BucketCounts: []uint64{0, 1, 1, 0},
   145  					Count:        2,
   146  					Max:          metricdata.NewExtrema[float64](2),
   147  					Min:          metricdata.NewExtrema[float64](1),
   148  					Sum:          3,
   149  				}},
   150  			},
   151  		}),
   152  	)
   153  }
   154  
   155  func TestSettableGauge(t *testing.T) {
   156  	r := sdkmetric.NewManualReader()
   157  	provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(r))
   158  	m := must(provider.Meter("meter").Float64Gauge("instrument"))
   159  	g := settableGauge{m, attribute.NewSet(attribute.String("key", "val"))}
   160  
   161  	g.Set(1)
   162  
   163  	metricstest.AssertMetrics(t, r,
   164  		metricstest.MetricsEqual("meter", metricdata.Metrics{
   165  			Name: "instrument",
   166  			Data: metricdata.Gauge[float64]{
   167  				DataPoints: []metricdata.DataPoint[float64]{{
   168  					Attributes: attribute.NewSet(attribute.String("key", "val")),
   169  					Value:      1,
   170  				}},
   171  			},
   172  		}),
   173  	)
   174  
   175  	g.Set(2)
   176  
   177  	metricstest.AssertMetrics(t, r,
   178  		metricstest.MetricsEqual("meter", metricdata.Metrics{
   179  			Name: "instrument",
   180  			Data: metricdata.Gauge[float64]{
   181  				DataPoints: []metricdata.DataPoint[float64]{{
   182  					Attributes: attribute.NewSet(attribute.String("key", "val")),
   183  					Value:      2,
   184  				}},
   185  			},
   186  		}),
   187  	)
   188  }
   189  
   190  func must[T any](val T, err error) T {
   191  	if err != nil {
   192  		panic(err)
   193  	}
   194  	return val
   195  }