chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
import { describe, expect, vi } from "vitest";
|
||||
|
||||
vi.mock("~/db.server", () => ({
|
||||
prisma: {},
|
||||
$replica: {},
|
||||
}));
|
||||
|
||||
vi.mock("~/services/taskIdentifierCache.server", () => ({
|
||||
getTaskIdentifiersFromCache: vi.fn().mockResolvedValue(null),
|
||||
populateTaskIdentifierCache: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
vi.mock("~/services/logger.server", () => ({
|
||||
logger: { error: vi.fn(), warn: vi.fn(), info: vi.fn() },
|
||||
}));
|
||||
|
||||
vi.mock("~/models/task.server", () => ({
|
||||
getAllTaskIdentifiers: vi.fn().mockResolvedValue([]),
|
||||
}));
|
||||
|
||||
import { setupAuthenticatedEnvironment } from "@internal/run-engine/tests";
|
||||
import { postgresTest } from "@internal/testcontainers";
|
||||
import { generateFriendlyId } from "@trigger.dev/core/v3/isomorphic";
|
||||
import type { PrismaClient } from "@trigger.dev/database";
|
||||
import {
|
||||
syncTaskIdentifiers,
|
||||
getTaskIdentifiers,
|
||||
} from "../../app/services/taskIdentifierRegistry.server";
|
||||
import type { AuthenticatedEnvironment } from "@internal/run-engine/tests";
|
||||
|
||||
vi.setConfig({ testTimeout: 30_000 });
|
||||
|
||||
async function createWorker(prisma: PrismaClient, env: AuthenticatedEnvironment) {
|
||||
return prisma.backgroundWorker.create({
|
||||
data: {
|
||||
friendlyId: generateFriendlyId("worker"),
|
||||
contentHash: `hash-${Date.now()}-${Math.random()}`,
|
||||
projectId: env.project.id,
|
||||
runtimeEnvironmentId: env.id,
|
||||
version: `${Date.now()}`,
|
||||
metadata: {},
|
||||
engine: "V2",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe("TaskIdentifierRegistry", () => {
|
||||
postgresTest("should create task identifiers on first sync", async ({ prisma }) => {
|
||||
const env = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
const worker = await createWorker(prisma, env);
|
||||
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker.id,
|
||||
[
|
||||
{ id: "task-a", triggerSource: "STANDARD" },
|
||||
{ id: "task-b", triggerSource: "SCHEDULED" },
|
||||
],
|
||||
prisma
|
||||
);
|
||||
|
||||
const rows = await prisma.taskIdentifier.findMany({
|
||||
where: { runtimeEnvironmentId: env.id },
|
||||
orderBy: { slug: "asc" },
|
||||
});
|
||||
|
||||
expect(rows).toHaveLength(2);
|
||||
expect(rows[0].slug).toBe("task-a");
|
||||
expect(rows[0].currentTriggerSource).toBe("STANDARD");
|
||||
expect(rows[0].isInLatestDeployment).toBe(true);
|
||||
expect(rows[1].slug).toBe("task-b");
|
||||
expect(rows[1].currentTriggerSource).toBe("SCHEDULED");
|
||||
expect(rows[1].isInLatestDeployment).toBe(true);
|
||||
});
|
||||
|
||||
postgresTest("should update triggerSource on re-deploy", async ({ prisma }) => {
|
||||
const env = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
const worker1 = await createWorker(prisma, env);
|
||||
|
||||
// First deploy: STANDARD
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker1.id,
|
||||
[{ id: "my-task", triggerSource: "STANDARD" }],
|
||||
prisma
|
||||
);
|
||||
|
||||
const worker2 = await createWorker(prisma, env);
|
||||
|
||||
// Second deploy: change to SCHEDULED
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker2.id,
|
||||
[{ id: "my-task", triggerSource: "SCHEDULED" }],
|
||||
prisma
|
||||
);
|
||||
|
||||
const rows = await prisma.taskIdentifier.findMany({
|
||||
where: { runtimeEnvironmentId: env.id },
|
||||
});
|
||||
|
||||
expect(rows).toHaveLength(1);
|
||||
expect(rows[0].slug).toBe("my-task");
|
||||
expect(rows[0].currentTriggerSource).toBe("SCHEDULED");
|
||||
expect(rows[0].currentWorkerId).toBe(worker2.id);
|
||||
});
|
||||
|
||||
postgresTest("should archive tasks removed in a deploy", async ({ prisma }) => {
|
||||
const env = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
const worker1 = await createWorker(prisma, env);
|
||||
|
||||
// Deploy with both tasks
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker1.id,
|
||||
[
|
||||
{ id: "task-a", triggerSource: "STANDARD" },
|
||||
{ id: "task-b", triggerSource: "STANDARD" },
|
||||
],
|
||||
prisma
|
||||
);
|
||||
|
||||
const worker2 = await createWorker(prisma, env);
|
||||
|
||||
// Deploy with only task-a (task-b removed)
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker2.id,
|
||||
[{ id: "task-a", triggerSource: "STANDARD" }],
|
||||
prisma
|
||||
);
|
||||
|
||||
const rows = await prisma.taskIdentifier.findMany({
|
||||
where: { runtimeEnvironmentId: env.id },
|
||||
orderBy: { slug: "asc" },
|
||||
});
|
||||
|
||||
expect(rows).toHaveLength(2);
|
||||
expect(rows[0].slug).toBe("task-a");
|
||||
expect(rows[0].isInLatestDeployment).toBe(true);
|
||||
expect(rows[1].slug).toBe("task-b");
|
||||
expect(rows[1].isInLatestDeployment).toBe(false);
|
||||
});
|
||||
|
||||
postgresTest("should resurrect archived tasks on re-deploy", async ({ prisma }) => {
|
||||
const env = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
const worker1 = await createWorker(prisma, env);
|
||||
|
||||
// Deploy with both
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker1.id,
|
||||
[
|
||||
{ id: "task-a", triggerSource: "STANDARD" },
|
||||
{ id: "task-b", triggerSource: "STANDARD" },
|
||||
],
|
||||
prisma
|
||||
);
|
||||
|
||||
const worker2 = await createWorker(prisma, env);
|
||||
|
||||
// Deploy without task-b
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker2.id,
|
||||
[{ id: "task-a", triggerSource: "STANDARD" }],
|
||||
prisma
|
||||
);
|
||||
|
||||
const worker3 = await createWorker(prisma, env);
|
||||
|
||||
// Deploy with task-b again
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker3.id,
|
||||
[
|
||||
{ id: "task-a", triggerSource: "STANDARD" },
|
||||
{ id: "task-b", triggerSource: "STANDARD" },
|
||||
],
|
||||
prisma
|
||||
);
|
||||
|
||||
const rows = await prisma.taskIdentifier.findMany({
|
||||
where: { runtimeEnvironmentId: env.id },
|
||||
orderBy: { slug: "asc" },
|
||||
});
|
||||
|
||||
expect(rows).toHaveLength(2);
|
||||
expect(rows[0].isInLatestDeployment).toBe(true);
|
||||
expect(rows[1].isInLatestDeployment).toBe(true);
|
||||
});
|
||||
|
||||
postgresTest(
|
||||
"should return identifiers sorted active-first from DB when cache misses",
|
||||
async ({ prisma }) => {
|
||||
const env = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
const worker1 = await createWorker(prisma, env);
|
||||
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker1.id,
|
||||
[
|
||||
{ id: "active-task", triggerSource: "STANDARD" },
|
||||
{ id: "archived-task", triggerSource: "STANDARD" },
|
||||
],
|
||||
prisma
|
||||
);
|
||||
|
||||
const worker2 = await createWorker(prisma, env);
|
||||
|
||||
// Archive one task
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker2.id,
|
||||
[{ id: "active-task", triggerSource: "STANDARD" }],
|
||||
prisma
|
||||
);
|
||||
|
||||
// Read with cache miss (mocked to return null)
|
||||
const result = await getTaskIdentifiers(env.id, prisma);
|
||||
|
||||
expect(result).toHaveLength(2);
|
||||
// Active first
|
||||
expect(result[0].slug).toBe("active-task");
|
||||
expect(result[0].isInLatestDeployment).toBe(true);
|
||||
// Archived second
|
||||
expect(result[1].slug).toBe("archived-task");
|
||||
expect(result[1].isInLatestDeployment).toBe(false);
|
||||
}
|
||||
);
|
||||
|
||||
postgresTest("should handle multiple triggerSource groups in one deploy", async ({ prisma }) => {
|
||||
const env = await setupAuthenticatedEnvironment(prisma, "PRODUCTION");
|
||||
const worker = await createWorker(prisma, env);
|
||||
|
||||
// Note: AGENT enum value is missing from migrations (no ALTER TYPE migration exists),
|
||||
// so we test with STANDARD + SCHEDULED only. AGENT works in prod because the enum
|
||||
// was added via prisma db push or manual ALTER.
|
||||
await syncTaskIdentifiers(
|
||||
env.id,
|
||||
env.project.id,
|
||||
worker.id,
|
||||
[
|
||||
{ id: "standard-task", triggerSource: "STANDARD" },
|
||||
{ id: "scheduled-task", triggerSource: "SCHEDULED" },
|
||||
],
|
||||
prisma
|
||||
);
|
||||
|
||||
const rows = await prisma.taskIdentifier.findMany({
|
||||
where: { runtimeEnvironmentId: env.id },
|
||||
orderBy: { slug: "asc" },
|
||||
});
|
||||
|
||||
expect(rows).toHaveLength(2);
|
||||
expect(rows[0].slug).toBe("scheduled-task");
|
||||
expect(rows[0].currentTriggerSource).toBe("SCHEDULED");
|
||||
expect(rows[1].slug).toBe("standard-task");
|
||||
expect(rows[1].currentTriggerSource).toBe("STANDARD");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user