Skip to content

Commit b58176f

Browse files
committed
fix: spin up real Redis container in startTestServer; pass host/port to startWebapp
1 parent 90f7f13 commit b58176f

2 files changed

Lines changed: 21 additions & 12 deletions

File tree

.github/workflows/e2e-webapp.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ jobs:
7272
run: |
7373
echo "Pre-pulling Docker images with authenticated session..."
7474
docker pull postgres:14
75+
docker pull redis:7-alpine
7576
docker pull testcontainers/ryuk:0.11.0
7677
echo "Image pre-pull complete"
7778

internal-packages/testcontainers/src/webapp.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { createServer } from "net";
33
import { delimiter, resolve } from "path";
44
import { Network } from "testcontainers";
55
import { PrismaClient } from "@trigger.dev/database";
6-
import { createPostgresContainer } from "./utils";
6+
import { createPostgresContainer, createRedisContainer } from "./utils";
77

88
const WEBAPP_ROOT = resolve(__dirname, "../../../apps/webapp");
99
// pnpm hoists transitive deps to node_modules/.pnpm/node_modules but does NOT symlink them
@@ -37,7 +37,10 @@ export interface WebappInstance {
3737
fetch(path: string, init?: RequestInit): Promise<Response>;
3838
}
3939

40-
export async function startWebapp(databaseUrl: string): Promise<{
40+
export async function startWebapp(
41+
databaseUrl: string,
42+
redis: { host: string; port: number }
43+
): Promise<{
4144
instance: WebappInstance;
4245
stop: () => Promise<void>;
4346
}> {
@@ -64,8 +67,8 @@ export async function startWebapp(databaseUrl: string): Promise<{
6467
CLICKHOUSE_URL: "http://localhost:19123", // dummy, auth paths never connect
6568
DEPLOY_REGISTRY_HOST: "registry.example.com", // dummy, not needed for auth tests
6669
ELECTRIC_ORIGIN: "http://localhost:3060",
67-
REDIS_HOST: "localhost", // dummy, satisfies module-level validation; auth paths never use Redis
68-
REDIS_PORT: "6379",
70+
REDIS_HOST: redis.host,
71+
REDIS_PORT: String(redis.port),
6972
NODE_PATH: nodePath,
7073
},
7174
stdio: ["ignore", "pipe", "pipe"],
@@ -135,37 +138,42 @@ export interface TestServer {
135138
stop: () => Promise<void>;
136139
}
137140

138-
/** Convenience helper: starts a postgres container + webapp and returns both for testing. */
141+
/** Convenience helper: starts a postgres + redis container + webapp and returns both for testing. */
139142
export async function startTestServer(): Promise<TestServer> {
140143
const network = await new Network().start();
141144

142145
// Track each resource as we acquire it so we can tear it down if a later step fails.
143-
// Without this, a healthcheck timeout in startWebapp() would leak the postgres
144-
// container, network, and PrismaClient connection indefinitely.
145-
let container: Awaited<ReturnType<typeof createPostgresContainer>>["container"] | undefined;
146+
let pgContainer: Awaited<ReturnType<typeof createPostgresContainer>>["container"] | undefined;
147+
let redisContainer: Awaited<ReturnType<typeof createRedisContainer>>["container"] | undefined;
146148
let prisma: PrismaClient | undefined;
147149
let stopWebapp: (() => Promise<void>) | undefined;
148150
let webapp: WebappInstance;
149151

150152
try {
151153
const pg = await createPostgresContainer(network);
152-
container = pg.container;
154+
pgContainer = pg.container;
155+
156+
const { container: rc } = await createRedisContainer({ network });
157+
redisContainer = rc;
158+
153159
prisma = new PrismaClient({ datasources: { db: { url: pg.url } } });
154-
const started = await startWebapp(pg.url);
160+
const started = await startWebapp(pg.url, { host: rc.getHost(), port: rc.getPort() });
155161
webapp = started.instance;
156162
stopWebapp = started.stop;
157163
} catch (err) {
158164
await stopWebapp?.().catch(() => {});
159165
await prisma?.$disconnect().catch(() => {});
160-
await container?.stop().catch(() => {});
166+
await pgContainer?.stop().catch(() => {});
167+
await redisContainer?.stop().catch(() => {});
161168
await network.stop().catch(() => {});
162169
throw err;
163170
}
164171

165172
const stop = async () => {
166173
await stopWebapp!().catch((err) => console.error("stopWebapp failed:", err));
167174
await prisma!.$disconnect().catch((err) => console.error("prisma.$disconnect failed:", err));
168-
await container!.stop().catch((err) => console.error("container.stop failed:", err));
175+
await pgContainer!.stop().catch((err) => console.error("pgContainer.stop failed:", err));
176+
await redisContainer!.stop().catch((err) => console.error("redisContainer.stop failed:", err));
169177
await network.stop().catch((err) => console.error("network.stop failed:", err));
170178
};
171179

0 commit comments

Comments
 (0)