feat: more robust Reusable containers experience#2768
feat: more robust Reusable containers experience#2768mdelapenya wants to merge 34 commits intotestcontainers:mainfrom
Conversation
Removing the sessionID label, it won't be pruned by Ryuk
✅ Deploy Preview for testcontainers-go ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
|
@stevenh as always, your wise 👀 are more than welcome! |
| // can proceed with the creation of the container. | ||
| // This is needed because we need to synchronize the creation of the container across | ||
| // different test programs. | ||
| c, err := p.waitContainerCreationInTimeout(ctx, hash, 5*time.Second) |
There was a problem hiding this comment.
I see this as a potential configuration:
- a property:
testcontainers.reuse.search.timeout, and - an env var:
TESTCONTAINERS_REUSE_SEARCH_TIMEOUT
There was a problem hiding this comment.
Since the PR description says:
We expect this change helps the community, but at the same time warn about its usage in parallel executions, as it could be the case that two concurrent test sessions get to the container creation at the same time, which could lead to the creation of two containers with the same request.
wouldn't we want to accept this limitation and allow for the race condition with the current implementation?
There was a problem hiding this comment.
Indeed. Added that comment as an idea for a potential follow-up
|
I wonder if this solves this bug: #2749 I'll do a small code review here as well. Thank you for this! |
docker.go
Outdated
| err = req.creatingHook(ctx) | ||
| if err != nil { | ||
| return nil, err | ||
| if req.Reuse { |
There was a problem hiding this comment.
question: Not sure about this, I would expect reused containers to still only persist while in use, is that the intent?
The edge case for shutdown while still in use, is addressed by reaper rework PRs, so it should be safe to remove this if the desired behaviour is to share between test runs that are within a reasonable window.
| reuseContainerMx.Lock() | ||
| defer reuseContainerMx.Unlock() |
There was a problem hiding this comment.
question: This will lock for the duration of rest of the call, is that the intention?
request_hash.go
Outdated
| if !ok { | ||
| // Calculate the hash of the file content only if it is a file. | ||
| fileContent, err = os.ReadFile(f.HostFilePath) | ||
| if err != nil { |
There was a problem hiding this comment.
bug: this will lead to unexplained issues.
There was a problem hiding this comment.
I see 🤔 . So it'd be ideal to get all the possible errors and fail the hash calculation, wouldn't it?
| ) | ||
|
|
||
| // containerHash represents the hash of the container configuration | ||
| type containerHash struct { |
There was a problem hiding this comment.
question: are two independent hashes needed.
|
@kiview I'm converting to draft until we discuss internally about the implications of switching from the container name-based approach to a hash-based approach. Will share here the discussion once it takes place. |
* main: (103 commits) feat(postgres): ssl for postgres (testcontainers#2473) feat(ollama): support calling the Ollama local process (testcontainers#2923) chore(deps): bump jinja2 from 3.1.4 to 3.1.5 (testcontainers#2935) chore(deps): bump sonarsource/sonarcloud-github-action (testcontainers#2933) feat(termination)!: make container termination timeout configurable (testcontainers#2926) chore(deps): bump slackapi/slack-github-action from 1.26.0 to 2.0.0 (testcontainers#2934) chore(deps): bump github/codeql-action from 3.25.15 to 3.28.0 (testcontainers#2932) feat(wait): log sub match callback (testcontainers#2929) fix: Handle nil value in CleanupNetwork (testcontainers#2928) fix: avoid double lock in DockerProvider.DaemonHost() (testcontainers#2900) feat!: build log writer for container request (testcontainers#2925) feat(gcloud)!: add support to seed data when using RunBigQueryContainer (testcontainers#2523) security(deps): bump golang.org/x/crypto from 0.28.0 to 0.31.0 (testcontainers#2916) chore(ci): add Github labels based on PR title (testcontainers#2914) chore(gha): Use official setup-docker-action (testcontainers#2913) chore(ci): enforce conventional commits syntax in PR titles (testcontainers#2911) feat(nats): WithConfigFile - pass a configuration file to nats server (testcontainers#2905) chore: enable implicit default logger only in testing with -v (testcontainers#2877) fix: container binds syntax (testcontainers#2899) refactor(cockroachdb): to use request driven options (testcontainers#2883) ...
Would the container name still influence the final hash? I think it would be good to still have a way to differentiate the same container for certain cases (e.g. I have Postgres snapshots with different migrations and fixtures). |
What does this PR do?
This PR modifies the way the Reuse mode is implemented in the project, taking tc-java as the implementation reference. For that:
github.com/mitchellh/hashstructure/v2for the hash of the container request, with the following exceptions:hash:"ignore"to identify them all.Filesfield contains a reference to a directory in the host, it won't participate in the calculation of the hash, as we don't want to traverse the directory getting the hash for the directory tree.Filesfield, we'll read their bytes and use them get a hash, which will be added to the struct hash.org.testcontainers.hash: the hash of the container request.org.testcontainers.copied_files.hash: the hash of the files copied to the container using theFilesfield in the container request.ReuseOrCreateContainerfrom the provider struct has been deprecated for removal in the upcoming releases.Why is it important?
Create a more consistent experience around reuse, based on the container state and not forcing the user to add a container name, that can be reused by mistake in a totally different container request.
We expect this change helps the community, but at the same time warn about its usage in parallel executions, as it could be the case that two concurrent test sessions get to the container creation at the same time, which could lead to the creation of two containers with the same request.
Related issues
Docs
Render URLs:
Follow-ups
Please try out this branch, and read the docs so that they can be improved if needed 🙏