* feat(runtime): start and ship the local agent * refactor: gate local agent behind feature flag * chore: skip agent manager if flag is false * fix: hot reload agents * test: fix config tests
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { afterEach, expect, test, vi } from "vitest";
|
|
import { Effect } from "effect";
|
|
import waitForExpect from "wait-for-expect";
|
|
import { fromPartial } from "@total-typescript/shoehorn";
|
|
import { createControllerMessage, parseAgentMessage } from "@zerobyte/contracts/agent-protocol";
|
|
import * as resticServer from "@zerobyte/core/restic/server";
|
|
import { createControllerSession } from "../controller-session";
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
test("emits backup.failed when a backup command hits a restic error", async () => {
|
|
vi.spyOn(resticServer, "createRestic").mockReturnValue(
|
|
fromPartial({
|
|
backup: () => Effect.fail("source path missing"),
|
|
}),
|
|
);
|
|
|
|
const outboundMessages: string[] = [];
|
|
const session = createControllerSession(
|
|
fromPartial({
|
|
send: (message: string) => {
|
|
outboundMessages.push(message);
|
|
},
|
|
}),
|
|
);
|
|
|
|
try {
|
|
session.onOpen();
|
|
session.onMessage(
|
|
createControllerMessage("backup.run", {
|
|
jobId: "job-1",
|
|
scheduleId: "schedule-1",
|
|
organizationId: "org-1",
|
|
sourcePath: "/tmp/missing-source",
|
|
repositoryConfig: {
|
|
backend: "local",
|
|
path: "/tmp/test-repository",
|
|
},
|
|
options: {},
|
|
runtime: {
|
|
password: "password",
|
|
cacheDir: "/tmp/restic-cache",
|
|
passFile: "/tmp/restic-pass",
|
|
defaultExcludes: [],
|
|
},
|
|
}),
|
|
);
|
|
|
|
await waitForExpect(() => {
|
|
const failedMessage = outboundMessages
|
|
.map((message) => parseAgentMessage(message))
|
|
.find((message) => message?.success && message.data.type === "backup.failed");
|
|
|
|
expect(failedMessage?.success).toBe(true);
|
|
if (!failedMessage || !failedMessage.success || failedMessage.data.type !== "backup.failed") {
|
|
return;
|
|
}
|
|
|
|
expect(failedMessage.data.payload).toEqual({
|
|
jobId: "job-1",
|
|
scheduleId: "schedule-1",
|
|
error: "source path missing",
|
|
errorDetails: "source path missing",
|
|
});
|
|
});
|
|
} finally {
|
|
session.close();
|
|
}
|
|
});
|