chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
import { describe, expect, vi } from "vitest";
|
||||
|
||||
// Redirect the module-level db client to the per-test container prisma so the worker-path
|
||||
// env resolution (`findEnvironmentById`/`controlPlaneResolver`, which read `~/db.server`)
|
||||
// hits the real container DB. The DB itself is never mocked — only the module binding is
|
||||
// pointed at the container client created by the fixture.
|
||||
const dbHolder = vi.hoisted(() => ({ prisma: undefined as any }));
|
||||
vi.mock("~/db.server", () => ({
|
||||
get prisma() {
|
||||
return dbHolder.prisma;
|
||||
},
|
||||
get $replica() {
|
||||
return dbHolder.prisma;
|
||||
},
|
||||
}));
|
||||
|
||||
import { RunEngine } from "@internal/run-engine";
|
||||
import { setupAuthenticatedEnvironment } from "@internal/run-engine/tests";
|
||||
import { PostgresRunStore, RoutingRunStore } from "@internal/run-store";
|
||||
import { containerTestWithIsolatedRedisNoClickhouse as containerTest } from "@internal/testcontainers";
|
||||
import { trace } from "@opentelemetry/api";
|
||||
import { BatchId } from "@trigger.dev/core/v3/isomorphic";
|
||||
import type { PrismaClient } from "@trigger.dev/database";
|
||||
import { RunEngineBatchTriggerService } from "../app/runEngine/services/batchTrigger.server";
|
||||
|
||||
vi.setConfig({ testTimeout: 120_000 });
|
||||
|
||||
function buildEngine(prisma: PrismaClient, redisOptions: any, store?: RoutingRunStore) {
|
||||
return new RunEngine({
|
||||
prisma,
|
||||
...(store ? { store } : {}),
|
||||
worker: {
|
||||
redis: redisOptions,
|
||||
workers: 1,
|
||||
tasksPerWorker: 10,
|
||||
pollIntervalMs: 100,
|
||||
disabled: true,
|
||||
},
|
||||
queue: { redis: redisOptions },
|
||||
runLock: { redis: redisOptions },
|
||||
machines: {
|
||||
defaultMachine: "small-1x",
|
||||
machines: {
|
||||
"small-1x": { name: "small-1x" as const, cpu: 0.5, memory: 0.5, centsPerMs: 0.0001 },
|
||||
},
|
||||
baseCostInCents: 0.0005,
|
||||
},
|
||||
batchQueue: { redis: redisOptions },
|
||||
tracer: trace.getTracer("test", "0.0.0"),
|
||||
});
|
||||
}
|
||||
|
||||
function batchCreateData(params: {
|
||||
id: string;
|
||||
friendlyId: string;
|
||||
runtimeEnvironmentId: string;
|
||||
runCount: number;
|
||||
payload: string;
|
||||
}) {
|
||||
return {
|
||||
id: params.id,
|
||||
friendlyId: params.friendlyId,
|
||||
runtimeEnvironmentId: params.runtimeEnvironmentId,
|
||||
runCount: params.runCount,
|
||||
runIds: [] as string[],
|
||||
payload: params.payload,
|
||||
payloadType: "application/json",
|
||||
options: {},
|
||||
batchVersion: "runengine:v1",
|
||||
};
|
||||
}
|
||||
|
||||
describe("RunEngineBatchTriggerService store routing", () => {
|
||||
// The service issues BatchTaskRun create/find/update through `this._engine.runStore`.
|
||||
// With an injected RoutingRunStore whose NEW slot is a PostgresRunStore, those calls
|
||||
// land on the run-ops store (born on NEW), not on a separate `this._prisma` path.
|
||||
containerTest(
|
||||
"create/find/update route through the injected run-ops store",
|
||||
async ({ prisma, redisOptions }) => {
|
||||
dbHolder.prisma = prisma;
|
||||
const runStore = new RoutingRunStore({
|
||||
new: new PostgresRunStore({ prisma, readOnlyPrisma: prisma }),
|
||||
legacy: new PostgresRunStore({ prisma, readOnlyPrisma: prisma }),
|
||||
});
|
||||
const engine = buildEngine(prisma, redisOptions, runStore);
|
||||
|
||||
const authenticatedEnvironment = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
|
||||
const service = new RunEngineBatchTriggerService("sequential", prisma, engine);
|
||||
|
||||
// The service holds the injected routing store.
|
||||
expect(service["_engine"].runStore).toBe(runStore);
|
||||
|
||||
// (create) Born on the run-ops store and present in the DB.
|
||||
const { id, friendlyId } = BatchId.generate();
|
||||
const created = await service["_engine"].runStore.createBatchTaskRun(
|
||||
batchCreateData({
|
||||
id,
|
||||
friendlyId,
|
||||
runtimeEnvironmentId: authenticatedEnvironment.id,
|
||||
runCount: 1,
|
||||
payload: "[]",
|
||||
})
|
||||
);
|
||||
expect(created.id).toBe(id);
|
||||
expect(await prisma.batchTaskRun.findUnique({ where: { id } })).not.toBeNull();
|
||||
|
||||
// (find + update) Drive the worker entrypoint with an empty payload so no child runs
|
||||
// are triggered: the path exercises findBatchTaskRunById -> findEnvironmentById ->
|
||||
// inline-payload parse -> updateBatchTaskRun, all through the store.
|
||||
await service.processBatchTaskRun({
|
||||
batchId: id,
|
||||
processingId: "0",
|
||||
range: { start: 0, count: 50 },
|
||||
attemptCount: 0,
|
||||
strategy: "sequential",
|
||||
});
|
||||
|
||||
// The update routed through the store ran (processingJobsCount incremented by the 0
|
||||
// processed items; runIds untouched). The row is the one written to the run-ops DB.
|
||||
const after = await prisma.batchTaskRun.findUnique({ where: { id } });
|
||||
expect(after).not.toBeNull();
|
||||
expect(after!.processingJobsCount).toBe(0);
|
||||
expect(after!.runIds).toEqual([]);
|
||||
|
||||
await engine.quit();
|
||||
}
|
||||
);
|
||||
|
||||
// Single-DB passthrough (self-host collapse): with no `store` injected, the engine
|
||||
// defaults to a PostgresRunStore over the one client, byte-identical to pre-routing.
|
||||
containerTest(
|
||||
"single-DB passthrough uses the default PostgresRunStore",
|
||||
async ({ prisma, redisOptions }) => {
|
||||
dbHolder.prisma = prisma;
|
||||
const engine = buildEngine(prisma, redisOptions);
|
||||
|
||||
const authenticatedEnvironment = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
|
||||
const service = new RunEngineBatchTriggerService("sequential", prisma, engine);
|
||||
|
||||
// The default store is a plain PostgresRunStore (no RoutingRunStore, no second client).
|
||||
expect(service["_engine"].runStore).toBeInstanceOf(PostgresRunStore);
|
||||
expect(service["_engine"].runStore).not.toBeInstanceOf(RoutingRunStore);
|
||||
|
||||
const { id, friendlyId } = BatchId.generate();
|
||||
await service["_engine"].runStore.createBatchTaskRun(
|
||||
batchCreateData({
|
||||
id,
|
||||
friendlyId,
|
||||
runtimeEnvironmentId: authenticatedEnvironment.id,
|
||||
runCount: 1,
|
||||
payload: "[]",
|
||||
})
|
||||
);
|
||||
|
||||
await service.processBatchTaskRun({
|
||||
batchId: id,
|
||||
processingId: "0",
|
||||
range: { start: 0, count: 50 },
|
||||
attemptCount: 0,
|
||||
strategy: "sequential",
|
||||
});
|
||||
|
||||
const after = await prisma.batchTaskRun.findUnique({ where: { id } });
|
||||
expect(after).not.toBeNull();
|
||||
expect(after!.processingJobsCount).toBe(0);
|
||||
|
||||
await engine.quit();
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user