chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
import { heteroRunOpsPostgresTest, postgresTest } from "@internal/testcontainers";
|
||||
import type { RunOpsPrismaClient } from "@internal/run-ops-database";
|
||||
import type { PrismaClient } from "@trigger.dev/database";
|
||||
import { generateRunOpsId } from "@trigger.dev/core/v3/isomorphic";
|
||||
import { describe, expect, vi } from "vitest";
|
||||
import type { PrismaReplicaClient } from "~/db.server";
|
||||
import { resolveWaitpointThroughReadThrough } from "~/runEngine/concerns/resolveWaitpointThroughReadThrough.server";
|
||||
|
||||
vi.setConfig({ testTimeout: 60_000 });
|
||||
|
||||
// 25-char cuid (no v1 version marker) -> LEGACY residency.
|
||||
function generateLegacyCuid() {
|
||||
const suffix = Array.from(
|
||||
{ length: 24 },
|
||||
() => "0123456789abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random() * 36)]
|
||||
).join("");
|
||||
return `c${suffix}`;
|
||||
}
|
||||
|
||||
function recording(client: PrismaClient | RunOpsPrismaClient, opts: { forbidden?: boolean } = {}) {
|
||||
const calls: unknown[] = [];
|
||||
const waitpoint = {
|
||||
findFirst: (args: unknown) => {
|
||||
calls.push(args);
|
||||
if (opts.forbidden) {
|
||||
throw new Error("this store must never be read");
|
||||
}
|
||||
return (client as unknown as PrismaReplicaClient).waitpoint.findFirst(args as never);
|
||||
},
|
||||
};
|
||||
return { handle: { ...client, waitpoint } as unknown as PrismaReplicaClient, calls };
|
||||
}
|
||||
|
||||
async function seedOrgProjectEnv(prisma: PrismaClient, suffix: string) {
|
||||
const organization = await prisma.organization.create({
|
||||
data: { title: `test-${suffix}`, slug: `test-${suffix}` },
|
||||
});
|
||||
const project = await prisma.project.create({
|
||||
data: {
|
||||
name: `test-${suffix}`,
|
||||
slug: `test-${suffix}`,
|
||||
organizationId: organization.id,
|
||||
externalRef: `test-${suffix}`,
|
||||
},
|
||||
});
|
||||
const environment = await prisma.runtimeEnvironment.create({
|
||||
data: {
|
||||
slug: `test-${suffix}`,
|
||||
type: "PRODUCTION",
|
||||
projectId: project.id,
|
||||
organizationId: organization.id,
|
||||
apiKey: `apikey-${suffix}`,
|
||||
pkApiKey: `pk-${suffix}`,
|
||||
shortcode: `test-${suffix}`,
|
||||
},
|
||||
});
|
||||
return { organization, project, environment };
|
||||
}
|
||||
|
||||
async function seedWaitpoint(
|
||||
prisma: PrismaClient | RunOpsPrismaClient,
|
||||
id: string,
|
||||
env: { id: string; projectId: string }
|
||||
) {
|
||||
return prisma.waitpoint.create({
|
||||
data: {
|
||||
id,
|
||||
friendlyId: `waitpoint_${id}`,
|
||||
type: "MANUAL",
|
||||
status: "PENDING",
|
||||
idempotencyKey: `idem-${id}`,
|
||||
userProvidedIdempotencyKey: false,
|
||||
projectId: env.projectId,
|
||||
environmentId: env.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const read = (waitpointId: string, environmentId: string) => (client: PrismaReplicaClient) =>
|
||||
client.waitpoint.findFirst({
|
||||
where: { id: waitpointId, environmentId },
|
||||
select: { id: true, status: true, projectId: true, environmentId: true },
|
||||
});
|
||||
|
||||
describe("resolveWaitpointThroughReadThrough (hetero PG14 legacy + dedicated run-ops PG17)", () => {
|
||||
heteroRunOpsPostgresTest(
|
||||
"run-ops waitpoint resolves on the dedicated run-ops client; legacy replica never touched",
|
||||
async ({ prisma17, prisma14 }) => {
|
||||
const id = generateRunOpsId();
|
||||
expect(id.length).toBe(26);
|
||||
|
||||
// The dedicated run-ops DB has no control-plane tables; the waitpoint's
|
||||
// environment/project FKs are synthetic scalar ids.
|
||||
const environmentId = generateRunOpsId();
|
||||
const projectId = generateRunOpsId();
|
||||
const seeded = await seedWaitpoint(prisma17, id, { id: environmentId, projectId });
|
||||
|
||||
const newClient = recording(prisma17);
|
||||
const legacy = recording(prisma14, { forbidden: true });
|
||||
|
||||
const result = await resolveWaitpointThroughReadThrough({
|
||||
waitpointId: id,
|
||||
environmentId,
|
||||
read: read(id, environmentId),
|
||||
deps: {
|
||||
splitEnabled: true,
|
||||
newClient: newClient.handle,
|
||||
legacyReplica: legacy.handle,
|
||||
},
|
||||
});
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.id).toBe(seeded.id);
|
||||
expect(result!.projectId).toBe(projectId);
|
||||
expect(result!.environmentId).toBe(environmentId);
|
||||
expect(newClient.calls.length).toBe(1);
|
||||
expect(legacy.calls.length).toBe(0);
|
||||
}
|
||||
);
|
||||
|
||||
heteroRunOpsPostgresTest(
|
||||
"cuid waitpoint resolves off the LEGACY replica (new probed first, miss)",
|
||||
async ({ prisma17, prisma14 }) => {
|
||||
const id = generateLegacyCuid();
|
||||
expect(id.length).toBe(25);
|
||||
|
||||
const { project, environment } = await seedOrgProjectEnv(prisma14, "legacy");
|
||||
const seeded = await seedWaitpoint(prisma14, id, {
|
||||
id: environment.id,
|
||||
projectId: project.id,
|
||||
});
|
||||
|
||||
const newClient = recording(prisma17);
|
||||
const legacy = recording(prisma14);
|
||||
|
||||
const result = await resolveWaitpointThroughReadThrough({
|
||||
waitpointId: id,
|
||||
environmentId: environment.id,
|
||||
read: read(id, environment.id),
|
||||
deps: {
|
||||
splitEnabled: true,
|
||||
newClient: newClient.handle,
|
||||
legacyReplica: legacy.handle,
|
||||
},
|
||||
});
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.id).toBe(seeded.id);
|
||||
expect(newClient.calls.length).toBe(1);
|
||||
expect(legacy.calls.length).toBe(1);
|
||||
}
|
||||
);
|
||||
|
||||
// Read-your-writes: a token completed immediately after mint may not be on the replicas yet. The
|
||||
// replica-only read-through misses, and without a primary fallback we 404 a valid token (the
|
||||
// authoritative completeWaitpoint never runs). The primary fallback must find it.
|
||||
heteroRunOpsPostgresTest(
|
||||
"a NEW-resident token missing on both replicas is found on the run-ops primary (no spurious 404)",
|
||||
async ({ prisma17, prisma14 }) => {
|
||||
// A NEW-resident token lives on the run-ops DB (prisma17); its cuid id fans new-then-legacy.
|
||||
// Both replicas here lack it (pointed at prisma14), so only the run-ops primary can serve it.
|
||||
const id = generateLegacyCuid();
|
||||
const environmentId = generateRunOpsId();
|
||||
const projectId = generateRunOpsId();
|
||||
const seeded = await seedWaitpoint(prisma17, id, { id: environmentId, projectId });
|
||||
|
||||
const newClient = recording(prisma14);
|
||||
const legacyReplica = recording(prisma14);
|
||||
const newPrimary = recording(prisma17);
|
||||
|
||||
const result = await resolveWaitpointThroughReadThrough({
|
||||
waitpointId: id,
|
||||
environmentId,
|
||||
read: read(id, environmentId),
|
||||
deps: {
|
||||
splitEnabled: true,
|
||||
newClient: newClient.handle,
|
||||
legacyReplica: legacyReplica.handle,
|
||||
newPrimary: newPrimary.handle,
|
||||
},
|
||||
});
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.id).toBe(seeded.id);
|
||||
// Both replicas probed and missed; the fallback read the run-ops primary (never control-plane).
|
||||
expect(newClient.calls.length).toBe(1);
|
||||
expect(legacyReplica.calls.length).toBe(1);
|
||||
expect(newPrimary.calls.length).toBe(1);
|
||||
}
|
||||
);
|
||||
|
||||
heteroRunOpsPostgresTest(
|
||||
"bare caller (no deps) resolves a NEW-resident waitpoint via the safe run-ops defaults",
|
||||
async ({ prisma17, prisma14 }) => {
|
||||
// The bare wait route passes NO `deps`; the `defaults` DI seam models old vs new
|
||||
// fallback against containers, avoiding the real db.server topology.
|
||||
const id = generateRunOpsId();
|
||||
expect(id.length).toBe(26);
|
||||
const environmentId = generateRunOpsId();
|
||||
const projectId = generateRunOpsId();
|
||||
const seeded = await seedWaitpoint(prisma17, id, { id: environmentId, projectId });
|
||||
|
||||
// FAIL-BEFORE: old default pinned newClient to control-plane ($replica ≈ prisma14) → miss.
|
||||
const oldDefaultResult = await resolveWaitpointThroughReadThrough({
|
||||
waitpointId: id,
|
||||
environmentId,
|
||||
read: read(id, environmentId),
|
||||
defaults: {
|
||||
newClient: prisma14 as unknown as PrismaReplicaClient,
|
||||
legacyReplica: prisma14 as unknown as PrismaReplicaClient,
|
||||
// Primaries also miss the NEW-resident waitpoint, so the miss stays a miss.
|
||||
newPrimary: prisma14 as unknown as PrismaReplicaClient,
|
||||
splitEnabled: true,
|
||||
},
|
||||
});
|
||||
expect(oldDefaultResult).toBeNull();
|
||||
|
||||
// PASS-AFTER: safe default routes newClient to the run-ops replica (runOpsNewReplica ≈ prisma17).
|
||||
const safeDefaultResult = await resolveWaitpointThroughReadThrough({
|
||||
waitpointId: id,
|
||||
environmentId,
|
||||
read: read(id, environmentId),
|
||||
defaults: {
|
||||
newClient: prisma17 as unknown as PrismaReplicaClient,
|
||||
legacyReplica: prisma14 as unknown as PrismaReplicaClient,
|
||||
newPrimary: prisma17 as unknown as PrismaReplicaClient,
|
||||
splitEnabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(safeDefaultResult).not.toBeNull();
|
||||
expect(safeDefaultResult!.id).toBe(seeded.id);
|
||||
expect(safeDefaultResult!.projectId).toBe(projectId);
|
||||
expect(safeDefaultResult!.environmentId).toBe(environmentId);
|
||||
}
|
||||
);
|
||||
|
||||
heteroRunOpsPostgresTest("not-found maps to null (no throw)", async ({ prisma17, prisma14 }) => {
|
||||
const id = generateLegacyCuid();
|
||||
const { environment } = await seedOrgProjectEnv(prisma14, "nf");
|
||||
|
||||
const result = await resolveWaitpointThroughReadThrough({
|
||||
waitpointId: id,
|
||||
environmentId: environment.id,
|
||||
read: read(id, environment.id),
|
||||
deps: {
|
||||
splitEnabled: true,
|
||||
newClient: recording(prisma17).handle,
|
||||
legacyReplica: recording(prisma14).handle,
|
||||
// The run-ops-primary fallback also misses this never-seeded token; inject a container client
|
||||
// so it does not reach for the unconnectable production singleton.
|
||||
newPrimary: recording(prisma17).handle,
|
||||
},
|
||||
});
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
postgresTest(
|
||||
"passthrough (single-DB): one plain read; legacy never invoked",
|
||||
async ({ prisma }) => {
|
||||
const id = generateRunOpsId();
|
||||
const { project, environment } = await seedOrgProjectEnv(prisma, "pt");
|
||||
const seeded = await seedWaitpoint(prisma, id, {
|
||||
id: environment.id,
|
||||
projectId: project.id,
|
||||
});
|
||||
|
||||
const single = recording(prisma);
|
||||
const legacy = recording(prisma, { forbidden: true });
|
||||
|
||||
const result = await resolveWaitpointThroughReadThrough({
|
||||
waitpointId: id,
|
||||
environmentId: environment.id,
|
||||
read: read(id, environment.id),
|
||||
deps: {
|
||||
splitEnabled: false,
|
||||
newClient: single.handle,
|
||||
legacyReplica: legacy.handle,
|
||||
},
|
||||
});
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.id).toBe(seeded.id);
|
||||
expect(single.calls.length).toBe(1);
|
||||
expect(legacy.calls.length).toBe(0);
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user