Skip to content

Commit 8b5d45a

Browse files
tianzhouclaude
andauthored
test: stop integration suites failing on container teardown timeout (#466)
* test: stop integration suites failing on container teardown timeout Recent CI failures on green code (MariaDB twice, postgres-ssh once) all read "Hook timed out in 10000ms" at the suite's afterAll. Teardown is Testcontainers' stop(), i.e. `docker stop -t 0` + `docker rm -v`. The suites share one Docker daemon, and while Oracle (1.2GB) or SQL Server is still pulling/extracting its image, removing a sibling container with its data volume can exceed Vitest's default 10s hookTimeout. Every beforeAll already carries an explicit 60-360s timeout; afterAll relied on the default. - vitest.config.ts: hookTimeout 60s for the integration project. - IntegrationTestBase.cleanup(): stop the container in a finally so a disconnect failure can't leak a running container. - testing skill: document the symptom and cause. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01TZPfFnRTrHzHhsCzjrZjgM * test: narrow the cleanup comment to what finally guarantees A pending disconnect() never reaches the finally, so the container-stop guarantee covers thrown errors, not hangs; say so. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01TZPfFnRTrHzHhsCzjrZjgM --------- Co-authored-by: Claude <[email protected]>
1 parent 5c3e6e7 commit 8b5d45a

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

‎.claude/skills/testing/SKILL.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ docker ps -a | grep testcontainers # Find leaked containers
145145
docker container prune # Clean up stopped containers
146146
```
147147

148+
### "Hook timed out in 10000ms" in `afterAll`
149+
All tests pass but the suite is marked failed at its `afterAll` (seen on MariaDB and
150+
postgres-ssh in CI). Teardown is `container.stop()`, which runs `docker stop -t 0`
151+
followed by `docker rm -v` (removing the data volume). On a shared Docker daemon that
152+
is simultaneously pulling/extracting the Oracle or SQL Server image, that removal can
153+
exceed Vitest's 10s default hook timeout. The integration project sets
154+
`hookTimeout: 60_000` in `vitest.config.ts` for this reason — do not pass a shorter
155+
timeout to `afterAll`, and if you add a suite with its own teardown, let it use the
156+
project default rather than the Vitest default.
157+
148158
### CI Failures
149159
The CI workflow (`.github/workflows/run-tests.yml`) runs unit and integration tests as separate parallel jobs on PR events. Unit tests don't need Docker; integration tests verify Docker availability first. Check the specific job that failed.
150160

‎src/connectors/__tests__/shared/integration-test-base.ts‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,18 @@ export abstract class IntegrationTestBase<TContainer extends TestContainer> {
7979
* Cleanup method to be called in afterAll
8080
*/
8181
async cleanup(): Promise<void> {
82-
if (this.connector) {
83-
await this.connector.disconnect();
84-
}
85-
if (this.container) {
86-
await this.container.stop();
82+
// Stop the container even if disconnecting throws: a connector error
83+
// here must not leak a running container into the next suite (or onto
84+
// the CI runner). A disconnect that never settles is bounded only by the
85+
// integration project's hookTimeout, not by this block.
86+
try {
87+
if (this.connector) {
88+
await this.connector.disconnect();
89+
}
90+
} finally {
91+
if (this.container) {
92+
await this.container.stop();
93+
}
8794
}
8895
}
8996

‎vitest.config.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ export default defineConfig({
2222
test: {
2323
name: 'integration',
2424
include: ['src/**/*integration*.test.ts'],
25+
// Container teardown (`docker stop` + `docker rm -v`) shares one Docker
26+
// daemon with every other suite in the run. While Oracle or SQL Server
27+
// is still pulling/extracting its image, removing a sibling container
28+
// and its data volume can take well over Vitest's 10s default, and the
29+
// `afterAll` hooks in these suites fail with "Hook timed out in 10000ms"
30+
// even though every test passed. Setup hooks keep their explicit
31+
// per-suite timeouts; this raises the floor for teardown.
32+
hookTimeout: 60_000,
2533
},
2634
},
2735
],

0 commit comments

Comments
 (0)