Skip to content

Commit 769aea2

Browse files
test: implement unit test for summary metrics in Prometheus conversion
Co-authored-by: aider (openai/claude-sonnet-4) <aider@aider.chat>
1 parent 20b194e commit 769aea2

File tree

1 file changed

+136
-1
lines changed

1 file changed

+136
-1
lines changed

internal/castai/client_test.go

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,142 @@ func TestConvertPrometheusMetricFamilies(t *testing.T) {
390390
})
391391

392392
t.Run("summary", func(t *testing.T) {
393-
// TODO: unit test for summary metrics
393+
r := require.New(t)
394+
395+
metricName := "test_summary"
396+
sampleCount := uint64(50)
397+
sampleSum := 125.75
398+
399+
// Create summary quantiles
400+
quantiles := []*dto.Quantile{
401+
{
402+
Quantile: lo.ToPtr(0.5),
403+
Value: lo.ToPtr(2.5),
404+
},
405+
{
406+
Quantile: lo.ToPtr(0.9),
407+
Value: lo.ToPtr(8.1),
408+
},
409+
{
410+
Quantile: lo.ToPtr(0.99),
411+
Value: lo.ToPtr(15.3),
412+
},
413+
}
414+
415+
labelName := "handler"
416+
labelValue := "api"
417+
418+
family := &dto.MetricFamily{
419+
Name: &metricName,
420+
Metric: []*dto.Metric{
421+
{
422+
Label: []*dto.LabelPair{
423+
{
424+
Name: &labelName,
425+
Value: &labelValue,
426+
},
427+
},
428+
Summary: &dto.Summary{
429+
SampleCount: &sampleCount,
430+
SampleSum: &sampleSum,
431+
Quantile: quantiles,
432+
},
433+
},
434+
},
435+
}
436+
437+
result := convertPrometheusMetricFamilies(gatherTime, "ctrl_pod", []*dto.MetricFamily{family})
438+
439+
// Should have 3 quantile timeseries + 1 _sum + 1 _count = 5 total
440+
r.Len(result.Timeseries, 5)
441+
442+
// Separate timeseries by type
443+
quantileTimeseries := []PrometheusTimeseries{}
444+
var sumTimeseries, countTimeseries *PrometheusTimeseries
445+
446+
for _, ts := range result.Timeseries {
447+
// Check which type this timeseries is by looking at __name__ label
448+
var metricNameValue string
449+
for _, label := range ts.Labels {
450+
if label.Name == "__name__" {
451+
metricNameValue = label.Value
452+
break
453+
}
454+
}
455+
456+
switch metricNameValue {
457+
case metricName + "_quantile":
458+
quantileTimeseries = append(quantileTimeseries, ts)
459+
case metricName + "_sum":
460+
sumTimeseries = &ts
461+
case metricName + "_count":
462+
countTimeseries = &ts
463+
default:
464+
t.Fatalf("Unexpected metric name: %s", metricNameValue)
465+
}
466+
467+
// Verify common labels are present on all timeseries
468+
assertLabelPresent(t, ts.Labels, "pod_name", "ctrl_pod")
469+
assertLabelPresent(t, ts.Labels, labelName, labelValue)
470+
471+
// Verify timestamp and sample structure
472+
r.Len(ts.Samples, 1)
473+
r.Equal(expectedTimestamp, ts.Samples[0].Timestamp)
474+
}
475+
476+
// Verify quantile timeseries (3 quantiles)
477+
r.Len(quantileTimeseries, 3)
478+
479+
// Verify each expected quantile exists
480+
expectedQuantiles := map[string]float64{
481+
"0.500000": 2.5,
482+
"0.900000": 8.1,
483+
"0.990000": 15.3,
484+
}
485+
486+
foundQuantiles := make(map[string]bool)
487+
for _, ts := range quantileTimeseries {
488+
assertLabelPresent(t, ts.Labels, "__name__", metricName+"_quantile")
489+
490+
// Find the 'quantile' label value
491+
var quantileValue string
492+
for _, label := range ts.Labels {
493+
if label.Name == "quantile" {
494+
quantileValue = label.Value
495+
break
496+
}
497+
}
498+
499+
r.NotEmpty(quantileValue, "Quantile timeseries should have 'quantile' label")
500+
501+
expectedValue, exists := expectedQuantiles[quantileValue]
502+
r.True(exists, "Unexpected quantile with quantile=%s", quantileValue)
503+
r.Equal(expectedValue, ts.Samples[0].Value)
504+
foundQuantiles[quantileValue] = true
505+
}
506+
507+
// Ensure all expected quantiles were found
508+
r.Len(foundQuantiles, len(expectedQuantiles))
509+
510+
// Verify _sum timeseries
511+
r.NotNil(sumTimeseries)
512+
assertLabelPresent(t, sumTimeseries.Labels, "__name__", metricName+"_sum")
513+
r.Equal(sampleSum, sumTimeseries.Samples[0].Value)
514+
515+
// Verify _sum doesn't have 'quantile' label
516+
for _, label := range sumTimeseries.Labels {
517+
r.NotEqual("quantile", label.Name, "_sum should not have 'quantile' label")
518+
}
519+
520+
// Verify _count timeseries
521+
r.NotNil(countTimeseries)
522+
assertLabelPresent(t, countTimeseries.Labels, "__name__", metricName+"_count")
523+
r.Equal(float64(sampleCount), countTimeseries.Samples[0].Value)
524+
525+
// Verify _count doesn't have 'quantile' label
526+
for _, label := range countTimeseries.Labels {
527+
r.NotEqual("quantile", label.Name, "_count should not have 'quantile' label")
528+
}
394529
})
395530
}
396531

0 commit comments

Comments
 (0)