import { describe, expect, vi } from "vitest"; // Mock the db prisma client vi.mock("~/db.server", () => ({ prisma: {}, $replica: {}, })); import { replicationContainerTest } from "@internal/testcontainers"; import { setTimeout } from "node:timers/promises"; import { RunsRepository } from "~/services/runsRepository/runsRepository.server"; import { setupClickhouseReplication } from "./utils/replicationUtils"; vi.setConfig({ testTimeout: 60_000 }); describe("RunsRepository (part 1/4)", () => { replicationContainerTest( "should list runs, using clickhouse as the source", async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => { const { clickhouse } = await setupClickhouseReplication({ prisma, databaseUrl: postgresContainer.getConnectionUri(), clickhouseUrl: clickhouseContainer.getConnectionUrl(), redisOptions, }); 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", }, }); // Now we insert a row into the table const taskRun = await prisma.taskRun.create({ data: { friendlyId: "run_1234", taskIdentifier: "my-task", payload: JSON.stringify({ foo: "bar" }), traceId: "1234", spanId: "1234", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await setTimeout(1000); const runsRepository = new RunsRepository({ prisma, clickhouse, }); const { runs, pagination } = await runsRepository.listRuns({ page: { size: 10 }, projectId: project.id, environmentId: runtimeEnvironment.id, organizationId: organization.id, }); expect(runs).toHaveLength(1); expect(runs[0].id).toBe(taskRun.id); expect(pagination.nextCursor).toBe(null); expect(pagination.previousCursor).toBe(null); } ); replicationContainerTest( "should filter runs by task identifiers", async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => { const { clickhouse } = await setupClickhouseReplication({ prisma, databaseUrl: postgresContainer.getConnectionUri(), clickhouseUrl: clickhouseContainer.getConnectionUrl(), redisOptions, }); 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", }, }); // Create runs with different task identifiers const _taskRun1 = await prisma.taskRun.create({ data: { friendlyId: "run_task1", taskIdentifier: "task-1", payload: JSON.stringify({ foo: "bar" }), traceId: "1234", spanId: "1234", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); const _taskRun2 = await prisma.taskRun.create({ data: { friendlyId: "run_task2", taskIdentifier: "task-2", payload: JSON.stringify({ foo: "bar" }), traceId: "1235", spanId: "1235", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); const _taskRun3 = await prisma.taskRun.create({ data: { friendlyId: "run_task3", taskIdentifier: "task-3", payload: JSON.stringify({ foo: "bar" }), traceId: "1236", spanId: "1236", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await setTimeout(1000); const runsRepository = new RunsRepository({ prisma, clickhouse, }); // Test filtering by specific tasks const { runs } = await runsRepository.listRuns({ page: { size: 10 }, projectId: project.id, environmentId: runtimeEnvironment.id, organizationId: organization.id, tasks: ["task-1", "task-2"], }); expect(runs).toHaveLength(2); expect(runs.map((r) => r.taskIdentifier).sort()).toEqual(["task-1", "task-2"]); } ); replicationContainerTest( "should filter runs by task versions", async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => { const { clickhouse } = await setupClickhouseReplication({ prisma, databaseUrl: postgresContainer.getConnectionUri(), clickhouseUrl: clickhouseContainer.getConnectionUrl(), redisOptions, }); 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", }, }); // Create runs with different task versions await prisma.taskRun.create({ data: { friendlyId: "run_v1", taskIdentifier: "my-task", taskVersion: "1.0.0", payload: JSON.stringify({ foo: "bar" }), traceId: "1234", spanId: "1234", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await prisma.taskRun.create({ data: { friendlyId: "run_v2", taskIdentifier: "my-task", taskVersion: "2.0.0", payload: JSON.stringify({ foo: "bar" }), traceId: "1235", spanId: "1235", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await prisma.taskRun.create({ data: { friendlyId: "run_v3", taskIdentifier: "my-task", taskVersion: "3.0.0", payload: JSON.stringify({ foo: "bar" }), traceId: "1236", spanId: "1236", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await setTimeout(1000); const runsRepository = new RunsRepository({ prisma, clickhouse, }); // Test filtering by specific versions const { runs } = await runsRepository.listRuns({ page: { size: 10 }, projectId: project.id, environmentId: runtimeEnvironment.id, organizationId: organization.id, versions: ["1.0.0", "3.0.0"], }); expect(runs).toHaveLength(2); expect(runs.map((r) => r.taskVersion).sort()).toEqual(["1.0.0", "3.0.0"]); } ); replicationContainerTest( "should filter runs by status", async ({ clickhouseContainer, redisOptions, postgresContainer, prisma }) => { const { clickhouse } = await setupClickhouseReplication({ prisma, databaseUrl: postgresContainer.getConnectionUri(), clickhouseUrl: clickhouseContainer.getConnectionUrl(), redisOptions, }); 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", }, }); // Create runs with different statuses await prisma.taskRun.create({ data: { friendlyId: "run_pending", taskIdentifier: "my-task", status: "PENDING", payload: JSON.stringify({ foo: "bar" }), traceId: "1234", spanId: "1234", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await prisma.taskRun.create({ data: { friendlyId: "run_executing", taskIdentifier: "my-task", status: "EXECUTING", payload: JSON.stringify({ foo: "bar" }), traceId: "1235", spanId: "1235", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await prisma.taskRun.create({ data: { friendlyId: "run_completed", taskIdentifier: "my-task", status: "COMPLETED_SUCCESSFULLY", payload: JSON.stringify({ foo: "bar" }), traceId: "1236", spanId: "1236", queue: "test", runtimeEnvironmentId: runtimeEnvironment.id, projectId: project.id, organizationId: organization.id, environmentType: "DEVELOPMENT", engine: "V2", }, }); await setTimeout(1000); const runsRepository = new RunsRepository({ prisma, clickhouse, }); // Test filtering by specific statuses const { runs } = await runsRepository.listRuns({ page: { size: 10 }, projectId: project.id, environmentId: runtimeEnvironment.id, organizationId: organization.id, statuses: ["PENDING", "COMPLETED_SUCCESSFULLY"], }); expect(runs).toHaveLength(2); expect(runs.map((r) => r.status).sort()).toEqual(["COMPLETED_SUCCESSFULLY", "PENDING"]); } ); });