Skip to content

test(repo): remove test Docker volumes once per run by creation label - #6923

Open
jgoux wants to merge 7 commits into
developfrom
fix/stack-test-volume-leak
Open

jgoux wants to merge 7 commits into
developfrom
fix/stack-test-volume-leak

Conversation

@jgoux

@jgoux jgoux commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Docker-backed stack tests left a named supabase-db-* volume behind on every run.

Docker database storage keeps one shared volume per state root and daemon. Stack destroy deliberately clears only the stack's namespace inside it, because the volume is shared with other stacks and holds the snapshot cache. Tests that run a Docker database under a temporary state root destroyed the stack and then deleted the root. After that, nothing could find the volume again.

This PR cleans up those volumes in one place per test run instead of in each test:

  • When SUPABASE_STACK_TEST_RUN is set, DockerDatabaseStorage adds a com.supabase.stack-test-run=<id> label to the volumes it creates, and the container runtime adds it to the containers it creates. Nothing else changes, and nothing changes when the variable is unset.

  • packages/stack/tests/docker-volume-run.ts is a vitest globalSetup for the stack and CLI integration and E2E projects. It generates a random id unless an outer invocation already owns one. Its teardown removes exactly the stack-managed volumes carrying that id, without force, and fails the run if a removal fails. It skips when Docker is unavailable.

  • Vitest workers, CLI subprocesses and detached stack owners inherit the id. processEnvLayer keeps it when it replaces the environment.

  • Docker test state roots must stay private to a run. The Commands.integration Docker variants passed a bare temporary directory as the database root, which made them share one never-removed volume keyed to the parent of $TMPDIR. They now use makeDockerDatabaseRoot like the other database service tests.

  • The stack-cache E2E's own marker-based volume cleanup is removed.

  • Under Bun, vitest exits on SIGINT and SIGTERM without running globalSetup teardown, so an interrupted run used to leave its volumes behind and its containers running. The owning setup now records a per-user, host-local marker with its pid, and deletes it at teardown. Each new run's setup finds markers whose process is dead and removes that run's labelled containers, then its labelled volumes, then the marker. Live runs, other machines sharing the daemon, and unlabelled resources are never touched.

Volumes created before this change carry no run label and are not cleaned up automatically.

…roots

Docker database storage keeps one shared volume per state root and daemon,
and stack destroy clears only the stack's namespace inside it. Tests that ran
a Docker database under a temporary state root deleted that root afterwards,
which orphaned the volume for good.

Add `removeStateRootVolume` to the stack Docker test fixture. It removes the
label-verified volume of one state root. Register it after allocating each
temporary Docker state root in the affected CLI and stack integration and E2E
tests, so it runs after the stacks are destroyed and before the root is
deleted. Route the Commands integration Docker variants through
`makeDockerDatabaseRoot`, and replace the stack-cache E2E's marker-based
cleanup with the shared helper.
@jgoux
jgoux requested a review from a team as a code owner September 30, 2026 17:50
@jgoux jgoux self-assigned this Sep 30, 2026

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Superseded by a newer AI review

🤖 AI Review

Both independent reviews completed. Confirmed Claude’s code-organization nit, narrowed to duplicated coupling to another package’s test layout; its claimed new typecheck impact is unsupported. No functional defects were verified. Runtime tests were not run.

Findings

Severity Location Category Sources Claim
⚪ NIT apps/cli/src/commands/db/diff/diff.stack-cache.e2e.test.ts:9 code-organization claude Eight CLI test files directly import removeStateRootVolume from packages/stack/tests/docker-fixture.ts, duplicating dependence on the stack package’s internal test layout.

Stats

Claude findings: 1 · Codex findings: 0 · Confirmed: 1 · Refuted: 0 · Uncertain: 0


Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: auto · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment thread apps/cli/src/commands/db/diff/diff.stack-cache.e2e.test.ts Outdated
Replace the per-test volume finalizers with one mechanism. When
SUPABASE_STACK_TEST_RUN is set, Docker database storage labels the volumes
it creates with com.supabase.stack-test-run=<id>. A shared vitest
globalSetup in the stack and CLI integration and E2E projects generates the
id, and its teardown removes exactly the stack-managed volumes carrying it.
Volume naming, namespaces, cache and destroy behaviour are unchanged, and
nothing changes when the variable is unset.
@jgoux jgoux changed the title test(repo): remove Docker data volumes owned by temporary test state roots test(repo): remove test Docker volumes once per run by creation label Oct 1, 2026
@jgoux

jgoux commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

/ai-review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 AI Review

Both independent reviews were available. All five supplied findings were verified against the checked-out code and trusted conventions. The duplicate labeling-test leak reports were merged, leaving four confirmed minor findings. Claude's stale test line numbers were corrected. Verification was by code inspection; runtime tests were not run.

Findings

Severity Location Category Sources Claim
🟡 MINOR packages/stack/src/storage/DockerDatabaseStorage.ts:118 error-handling claude A malformed SUPABASE_STACK_TEST_RUN value can block Docker database preparation even though this optional variable only controls a test-cleanup label.
🟡 MINOR packages/stack/src/storage/DockerDatabaseStorage.integration.test.ts:639 resource-cleanup claude+codex The labeling test can leak its Docker volume when preparation fails after creating it, or when a subsequent operation fails before inline removal.
🟡 MINOR packages/stack/tests/docker-volume-run.ts:80 resource-lifecycle codex After teardown, a subsequent setup in the same process skips registering cleanup because the completed owner's environment variable remains set.
🟡 MINOR packages/stack/tests/docker-volume-run.integration.test.ts:23 test-quality codex The cleanup test ignores Docker exit codes, allowing failed owned-volume creation to satisfy the removal assertion and failed fixture removal to go unnoticed.

Stats

Claude findings: 2 · Codex findings: 3 · Confirmed: 4 · Refuted: 0 · Uncertain: 0


Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment thread packages/stack/src/storage/DockerDatabaseStorage.ts Outdated
Comment thread packages/stack/src/storage/DockerDatabaseStorage.integration.test.ts Outdated
Comment thread packages/stack/tests/docker-volume-run.ts
Comment thread packages/stack/tests/docker-volume-run.integration.test.ts Outdated
The storage labelling test registers its own run cleanup before creating
storage, so a failure cannot leak its volume. The selection test checks
every Docker result. The run teardown releases the run id it owned.
Under Bun, vitest exits on SIGINT and SIGTERM without running globalSetup
teardown, so an interrupted run leaked its labelled volumes and left its
stack containers running.

The owning setup now records a per-user, host-local marker with its pid,
and teardown deletes it. Each new setup finds markers whose process is
dead and removes that run's labelled containers, then its labelled
volumes, then the marker. Live runs and unlabelled resources are never
touched. Stack-created containers carry the same run label as volumes,
and the env name and label key live in one shared module.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants