Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/component/otelcol/receiver/prometheus/internal/transaction_test.go
5414 views
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
15
package internal
16
17
import (
18
"context"
19
"errors"
20
"testing"
21
"time"
22
23
"github.com/prometheus/common/model"
24
"github.com/prometheus/prometheus/model/labels"
25
"github.com/prometheus/prometheus/model/metadata"
26
"github.com/prometheus/prometheus/scrape"
27
"github.com/stretchr/testify/assert"
28
"github.com/stretchr/testify/require"
29
"go.opentelemetry.io/collector/component/componenttest"
30
"go.opentelemetry.io/collector/config"
31
"go.opentelemetry.io/collector/consumer/consumertest"
32
"go.opentelemetry.io/collector/obsreport"
33
"go.opentelemetry.io/collector/pdata/pcommon"
34
"go.opentelemetry.io/collector/pdata/pmetric"
35
)
36
37
const (
38
startTimestamp = pcommon.Timestamp(1555366608340000000)
39
ts = int64(1555366610000)
40
interval = int64(15 * 1000)
41
tsNanos = pcommon.Timestamp(ts * 1e6)
42
tsPlusIntervalNanos = pcommon.Timestamp((ts + interval) * 1e6)
43
)
44
45
var (
46
target = scrape.NewTarget(
47
// processedLabels contain label values after processing (e.g. relabeling)
48
labels.FromMap(map[string]string{
49
model.InstanceLabel: "localhost:8080",
50
}),
51
// discoveredLabels contain labels prior to any processing
52
labels.FromMap(map[string]string{
53
model.AddressLabel: "address:8080",
54
model.SchemeLabel: "http",
55
}),
56
nil)
57
58
scrapeCtx = scrape.ContextWithMetricMetadataStore(
59
scrape.ContextWithTarget(context.Background(), target),
60
testMetadataStore(testMetadata))
61
)
62
63
func TestTransactionCommitWithoutAdding(t *testing.T) {
64
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, consumertest.NewNop(), nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
65
assert.NoError(t, tr.Commit())
66
}
67
68
func TestTransactionRollbackDoesNothing(t *testing.T) {
69
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, consumertest.NewNop(), nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
70
assert.NoError(t, tr.Rollback())
71
}
72
73
func TestTransactionUpdateMetadataDoesNothing(t *testing.T) {
74
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, consumertest.NewNop(), nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
75
_, err := tr.UpdateMetadata(0, labels.New(), metadata.Metadata{})
76
assert.NoError(t, err)
77
}
78
79
func TestTransactionAppendNoTarget(t *testing.T) {
80
badLabels := labels.FromStrings(model.MetricNameLabel, "counter_test")
81
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, consumertest.NewNop(), nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
82
_, err := tr.Append(0, badLabels, time.Now().Unix()*1000, 1.0)
83
assert.Error(t, err)
84
}
85
86
func TestTransactionAppendNoMetricName(t *testing.T) {
87
jobNotFoundLb := labels.FromMap(map[string]string{
88
model.InstanceLabel: "localhost:8080",
89
model.JobLabel: "test2",
90
})
91
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, consumertest.NewNop(), nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
92
_, err := tr.Append(0, jobNotFoundLb, time.Now().Unix()*1000, 1.0)
93
assert.ErrorIs(t, err, errMetricNameNotFound)
94
95
assert.ErrorIs(t, tr.Commit(), errNoDataToBuild)
96
}
97
98
func TestTransactionAppendEmptyMetricName(t *testing.T) {
99
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, consumertest.NewNop(), nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
100
_, err := tr.Append(0, labels.FromMap(map[string]string{
101
model.InstanceLabel: "localhost:8080",
102
model.JobLabel: "test2",
103
model.MetricNameLabel: "",
104
}), time.Now().Unix()*1000, 1.0)
105
assert.ErrorIs(t, err, errMetricNameNotFound)
106
}
107
108
func TestTransactionAppendResource(t *testing.T) {
109
sink := new(consumertest.MetricsSink)
110
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, sink, nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
111
_, err := tr.Append(0, labels.FromMap(map[string]string{
112
model.InstanceLabel: "localhost:8080",
113
model.JobLabel: "test",
114
model.MetricNameLabel: "counter_test",
115
}), time.Now().Unix()*1000, 1.0)
116
assert.NoError(t, err)
117
_, err = tr.Append(0, labels.FromMap(map[string]string{
118
model.InstanceLabel: "localhost:8080",
119
model.JobLabel: "test",
120
model.MetricNameLabel: startTimeMetricName,
121
}), time.Now().UnixMilli(), 1.0)
122
assert.NoError(t, err)
123
assert.NoError(t, tr.Commit())
124
expectedResource := CreateResource("test", "localhost:8080", labels.FromStrings(model.SchemeLabel, "http"))
125
mds := sink.AllMetrics()
126
require.Len(t, mds, 1)
127
gotResource := mds[0].ResourceMetrics().At(0).Resource()
128
require.Equal(t, expectedResource, gotResource)
129
}
130
131
func TestTransactionCommitErrorWhenAdjusterError(t *testing.T) {
132
goodLabels := labels.FromMap(map[string]string{
133
model.InstanceLabel: "localhost:8080",
134
model.JobLabel: "test",
135
model.MetricNameLabel: "counter_test",
136
})
137
sink := new(consumertest.MetricsSink)
138
adjusterErr := errors.New("adjuster error")
139
tr := newTransaction(scrapeCtx, &errorAdjuster{err: adjusterErr}, sink, nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
140
_, err := tr.Append(0, goodLabels, time.Now().Unix()*1000, 1.0)
141
assert.NoError(t, err)
142
assert.ErrorIs(t, tr.Commit(), adjusterErr)
143
}
144
145
// Ensure that we reject duplicate label keys. See https://github.com/open-telemetry/wg-prometheus/issues/44.
146
func TestTransactionAppendDuplicateLabels(t *testing.T) {
147
sink := new(consumertest.MetricsSink)
148
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, sink, nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
149
150
dupLabels := labels.FromStrings(
151
model.InstanceLabel, "0.0.0.0:8855",
152
model.JobLabel, "test",
153
model.MetricNameLabel, "counter_test",
154
"a", "1",
155
"a", "6",
156
"z", "9",
157
)
158
159
_, err := tr.Append(0, dupLabels, 1917, 1.0)
160
require.Error(t, err)
161
assert.Contains(t, err.Error(), `invalid sample: non-unique label names: "a"`)
162
}
163
164
func TestTransactionAppendHistogramNoLe(t *testing.T) {
165
sink := new(consumertest.MetricsSink)
166
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, sink, nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
167
168
goodLabels := labels.FromStrings(
169
model.InstanceLabel, "0.0.0.0:8855",
170
model.JobLabel, "test",
171
model.MetricNameLabel, "hist_test_bucket",
172
)
173
174
_, err := tr.Append(0, goodLabels, 1917, 1.0)
175
require.ErrorIs(t, err, errEmptyLeLabel)
176
}
177
178
func TestTransactionAppendSummaryNoQuantile(t *testing.T) {
179
sink := new(consumertest.MetricsSink)
180
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, sink, nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
181
182
goodLabels := labels.FromStrings(
183
model.InstanceLabel, "0.0.0.0:8855",
184
model.JobLabel, "test",
185
model.MetricNameLabel, "summary_test",
186
)
187
188
_, err := tr.Append(0, goodLabels, 1917, 1.0)
189
require.ErrorIs(t, err, errEmptyQuantileLabel)
190
}
191
192
func nopObsRecv() *obsreport.Receiver {
193
return obsreport.NewReceiver(obsreport.ReceiverSettings{
194
ReceiverID: config.NewComponentID("prometheus"),
195
Transport: transport,
196
ReceiverCreateSettings: componenttest.NewNopReceiverCreateSettings(),
197
})
198
}
199
200
func TestMetricBuilderCounters(t *testing.T) {
201
tests := []buildTestData{
202
{
203
name: "single-item",
204
inputs: []*testScrapedPage{
205
{
206
pts: []*testDataPoint{
207
createDataPoint("counter_test", 100, "foo", "bar"),
208
},
209
},
210
},
211
wants: func() []pmetric.Metrics {
212
md0 := pmetric.NewMetrics()
213
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
214
m0 := mL0.AppendEmpty()
215
m0.SetName("counter_test")
216
sum := m0.SetEmptySum()
217
sum.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
218
sum.SetIsMonotonic(true)
219
pt0 := sum.DataPoints().AppendEmpty()
220
pt0.SetDoubleValue(100.0)
221
pt0.SetStartTimestamp(startTimestamp)
222
pt0.SetTimestamp(tsNanos)
223
pt0.Attributes().PutStr("foo", "bar")
224
225
return []pmetric.Metrics{md0}
226
},
227
},
228
{
229
name: "two-items",
230
inputs: []*testScrapedPage{
231
{
232
pts: []*testDataPoint{
233
createDataPoint("counter_test", 150, "foo", "bar"),
234
createDataPoint("counter_test", 25, "foo", "other"),
235
},
236
},
237
},
238
wants: func() []pmetric.Metrics {
239
md0 := pmetric.NewMetrics()
240
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
241
m0 := mL0.AppendEmpty()
242
m0.SetName("counter_test")
243
sum := m0.SetEmptySum()
244
sum.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
245
sum.SetIsMonotonic(true)
246
pt0 := sum.DataPoints().AppendEmpty()
247
pt0.SetDoubleValue(150.0)
248
pt0.SetStartTimestamp(startTimestamp)
249
pt0.SetTimestamp(tsNanos)
250
pt0.Attributes().PutStr("foo", "bar")
251
252
pt1 := sum.DataPoints().AppendEmpty()
253
pt1.SetDoubleValue(25.0)
254
pt1.SetStartTimestamp(startTimestamp)
255
pt1.SetTimestamp(tsNanos)
256
pt1.Attributes().PutStr("foo", "other")
257
258
return []pmetric.Metrics{md0}
259
},
260
},
261
{
262
name: "two-metrics",
263
inputs: []*testScrapedPage{
264
{
265
pts: []*testDataPoint{
266
createDataPoint("counter_test", 150, "foo", "bar"),
267
createDataPoint("counter_test", 25, "foo", "other"),
268
createDataPoint("counter_test2", 100, "foo", "bar"),
269
},
270
},
271
},
272
wants: func() []pmetric.Metrics {
273
md0 := pmetric.NewMetrics()
274
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
275
m0 := mL0.AppendEmpty()
276
m0.SetName("counter_test")
277
sum0 := m0.SetEmptySum()
278
sum0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
279
sum0.SetIsMonotonic(true)
280
pt0 := sum0.DataPoints().AppendEmpty()
281
pt0.SetDoubleValue(150.0)
282
pt0.SetStartTimestamp(startTimestamp)
283
pt0.SetTimestamp(tsNanos)
284
pt0.Attributes().PutStr("foo", "bar")
285
286
pt1 := sum0.DataPoints().AppendEmpty()
287
pt1.SetDoubleValue(25.0)
288
pt1.SetStartTimestamp(startTimestamp)
289
pt1.SetTimestamp(tsNanos)
290
pt1.Attributes().PutStr("foo", "other")
291
292
m1 := mL0.AppendEmpty()
293
m1.SetName("counter_test2")
294
sum1 := m1.SetEmptySum()
295
sum1.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
296
sum1.SetIsMonotonic(true)
297
pt2 := sum1.DataPoints().AppendEmpty()
298
pt2.SetDoubleValue(100.0)
299
pt2.SetStartTimestamp(startTimestamp)
300
pt2.SetTimestamp(tsNanos)
301
pt2.Attributes().PutStr("foo", "bar")
302
303
return []pmetric.Metrics{md0}
304
},
305
},
306
{
307
name: "metrics-with-poor-names",
308
inputs: []*testScrapedPage{
309
{
310
pts: []*testDataPoint{
311
createDataPoint("poor_name_count", 100, "foo", "bar"),
312
},
313
},
314
},
315
wants: func() []pmetric.Metrics {
316
md0 := pmetric.NewMetrics()
317
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
318
m0 := mL0.AppendEmpty()
319
m0.SetName("poor_name_count")
320
sum := m0.SetEmptySum()
321
sum.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
322
sum.SetIsMonotonic(true)
323
pt0 := sum.DataPoints().AppendEmpty()
324
pt0.SetDoubleValue(100.0)
325
pt0.SetStartTimestamp(startTimestamp)
326
pt0.SetTimestamp(tsNanos)
327
pt0.Attributes().PutStr("foo", "bar")
328
329
return []pmetric.Metrics{md0}
330
},
331
},
332
}
333
334
for _, tt := range tests {
335
t.Run(tt.name, func(t *testing.T) {
336
tt.run(t)
337
})
338
}
339
}
340
341
func TestMetricBuilderGauges(t *testing.T) {
342
tests := []buildTestData{
343
{
344
name: "one-gauge",
345
inputs: []*testScrapedPage{
346
{
347
pts: []*testDataPoint{
348
createDataPoint("gauge_test", 100, "foo", "bar"),
349
},
350
},
351
{
352
pts: []*testDataPoint{
353
createDataPoint("gauge_test", 90, "foo", "bar"),
354
},
355
},
356
},
357
wants: func() []pmetric.Metrics {
358
md0 := pmetric.NewMetrics()
359
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
360
m0 := mL0.AppendEmpty()
361
m0.SetName("gauge_test")
362
gauge0 := m0.SetEmptyGauge()
363
pt0 := gauge0.DataPoints().AppendEmpty()
364
pt0.SetDoubleValue(100.0)
365
pt0.SetStartTimestamp(0)
366
pt0.SetTimestamp(tsNanos)
367
pt0.Attributes().PutStr("foo", "bar")
368
369
md1 := pmetric.NewMetrics()
370
mL1 := md1.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
371
m1 := mL1.AppendEmpty()
372
m1.SetName("gauge_test")
373
gauge1 := m1.SetEmptyGauge()
374
pt1 := gauge1.DataPoints().AppendEmpty()
375
pt1.SetDoubleValue(90.0)
376
pt1.SetStartTimestamp(0)
377
pt1.SetTimestamp(tsPlusIntervalNanos)
378
pt1.Attributes().PutStr("foo", "bar")
379
380
return []pmetric.Metrics{md0, md1}
381
},
382
},
383
{
384
name: "gauge-with-different-tags",
385
inputs: []*testScrapedPage{
386
{
387
pts: []*testDataPoint{
388
createDataPoint("gauge_test", 100, "foo", "bar"),
389
createDataPoint("gauge_test", 200, "bar", "foo"),
390
},
391
},
392
},
393
wants: func() []pmetric.Metrics {
394
md0 := pmetric.NewMetrics()
395
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
396
m0 := mL0.AppendEmpty()
397
m0.SetName("gauge_test")
398
gauge0 := m0.SetEmptyGauge()
399
pt0 := gauge0.DataPoints().AppendEmpty()
400
pt0.SetDoubleValue(100.0)
401
pt0.SetStartTimestamp(0)
402
pt0.SetTimestamp(tsNanos)
403
pt0.Attributes().PutStr("foo", "bar")
404
405
pt1 := gauge0.DataPoints().AppendEmpty()
406
pt1.SetDoubleValue(200.0)
407
pt1.SetStartTimestamp(0)
408
pt1.SetTimestamp(tsNanos)
409
pt1.Attributes().PutStr("bar", "foo")
410
411
return []pmetric.Metrics{md0}
412
},
413
},
414
{
415
// TODO: A decision need to be made. If we want to have the behavior which can generate different tag key
416
// sets because metrics come and go
417
name: "gauge-comes-and-go-with-different-tagset",
418
inputs: []*testScrapedPage{
419
{
420
pts: []*testDataPoint{
421
createDataPoint("gauge_test", 100, "foo", "bar"),
422
createDataPoint("gauge_test", 200, "bar", "foo"),
423
},
424
},
425
{
426
pts: []*testDataPoint{
427
createDataPoint("gauge_test", 20, "foo", "bar"),
428
},
429
},
430
},
431
wants: func() []pmetric.Metrics {
432
md0 := pmetric.NewMetrics()
433
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
434
m0 := mL0.AppendEmpty()
435
m0.SetName("gauge_test")
436
gauge0 := m0.SetEmptyGauge()
437
pt0 := gauge0.DataPoints().AppendEmpty()
438
pt0.SetDoubleValue(100.0)
439
pt0.SetStartTimestamp(0)
440
pt0.SetTimestamp(tsNanos)
441
pt0.Attributes().PutStr("foo", "bar")
442
443
pt1 := gauge0.DataPoints().AppendEmpty()
444
pt1.SetDoubleValue(200.0)
445
pt1.SetStartTimestamp(0)
446
pt1.SetTimestamp(tsNanos)
447
pt1.Attributes().PutStr("bar", "foo")
448
449
md1 := pmetric.NewMetrics()
450
mL1 := md1.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
451
m1 := mL1.AppendEmpty()
452
m1.SetName("gauge_test")
453
gauge1 := m1.SetEmptyGauge()
454
pt2 := gauge1.DataPoints().AppendEmpty()
455
pt2.SetDoubleValue(20.0)
456
pt2.SetStartTimestamp(0)
457
pt2.SetTimestamp(tsPlusIntervalNanos)
458
pt2.Attributes().PutStr("foo", "bar")
459
460
return []pmetric.Metrics{md0, md1}
461
},
462
},
463
}
464
465
for _, tt := range tests {
466
t.Run(tt.name, func(t *testing.T) {
467
tt.run(t)
468
})
469
}
470
}
471
472
func TestMetricBuilderUntyped(t *testing.T) {
473
tests := []buildTestData{
474
{
475
name: "one-unknown",
476
inputs: []*testScrapedPage{
477
{
478
pts: []*testDataPoint{
479
createDataPoint("unknown_test", 100, "foo", "bar"),
480
},
481
},
482
},
483
wants: func() []pmetric.Metrics {
484
md0 := pmetric.NewMetrics()
485
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
486
m0 := mL0.AppendEmpty()
487
m0.SetName("unknown_test")
488
gauge0 := m0.SetEmptyGauge()
489
pt0 := gauge0.DataPoints().AppendEmpty()
490
pt0.SetDoubleValue(100.0)
491
pt0.SetStartTimestamp(0)
492
pt0.SetTimestamp(tsNanos)
493
pt0.Attributes().PutStr("foo", "bar")
494
495
return []pmetric.Metrics{md0}
496
},
497
},
498
{
499
name: "no-type-hint",
500
inputs: []*testScrapedPage{
501
{
502
pts: []*testDataPoint{
503
createDataPoint("something_not_exists", 100, "foo", "bar"),
504
createDataPoint("theother_not_exists", 200, "foo", "bar"),
505
createDataPoint("theother_not_exists", 300, "bar", "foo"),
506
},
507
},
508
},
509
wants: func() []pmetric.Metrics {
510
md0 := pmetric.NewMetrics()
511
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
512
m0 := mL0.AppendEmpty()
513
m0.SetName("something_not_exists")
514
gauge0 := m0.SetEmptyGauge()
515
pt0 := gauge0.DataPoints().AppendEmpty()
516
pt0.SetDoubleValue(100.0)
517
pt0.SetTimestamp(tsNanos)
518
pt0.Attributes().PutStr("foo", "bar")
519
520
m1 := mL0.AppendEmpty()
521
m1.SetName("theother_not_exists")
522
gauge1 := m1.SetEmptyGauge()
523
pt1 := gauge1.DataPoints().AppendEmpty()
524
pt1.SetDoubleValue(200.0)
525
pt1.SetTimestamp(tsNanos)
526
pt1.Attributes().PutStr("foo", "bar")
527
528
pt2 := gauge1.DataPoints().AppendEmpty()
529
pt2.SetDoubleValue(300.0)
530
pt2.SetTimestamp(tsNanos)
531
pt2.Attributes().PutStr("bar", "foo")
532
533
return []pmetric.Metrics{md0}
534
},
535
},
536
{
537
name: "untype-metric-poor-names",
538
inputs: []*testScrapedPage{
539
{
540
pts: []*testDataPoint{
541
createDataPoint("some_count", 100, "foo", "bar"),
542
},
543
},
544
},
545
wants: func() []pmetric.Metrics {
546
md0 := pmetric.NewMetrics()
547
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
548
m0 := mL0.AppendEmpty()
549
m0.SetName("some_count")
550
gauge0 := m0.SetEmptyGauge()
551
pt0 := gauge0.DataPoints().AppendEmpty()
552
pt0.SetDoubleValue(100.0)
553
pt0.SetTimestamp(tsNanos)
554
pt0.Attributes().PutStr("foo", "bar")
555
556
return []pmetric.Metrics{md0}
557
},
558
},
559
}
560
561
for _, tt := range tests {
562
t.Run(tt.name, func(t *testing.T) {
563
tt.run(t)
564
})
565
}
566
}
567
568
func TestMetricBuilderHistogram(t *testing.T) {
569
tests := []buildTestData{
570
{
571
name: "single item",
572
inputs: []*testScrapedPage{
573
{
574
pts: []*testDataPoint{
575
createDataPoint("hist_test_bucket", 1, "foo", "bar", "le", "10"),
576
createDataPoint("hist_test_bucket", 2, "foo", "bar", "le", "20"),
577
createDataPoint("hist_test_bucket", 10, "foo", "bar", "le", "+inf"),
578
createDataPoint("hist_test_sum", 99, "foo", "bar"),
579
createDataPoint("hist_test_count", 10, "foo", "bar"),
580
},
581
},
582
},
583
wants: func() []pmetric.Metrics {
584
md0 := pmetric.NewMetrics()
585
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
586
m0 := mL0.AppendEmpty()
587
m0.SetName("hist_test")
588
hist0 := m0.SetEmptyHistogram()
589
hist0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
590
pt0 := hist0.DataPoints().AppendEmpty()
591
pt0.SetCount(10)
592
pt0.SetSum(99)
593
pt0.ExplicitBounds().FromRaw([]float64{10, 20})
594
pt0.BucketCounts().FromRaw([]uint64{1, 1, 8})
595
pt0.SetTimestamp(tsNanos)
596
pt0.SetStartTimestamp(startTimestamp)
597
pt0.Attributes().PutStr("foo", "bar")
598
599
return []pmetric.Metrics{md0}
600
},
601
},
602
{
603
name: "multi-groups",
604
inputs: []*testScrapedPage{
605
{
606
pts: []*testDataPoint{
607
createDataPoint("hist_test_bucket", 1, "foo", "bar", "le", "10"),
608
createDataPoint("hist_test_bucket", 2, "foo", "bar", "le", "20"),
609
createDataPoint("hist_test_bucket", 10, "foo", "bar", "le", "+inf"),
610
createDataPoint("hist_test_sum", 99, "foo", "bar"),
611
createDataPoint("hist_test_count", 10, "foo", "bar"),
612
createDataPoint("hist_test_bucket", 1, "key2", "v2", "le", "10"),
613
createDataPoint("hist_test_bucket", 2, "key2", "v2", "le", "20"),
614
createDataPoint("hist_test_bucket", 3, "key2", "v2", "le", "+inf"),
615
createDataPoint("hist_test_sum", 50, "key2", "v2"),
616
createDataPoint("hist_test_count", 3, "key2", "v2"),
617
},
618
},
619
},
620
wants: func() []pmetric.Metrics {
621
md0 := pmetric.NewMetrics()
622
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
623
m0 := mL0.AppendEmpty()
624
m0.SetName("hist_test")
625
hist0 := m0.SetEmptyHistogram()
626
hist0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
627
pt0 := hist0.DataPoints().AppendEmpty()
628
pt0.SetCount(10)
629
pt0.SetSum(99)
630
pt0.ExplicitBounds().FromRaw([]float64{10, 20})
631
pt0.BucketCounts().FromRaw([]uint64{1, 1, 8})
632
pt0.SetTimestamp(tsNanos)
633
pt0.SetStartTimestamp(startTimestamp)
634
pt0.Attributes().PutStr("foo", "bar")
635
636
pt1 := hist0.DataPoints().AppendEmpty()
637
pt1.SetCount(3)
638
pt1.SetSum(50)
639
pt1.ExplicitBounds().FromRaw([]float64{10, 20})
640
pt1.BucketCounts().FromRaw([]uint64{1, 1, 1})
641
pt1.SetTimestamp(tsNanos)
642
pt1.SetStartTimestamp(startTimestamp)
643
pt1.Attributes().PutStr("key2", "v2")
644
645
return []pmetric.Metrics{md0}
646
},
647
},
648
{
649
name: "multi-groups-and-families",
650
inputs: []*testScrapedPage{
651
{
652
pts: []*testDataPoint{
653
createDataPoint("hist_test_bucket", 1, "foo", "bar", "le", "10"),
654
createDataPoint("hist_test_bucket", 2, "foo", "bar", "le", "20"),
655
createDataPoint("hist_test_bucket", 10, "foo", "bar", "le", "+inf"),
656
createDataPoint("hist_test_sum", 99, "foo", "bar"),
657
createDataPoint("hist_test_count", 10, "foo", "bar"),
658
createDataPoint("hist_test_bucket", 1, "key2", "v2", "le", "10"),
659
createDataPoint("hist_test_bucket", 2, "key2", "v2", "le", "20"),
660
createDataPoint("hist_test_bucket", 3, "key2", "v2", "le", "+inf"),
661
createDataPoint("hist_test_sum", 50, "key2", "v2"),
662
createDataPoint("hist_test_count", 3, "key2", "v2"),
663
createDataPoint("hist_test2_bucket", 1, "foo", "bar", "le", "10"),
664
createDataPoint("hist_test2_bucket", 2, "foo", "bar", "le", "20"),
665
createDataPoint("hist_test2_bucket", 3, "foo", "bar", "le", "+inf"),
666
createDataPoint("hist_test2_sum", 50, "foo", "bar"),
667
createDataPoint("hist_test2_count", 3, "foo", "bar"),
668
},
669
},
670
},
671
wants: func() []pmetric.Metrics {
672
md0 := pmetric.NewMetrics()
673
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
674
m0 := mL0.AppendEmpty()
675
m0.SetName("hist_test")
676
hist0 := m0.SetEmptyHistogram()
677
hist0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
678
pt0 := hist0.DataPoints().AppendEmpty()
679
pt0.SetCount(10)
680
pt0.SetSum(99)
681
pt0.ExplicitBounds().FromRaw([]float64{10, 20})
682
pt0.BucketCounts().FromRaw([]uint64{1, 1, 8})
683
pt0.SetTimestamp(tsNanos)
684
pt0.SetStartTimestamp(startTimestamp)
685
pt0.Attributes().PutStr("foo", "bar")
686
687
pt1 := hist0.DataPoints().AppendEmpty()
688
pt1.SetCount(3)
689
pt1.SetSum(50)
690
pt1.ExplicitBounds().FromRaw([]float64{10, 20})
691
pt1.BucketCounts().FromRaw([]uint64{1, 1, 1})
692
pt1.SetTimestamp(tsNanos)
693
pt1.SetStartTimestamp(startTimestamp)
694
pt1.Attributes().PutStr("key2", "v2")
695
696
m1 := mL0.AppendEmpty()
697
m1.SetName("hist_test2")
698
hist1 := m1.SetEmptyHistogram()
699
hist1.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
700
pt2 := hist1.DataPoints().AppendEmpty()
701
pt2.SetCount(3)
702
pt2.SetSum(50)
703
pt2.ExplicitBounds().FromRaw([]float64{10, 20})
704
pt2.BucketCounts().FromRaw([]uint64{1, 1, 1})
705
pt2.SetTimestamp(tsNanos)
706
pt2.SetStartTimestamp(startTimestamp)
707
pt2.Attributes().PutStr("foo", "bar")
708
709
return []pmetric.Metrics{md0}
710
},
711
},
712
{
713
name: "unordered-buckets",
714
inputs: []*testScrapedPage{
715
{
716
pts: []*testDataPoint{
717
createDataPoint("hist_test_bucket", 10, "foo", "bar", "le", "+inf"),
718
createDataPoint("hist_test_bucket", 1, "foo", "bar", "le", "10"),
719
createDataPoint("hist_test_bucket", 2, "foo", "bar", "le", "20"),
720
createDataPoint("hist_test_sum", 99, "foo", "bar"),
721
createDataPoint("hist_test_count", 10, "foo", "bar"),
722
},
723
},
724
},
725
wants: func() []pmetric.Metrics {
726
md0 := pmetric.NewMetrics()
727
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
728
m0 := mL0.AppendEmpty()
729
m0.SetName("hist_test")
730
hist0 := m0.SetEmptyHistogram()
731
hist0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
732
pt0 := hist0.DataPoints().AppendEmpty()
733
pt0.SetCount(10)
734
pt0.SetSum(99)
735
pt0.ExplicitBounds().FromRaw([]float64{10, 20})
736
pt0.BucketCounts().FromRaw([]uint64{1, 1, 8})
737
pt0.SetTimestamp(tsNanos)
738
pt0.SetStartTimestamp(startTimestamp)
739
pt0.Attributes().PutStr("foo", "bar")
740
741
return []pmetric.Metrics{md0}
742
},
743
},
744
{
745
// this won't likely happen in real env, as prometheus won't generate histogram with less than 3 buckets
746
name: "only-one-bucket",
747
inputs: []*testScrapedPage{
748
{
749
pts: []*testDataPoint{
750
createDataPoint("hist_test_bucket", 3, "foo", "bar", "le", "+inf"),
751
createDataPoint("hist_test_count", 3, "foo", "bar"),
752
createDataPoint("hist_test_sum", 100, "foo", "bar"),
753
},
754
},
755
},
756
wants: func() []pmetric.Metrics {
757
md0 := pmetric.NewMetrics()
758
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
759
m0 := mL0.AppendEmpty()
760
m0.SetName("hist_test")
761
hist0 := m0.SetEmptyHistogram()
762
hist0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
763
pt0 := hist0.DataPoints().AppendEmpty()
764
pt0.SetCount(3)
765
pt0.SetSum(100)
766
pt0.BucketCounts().FromRaw([]uint64{3})
767
pt0.SetTimestamp(tsNanos)
768
pt0.SetStartTimestamp(startTimestamp)
769
pt0.Attributes().PutStr("foo", "bar")
770
771
return []pmetric.Metrics{md0}
772
},
773
},
774
{
775
// this won't likely happen in real env, as prometheus won't generate histogram with less than 3 buckets
776
name: "only-one-bucket-noninf",
777
inputs: []*testScrapedPage{
778
{
779
pts: []*testDataPoint{
780
createDataPoint("hist_test_bucket", 3, "foo", "bar", "le", "20"),
781
createDataPoint("hist_test_count", 3, "foo", "bar"),
782
createDataPoint("hist_test_sum", 100, "foo", "bar"),
783
},
784
},
785
},
786
wants: func() []pmetric.Metrics {
787
md0 := pmetric.NewMetrics()
788
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
789
m0 := mL0.AppendEmpty()
790
m0.SetName("hist_test")
791
hist0 := m0.SetEmptyHistogram()
792
hist0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
793
pt0 := hist0.DataPoints().AppendEmpty()
794
pt0.SetCount(3)
795
pt0.SetSum(100)
796
pt0.BucketCounts().FromRaw([]uint64{3})
797
pt0.SetTimestamp(tsNanos)
798
pt0.SetStartTimestamp(startTimestamp)
799
pt0.Attributes().PutStr("foo", "bar")
800
801
return []pmetric.Metrics{md0}
802
},
803
},
804
{
805
name: "no-sum",
806
inputs: []*testScrapedPage{
807
{
808
pts: []*testDataPoint{
809
createDataPoint("hist_test_bucket", 1, "foo", "bar", "le", "10"),
810
createDataPoint("hist_test_bucket", 2, "foo", "bar", "le", "20"),
811
createDataPoint("hist_test_bucket", 3, "foo", "bar", "le", "+inf"),
812
createDataPoint("hist_test_count", 3, "foo", "bar"),
813
},
814
},
815
},
816
wants: func() []pmetric.Metrics {
817
md0 := pmetric.NewMetrics()
818
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
819
m0 := mL0.AppendEmpty()
820
m0.SetName("hist_test")
821
hist0 := m0.SetEmptyHistogram()
822
hist0.SetAggregationTemporality(pmetric.AggregationTemporalityCumulative)
823
pt0 := hist0.DataPoints().AppendEmpty()
824
pt0.SetCount(3)
825
pt0.ExplicitBounds().FromRaw([]float64{10, 20})
826
pt0.BucketCounts().FromRaw([]uint64{1, 1, 1})
827
pt0.SetTimestamp(tsNanos)
828
pt0.SetStartTimestamp(startTimestamp)
829
pt0.Attributes().PutStr("foo", "bar")
830
831
return []pmetric.Metrics{md0}
832
},
833
},
834
{
835
name: "corrupted-no-buckets",
836
inputs: []*testScrapedPage{
837
{
838
pts: []*testDataPoint{
839
createDataPoint("hist_test_sum", 99),
840
createDataPoint("hist_test_count", 10),
841
},
842
},
843
},
844
wants: func() []pmetric.Metrics {
845
return []pmetric.Metrics{pmetric.NewMetrics()}
846
},
847
},
848
{
849
name: "corrupted-no-count",
850
inputs: []*testScrapedPage{
851
{
852
pts: []*testDataPoint{
853
createDataPoint("hist_test_bucket", 1, "foo", "bar", "le", "10"),
854
createDataPoint("hist_test_bucket", 2, "foo", "bar", "le", "20"),
855
createDataPoint("hist_test_bucket", 3, "foo", "bar", "le", "+inf"),
856
createDataPoint("hist_test_sum", 99, "foo", "bar"),
857
},
858
},
859
},
860
wants: func() []pmetric.Metrics {
861
return []pmetric.Metrics{pmetric.NewMetrics()}
862
},
863
},
864
}
865
866
for _, tt := range tests {
867
t.Run(tt.name, func(t *testing.T) {
868
tt.run(t)
869
})
870
}
871
}
872
873
func TestMetricBuilderSummary(t *testing.T) {
874
tests := []buildTestData{
875
{
876
name: "no-sum-and-count",
877
inputs: []*testScrapedPage{
878
{
879
pts: []*testDataPoint{
880
createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"),
881
},
882
},
883
},
884
wants: func() []pmetric.Metrics {
885
return []pmetric.Metrics{pmetric.NewMetrics()}
886
},
887
},
888
{
889
name: "no-count",
890
inputs: []*testScrapedPage{
891
{
892
pts: []*testDataPoint{
893
createDataPoint("summary_test", 1, "foo", "bar", "quantile", "0.5"),
894
createDataPoint("summary_test", 2, "foo", "bar", "quantile", "0.75"),
895
createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"),
896
createDataPoint("summary_test_sum", 500, "foo", "bar"),
897
},
898
},
899
},
900
wants: func() []pmetric.Metrics {
901
return []pmetric.Metrics{pmetric.NewMetrics()}
902
},
903
},
904
{
905
name: "no-sum",
906
inputs: []*testScrapedPage{
907
{
908
pts: []*testDataPoint{
909
createDataPoint("summary_test", 1, "foo", "bar", "quantile", "0.5"),
910
createDataPoint("summary_test", 2, "foo", "bar", "quantile", "0.75"),
911
createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"),
912
createDataPoint("summary_test_count", 500, "foo", "bar"),
913
},
914
},
915
},
916
wants: func() []pmetric.Metrics {
917
md0 := pmetric.NewMetrics()
918
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
919
m0 := mL0.AppendEmpty()
920
m0.SetName("summary_test")
921
sum0 := m0.SetEmptySummary()
922
pt0 := sum0.DataPoints().AppendEmpty()
923
pt0.SetTimestamp(tsNanos)
924
pt0.SetStartTimestamp(startTimestamp)
925
pt0.SetCount(500)
926
pt0.SetSum(0.0)
927
pt0.Attributes().PutStr("foo", "bar")
928
qvL := pt0.QuantileValues()
929
q50 := qvL.AppendEmpty()
930
q50.SetQuantile(.50)
931
q50.SetValue(1.0)
932
q75 := qvL.AppendEmpty()
933
q75.SetQuantile(.75)
934
q75.SetValue(2.0)
935
q100 := qvL.AppendEmpty()
936
q100.SetQuantile(1)
937
q100.SetValue(5.0)
938
939
return []pmetric.Metrics{md0}
940
},
941
},
942
{
943
name: "empty-quantiles",
944
inputs: []*testScrapedPage{
945
{
946
pts: []*testDataPoint{
947
createDataPoint("summary_test_sum", 100, "foo", "bar"),
948
createDataPoint("summary_test_count", 500, "foo", "bar"),
949
},
950
},
951
},
952
wants: func() []pmetric.Metrics {
953
md0 := pmetric.NewMetrics()
954
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
955
m0 := mL0.AppendEmpty()
956
m0.SetName("summary_test")
957
sum0 := m0.SetEmptySummary()
958
pt0 := sum0.DataPoints().AppendEmpty()
959
pt0.SetStartTimestamp(startTimestamp)
960
pt0.SetTimestamp(tsNanos)
961
pt0.SetCount(500)
962
pt0.SetSum(100.0)
963
pt0.Attributes().PutStr("foo", "bar")
964
965
return []pmetric.Metrics{md0}
966
},
967
},
968
{
969
name: "regular-summary",
970
inputs: []*testScrapedPage{
971
{
972
pts: []*testDataPoint{
973
createDataPoint("summary_test", 1, "foo", "bar", "quantile", "0.5"),
974
createDataPoint("summary_test", 2, "foo", "bar", "quantile", "0.75"),
975
createDataPoint("summary_test", 5, "foo", "bar", "quantile", "1"),
976
createDataPoint("summary_test_sum", 100, "foo", "bar"),
977
createDataPoint("summary_test_count", 500, "foo", "bar"),
978
},
979
},
980
},
981
wants: func() []pmetric.Metrics {
982
md0 := pmetric.NewMetrics()
983
mL0 := md0.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics()
984
m0 := mL0.AppendEmpty()
985
m0.SetName("summary_test")
986
sum0 := m0.SetEmptySummary()
987
pt0 := sum0.DataPoints().AppendEmpty()
988
pt0.SetStartTimestamp(startTimestamp)
989
pt0.SetTimestamp(tsNanos)
990
pt0.SetCount(500)
991
pt0.SetSum(100.0)
992
pt0.Attributes().PutStr("foo", "bar")
993
qvL := pt0.QuantileValues()
994
q50 := qvL.AppendEmpty()
995
q50.SetQuantile(.50)
996
q50.SetValue(1.0)
997
q75 := qvL.AppendEmpty()
998
q75.SetQuantile(.75)
999
q75.SetValue(2.0)
1000
q100 := qvL.AppendEmpty()
1001
q100.SetQuantile(1)
1002
q100.SetValue(5.0)
1003
1004
return []pmetric.Metrics{md0}
1005
},
1006
},
1007
}
1008
1009
for _, tt := range tests {
1010
t.Run(tt.name, func(t *testing.T) {
1011
tt.run(t)
1012
})
1013
}
1014
}
1015
1016
type buildTestData struct {
1017
name string
1018
inputs []*testScrapedPage
1019
wants func() []pmetric.Metrics
1020
}
1021
1022
func (tt buildTestData) run(t *testing.T) {
1023
wants := tt.wants()
1024
assert.EqualValues(t, len(wants), len(tt.inputs))
1025
st := ts
1026
for i, page := range tt.inputs {
1027
sink := new(consumertest.MetricsSink)
1028
tr := newTransaction(scrapeCtx, &startTimeAdjuster{startTime: startTimestamp}, sink, nil, componenttest.NewNopReceiverCreateSettings(), nopObsRecv())
1029
for _, pt := range page.pts {
1030
// set ts for testing
1031
pt.t = st
1032
_, err := tr.Append(0, pt.lb, pt.t, pt.v)
1033
assert.NoError(t, err)
1034
}
1035
assert.NoError(t, tr.Commit())
1036
mds := sink.AllMetrics()
1037
if wants[i].ResourceMetrics().Len() == 0 {
1038
// Receiver does not emit empty metrics, so will not have anything in the sink.
1039
require.Len(t, mds, 0)
1040
st += interval
1041
continue
1042
}
1043
require.Len(t, mds, 1)
1044
assertEquivalentMetrics(t, wants[i], mds[0])
1045
st += interval
1046
}
1047
}
1048
1049
type errorAdjuster struct {
1050
err error
1051
}
1052
1053
func (ea *errorAdjuster) AdjustMetrics(pmetric.Metrics) error {
1054
return ea.err
1055
}
1056
1057
type startTimeAdjuster struct {
1058
startTime pcommon.Timestamp
1059
}
1060
1061
func (s *startTimeAdjuster) AdjustMetrics(metrics pmetric.Metrics) error {
1062
for i := 0; i < metrics.ResourceMetrics().Len(); i++ {
1063
rm := metrics.ResourceMetrics().At(i)
1064
for j := 0; j < rm.ScopeMetrics().Len(); j++ {
1065
ilm := rm.ScopeMetrics().At(j)
1066
for k := 0; k < ilm.Metrics().Len(); k++ {
1067
metric := ilm.Metrics().At(k)
1068
switch metric.Type() {
1069
case pmetric.MetricTypeSum:
1070
dps := metric.Sum().DataPoints()
1071
for l := 0; l < dps.Len(); l++ {
1072
dps.At(l).SetStartTimestamp(s.startTime)
1073
}
1074
case pmetric.MetricTypeSummary:
1075
dps := metric.Summary().DataPoints()
1076
for l := 0; l < dps.Len(); l++ {
1077
dps.At(l).SetStartTimestamp(s.startTime)
1078
}
1079
case pmetric.MetricTypeHistogram:
1080
dps := metric.Histogram().DataPoints()
1081
for l := 0; l < dps.Len(); l++ {
1082
dps.At(l).SetStartTimestamp(s.startTime)
1083
}
1084
}
1085
}
1086
}
1087
}
1088
return nil
1089
}
1090
1091
type testDataPoint struct {
1092
lb labels.Labels
1093
t int64
1094
v float64
1095
}
1096
1097
type testScrapedPage struct {
1098
pts []*testDataPoint
1099
}
1100
1101
func createDataPoint(mname string, value float64, tagPairs ...string) *testDataPoint {
1102
var lbls []string
1103
lbls = append(lbls, tagPairs...)
1104
lbls = append(lbls, model.MetricNameLabel, mname)
1105
lbls = append(lbls, model.JobLabel, "job")
1106
lbls = append(lbls, model.InstanceLabel, "instance")
1107
1108
return &testDataPoint{
1109
lb: labels.FromStrings(lbls...),
1110
t: ts,
1111
v: value,
1112
}
1113
}
1114
1115
func assertEquivalentMetrics(t *testing.T, want, got pmetric.Metrics) {
1116
require.Equal(t, want.ResourceMetrics().Len(), got.ResourceMetrics().Len())
1117
if want.ResourceMetrics().Len() == 0 {
1118
return
1119
}
1120
for i := 0; i < want.ResourceMetrics().Len(); i++ {
1121
wantSm := want.ResourceMetrics().At(i).ScopeMetrics()
1122
gotSm := got.ResourceMetrics().At(i).ScopeMetrics()
1123
require.Equal(t, wantSm.Len(), gotSm.Len())
1124
if wantSm.Len() == 0 {
1125
return
1126
}
1127
1128
for j := 0; j < wantSm.Len(); j++ {
1129
wantMs := wantSm.At(j).Metrics()
1130
gotMs := gotSm.At(j).Metrics()
1131
require.Equal(t, wantMs.Len(), gotMs.Len())
1132
1133
wmap := map[string]pmetric.Metric{}
1134
gmap := map[string]pmetric.Metric{}
1135
1136
for k := 0; k < wantMs.Len(); k++ {
1137
wi := wantMs.At(k)
1138
wmap[wi.Name()] = wi
1139
gi := gotMs.At(k)
1140
gmap[gi.Name()] = gi
1141
}
1142
assert.EqualValues(t, wmap, gmap)
1143
}
1144
}
1145
}
1146
1147