Repository navigation
test: wait for pool connections to close before dropping test dbs - #67
Merged
Merged
Conversation
migrations.spec.ts ended its pools with pool.end(), which resolves once each connection was told to close, not once it has. The test database's DROP DATABASE ... WITH (FORCE) right after terminated the connections still closing, and their pools, which nothing listened to, threw the 57P01 as uncaught errors, the most common reason an e2e job went red. Kysely's db.destroy() ends the pool it was given the same way. Both now wait for the connections to close with endPool(), which takes the library's own end for Kysely's.
The case never looked at what its claims and the parent's write returned, so a claim that missed the child surfaced two steps later as "the lease holder ends the child". It now checks each, so a run that misses one names that step.
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.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
About one CI run in five fails (66 of the last 337). Most of those are an e2e job whose tests all passed, failed by
Vitest caught N unhandled errors:error: terminating connection due to administrator command(57P01). Over the last month,tests/postgres/migrations.spec.tsproduced 176 of these errors, on master, renovate and feature branches alike, andtests/postgres/contract-kysely.spec.tsproduced 3.The cause:
pool.end()resolves once it has told each connection to close, not once they have. Right after, the test database'safterAllrunsDROP DATABASE ... WITH (FORCE), which terminates the connections still closing. Their pool re-emits the 57P01 aserror, nothing listens, and it becomes an uncaught exception.tests/support/postgres.tsalready hasendPool()for exactly this, butmigrations.spec.tsended its pools withpool.end(), and the Kysely client'sdb.destroy()ends its pool the same way. TypeORM and adapter-pg listen for their pools' errors, so a late 57P01 there is logged, not thrown.Separately,
contract-prisma.spec.tsfailed once (2026-10-29):write() with a signal records it as signal() does, only when the write landsreported "the lease holder ends the child: expected true, got false". The case never checks what its claims return, so the miss surfaced two steps after it happened. It can only mean the claim at 5 didn't lease the child.What is the new behavior?
migrations.spec.tsends its pools withendPool(). Vitest runsafterAllhooks in reverse registration order (sequence.hooks: 'stack'), so that runs before the database is dropped.endPool(pool, () => db.destroy()).endPool()takes anendfor a pool a library holds, and still waits for its connections to close.Evidence, against a
postgres:18.6container like CI's service:pool.end(): the pool emitted an error in 38 of 40 rounds (68 errors in 40 rounds with the wholepostgres-storeproject running beside it). Right afterendPool(): none, both times.fromPrisma1,800 times (300 alone, 1,500 beside the whole project), never missed. Neither did 4 passes of the whole Prisma contract (200 cases), and no connection was left idle in a transaction after any of them. Prisma runs a raw query straight on the pool and awaits itsCOMMIT, so I found no lock that could outlive a statement. Its cause is unknown; the checks above will say which step misses if it happens again.Checked locally:
postgres-storeproject on the container: 11 files, 369 passed, no unhandled errors.Not addressed here: MySQL's shutdown hand-back cases (
interrupts,deployment,recovery) failed 5 times up to 2026-10-13 and not since, andtiny-queue.spec.tsfailed once (2026-10-07).Does this PR introduce a breaking change?
The contract (
@nestjs/workflows/testing) checks more in one case. A store that passes the claim cases passes these checks.Other information