Skip to content

Commit 4d76aa2

Browse files
committed
fix(testcontainers): create template_db explicitly + throw on failed schema push
1 parent 88ecb95 commit 4d76aa2

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

internal-packages/testcontainers/src/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ const getWorkerPostgresContainer = () => {
151151
const container = await withCiResourceLimits(new PostgreSqlContainer("docker.io/postgres:14"))
152152
.withCommand(["-c", "listen_addresses=*", "-c", "wal_level=logical"])
153153
.start();
154+
// Create the template db explicitly via an admin connection (the same primitive the per-test
155+
// clone uses) instead of relying on `prisma db push` to create a missing database. That
156+
// create-if-missing path behaves differently on CI and - because push errors were swallowed -
157+
// surfaced only later as a confusing "template database template_db does not exist" at clone
158+
// time. Pushing into an already-existing db is the path the pre-worker-scope code always used.
159+
const admin = new PrismaClient({
160+
datasources: {
161+
db: { url: postgresUriWithDatabase(container.getConnectionUri(), "postgres") },
162+
},
163+
});
164+
await admin.$executeRawUnsafe(`CREATE DATABASE "${POSTGRES_TEMPLATE_DB}"`);
165+
await admin.$disconnect();
154166
await pushDatabaseSchema(
155167
postgresUriWithDatabase(container.getConnectionUri(), POSTGRES_TEMPLATE_DB)
156168
);

internal-packages/testcontainers/src/utils.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ export function postgresUriWithDatabase(uri: string, database: string): string {
1919
return url.toString();
2020
}
2121

22-
/** Pushes the Prisma schema into the database at `databaseUrl` (creating it if missing). */
22+
/** Pushes the Prisma schema into the database at `databaseUrl` (which must already exist). */
2323
export async function pushDatabaseSchema(databaseUrl: string) {
2424
const databasePath = path.resolve(__dirname, "../../database");
2525

26-
await x(
26+
// throwOnError is essential: without it tinyexec swallows a non-zero `prisma db push`, so a failed
27+
// push looks like success and only surfaces much later as a confusing downstream error.
28+
const result = await x(
2729
`${databasePath}/node_modules/.bin/prisma`,
2830
[
2931
"db",
@@ -35,6 +37,7 @@ export async function pushDatabaseSchema(databaseUrl: string) {
3537
`${databasePath}/prisma/schema.prisma`,
3638
],
3739
{
40+
throwOnError: true,
3841
nodeOptions: {
3942
env: {
4043
...process.env,
@@ -44,6 +47,8 @@ export async function pushDatabaseSchema(databaseUrl: string) {
4447
},
4548
}
4649
);
50+
51+
return result;
4752
}
4853

4954
/**

0 commit comments

Comments
 (0)