From 2ac28a9cf089fb6f7debb99d52faf4d280282495 Mon Sep 17 00:00:00 2001 From: hyunuk Date: Sun, 13 Apr 2025 23:34:46 +0900 Subject: [PATCH] test(registry): Add goleak-based goroutine leak detection Signed-off-by: hyunuk --- go.mod | 1 + go.sum | 6 ++++++ prometheus/registry_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/go.mod b/go.mod index fd93c0f10..b3a5c7f70 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/prometheus/client_model v0.6.1 github.com/prometheus/common v0.63.0 github.com/prometheus/procfs v0.16.0 + go.uber.org/goleak v1.2.0 golang.org/x/sys v0.30.0 google.golang.org/protobuf v1.36.6 ) diff --git a/go.sum b/go.sum index aa6f797f0..1eaf5a6d6 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= @@ -54,6 +58,8 @@ golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/prometheus/registry_test.go b/prometheus/registry_test.go index b8505c7d2..12b09d623 100644 --- a/prometheus/registry_test.go +++ b/prometheus/registry_test.go @@ -37,6 +37,7 @@ import ( dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" + "go.uber.org/goleak" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -1339,3 +1340,28 @@ func TestCheckMetricConsistency(t *testing.T) { } reg.Unregister(invalidCollector) } + +func TestGatherDoesNotLeakGoroutines(t *testing.T) { + // Use goleak to verify that no unexpected goroutines are leaked during the test. + defer goleak.VerifyNone(t) + + // Create a new Prometheus registry without any default collectors. + reg := prometheus.NewRegistry() + + // Register 100 simple Gauge metrics with distinct names and constant labels. + for i := 0; i < 100; i++ { + reg.MustRegister(prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "test_metric_" + string(rune(i)), + Help: "Test metric", + ConstLabels: prometheus.Labels{"id": string(rune(i))}, + })) + } + + // Call Gather repeatedly to simulate stress and check for potential goroutine leaks. + for i := 0; i < 1000; i++ { + _, err := reg.Gather() + if err != nil { + t.Fatalf("unexpected error from Gather: %v", err) + } + } +}