pkg/prom/queries_test.go
Rama main · réplica de lectura del repositorio original.
package prom
import (
"strings"
"testing"
)
func TestBuildPodSetQueryMatchesExactPodNames(t *testing.T) {
pods := []string{"api-7d9f-abc12", "api-7d9f-def34"}
want := `pod=~'^(api-7d9f-abc12|api-7d9f-def34)$'`
for _, cat := range []MetricCategory{CategoryCPU, CategoryMemory, CategoryRestarts} {
q := BuildPodSetQuery("shop", pods, cat)
if !strings.Contains(q, want) {
t.Errorf("%s: query %q lacks anchored pod set %q", cat, q, want)
}
if !strings.Contains(q, `namespace='shop'`) {
t.Errorf("%s: query %q lacks namespace matcher", cat, q)
}
if strings.Contains(q, "api-.*") {
t.Errorf("%s: query %q uses the workload prefix pattern", cat, q)
}
if !strings.HasPrefix(q, "sum(") || strings.HasSuffix(q, "by (pod,namespace)") {
t.Errorf("%s: query %q splits the set per pod instead of one sum", cat, q)
}
}
}
func TestBuildPodSetQueryReusesCategoryExpressions(t *testing.T) {
pods := []string{"web-0"}
cases := map[MetricCategory]string{
CategoryCPU: `sum(rate(container_cpu_usage_seconds_total{container!='',namespace='ns',pod=~'^(web-0)$'}[5m]))`,
CategoryMemory: `sum(max by (pod,namespace,container) (container_memory_working_set_bytes{container!='',namespace='ns',pod=~'^(web-0)$'}))`,
CategoryRestarts: `sum(round(increase(kube_pod_container_status_restarts_total{namespace='ns',pod=~'^(web-0)$'}[1h])))`,
}
for cat, want := range cases {
if got := BuildPodSetQuery("ns", pods, cat); got != want {
t.Errorf("%s:\n got %s\nwant %s", cat, got, want)
}
}
noFilter := BuildPodSetQueryNoContainerFilter("ns", pods, CategoryCPU)
if strings.Contains(noFilter, "container!=") {
t.Errorf("no-container-filter variant still filters: %s", noFilter)
}
if BuildPodSetQueryNoContainerFilter("ns", pods, CategoryRestarts) != cases[CategoryRestarts] {
t.Error("restarts query should not change without the container filter")
}
}
func TestBuildPodSetQueryRestartsReadCounterIncrease(t *testing.T) {
q := BuildPodSetQuery("ns", []string{"web-0"}, CategoryRestarts)
if strings.Contains(q, "changes(") {
t.Fatalf("restarts query counts sample transitions, undercounting bursts between scrapes: %s", q)
}
if !strings.Contains(q, "round(increase(kube_pod_container_status_restarts_total") {
t.Fatalf("restarts query should read the rounded counter increase: %s", q)
}
}
func TestBuildPodSetQueryEscapesNames(t *testing.T) {
q := BuildPodSetQuery("te'st", []string{"a.b", `c{d}`}, CategoryCPU)
if !strings.Contains(q, `namespace='te\'st'`) {
t.Errorf("namespace not sanitized: %s", q)
}
if !strings.Contains(q, `^(a\\.b|`) {
t.Errorf("regex metacharacters not escaped: %s", q)
}
if strings.Contains(q, "c{d}") {
t.Errorf("label-matcher characters not sanitized: %s", q)
}
}
func TestBuildPodSetQueryEmptyCases(t *testing.T) {
if q := BuildPodSetQuery("ns", nil, CategoryCPU); q != "" {
t.Errorf("empty pod set should yield no query, got %q", q)
}
if q := BuildPodSetQuery("ns", []string{"a"}, CategoryNetworkRX); q != "" {
t.Errorf("unsupported category should yield no query, got %q", q)
}
}