Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all: fix goroutine leaks #1358

Merged
merged 1 commit into from
Aug 9, 2023

Conversation

AlexanderYastrebov
Copy link
Contributor

@AlexanderYastrebov AlexanderYastrebov commented Jul 10, 2023

Fixes various goroutine leaks by moving around and adding missing Close calls.

Leaks were detected by https://github.com/AlexanderYastrebov/noleak by adding

// go get github.com/AlexanderYastrebov/noleak@latest
// cat main_test.go
package testcontainers

import (
        "os"
        "testing"

        "github.com/AlexanderYastrebov/noleak"
)

func TestMain(m *testing.M) {
        os.Exit(noleak.CheckMain(m))
}

Not all leaks could be fixed e.g. due to #1357 therefore this change does not add leak detector, only fixes.

Updates #321

What does this PR do?

Why is it important?

Related issues

@AlexanderYastrebov AlexanderYastrebov requested a review from a team as a code owner July 10, 2023 20:06
@netlify
Copy link

netlify bot commented Jul 10, 2023

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 2b055df
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-go/deploys/64cfcc0b81026d000882479e
😎 Deploy Preview https://deploy-preview-1358--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@AlexanderYastrebov
Copy link
Contributor Author

AlexanderYastrebov commented Jul 12, 2023

Fixed golangci-lint "Error return value of n.Remove is not checked (errcheck)"

Copy link
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few minor comments, will postpone the final review until we discuss them.

Other than that, LGTM. Thanks for your dedication!

@mdelapenya mdelapenya self-assigned this Aug 2, 2023
@mdelapenya mdelapenya added chore Changes that do not impact the existing functionality bug An issue with the library and removed chore Changes that do not impact the existing functionality labels Aug 2, 2023
@AlexanderYastrebov AlexanderYastrebov force-pushed the fix-leaks branch 3 times, most recently from 74f21a9 to b5b70e3 Compare August 6, 2023 13:19
@AlexanderYastrebov
Copy link
Contributor Author

AlexanderYastrebov commented Aug 6, 2023

Not all leaks could be fixed e.g. due to #1357 therefore this change does not add leak detector, only fixes.

There is another tricky case besides #1357 - reused containers.
In the TestParallelContainersWithReuse reused container has reaper that would not be closed:

res, err := ParallelContainers(ctx, parallelRequest, ParallelContainersOptions{})
if err != nil {
e, _ := err.(ParallelContainersError)
t.Fatalf("expected errors: %d, got: %d\n", 0, len(e.Errors))
}
// Container is reused, only terminate first container
terminateContainerOnEnd(t, ctx, res[0])

Closing all containers produces error as there is only one real container.

In the TestGenericReusableContainer reused container also can not be closed but even if we remove reaper it still calls Exec:

if err == nil {
c, _, err := n2.Exec(ctx, []string{"/bin/ash", copiedFileName})
require.NoError(t, err)
require.Zero(t, c)
}

which creates an idle connection in the client and the problem is that reused containers have their own provider:
provider, err := req.ProviderType.GetProvider(WithLogger(logging))
if err != nil {
return nil, err
}
var c Container
if req.Reuse {
// we must protect the reusability of the container in the case it's invoked
// in a parallel execution, via ParallelContainers or t.Parallel()
reuseContainerMx.Lock()
defer reuseContainerMx.Unlock()
c, err = provider.ReuseOrCreateContainer(ctx, req.ContainerRequest)
} else {

testcontainers-go/docker.go

Lines 1139 to 1149 in 5011016

dc := &DockerContainer{
ID: c.ID,
WaitingFor: req.WaitingFor,
Image: c.Image,
sessionID: testcontainerssession.ID(),
provider: p,
terminationSignal: termSignal,
stopProducer: nil,
logger: p.Logger,
isRunning: c.State == "running",
}

Fixes various goroutine leaks by moving around and adding missing Close calls.

Leaks were detected by github.com/AlexanderYastrebov/noleak by adding

```go
// go get github.com/AlexanderYastrebov/noleak@latest
// cat main_test.go
package testcontainers

import (
        "os"
        "testing"

        "github.com/AlexanderYastrebov/noleak"
)

func TestMain(m *testing.M) {
        os.Exit(noleak.CheckMain(m))
}
```

Not all leaks could be fixed e.g. due to testcontainers#1357 therefore this change
does not add leak detector, only fixes.

Updates testcontainers#321
@sonarqubecloud
Copy link

sonarqubecloud bot commented Aug 6, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

No Coverage information No Coverage information
7.4% 7.4% Duplication

Copy link
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for your patience while reviewing the PR.

As you seem very proficient with goroutines, would you participate in an eventual redesign for a revamp of the current Docker client infrastructure, in a v1 branch?

@mdelapenya mdelapenya merged commit 7b4cf84 into testcontainers:main Aug 9, 2023
mdelapenya added a commit to mdelapenya/testcontainers-go that referenced this pull request Aug 9, 2023
* main:
  chore(deps): bump github.com/aws dependencies in /modules/localstack (testcontainers#1472)
  chore(deps): bump Google emulators dependencies in /examples (testcontainers#1471)
  all: fix goroutine leaks (testcontainers#1358)
  chore(deps): bump github.com/neo4j/neo4j-go-driver/v5 in /modules/neo4j (testcontainers#1427)
@AlexanderYastrebov
Copy link
Contributor Author

@mdelapenya Thank you.

would you participate in an eventual redesign

Just tag me and I'll think whether I could contribute anything meaningful.

@AlexanderYastrebov AlexanderYastrebov deleted the fix-leaks branch August 9, 2023 17:57
mdelapenya added a commit to mdelapenya/testcontainers-go that referenced this pull request Aug 10, 2023
* main: (29 commits)
  Add support for MongoDB testing module (testcontainers#1447)
  Support groups in dependabot updates (testcontainers#1459)
  chore: run modulegen tests on Windows (testcontainers#1478)
  Add default labels when Ryuk is disabled (testcontainers#1339)
  feat: add clickhouse module (testcontainers#1372)
  chore: increase timeout for go test and GH action steps (testcontainers#1475)
  chore: triple max timeout for the workflow run, which takes +10m (testcontainers#1474)
  chore(deps): bump github.com/aws dependencies in /modules/localstack (testcontainers#1472)
  chore(deps): bump Google emulators dependencies in /examples (testcontainers#1471)
  all: fix goroutine leaks (testcontainers#1358)
  chore(deps): bump github.com/neo4j/neo4j-go-driver/v5 in /modules/neo4j (testcontainers#1427)
  chore(deps): bump github.com/tidwall/gjson from 1.14.4 to 1.15.0 in /modules/vault (testcontainers#1428)
  chore: add a GH action for release drafter (testcontainers#1470)
  chore(deps): bump mkdocs-material from 3.2.0 to 8.2.7 (testcontainers#1468)
  Add global testcontainers header to docs (testcontainers#1308)
  Simplify dependabot updates sorting (testcontainers#1460)
  feat: use credential helper in docker config, even if auth is empty in .docker/config.json (testcontainers#1079)
  chore(deps): bump github.com/aws/aws-sdk-go-v2/service/s3 (testcontainers#1457)
  Revert "chore: run Windows tests on a Linux container (testcontainers#1456)"
  chore: run Windows tests on a Linux container (testcontainers#1456)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An issue with the library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants