Skip to content

Commit 7cc4c14

Browse files
odubajDTcodeboten
authored andcommitted
[chore]: fix go routine leaks in tests (open-telemetry#34729)
**Description:** <Describe what has changed.> - removing re-running parameter from gotestsum - fixing tests/code with go routine leaks - resolving race conditions (mostly caused by parallel tests) - placing goleak ignorers for go routine leaks from external libraries **Link to tracking Issue:** open-telemetry#34495 --------- Signed-off-by: odubajDT <[email protected]> Co-authored-by: Alex Boten <[email protected]>
1 parent 657be94 commit 7cc4c14

File tree

35 files changed

+111
-47
lines changed

35 files changed

+111
-47
lines changed

exporter/awscloudwatchlogsexporter/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporter/awscloudwatchlogsexporter/metadata.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@ tests:
1717
retry_on_failure:
1818
enabled: false
1919
expect_consumer_error: true
20+
goleak:
21+
ignore:
22+
top:
23+
# See https://github.com/census-instrumentation/opencensus-go/issues/1191 for more information.
24+
- "go.opencensus.io/stats/view.(*worker).start"
25+
- "net/http.(*persistConn).writeLoop"
26+
- "internal/poll.runtime_pollWait"

exporter/awss3exporter/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exporter/awss3exporter/metadata.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,8 @@ status:
1010

1111
tests:
1212
expect_consumer_error: true
13+
goleak:
14+
ignore:
15+
top:
16+
- "net/http.(*persistConn).writeLoop"
17+
- "internal/poll.runtime_pollWait"

extension/observer/dockerobserver/extension.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func (d *dockerObserver) Start(ctx context.Context, _ component.Host) error {
104104
}
105105

106106
func (d *dockerObserver) Shutdown(_ context.Context) error {
107+
d.StopListAndWatch()
107108
d.cancel()
108109
return nil
109110
}

extension/observer/dockerobserver/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension/observer/dockerobserver/metadata.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ status:
1111
# TODO: The tests are not passing on Windows. Either fix them or mark component as not supported on Windows.
1212
tests:
1313
skip_lifecycle: true
14-
skip_shutdown: true
14+
skip_shutdown: true
15+
goleak:
16+
ignore:
17+
top:
18+
- "net/http.(*persistConn).writeLoop"
19+
- "internal/poll.runtime_pollWait"

extension/observer/k8sobserver/extension_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func TestExtensionObserveServices(t *testing.T) {
127127
}, sink.removed[0])
128128

129129
require.NoError(t, ext.Shutdown(context.Background()))
130+
obs.StopListAndWatch()
130131
}
131132

132133
func TestExtensionObservePods(t *testing.T) {
@@ -209,6 +210,7 @@ func TestExtensionObservePods(t *testing.T) {
209210
}, sink.removed[0])
210211

211212
require.NoError(t, ext.Shutdown(context.Background()))
213+
obs.StopListAndWatch()
212214
}
213215

214216
func TestExtensionObserveNodes(t *testing.T) {
@@ -308,4 +310,5 @@ func TestExtensionObserveNodes(t *testing.T) {
308310
}, sink.removed[0])
309311

310312
require.NoError(t, ext.Shutdown(context.Background()))
313+
obs.StopListAndWatch()
311314
}

extension/observer/k8sobserver/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension/observer/k8sobserver/metadata.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ status:
1212
tests:
1313
skip_lifecycle: true
1414
skip_shutdown: true
15+
goleak:
16+
ignore:
17+
top:
18+
- "k8s.io/apimachinery/pkg/watch.(*Broadcaster).loop"

extension/sigv4authextension/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension/sigv4authextension/metadata.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ status:
1010
active: [Aneurysm9, erichsueh3]
1111

1212
tests:
13+
goleak:
14+
ignore:
15+
top:
16+
- "net/http.(*persistConn).writeLoop"
17+
- "internal/poll.runtime_pollWait"
1318
config:

internal/aws/metrics/metric_calculator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ type MapWithExpiry struct {
122122
// NewMapWithExpiry automatically starts a sweeper to enforce the maps TTL. ShutDown() must be called to ensure that these
123123
// go routines are properly cleaned up ShutDown() must be called.
124124
func NewMapWithExpiry(ttl time.Duration) *MapWithExpiry {
125-
m := &MapWithExpiry{lock: &sync.Mutex{}, ttl: ttl, entries: make(map[any]*MetricValue), doneChan: make(chan struct{})}
125+
m := &MapWithExpiry{lock: &sync.Mutex{}, ttl: ttl, entries: make(map[any]*MetricValue), doneChan: make(chan struct{}, 1000)}
126126
go m.sweep(m.CleanUp)
127127
return m
128128
}

processor/geoipprocessor/integration_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import (
1313
)
1414

1515
func TestProcessorWithMaxMind(t *testing.T) {
16-
t.Parallel()
17-
1816
tmpDBfiles := testdata.GenerateLocalDB(t, "./internal/provider/maxmindprovider/testdata/")
1917
defer os.RemoveAll(tmpDBfiles)
2018

receiver/aerospikereceiver/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/aerospikereceiver/metadata.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ status:
99
active: [djaglowski, antonblock]
1010
seeking_new: true
1111

12+
tests:
13+
goleak:
14+
ignore:
15+
top:
16+
- "github.com/aerospike/aerospike-client-go/v7.(*baseMultiCommand).parseRecordResults"
17+
- "github.com/aerospike/aerospike-client-go/v7.(*Cluster).clusterBoss"
18+
- "sync.runtime_Semacquire"
19+
1220
resource_attributes:
1321
aerospike.node.name:
1422
description: Name of the Aerospike node collected from

receiver/awscontainerinsightreceiver/internal/cadvisor/cadvisor_linux.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ type Cadvisor struct {
122122
k8sDecorator Decorator
123123
ecsInfo EcsInfo
124124
containerOrchestrator string
125+
metricsExtractors []extractors.MetricExtractor
125126
}
126127

127128
func init() {
@@ -158,15 +159,13 @@ func New(containerOrchestrator string, hostInfo hostInfo, logger *zap.Logger, op
158159
return c, nil
159160
}
160161

161-
var metricsExtractors = []extractors.MetricExtractor{}
162-
163-
func GetMetricsExtractors() []extractors.MetricExtractor {
164-
return metricsExtractors
162+
func (c *Cadvisor) GetMetricsExtractors() []extractors.MetricExtractor {
163+
return c.metricsExtractors
165164
}
166165

167166
func (c *Cadvisor) Shutdown() error {
168167
var errs error
169-
for _, ext := range metricsExtractors {
168+
for _, ext := range c.metricsExtractors {
170169
errs = errors.Join(errs, ext.Shutdown())
171170
}
172171

@@ -341,7 +340,7 @@ func (c *Cadvisor) GetMetrics() []pmetric.Metrics {
341340
return result
342341
}
343342

344-
out := processContainers(containerinfos, c.hostInfo, c.containerOrchestrator, c.logger)
343+
out := processContainers(containerinfos, c.hostInfo, c.containerOrchestrator, c.logger, c.GetMetricsExtractors())
345344
results := c.decorateMetrics(out)
346345

347346
if c.containerOrchestrator == ci.ECS {
@@ -394,12 +393,12 @@ func (c *Cadvisor) initManager(createManager createCadvisorManager) error {
394393
return err
395394
}
396395

397-
metricsExtractors = []extractors.MetricExtractor{}
398-
metricsExtractors = append(metricsExtractors, extractors.NewCPUMetricExtractor(c.logger))
399-
metricsExtractors = append(metricsExtractors, extractors.NewMemMetricExtractor(c.logger))
400-
metricsExtractors = append(metricsExtractors, extractors.NewDiskIOMetricExtractor(c.logger))
401-
metricsExtractors = append(metricsExtractors, extractors.NewNetMetricExtractor(c.logger))
402-
metricsExtractors = append(metricsExtractors, extractors.NewFileSystemMetricExtractor(c.logger))
396+
c.metricsExtractors = make([]extractors.MetricExtractor, 0, 5)
397+
c.metricsExtractors = append(c.metricsExtractors, extractors.NewCPUMetricExtractor(c.logger))
398+
c.metricsExtractors = append(c.metricsExtractors, extractors.NewMemMetricExtractor(c.logger))
399+
c.metricsExtractors = append(c.metricsExtractors, extractors.NewDiskIOMetricExtractor(c.logger))
400+
c.metricsExtractors = append(c.metricsExtractors, extractors.NewNetMetricExtractor(c.logger))
401+
c.metricsExtractors = append(c.metricsExtractors, extractors.NewFileSystemMetricExtractor(c.logger))
403402

404403
return nil
405404
}

receiver/awscontainerinsightreceiver/internal/cadvisor/cadvisor_linux_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ func TestGetMetrics(t *testing.T) {
8989
assert.NotNil(t, c)
9090
assert.NoError(t, err)
9191
assert.NotNil(t, c.GetMetrics())
92+
assert.NoError(t, c.Shutdown())
9293
}
9394

9495
func TestGetMetricsNoEnv(t *testing.T) {
@@ -109,6 +110,7 @@ func TestGetMetricsNoClusterName(t *testing.T) {
109110
assert.NotNil(t, c)
110111
assert.NoError(t, err)
111112
assert.Nil(t, c.GetMetrics())
113+
assert.NoError(t, c.Shutdown())
112114
}
113115

114116
func TestGetMetricsErrorWhenCreatingManager(t *testing.T) {

receiver/awscontainerinsightreceiver/internal/cadvisor/container_info_processor.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type podKey struct {
3737
namespace string
3838
}
3939

40-
func processContainers(cInfos []*cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProvider, containerOrchestrator string, logger *zap.Logger) []*extractors.CAdvisorMetric {
40+
func processContainers(cInfos []*cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProvider, containerOrchestrator string, logger *zap.Logger, metricExtractors []extractors.MetricExtractor) []*extractors.CAdvisorMetric {
4141
var metrics []*extractors.CAdvisorMetric
4242
podKeys := make(map[string]podKey)
4343

@@ -47,7 +47,7 @@ func processContainers(cInfos []*cInfo.ContainerInfo, mInfo extractors.CPUMemInf
4747
if len(info.Stats) == 0 {
4848
continue
4949
}
50-
outMetrics, outPodKey, err := processContainer(info, mInfo, containerOrchestrator, logger)
50+
outMetrics, outPodKey, err := processContainer(info, mInfo, containerOrchestrator, logger, metricExtractors)
5151
if err != nil {
5252
logger.Warn("drop some container info", zap.Error(err))
5353
continue
@@ -73,7 +73,7 @@ func processContainers(cInfos []*cInfo.ContainerInfo, mInfo extractors.CPUMemInf
7373
continue
7474
}
7575

76-
metrics = append(metrics, processPod(info, mInfo, podKeys, logger)...)
76+
metrics = append(metrics, processPod(info, mInfo, podKeys, logger, metricExtractors)...)
7777
}
7878

7979
// This happens when our cgroup path based pod detection logic is not working.
@@ -87,7 +87,7 @@ func processContainers(cInfos []*cInfo.ContainerInfo, mInfo extractors.CPUMemInf
8787
}
8888

8989
// processContainers get metrics for individual container and gather information for pod so we can look it up later.
90-
func processContainer(info *cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProvider, containerOrchestrator string, logger *zap.Logger) ([]*extractors.CAdvisorMetric, *podKey, error) {
90+
func processContainer(info *cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProvider, containerOrchestrator string, logger *zap.Logger, metricExtractors []extractors.MetricExtractor) ([]*extractors.CAdvisorMetric, *podKey, error) {
9191
var result []*extractors.CAdvisorMetric
9292
var pKey *podKey
9393

@@ -152,7 +152,7 @@ func processContainer(info *cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProv
152152

153153
tags[ci.Timestamp] = strconv.FormatInt(extractors.GetStats(info).Timestamp.UnixNano(), 10)
154154

155-
for _, extractor := range GetMetricsExtractors() {
155+
for _, extractor := range metricExtractors {
156156
if extractor.HasValue(info) {
157157
result = append(result, extractor.GetValue(info, mInfo, containerType)...)
158158
}
@@ -164,7 +164,7 @@ func processContainer(info *cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProv
164164
return result, pKey, nil
165165
}
166166

167-
func processPod(info *cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProvider, podKeys map[string]podKey, logger *zap.Logger) []*extractors.CAdvisorMetric {
167+
func processPod(info *cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProvider, podKeys map[string]podKey, logger *zap.Logger, metricExtractors []extractors.MetricExtractor) []*extractors.CAdvisorMetric {
168168
var result []*extractors.CAdvisorMetric
169169
if isContainerInContainer(info.Name) {
170170
logger.Debug("drop metric because it's nested container", zap.String("name", info.Name))
@@ -183,7 +183,7 @@ func processPod(info *cInfo.ContainerInfo, mInfo extractors.CPUMemInfoProvider,
183183

184184
tags[ci.Timestamp] = strconv.FormatInt(extractors.GetStats(info).Timestamp.UnixNano(), 10)
185185

186-
for _, extractor := range GetMetricsExtractors() {
186+
for _, extractor := range metricExtractors {
187187
if extractor.HasValue(info) {
188188
result = append(result, extractor.GetValue(info, mInfo, ci.TypePod)...)
189189
}

receiver/awscontainerinsightreceiver/internal/cadvisor/container_info_processor_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010

1111
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
1213
"go.uber.org/zap"
1314

1415
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscontainerinsightreceiver/internal/cadvisor/extractors"
@@ -49,8 +50,7 @@ func TestIsContainerInContainer(t *testing.T) {
4950

5051
func TestProcessContainers(t *testing.T) {
5152
// set the metrics extractors for testing
52-
originalMetricsExtractors := metricsExtractors
53-
metricsExtractors = []extractors.MetricExtractor{}
53+
metricsExtractors := []extractors.MetricExtractor{}
5454
metricsExtractors = append(metricsExtractors, extractors.NewCPUMetricExtractor(zap.NewNop()))
5555
metricsExtractors = append(metricsExtractors, extractors.NewMemMetricExtractor(zap.NewNop()))
5656
metricsExtractors = append(metricsExtractors, extractors.NewDiskIOMetricExtractor(zap.NewNop()))
@@ -63,9 +63,10 @@ func TestProcessContainers(t *testing.T) {
6363
containerInContainerInfos := testutils.LoadContainerInfo(t, "./extractors/testdata/ContainerInContainer.json")
6464
containerInfos = append(containerInfos, containerInContainerInfos...)
6565
mInfo := testutils.MockCPUMemInfo{}
66-
metrics := processContainers(containerInfos, mInfo, "eks", zap.NewNop())
66+
metrics := processContainers(containerInfos, mInfo, "eks", zap.NewNop(), metricsExtractors)
6767
assert.Len(t, metrics, 3)
6868

69-
// restore the original value of metrics extractors
70-
metricsExtractors = originalMetricsExtractors
69+
for _, e := range metricsExtractors {
70+
require.NoError(t, e.Shutdown())
71+
}
7172
}

receiver/awscontainerinsightreceiver/internal/cadvisor/extractors/net_extractor_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func TestNetStats(t *testing.T) {
1919

2020
containerType := ci.TypeNode
2121
extractor := NewNetMetricExtractor(nil)
22+
defer require.NoError(t, extractor.Shutdown())
2223
var cMetrics []*CAdvisorMetric
2324
if extractor.HasValue(result[0]) {
2425
cMetrics = extractor.GetValue(result[0], nil, containerType)
@@ -156,5 +157,4 @@ func TestNetStats(t *testing.T) {
156157
for i := range expectedFields {
157158
AssertContainsTaggedField(t, cMetrics[i], expectedFields[i], expectedTags[i])
158159
}
159-
require.NoError(t, extractor.Shutdown())
160160
}

receiver/datadogreceiver/receiver_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,6 @@ func TestDatadogInfoEndpoint(t *testing.T) {
213213
} {
214214
tc := tc
215215
t.Run(tc.name, func(t *testing.T) {
216-
t.Parallel()
217-
218216
cfg := createDefaultConfig().(*Config)
219217
cfg.Endpoint = "localhost:0" // Using a randomly assigned address
220218

receiver/dockerstatsreceiver/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

receiver/dockerstatsreceiver/metadata.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ status:
1111

1212
sem_conv_version: 1.6.1
1313

14+
tests:
15+
goleak:
16+
ignore:
17+
top:
18+
- "github.com/testcontainers/testcontainers-go.(*Reaper).Connect.func1"
19+
- "net/http.(*persistConn).writeLoop"
20+
- "internal/poll.runtime_pollWait"
21+
1422
# Note: there are other, additional resource attributes that the user can configure through the yaml
1523
resource_attributes:
1624
container.runtime:

receiver/googlecloudspannerreceiver/internal/filter/itemcardinality_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func TestItemCardinalityFilter_Filter(t *testing.T) {
147147
assert.Empty(t, filteredItems)
148148

149149
// Doing this to avoid of relying on timeouts and sleeps(avoid potential flaky tests)
150-
syncChannel := make(chan bool)
150+
syncChannel := make(chan bool, 10)
151151

152152
filterCasted.cache.SetExpirationCallback(func(string, any) {
153153
if filterCasted.cache.Count() > 0 {
@@ -208,7 +208,7 @@ func TestItemCardinalityFilter_FilterItems(t *testing.T) {
208208
assert.Len(t, filteredItems, totalLimit)
209209

210210
// Doing this to avoid of relying on timeouts and sleeps(avoid potential flaky tests)
211-
syncChannel := make(chan bool)
211+
syncChannel := make(chan bool, 10)
212212

213213
filterCasted.cache.SetExpirationCallback(func(string, any) {
214214
if filterCasted.cache.Count() > 0 {

receiver/googlecloudspannerreceiver/internal/filter/package_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ import (
1010
)
1111

1212
func TestMain(m *testing.M) {
13-
goleak.VerifyTestMain(m)
13+
goleak.VerifyTestMain(m, goleak.IgnoreTopFunction("github.com/ReneKroon/ttlcache/v2.(*Cache).checkExpirationCallback"))
1414
}

receiver/jmxreceiver/generated_package_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)