702 lines
21 KiB
TypeScript
702 lines
21 KiB
TypeScript
import { ClickHouse } from "@internal/clickhouse";
|
|
import { replicationContainerTest } from "@internal/testcontainers";
|
|
import { setTimeout } from "node:timers/promises";
|
|
import superjson from "superjson";
|
|
import { z } from "zod";
|
|
import { RunsReplicationService } from "~/services/runsReplicationService.server";
|
|
import { TestReplicationClickhouseFactory } from "./utils/testReplicationClickhouseFactory";
|
|
import { createInMemoryTracing } from "./utils/tracing";
|
|
|
|
vi.setConfig({ testTimeout: 60_000 });
|
|
|
|
describe("RunsReplicationService (part 1/7)", () => {
|
|
replicationContainerTest(
|
|
"should replicate runs to clickhouse",
|
|
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
|
|
await prisma.$executeRawUnsafe(`ALTER TABLE public."TaskRun" REPLICA IDENTITY FULL;`);
|
|
|
|
const clickhouse = new ClickHouse({
|
|
url: clickhouseContainer.getConnectionUrl(),
|
|
name: "runs-replication",
|
|
compression: {
|
|
request: true,
|
|
},
|
|
logLevel: "warn",
|
|
});
|
|
|
|
const { tracer, exporter } = createInMemoryTracing();
|
|
|
|
const runsReplicationService = new RunsReplicationService({
|
|
clickhouseFactory: new TestReplicationClickhouseFactory(clickhouse),
|
|
pgConnectionUrl: postgresContainer.getConnectionUri(),
|
|
serviceName: "runs-replication",
|
|
slotName: "task_runs_to_clickhouse_v1",
|
|
publicationName: "task_runs_to_clickhouse_v1_publication",
|
|
redisOptions,
|
|
maxFlushConcurrency: 1,
|
|
flushIntervalMs: 100,
|
|
flushBatchSize: 1,
|
|
leaderLockTimeoutMs: 5000,
|
|
leaderLockExtendIntervalMs: 1000,
|
|
ackIntervalSeconds: 5,
|
|
tracer,
|
|
logLevel: "warn",
|
|
});
|
|
|
|
await runsReplicationService.start();
|
|
|
|
const organization = await prisma.organization.create({
|
|
data: {
|
|
title: "test",
|
|
slug: "test",
|
|
},
|
|
});
|
|
|
|
const project = await prisma.project.create({
|
|
data: {
|
|
name: "test",
|
|
slug: "test",
|
|
organizationId: organization.id,
|
|
externalRef: "test",
|
|
},
|
|
});
|
|
|
|
const runtimeEnvironment = await prisma.runtimeEnvironment.create({
|
|
data: {
|
|
slug: "test",
|
|
type: "DEVELOPMENT",
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
apiKey: "test",
|
|
pkApiKey: "test",
|
|
shortcode: "test",
|
|
},
|
|
});
|
|
|
|
const taskRun = await prisma.taskRun.create({
|
|
data: {
|
|
friendlyId: "run_1234",
|
|
taskIdentifier: "my-task",
|
|
payload: JSON.stringify({ foo: "bar" }),
|
|
traceId: "1234",
|
|
spanId: "1234",
|
|
queue: "test",
|
|
workerQueue: "us-east-1-next",
|
|
region: "us-east-1",
|
|
planType: "free",
|
|
runtimeEnvironmentId: runtimeEnvironment.id,
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
environmentType: "DEVELOPMENT",
|
|
engine: "V2",
|
|
annotations: {
|
|
triggerSource: "api",
|
|
triggerAction: "trigger",
|
|
rootTriggerSource: "dashboard",
|
|
},
|
|
isWarmStart: true,
|
|
},
|
|
});
|
|
|
|
const queryRuns = clickhouse.reader.query({
|
|
name: "runs-replication",
|
|
query: "SELECT * FROM trigger_dev.task_runs_v2",
|
|
schema: z.any(),
|
|
});
|
|
|
|
const result = await vi.waitFor(
|
|
async () => {
|
|
const [queryError, rows] = await queryRuns({});
|
|
|
|
expect(queryError).toBeNull();
|
|
expect(rows?.length).toBe(1);
|
|
|
|
return rows;
|
|
},
|
|
{ timeout: 30_000, interval: 250 }
|
|
);
|
|
expect(result?.[0]).toEqual(
|
|
expect.objectContaining({
|
|
run_id: taskRun.id,
|
|
friendly_id: taskRun.friendlyId,
|
|
task_identifier: taskRun.taskIdentifier,
|
|
environment_id: runtimeEnvironment.id,
|
|
project_id: project.id,
|
|
organization_id: organization.id,
|
|
environment_type: "DEVELOPMENT",
|
|
engine: "V2",
|
|
trigger_source: "api",
|
|
root_trigger_source: "dashboard",
|
|
is_warm_start: 1,
|
|
// worker_queue stays the raw backing (operators); region is the geo (customers)
|
|
worker_queue: "us-east-1-next",
|
|
region: "us-east-1",
|
|
plan_type: "free",
|
|
})
|
|
);
|
|
|
|
const spans = exporter.getFinishedSpans();
|
|
|
|
expect(spans.length).toBeGreaterThan(0);
|
|
|
|
const flushBatchSpan = spans.find((span) => span.name === "flushBatch");
|
|
expect(flushBatchSpan).toBeDefined();
|
|
|
|
await runsReplicationService.stop();
|
|
}
|
|
);
|
|
|
|
replicationContainerTest(
|
|
"should replicate runs with super json payloads to clickhouse",
|
|
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
|
|
await prisma.$executeRawUnsafe(`ALTER TABLE public."TaskRun" REPLICA IDENTITY FULL;`);
|
|
|
|
const clickhouse = new ClickHouse({
|
|
url: clickhouseContainer.getConnectionUrl(),
|
|
name: "runs-replication",
|
|
compression: {
|
|
request: true,
|
|
},
|
|
logLevel: "warn",
|
|
});
|
|
|
|
const { tracer, exporter: _exporter } = createInMemoryTracing();
|
|
|
|
const runsReplicationService = new RunsReplicationService({
|
|
clickhouseFactory: new TestReplicationClickhouseFactory(clickhouse),
|
|
pgConnectionUrl: postgresContainer.getConnectionUri(),
|
|
serviceName: "runs-replication",
|
|
slotName: "task_runs_to_clickhouse_v1",
|
|
publicationName: "task_runs_to_clickhouse_v1_publication",
|
|
redisOptions,
|
|
maxFlushConcurrency: 1,
|
|
flushIntervalMs: 100,
|
|
flushBatchSize: 1,
|
|
leaderLockTimeoutMs: 5000,
|
|
leaderLockExtendIntervalMs: 1000,
|
|
ackIntervalSeconds: 5,
|
|
tracer,
|
|
logLevel: "warn",
|
|
});
|
|
|
|
await runsReplicationService.start();
|
|
|
|
const organization = await prisma.organization.create({
|
|
data: {
|
|
title: "test",
|
|
slug: "test",
|
|
},
|
|
});
|
|
|
|
const project = await prisma.project.create({
|
|
data: {
|
|
name: "test",
|
|
slug: "test",
|
|
organizationId: organization.id,
|
|
externalRef: "test",
|
|
},
|
|
});
|
|
|
|
const runtimeEnvironment = await prisma.runtimeEnvironment.create({
|
|
data: {
|
|
slug: "test",
|
|
type: "DEVELOPMENT",
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
apiKey: "test",
|
|
pkApiKey: "test",
|
|
shortcode: "test",
|
|
},
|
|
});
|
|
|
|
const date = new Date();
|
|
|
|
const taskRun = await prisma.taskRun.create({
|
|
data: {
|
|
friendlyId: "run_1234",
|
|
taskIdentifier: "my-task",
|
|
payload: superjson.stringify({
|
|
foo: "bar",
|
|
bigint: BigInt(1234),
|
|
date,
|
|
map: new Map([["foo", "bar"]]),
|
|
}),
|
|
payloadType: "application/super+json",
|
|
traceId: "1234",
|
|
spanId: "1234",
|
|
queue: "test",
|
|
runtimeEnvironmentId: runtimeEnvironment.id,
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
environmentType: "DEVELOPMENT",
|
|
engine: "V2",
|
|
},
|
|
});
|
|
|
|
const queryRuns = clickhouse.reader.query({
|
|
name: "runs-replication",
|
|
query: "SELECT * FROM trigger_dev.task_runs_v2",
|
|
schema: z.any(),
|
|
});
|
|
|
|
const result = await vi.waitFor(
|
|
async () => {
|
|
const [queryError, rows] = await queryRuns({});
|
|
|
|
expect(queryError).toBeNull();
|
|
expect(rows?.length).toBe(1);
|
|
|
|
return rows;
|
|
},
|
|
{ timeout: 30_000, interval: 250 }
|
|
);
|
|
expect(result?.[0]).toEqual(
|
|
expect.objectContaining({
|
|
run_id: taskRun.id,
|
|
friendly_id: taskRun.friendlyId,
|
|
task_identifier: taskRun.taskIdentifier,
|
|
environment_id: runtimeEnvironment.id,
|
|
project_id: project.id,
|
|
organization_id: organization.id,
|
|
environment_type: "DEVELOPMENT",
|
|
engine: "V2",
|
|
})
|
|
);
|
|
|
|
const queryPayloads = clickhouse.reader.query({
|
|
name: "runs-replication",
|
|
query: "SELECT * FROM trigger_dev.raw_task_runs_payload_v1 WHERE run_id = {run_id:String}",
|
|
schema: z.any(),
|
|
params: z.object({ run_id: z.string() }),
|
|
});
|
|
|
|
const payloadResult = await vi.waitFor(
|
|
async () => {
|
|
const [payloadQueryError, payloadRows] = await queryPayloads({ run_id: taskRun.id });
|
|
|
|
expect(payloadQueryError).toBeNull();
|
|
expect(payloadRows?.length).toBe(1);
|
|
|
|
return payloadRows;
|
|
},
|
|
{ timeout: 30_000, interval: 250 }
|
|
);
|
|
expect(payloadResult?.[0]).toEqual(
|
|
expect.objectContaining({
|
|
run_id: taskRun.id,
|
|
payload: {
|
|
data: expect.objectContaining({
|
|
foo: "bar",
|
|
bigint: "1234",
|
|
date: date.toISOString(),
|
|
map: [["foo", "bar"]],
|
|
}),
|
|
},
|
|
})
|
|
);
|
|
|
|
await runsReplicationService.stop();
|
|
}
|
|
);
|
|
|
|
replicationContainerTest(
|
|
"should not produce any flush spans when no TaskRun events are produced",
|
|
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
|
|
await prisma.$executeRawUnsafe(`ALTER TABLE public."TaskRun" REPLICA IDENTITY FULL;`);
|
|
|
|
const clickhouse = new ClickHouse({
|
|
url: clickhouseContainer.getConnectionUrl(),
|
|
name: "runs-replication",
|
|
logLevel: "warn",
|
|
});
|
|
|
|
const { tracer, exporter } = createInMemoryTracing();
|
|
|
|
const runsReplicationService = new RunsReplicationService({
|
|
clickhouseFactory: new TestReplicationClickhouseFactory(clickhouse),
|
|
pgConnectionUrl: postgresContainer.getConnectionUri(),
|
|
serviceName: "runs-replication",
|
|
slotName: "task_runs_to_clickhouse_v1",
|
|
publicationName: "task_runs_to_clickhouse_v1_publication",
|
|
redisOptions,
|
|
maxFlushConcurrency: 1,
|
|
flushIntervalMs: 100,
|
|
flushBatchSize: 1,
|
|
leaderLockTimeoutMs: 5000,
|
|
leaderLockExtendIntervalMs: 1000,
|
|
ackIntervalSeconds: 5,
|
|
tracer,
|
|
logLevel: "warn",
|
|
});
|
|
|
|
await runsReplicationService.start();
|
|
|
|
const organization = await prisma.organization.create({
|
|
data: {
|
|
title: "test",
|
|
slug: "test",
|
|
},
|
|
});
|
|
|
|
const project = await prisma.project.create({
|
|
data: {
|
|
name: "test",
|
|
slug: "test",
|
|
organizationId: organization.id,
|
|
externalRef: "test",
|
|
},
|
|
});
|
|
|
|
await prisma.runtimeEnvironment.create({
|
|
data: {
|
|
slug: "test",
|
|
type: "DEVELOPMENT",
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
apiKey: "test",
|
|
pkApiKey: "test",
|
|
shortcode: "test",
|
|
},
|
|
});
|
|
|
|
await setTimeout(1000);
|
|
|
|
const spans = exporter.getFinishedSpans();
|
|
|
|
const flushBatchSpans = spans.filter((span) => span.name === "flushBatch");
|
|
|
|
expect(flushBatchSpans.length).toBe(0);
|
|
|
|
await runsReplicationService.stop();
|
|
}
|
|
);
|
|
|
|
replicationContainerTest(
|
|
"should replicate a new TaskRun to ClickHouse using batching insert strategy",
|
|
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
|
|
await prisma.$executeRawUnsafe(`ALTER TABLE public."TaskRun" REPLICA IDENTITY FULL;`);
|
|
|
|
const clickhouse = new ClickHouse({
|
|
url: clickhouseContainer.getConnectionUrl(),
|
|
name: "runs-replication-batching",
|
|
logLevel: "warn",
|
|
});
|
|
|
|
const runsReplicationService = new RunsReplicationService({
|
|
clickhouseFactory: new TestReplicationClickhouseFactory(clickhouse),
|
|
pgConnectionUrl: postgresContainer.getConnectionUri(),
|
|
serviceName: "runs-replication-batching",
|
|
slotName: "task_runs_to_clickhouse_v1",
|
|
publicationName: "task_runs_to_clickhouse_v1_publication",
|
|
redisOptions,
|
|
maxFlushConcurrency: 1,
|
|
flushIntervalMs: 100,
|
|
flushBatchSize: 1,
|
|
leaderLockTimeoutMs: 5000,
|
|
leaderLockExtendIntervalMs: 1000,
|
|
ackIntervalSeconds: 5,
|
|
logLevel: "warn",
|
|
});
|
|
|
|
await runsReplicationService.start();
|
|
|
|
const organization = await prisma.organization.create({
|
|
data: {
|
|
title: "test-batching",
|
|
slug: "test-batching",
|
|
},
|
|
});
|
|
|
|
const project = await prisma.project.create({
|
|
data: {
|
|
name: "test-batching",
|
|
slug: "test-batching",
|
|
organizationId: organization.id,
|
|
externalRef: "test-batching",
|
|
},
|
|
});
|
|
|
|
const runtimeEnvironment = await prisma.runtimeEnvironment.create({
|
|
data: {
|
|
slug: "test-batching",
|
|
type: "DEVELOPMENT",
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
apiKey: "test-batching",
|
|
pkApiKey: "test-batching",
|
|
shortcode: "test-batching",
|
|
},
|
|
});
|
|
|
|
const uniqueFriendlyId = `run_batching_${Date.now()}`;
|
|
const taskRun = await prisma.taskRun.create({
|
|
data: {
|
|
friendlyId: uniqueFriendlyId,
|
|
taskIdentifier: "my-task-batching",
|
|
payload: JSON.stringify({ foo: "bar-batching" }),
|
|
traceId: "batching-1234",
|
|
spanId: "batching-1234",
|
|
queue: "test-batching",
|
|
runtimeEnvironmentId: runtimeEnvironment.id,
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
environmentType: "DEVELOPMENT",
|
|
engine: "V2",
|
|
},
|
|
});
|
|
|
|
const queryRuns = clickhouse.reader.query({
|
|
name: "runs-replication-batching",
|
|
query: "SELECT * FROM trigger_dev.task_runs_v2 WHERE run_id = {run_id:String}",
|
|
schema: z.any(),
|
|
params: z.object({ run_id: z.string() }),
|
|
});
|
|
|
|
const result = await vi.waitFor(
|
|
async () => {
|
|
const [queryError, rows] = await queryRuns({ run_id: taskRun.id });
|
|
|
|
expect(queryError).toBeNull();
|
|
expect(rows?.length).toBe(1);
|
|
|
|
return rows;
|
|
},
|
|
{ timeout: 30_000, interval: 250 }
|
|
);
|
|
expect(result?.[0]).toEqual(
|
|
expect.objectContaining({
|
|
run_id: taskRun.id,
|
|
friendly_id: taskRun.friendlyId,
|
|
task_identifier: taskRun.taskIdentifier,
|
|
environment_id: runtimeEnvironment.id,
|
|
project_id: project.id,
|
|
organization_id: organization.id,
|
|
environment_type: "DEVELOPMENT",
|
|
engine: "V2",
|
|
})
|
|
);
|
|
|
|
await runsReplicationService.stop();
|
|
}
|
|
);
|
|
|
|
replicationContainerTest(
|
|
"should insert the payload into ClickHouse when a TaskRun is created",
|
|
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
|
|
await prisma.$executeRawUnsafe(`ALTER TABLE public."TaskRun" REPLICA IDENTITY FULL;`);
|
|
|
|
const clickhouse = new ClickHouse({
|
|
url: clickhouseContainer.getConnectionUrl(),
|
|
name: "runs-replication-payload",
|
|
logLevel: "warn",
|
|
});
|
|
|
|
const runsReplicationService = new RunsReplicationService({
|
|
clickhouseFactory: new TestReplicationClickhouseFactory(clickhouse),
|
|
pgConnectionUrl: postgresContainer.getConnectionUri(),
|
|
serviceName: "runs-replication-payload",
|
|
slotName: "task_runs_to_clickhouse_v1",
|
|
publicationName: "task_runs_to_clickhouse_v1_publication",
|
|
redisOptions,
|
|
maxFlushConcurrency: 1,
|
|
flushIntervalMs: 100,
|
|
flushBatchSize: 1,
|
|
leaderLockTimeoutMs: 5000,
|
|
leaderLockExtendIntervalMs: 1000,
|
|
ackIntervalSeconds: 5,
|
|
logLevel: "warn",
|
|
});
|
|
|
|
await runsReplicationService.start();
|
|
|
|
const organization = await prisma.organization.create({
|
|
data: {
|
|
title: "test-payload",
|
|
slug: "test-payload",
|
|
},
|
|
});
|
|
|
|
const project = await prisma.project.create({
|
|
data: {
|
|
name: "test-payload",
|
|
slug: "test-payload",
|
|
organizationId: organization.id,
|
|
externalRef: "test-payload",
|
|
},
|
|
});
|
|
|
|
const runtimeEnvironment = await prisma.runtimeEnvironment.create({
|
|
data: {
|
|
slug: "test-payload",
|
|
type: "DEVELOPMENT",
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
apiKey: "test-payload",
|
|
pkApiKey: "test-payload",
|
|
shortcode: "test-payload",
|
|
},
|
|
});
|
|
|
|
const uniquePayload = { foo: "payload-test", bar: Date.now() };
|
|
const taskRun = await prisma.taskRun.create({
|
|
data: {
|
|
friendlyId: `run_payload_${Date.now()}`,
|
|
taskIdentifier: "my-task-payload",
|
|
payload: JSON.stringify(uniquePayload),
|
|
payloadType: "application/json",
|
|
traceId: "payload-1234",
|
|
spanId: "payload-1234",
|
|
queue: "test-payload",
|
|
runtimeEnvironmentId: runtimeEnvironment.id,
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
environmentType: "DEVELOPMENT",
|
|
engine: "V2",
|
|
},
|
|
});
|
|
|
|
const queryPayloads = clickhouse.reader.query({
|
|
name: "runs-replication-payload",
|
|
query: "SELECT * FROM trigger_dev.raw_task_runs_payload_v1 WHERE run_id = {run_id:String}",
|
|
schema: z.any(),
|
|
params: z.object({ run_id: z.string() }),
|
|
});
|
|
|
|
const result = await vi.waitFor(
|
|
async () => {
|
|
const [queryError, rows] = await queryPayloads({ run_id: taskRun.id });
|
|
|
|
expect(queryError).toBeNull();
|
|
expect(rows?.length).toBe(1);
|
|
|
|
return rows;
|
|
},
|
|
{ timeout: 30_000, interval: 250 }
|
|
);
|
|
|
|
expect(result?.[0]).toEqual(
|
|
expect.objectContaining({
|
|
run_id: taskRun.id,
|
|
payload: expect.objectContaining({
|
|
data: uniquePayload,
|
|
}),
|
|
})
|
|
);
|
|
|
|
await runsReplicationService.stop();
|
|
}
|
|
);
|
|
|
|
replicationContainerTest(
|
|
"should insert the payload even if it's very large into ClickHouse when a TaskRun is created",
|
|
async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => {
|
|
await prisma.$executeRawUnsafe(`ALTER TABLE public."TaskRun" REPLICA IDENTITY FULL;`);
|
|
|
|
const clickhouse = new ClickHouse({
|
|
url: clickhouseContainer.getConnectionUrl(),
|
|
name: "runs-replication-payload",
|
|
logLevel: "warn",
|
|
});
|
|
|
|
const runsReplicationService = new RunsReplicationService({
|
|
clickhouseFactory: new TestReplicationClickhouseFactory(clickhouse),
|
|
pgConnectionUrl: postgresContainer.getConnectionUri(),
|
|
serviceName: "runs-replication-payload",
|
|
slotName: "task_runs_to_clickhouse_v1",
|
|
publicationName: "task_runs_to_clickhouse_v1_publication",
|
|
redisOptions,
|
|
maxFlushConcurrency: 1,
|
|
flushIntervalMs: 100,
|
|
flushBatchSize: 1,
|
|
leaderLockTimeoutMs: 5000,
|
|
leaderLockExtendIntervalMs: 1000,
|
|
ackIntervalSeconds: 5,
|
|
logLevel: "warn",
|
|
});
|
|
|
|
await runsReplicationService.start();
|
|
|
|
const organization = await prisma.organization.create({
|
|
data: {
|
|
title: "test-payload",
|
|
slug: "test-payload",
|
|
},
|
|
});
|
|
|
|
const project = await prisma.project.create({
|
|
data: {
|
|
name: "test-payload",
|
|
slug: "test-payload",
|
|
organizationId: organization.id,
|
|
externalRef: "test-payload",
|
|
},
|
|
});
|
|
|
|
const runtimeEnvironment = await prisma.runtimeEnvironment.create({
|
|
data: {
|
|
slug: "test-payload",
|
|
type: "DEVELOPMENT",
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
apiKey: "test-payload",
|
|
pkApiKey: "test-payload",
|
|
shortcode: "test-payload",
|
|
},
|
|
});
|
|
|
|
const largePayload = {
|
|
foo: Array.from({ length: 100 }, () => "foo").join(""),
|
|
bar: Array.from({ length: 100 }, () => "bar").join(""),
|
|
baz: Array.from({ length: 100 }, () => "baz").join(""),
|
|
};
|
|
|
|
const taskRun = await prisma.taskRun.create({
|
|
data: {
|
|
friendlyId: `run_payload_${Date.now()}`,
|
|
taskIdentifier: "my-task-payload",
|
|
payload: JSON.stringify(largePayload),
|
|
payloadType: "application/json",
|
|
traceId: "payload-1234",
|
|
spanId: "payload-1234",
|
|
queue: "test-payload",
|
|
runtimeEnvironmentId: runtimeEnvironment.id,
|
|
projectId: project.id,
|
|
organizationId: organization.id,
|
|
environmentType: "DEVELOPMENT",
|
|
engine: "V2",
|
|
},
|
|
});
|
|
|
|
const queryPayloads = clickhouse.reader.query({
|
|
name: "runs-replication-payload",
|
|
query: "SELECT * FROM trigger_dev.raw_task_runs_payload_v1 WHERE run_id = {run_id:String}",
|
|
schema: z.any(),
|
|
params: z.object({ run_id: z.string() }),
|
|
});
|
|
|
|
const result = await vi.waitFor(
|
|
async () => {
|
|
const [queryError, rows] = await queryPayloads({ run_id: taskRun.id });
|
|
|
|
expect(queryError).toBeNull();
|
|
expect(rows?.length).toBe(1);
|
|
|
|
return rows;
|
|
},
|
|
{ timeout: 30_000, interval: 250 }
|
|
);
|
|
|
|
expect(result?.[0]).toEqual(
|
|
expect.objectContaining({
|
|
run_id: taskRun.id,
|
|
payload: expect.objectContaining({
|
|
data: largePayload,
|
|
}),
|
|
})
|
|
);
|
|
|
|
await runsReplicationService.stop();
|
|
}
|
|
);
|
|
});
|