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

fix: avoid double lock in DockerProvider.DaemonHost() #2900

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

vikstrous
Copy link

What does this PR do?

I carved out a code path for the DockerProvider.DaemonHost() code that avoids double locking.

Why is it important?

I was getting a deadlock. See #2897

Related issues

How to test this PR

See #2897

Follow-ups

Is there a test for running testcontainers from within a container?

@vikstrous vikstrous requested a review from a team as a code owner November 29, 2024 02:18
Copy link

netlify bot commented Nov 29, 2024

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit e1c69cd
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-go/deploys/6763d3908bbb380008458011
😎 Deploy Preview https://deploy-preview-2900--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.

Copy link
Collaborator

@stevenh stevenh left a comment

Choose a reason for hiding this comment

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

Thanks for the PR @vikstrous nice catch.

Could I ask you to take a different approach, splitting ensureDefaultNetwork into two ensureDefaultNetwork and ensureDefaultNetworkLocked avoiding the need to pass a boolean and making it clear the intent of the calls to the locked method.

Could you also construct a test which exercises this issue to ensure we don't have regression.

docker.go Show resolved Hide resolved
@vikstrous
Copy link
Author

@stevenh are there existing tests where testcontainers code is being run in containers (testcontainers?)?

@vikstrous
Copy link
Author

I added a regression test. Without my change, the test fails and shows the stack trace you'd expect. With my change, it passes. The test runs in about 20s because it has to re-download go mod dependencies within the test container. This test can obviously be written a lot better, but I'd prefer it if you guys take over from here and make it conform to your best practices for writing tests.

Copy link
Collaborator

@stevenh stevenh left a comment

Choose a reason for hiding this comment

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

Thanks for the rework, have suggested a few changes and a question.

docker_test.go Outdated Show resolved Hide resolved
docker_test.go Outdated Show resolved Hide resolved
docker_test.go Outdated Show resolved Hide resolved
docker_test.go Outdated Show resolved Hide resolved
docker_test.go Outdated

outputBytes, err := io.ReadAll(outputReader)
require.NoError(t, err, "failed to read output")
t.Logf("%s", outputBytes)
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: looks like this was just debug?

Copy link
Author

Choose a reason for hiding this comment

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

Without this, you can't see the output of stage 2, so you don't really know if it's working. I'll remove the extra print in case of error though.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ahh, got you because it's basically a sub test

Copy link
Collaborator

@stevenh stevenh left a comment

Choose a reason for hiding this comment

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

Unfortunately the test is failing in rootless setup, see CI output.

@vikstrous
Copy link
Author

I got the same error locally when I didn't bind mount /var/run. I shared the docker socket with stage 2 by bind mounting /var/run from stage 1. I don't know how this works in your CI environment / with rootless docker. I'm basically just trying to make sure that stage 2 thinks it's in a container.

I'll need help with this part.

docker_test.go Outdated Show resolved Hide resolved
@mdelapenya mdelapenya added the bug An issue with the library label Dec 4, 2024
@vikstrous
Copy link
Author

I think the rootless test is actually finding another version of this bug

@vikstrous
Copy link
Author

Actually, I don't really know what's going on. I've never used rootless docker before and I think it would be best for someone to take over this PR. The bug makes testcontainers unusable within containers, which is a common scenario, so I want to get it fixed soon.

@stevenh
Copy link
Collaborator

stevenh commented Dec 10, 2024

Just a quick note to say this on my list thank @vikstrous just need to find some time, appreciate your time on this 😄

Fix the DaemonHost locking test by implementing a way to change the
location of the file the core library tests for.
@vikstrous
Copy link
Author

vikstrous commented Dec 18, 2024

Nice improvement! Much simpler than actually running in a container.

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.

[Bug]: deadlock in container.Host()
3 participants