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
Collaborator

@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!

docker.go Show resolved Hide resolved
docker_test.go Outdated Show resolved Hide resolved
@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
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
@sonarcloud
Copy link

sonarcloud 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
Collaborator

@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
106 checks passed
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.

None yet

2 participants