refactor(test): make all Docker tests hermetic#439
Open
sbalabanov wants to merge 1 commit into
Open
Conversation
Docker-based integration/e2e tests previously resolved the repository root (via MODULE.bazel / go.mod runfile symlinks or git) and handed it to docker compose as the image build context, relying on pre-built .docker-bin binaries produced by `make build-*-linux` outside of Bazel's action graph. Now every input is an explicit Bazel data dependency: - Each service gets a `go_cross_binary` `<name>_linux` target; tests depend on it directly, so Bazel builds the exact binary that lands in the image. - testutil.WithBuildContext stages a minimal docker build context (binary, Dockerfile, configs) from declared runfiles into a temp dir; compose's REPO_ROOT variable points at that staged context, never at the checkout. - testutil.Runfile resolves the compose file from runfiles; FindRepoRoot and all MODULE.bazel / go.mod data dependencies are removed. - Image tag prefix derives from TEST_TARGET instead of the checkout path. - Compose V2 plugin is preferred over a standalone docker-compose binary (legacy V1 lacks `up --wait`); DOCKER_CONFIG falls back to the invoking user's config dir so user-level CLI plugins are found under Bazel's scratch HOME. Stricter sandbox settings now that tests are hermetic: - --incompatible_strict_action_env: static action/test environment. - --sandbox_default_allow_network=false: sandboxed actions get no network; Docker tests opt back in via tags = ["requires-network"]. - The `external` tag is dropped, so passing integration/e2e results are cached and re-run only when a declared input changes. `make integration-test` / `make e2e-test` no longer need build-all-linux; the local docker-compose flows (local-*) still use it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sbalabanov
marked this pull request as ready for review
July 24, 2026 17:10
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Make every Docker-based test fully hermetic: all inputs are explicit Bazel
datadependencies, no test resolves the repository root, and the Bazel sandbox is stricter than before.Problem
Docker suites resolved the source checkout at runtime —
testutil.FindRepoRootwalked runfile symlinks ofMODULE.bazel/go.mod(declared asdatasolely for that purpose) or shelled out to git — and handed the checkout todocker composeas the image build context. The imagesCOPY'd pre-built.docker-bin/*binaries produced bymake build-*-linuxoutside Bazel's action graph, sobazel testresults depended on undeclared, stale-able state.Changes
Hermetic inputs
go_cross_binarytargets (gateway_linux,orchestrator_linux,runway_linux,stovepipe_linux): Bazel builds the exact Linux binary that lands in each image; tests depend on them asdata.testutil.WithBuildContextstages a minimal docker build context (binary + Dockerfile + configs, all from declared runfiles) into a test temp dir; compose'sREPO_ROOTvariable now points at that staged context. Existing compose files andlocal-*Makefile flows are unchanged.testutil.Runfileresolves compose files from runfiles;FindRepoRootis deleted and every//:MODULE.bazel///:go.moddata dep is removed.TEST_TARGET(stable per target) instead of the checkout path, so parallel targets no longer share tags.docker-compose(legacy V1 lacksup --wait);DOCKER_CONFIGfalls back to the invoking user's config dir so user-level CLI plugins are found despite Bazel's scratchHOME.Stricter sandbox (beneficial now that tests are hermetic)
--incompatible_strict_action_env: static action/test environment — no client env leaks into results.--sandbox_default_allow_network=false: sandboxed actions get their own network namespace by default; Docker tests opt back in viatags = ["requires-network"].externaltag: hermetic test results are now cacheable — unchanged integration/e2e suites skip entirely (verified locally:(cached) PASSED).DOCKER_HOST/SKIP_CLEANUPare explicit--test_envpass-throughs.Makefile / docs
integration-test*/e2e-testno longer depend onbuild-all-linux(still used bylocal-*compose flows).Test Plan
bazel teston all 9 Docker suites passes locally (5 MySQL-only + gateway + orchestrator + stovepipe + both e2e)make test(79 unit tests) passesmake lint,make check-tidy,make check-gazellepass(cached) PASSED)🤖 Generated with Claude Code