Skip to content

Commit d2f19d6

Browse files
WOOP-1151: fix inconsistent metric nil vs empty slice in flattenPrometheusConfig and add unit tests
1 parent 382db5f commit d2f19d6

File tree

2 files changed

+151
-1
lines changed

2 files changed

+151
-1
lines changed

castai/resource_workload_custom_metrics_data_source.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ func flattenPrometheusConfig(prom *sdk.WorkloadoptimizationV1CustomMetricsDataSo
424424
}
425425
promMap["metric"] = metrics
426426
} else {
427-
promMap["metric"] = []interface{}{}
427+
promMap["metric"] = nil
428428
}
429429

430430
return []interface{}{promMap}

castai/resource_workload_custom_metrics_data_source_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,156 @@ func TestWorkloadCustomMetricsDataSource_DeleteNotFound(t *testing.T) {
476476
r.Empty(diags)
477477
}
478478

479+
func TestFlattenPrometheusConfig(t *testing.T) {
480+
tests := map[string]struct {
481+
prom *sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus
482+
expectedURL string
483+
expectedTimeout string
484+
expectedPresets []string
485+
expectedMetric []interface{} // nil means metric key should be nil
486+
}{
487+
"minimal config with nil metrics": {
488+
prom: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus{
489+
DataSource: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusDataSource{
490+
Url: "http://prometheus:9090",
491+
},
492+
},
493+
expectedURL: "http://prometheus:9090",
494+
expectedTimeout: "",
495+
expectedPresets: []string{},
496+
expectedMetric: nil,
497+
},
498+
"with timeout": {
499+
prom: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus{
500+
DataSource: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusDataSource{
501+
Url: "http://prometheus:9090",
502+
Timeout: toPtr("30s"),
503+
},
504+
},
505+
expectedURL: "http://prometheus:9090",
506+
expectedTimeout: "30s",
507+
expectedPresets: []string{},
508+
expectedMetric: nil,
509+
},
510+
"with presets": {
511+
prom: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus{
512+
DataSource: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusDataSource{
513+
Url: "http://prometheus:9090",
514+
},
515+
Metrics: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetrics{
516+
Presets: &[]string{"jvm", "kafka"},
517+
},
518+
},
519+
expectedURL: "http://prometheus:9090",
520+
expectedTimeout: "",
521+
expectedPresets: []string{"jvm", "kafka"},
522+
expectedMetric: nil,
523+
},
524+
"resolved with only preset metrics": {
525+
prom: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus{
526+
DataSource: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusDataSource{
527+
Url: "http://prometheus:9090",
528+
},
529+
Metrics: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetrics{
530+
Presets: &[]string{"jvm"},
531+
Resolved: &[]sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetric{
532+
{Name: "jvm_threads", Queries: []sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQuery{
533+
{Value: "jvm_threads_current", Origin: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQueryOriginPRESET},
534+
}},
535+
},
536+
},
537+
},
538+
expectedURL: "http://prometheus:9090",
539+
expectedTimeout: "",
540+
expectedPresets: []string{"jvm"},
541+
expectedMetric: nil,
542+
},
543+
"resolved with empty list": {
544+
prom: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus{
545+
DataSource: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusDataSource{
546+
Url: "http://prometheus:9090",
547+
},
548+
Metrics: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetrics{
549+
Resolved: &[]sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetric{},
550+
},
551+
},
552+
expectedURL: "http://prometheus:9090",
553+
expectedTimeout: "",
554+
expectedPresets: []string{},
555+
expectedMetric: nil,
556+
},
557+
"resolved with manual metrics": {
558+
prom: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus{
559+
DataSource: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusDataSource{
560+
Url: "http://prometheus:9090",
561+
Timeout: toPtr("15s"),
562+
},
563+
Metrics: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetrics{
564+
Resolved: &[]sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetric{
565+
{Name: "http_requests_total", Queries: []sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQuery{
566+
{Value: "sum(rate(http_requests_total[5m])) by (pod)", Origin: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQueryOriginMANUAL},
567+
}},
568+
{Name: "queue_depth", Queries: []sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQuery{
569+
{Value: "avg(queue_depth) by (pod)", Origin: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQueryOriginMANUAL},
570+
}},
571+
},
572+
},
573+
},
574+
expectedURL: "http://prometheus:9090",
575+
expectedTimeout: "15s",
576+
expectedPresets: []string{},
577+
expectedMetric: []interface{}{
578+
map[string]interface{}{"name": "http_requests_total", "query": "sum(rate(http_requests_total[5m])) by (pod)"},
579+
map[string]interface{}{"name": "queue_depth", "query": "avg(queue_depth) by (pod)"},
580+
},
581+
},
582+
"resolved with mixed preset and manual metrics": {
583+
prom: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheus{
584+
DataSource: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusDataSource{
585+
Url: "http://prometheus:9090",
586+
},
587+
Metrics: &sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetrics{
588+
Presets: &[]string{"jvm"},
589+
Resolved: &[]sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetric{
590+
{Name: "jvm_threads", Queries: []sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQuery{
591+
{Value: "jvm_threads_current", Origin: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQueryOriginPRESET},
592+
}},
593+
{Name: "custom_metric", Queries: []sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQuery{
594+
{Value: "my_custom_query", Origin: sdk.WorkloadoptimizationV1CustomMetricsDataSourceDataPrometheusMetricsResolvedMetricQueryOriginMANUAL},
595+
}},
596+
},
597+
},
598+
},
599+
expectedURL: "http://prometheus:9090",
600+
expectedTimeout: "",
601+
expectedPresets: []string{"jvm"},
602+
expectedMetric: []interface{}{
603+
map[string]interface{}{"name": "custom_metric", "query": "my_custom_query"},
604+
},
605+
},
606+
}
607+
608+
for name, tc := range tests {
609+
t.Run(name, func(t *testing.T) {
610+
r := require.New(t)
611+
612+
result := flattenPrometheusConfig(tc.prom)
613+
r.Len(result, 1)
614+
615+
promMap := result[0].(map[string]interface{})
616+
r.Equal(tc.expectedURL, promMap["url"])
617+
r.Equal(tc.expectedTimeout, promMap["timeout"])
618+
r.Equal(tc.expectedPresets, promMap["presets"])
619+
620+
if tc.expectedMetric == nil {
621+
r.Nil(promMap["metric"])
622+
} else {
623+
r.Equal(tc.expectedMetric, promMap["metric"])
624+
}
625+
})
626+
}
627+
}
628+
479629
func TestWorkloadCustomMetricsDataSource_Importer(t *testing.T) {
480630
type testCase struct {
481631
importID string

0 commit comments

Comments
 (0)