chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:32:57 +08:00
commit cd420f9332
4811 changed files with 884702 additions and 0 deletions
@@ -0,0 +1,436 @@
import { describe, expect, vi } from "vitest";
// The runsRepository module graph imports `~/v3/runStore.server`, which imports `~/db.server`
// at load. Stub it (the existing runsRepository.part*.test.ts do the same) — the repo under test
// is driven entirely through injected real containers, never the stubbed module singletons.
vi.mock("~/db.server", () => ({
prisma: {},
$replica: {},
}));
import { PostgresRunStore } from "@internal/run-store";
import { createPostgresContainer, replicationContainerTest } from "@internal/testcontainers";
import { PrismaClient } from "@trigger.dev/database";
import { setTimeout } from "node:timers/promises";
import { RunsRepository } from "~/services/runsRepository/runsRepository.server";
import { setupClickhouseReplication } from "./utils/replicationUtils";
vi.setConfig({ testTimeout: 90_000 });
type SeedContext = {
organizationId: string;
projectId: string;
environmentId: string;
};
/**
* Creates the org/project/env parents on a single prisma client. TaskRun FKs require
* these to exist on every DB a run is hydrated from, so we seed identical parents
* (same ids) on both the legacy (PG14) and new (PG17) databases.
*/
async function seedParents(prisma: PrismaClient, slug: string): Promise<SeedContext> {
const organization = await prisma.organization.create({
data: { title: `org-${slug}`, slug: `org-${slug}` },
});
const project = await prisma.project.create({
data: {
name: `proj-${slug}`,
slug: `proj-${slug}`,
organizationId: organization.id,
externalRef: `proj-${slug}`,
},
});
const runtimeEnvironment = await prisma.runtimeEnvironment.create({
data: {
slug: `env-${slug}`,
type: "DEVELOPMENT",
projectId: project.id,
organizationId: organization.id,
apiKey: `tr_dev_${slug}`,
pkApiKey: `pk_dev_${slug}`,
shortcode: `sc-${slug}`,
},
});
return {
organizationId: organization.id,
projectId: project.id,
environmentId: runtimeEnvironment.id,
};
}
/** Mirrors the org/project/env parents onto a second DB with the SAME ids. */
async function mirrorParents(prisma: PrismaClient, ctx: SeedContext, slug: string): Promise<void> {
await prisma.organization.create({
data: { id: ctx.organizationId, title: `org-${slug}`, slug: `org-${slug}` },
});
await prisma.project.create({
data: {
id: ctx.projectId,
name: `proj-${slug}`,
slug: `proj-${slug}`,
organizationId: ctx.organizationId,
externalRef: `proj-${slug}`,
},
});
await prisma.runtimeEnvironment.create({
data: {
id: ctx.environmentId,
slug: `env-${slug}`,
type: "DEVELOPMENT",
projectId: ctx.projectId,
organizationId: ctx.organizationId,
apiKey: `tr_dev_${slug}_b`,
pkApiKey: `pk_dev_${slug}_b`,
shortcode: `sc-${slug}-b`,
},
});
}
async function createRun(
prisma: PrismaClient,
ctx: SeedContext,
run: {
id?: string;
friendlyId: string;
taskIdentifier?: string;
status?: any;
runTags?: string[];
createdAt?: Date;
}
) {
return prisma.taskRun.create({
data: {
...(run.id ? { id: run.id } : {}),
friendlyId: run.friendlyId,
taskIdentifier: run.taskIdentifier ?? "my-task",
status: run.status ?? "PENDING",
payload: JSON.stringify({ foo: run.friendlyId }),
traceId: run.friendlyId,
spanId: run.friendlyId,
queue: "test",
runTags: run.runTags ?? [],
runtimeEnvironmentId: ctx.environmentId,
projectId: ctx.projectId,
organizationId: ctx.organizationId,
environmentType: "DEVELOPMENT",
engine: "V2",
...(run.createdAt ? { createdAt: run.createdAt } : {}),
},
});
}
describe("RunsRepository read-through id-set hydrate (PG14 legacy + PG17 new)", () => {
// --- DoD line + e2e #6: split fan-out across new + legacy-replica with known-migrated filter ---
replicationContainerTest(
"split mode hydrates the CH id-set as the union of NEW + legacy-replica rows, byte-identical and id-desc ordered",
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma, network }) => {
// The fixture's PG14 container is the LEGACY read replica AND the replication source that
// feeds the ClickHouse id-set. The dedicated PG17 container is the NEW run-ops DB.
const { clickhouse } = await setupClickhouseReplication({
prisma,
databaseUrl: postgresContainer.getConnectionUri(),
clickhouseUrl: clickhouseContainer.getConnectionUrl(),
redisOptions,
});
const { url: newUrl } = await createPostgresContainer(network, {
imageTag: "docker.io/postgres:17",
});
const prismaNew = new PrismaClient({ datasources: { db: { url: newUrl } } });
try {
const ctx = await seedParents(prisma, "split1");
await mirrorParents(prismaNew, ctx, "split1");
// Seed all four runs on PG14 (legacy + replication source -> CH gets the full id-set).
const legacyOnlyA = await createRun(prisma, ctx, { friendlyId: "run_legacyA" });
const legacyOnlyB = await createRun(prisma, ctx, { friendlyId: "run_legacyB" });
const migratedA = await createRun(prisma, ctx, { friendlyId: "run_newA" });
const migratedB = await createRun(prisma, ctx, { friendlyId: "run_newB" });
// The two "migrated" runs ALSO live on the NEW DB (authoritative during retention).
// Same ids so set-membership and ordering line up with the CH id-set.
await createRun(prismaNew, { ...ctx }, { friendlyId: "run_newA" });
await createRun(prismaNew, { ...ctx }, { friendlyId: "run_newB" });
// Force the NEW rows to share the legacy ids exactly.
await prismaNew.taskRun.update({
where: { friendlyId: "run_newA" },
data: { id: migratedA.id },
});
await prismaNew.taskRun.update({
where: { friendlyId: "run_newB" },
data: { id: migratedB.id },
});
await setTimeout(1500);
const runsRepository = new RunsRepository({
prisma, // single-DB default handle (unused on the split path here)
clickhouse,
runStore: new PostgresRunStore({ prisma: prismaNew, readOnlyPrisma: prismaNew }),
readThrough: {
splitEnabled: true,
newClient: prismaNew,
legacyReplica: prisma,
},
});
const { runs } = await runsRepository.listRuns({
page: { size: 10 },
projectId: ctx.projectId,
environmentId: ctx.environmentId,
organizationId: ctx.organizationId,
});
// Union of all four, id-desc ordered.
const expectedIds = [migratedA.id, migratedB.id, legacyOnlyA.id, legacyOnlyB.id].sort(
(a, b) => (a < b ? 1 : a > b ? -1 : 0)
);
expect(runs.map((r) => r.id)).toEqual(expectedIds);
// Byte-identity for a NEW-served row (from PG17) and a legacy-served row (from PG14).
const newRow = runs.find((r) => r.id === migratedA.id)!;
expect(newRow.friendlyId).toBe("run_newA");
expect(newRow.taskIdentifier).toBe("my-task");
const legacyRow = runs.find((r) => r.id === legacyOnlyA.id)!;
expect(legacyRow.friendlyId).toBe("run_legacyA");
// Order parity with single-DB: a pure id-desc sort of the same ids.
expect(runs.map((r) => r.id)).toEqual(
[...runs.map((r) => r.id)].sort((a, b) => (a < b ? 1 : a > b ? -1 : 0))
);
} finally {
await prismaNew.$disconnect();
}
}
);
// --- Passthrough (single-DB): one plain store read, legacy never touched ---
replicationContainerTest(
"single-DB passthrough hydrates from one store read and never touches the legacy boundary",
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
const { clickhouse } = await setupClickhouseReplication({
prisma,
databaseUrl: postgresContainer.getConnectionUri(),
clickhouseUrl: clickhouseContainer.getConnectionUrl(),
redisOptions,
});
const ctx = await seedParents(prisma, "passthrough");
const run = await createRun(prisma, ctx, { friendlyId: "run_passthrough" });
await setTimeout(1500);
// splitEnabled false → the split branch is never entered (one plain store read).
const runsRepository = new RunsRepository({
prisma,
clickhouse,
readThrough: {
splitEnabled: false,
legacyReplica: prisma,
},
});
const { runs } = await runsRepository.listRuns({
page: { size: 10 },
projectId: ctx.projectId,
environmentId: ctx.environmentId,
organizationId: ctx.organizationId,
});
expect(runs).toHaveLength(1);
expect(runs[0].id).toBe(run.id);
const friendlyIds = await runsRepository.listFriendlyRunIds({
page: { size: 10 },
projectId: ctx.projectId,
environmentId: ctx.environmentId,
organizationId: ctx.organizationId,
});
expect(friendlyIds).toEqual(["run_passthrough"]);
}
);
// --- Ordering: the hydrated page follows the ClickHouse keyset (created_at desc), NOT raw id ---
replicationContainerTest(
"listRuns orders by the ClickHouse created_at keyset, not by raw id",
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
const { clickhouse } = await setupClickhouseReplication({
prisma,
databaseUrl: postgresContainer.getConnectionUri(),
clickhouseUrl: clickhouseContainer.getConnectionUrl(),
redisOptions,
});
const ctx = await seedParents(prisma, "ordering");
// Make chronological order the OPPOSITE of id order: the run created FIRST (smaller
// time-prefixed cuid id) is given the MOST-RECENT created_at. A correct list returns
// [mostRecent, oldest] (created_at desc); the old id-desc hydrate would invert it.
// created_at is set at insert time (not via update) so ClickHouse never holds a second
// ReplacingMergeTree version that could surface as a duplicate.
const now = Date.now();
const mostRecent = await createRun(prisma, ctx, {
friendlyId: "run_orderA",
createdAt: new Date(now),
});
const oldest = await createRun(prisma, ctx, {
friendlyId: "run_orderB",
createdAt: new Date(now - 3_600_000),
});
expect(mostRecent.id < oldest.id).toBe(true); // raw id-desc would yield [oldest, mostRecent]
await setTimeout(1500);
const runsRepository = new RunsRepository({ prisma, clickhouse });
const { runs } = await runsRepository.listRuns({
page: { size: 10 },
projectId: ctx.projectId,
environmentId: ctx.environmentId,
organizationId: ctx.organizationId,
});
expect(runs.map((r) => r.id)).toEqual([mostRecent.id, oldest.id]);
}
);
// --- listFriendlyRunIds parity: split union, id projected away to a plain string[] ---
replicationContainerTest(
"listFriendlyRunIds returns the union of friendly ids across new + legacy, projecting id away",
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma, network }) => {
const { clickhouse } = await setupClickhouseReplication({
prisma,
databaseUrl: postgresContainer.getConnectionUri(),
clickhouseUrl: clickhouseContainer.getConnectionUrl(),
redisOptions,
});
const { url: newUrl } = await createPostgresContainer(network, {
imageTag: "docker.io/postgres:17",
});
const prismaNew = new PrismaClient({ datasources: { db: { url: newUrl } } });
try {
const ctx = await seedParents(prisma, "friendly");
await mirrorParents(prismaNew, ctx, "friendly");
const legacy = await createRun(prisma, ctx, { friendlyId: "run_fLegacy" });
const migrated = await createRun(prisma, ctx, { friendlyId: "run_fNew" });
await createRun(prismaNew, ctx, { friendlyId: "run_fNew" });
await prismaNew.taskRun.update({
where: { friendlyId: "run_fNew" },
data: { id: migrated.id },
});
await setTimeout(1500);
const runsRepository = new RunsRepository({
prisma,
clickhouse,
runStore: new PostgresRunStore({ prisma: prismaNew, readOnlyPrisma: prismaNew }),
readThrough: {
splitEnabled: true,
newClient: prismaNew,
legacyReplica: prisma,
},
});
const friendlyIds = await runsRepository.listFriendlyRunIds({
page: { size: 10 },
projectId: ctx.projectId,
environmentId: ctx.environmentId,
organizationId: ctx.organizationId,
});
expect(friendlyIds.every((f) => typeof f === "string")).toBe(true);
expect([...friendlyIds].sort()).toEqual(["run_fLegacy", "run_fNew"]);
// id projected away: a friendlyId is never a run internal id.
expect(friendlyIds).not.toContain(legacy.id);
} finally {
await prismaNew.$disconnect();
}
}
);
// Full-keyset walk over interleaved cuid + run-ops ids: hydration must preserve the ClickHouse
// (created_at DESC, run_id DESC) order across the id-space seam. A hydrate that reverts to lexical
// `id desc` splits the two id-spaces into separate blocks, so it would fail this walk.
replicationContainerTest(
"paginating the full keyset enumerates every interleaved cuid/run-ops id once, in CH keyset order, with no empty page",
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
const { clickhouse } = await setupClickhouseReplication({
prisma,
databaseUrl: postgresContainer.getConnectionUri(),
clickhouseUrl: clickhouseContainer.getConnectionUrl(),
redisOptions,
});
const ctx = await seedParents(prisma, "keysetwalk");
// cuid-shaped ids (25 chars, "c" prefix) and v1-shaped ids (26 chars, "2" prefix, version "1"). Lexical
// `id desc` groups all "c" ids ahead of all "2" ids; the created_at order below interleaves
// them, so the two orders genuinely differ across the seam.
const cuid = (n: number) => `c${String(n).padStart(24, "0")}`;
const runOpsId = (n: number) => `2${String(n).padStart(23, "0")}01`;
// created_at DESC order (index 0 = most recent) interleaves the id-spaces: run-ops id, cuid,
// run-ops id, cuid, run-ops id, cuid.
const now = Date.now();
const seeds = [
{ id: runOpsId(6), friendlyId: "run_k6", createdAt: new Date(now - 0 * 60_000) },
{ id: cuid(5), friendlyId: "run_c5", createdAt: new Date(now - 1 * 60_000) },
{ id: runOpsId(4), friendlyId: "run_k4", createdAt: new Date(now - 2 * 60_000) },
{ id: cuid(3), friendlyId: "run_c3", createdAt: new Date(now - 3 * 60_000) },
{ id: runOpsId(2), friendlyId: "run_k2", createdAt: new Date(now - 4 * 60_000) },
{ id: cuid(1), friendlyId: "run_c1", createdAt: new Date(now - 5 * 60_000) },
];
for (const s of seeds) {
await createRun(prisma, ctx, s);
}
await setTimeout(1500);
const runsRepository = new RunsRepository({ prisma, clickhouse });
// The authoritative order the hydrate must reproduce: exactly the CH keyset the id-list scan
// returns (created_at DESC, run_id DESC). Lexical id-desc of the same ids differs from this.
const chOrder = await runsRepository.listRunIds({
page: { size: 100 },
projectId: ctx.projectId,
environmentId: ctx.environmentId,
organizationId: ctx.organizationId,
});
const expectedOrder = chOrder.runIds;
const lexicalIdDesc = [...expectedOrder].sort((a, b) => (a < b ? 1 : a > b ? -1 : 0));
expect(expectedOrder).not.toEqual(lexicalIdDesc); // the seam actually separates the two orders
// Walk the whole keyset a page at a time.
const walked: string[] = [];
let cursor: string | undefined;
let pages = 0;
while (true) {
const { runs, pagination } = await runsRepository.listRuns({
page: { size: 2, cursor },
projectId: ctx.projectId,
environmentId: ctx.environmentId,
organizationId: ctx.organizationId,
});
pages++;
expect(pages).toBeLessThan(20); // guard against a non-terminating walk
for (const r of runs) walked.push(r.id);
if (!pagination.nextCursor) break;
// No empty page may be returned while more pages exist.
expect(runs.length).toBeGreaterThan(0);
cursor = pagination.nextCursor;
}
// Every seeded id enumerated exactly once.
expect(walked.slice().sort()).toEqual(seeds.map((s) => s.id).sort());
expect(new Set(walked).size).toBe(seeds.length);
// The emitted order equals the CH keyset order across the id-space seam.
expect(walked).toEqual(expectedOrder);
}
);
});