knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/observability/metrics/metricstest/assert_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 metricstest 18 19 import ( 20 "context" 21 "testing" 22 23 "go.opentelemetry.io/otel/attribute" 24 "go.opentelemetry.io/otel/sdk/instrumentation" 25 "go.opentelemetry.io/otel/sdk/metric/metricdata" 26 ) 27 28 func TestAssertMetricsPresent(t *testing.T) { 29 ft := &fakeT{} 30 31 m := &metrics{ 32 ScopeMetrics: []metricdata.ScopeMetrics{{ 33 Scope: instrumentation.Scope{ 34 Name: "first", 35 }, 36 Metrics: []metricdata.Metrics{{ 37 Name: "a", 38 }}, 39 }}, 40 } 41 42 AssertMetrics(ft, m, MetricsPresent("first", "a")) 43 44 if ft.Failed() { 45 t.Error("unexpected failure") 46 } 47 48 ft = &fakeT{} 49 50 AssertMetrics(ft, m, MetricsPresent("second", "a")) 51 52 if !ft.Failed() { 53 t.Error("should have failed") 54 } 55 56 AssertMetrics(ft, m, MetricsPresent("first", "b")) 57 58 if !ft.Failed() { 59 t.Error("should have failed") 60 } 61 } 62 63 func TestHasAttributes(t *testing.T) { 64 m := &metrics{ 65 ScopeMetrics: []metricdata.ScopeMetrics{{ 66 Scope: instrumentation.Scope{Name: "first-scope"}, 67 Metrics: []metricdata.Metrics{{ 68 Name: "a-metric", 69 Data: metricdata.Sum[int64]{ 70 DataPoints: []metricdata.DataPoint[int64]{{ 71 Attributes: attribute.NewSet( 72 attribute.String("k", "v"), 73 ), 74 }}, 75 }, 76 }}, 77 }, { 78 Scope: instrumentation.Scope{Name: "second-scope"}, 79 Metrics: []metricdata.Metrics{{ 80 Name: "b-metric", 81 Data: metricdata.Sum[int64]{ 82 DataPoints: []metricdata.DataPoint[int64]{{ 83 Attributes: attribute.NewSet( 84 attribute.String("k", "v"), 85 ), 86 }}, 87 }, 88 }, { 89 Name: "c-metric", 90 Data: metricdata.Histogram[int64]{ 91 DataPoints: []metricdata.HistogramDataPoint[int64]{{ 92 Attributes: attribute.NewSet( 93 attribute.String("k", "v"), 94 ), 95 }}, 96 }, 97 }, { 98 Name: "d-metric", 99 Data: metricdata.Histogram[float64]{ 100 DataPoints: []metricdata.HistogramDataPoint[float64]{{ 101 Attributes: attribute.NewSet( 102 attribute.String("k", "v"), 103 ), 104 }}, 105 }, 106 }}, 107 }}, 108 } 109 110 t.Run("no attributes", func(t *testing.T) { 111 ft := &fakeT{} 112 113 AssertMetrics(ft, m, HasAttributes("first", "a")) 114 115 // no metric prefix 116 AssertMetrics(ft, m, HasAttributes("first", "")) 117 118 // no scope prefix 119 AssertMetrics(ft, m, HasAttributes("", "a", 120 attribute.String("k", "v"), 121 )) 122 123 // no scope and metric prefix 124 AssertMetrics(ft, m, HasAttributes("", "")) 125 126 if ft.Failed() { 127 t.Error("unexpected failure") 128 } 129 }) 130 131 t.Run("has attributes", func(t *testing.T) { 132 ft := &fakeT{} 133 134 AssertMetrics(ft, m, HasAttributes("first", "a", 135 attribute.String("k", "v"), 136 )) 137 138 // no metric prefix 139 AssertMetrics(ft, m, HasAttributes("first", "", 140 attribute.String("k", "v"), 141 )) 142 143 // no scope prefix 144 AssertMetrics(ft, m, HasAttributes("", "a", 145 attribute.String("k", "v"), 146 )) 147 148 // no scope and metric prefix 149 AssertMetrics(ft, m, HasAttributes("", "", 150 attribute.String("k", "v"), 151 )) 152 153 if ft.Failed() { 154 t.Error("unexpected failure") 155 } 156 }) 157 158 t.Run("no match", func(t *testing.T) { 159 ft := &fakeT{} 160 161 AssertMetrics(ft, m, 162 HasAttributes("", "", attribute.String("k", "a"))) 163 164 if !ft.Failed() { 165 t.Error("expected failure") 166 } 167 }) 168 169 t.Run("no metrics", func(t *testing.T) { 170 ft := &fakeT{} 171 m := &metrics{} 172 173 AssertMetrics(ft, m, 174 HasAttributes("first", "a", attribute.String("k", "a"))) 175 176 if !ft.Failed() { 177 t.Error("expected failure") 178 } 179 }) 180 } 181 182 type metrics metricdata.ResourceMetrics 183 184 func (f *metrics) Collect(ctx context.Context, rm *metricdata.ResourceMetrics) error { 185 *rm = (metricdata.ResourceMetrics)(*f) 186 return nil 187 } 188 189 type fakeT struct { 190 failed bool 191 } 192 193 func (t *fakeT) Failed() bool { 194 return t.failed 195 } 196 func (t *fakeT) Error(args ...any) { t.failed = true } 197 func (t *fakeT) Errorf(format string, args ...any) { t.failed = true } 198 func (t *fakeT) Fatal(args ...any) { t.failed = true } 199 func (t *fakeT) Fatalf(format string, args ...any) { t.failed = true } 200 func (t *fakeT) Helper() {}