mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
test(backup): align archive stream fixtures
Adapt the stream-shaped test harness required by the v6.11 backup backport. (cherry picked from commit 13c1d3c408353d226d2968ff2a0a8108252976e1)
This commit is contained in:
@@ -6,6 +6,7 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi }
|
||||
import { createTempHomeEnv, type TempHomeEnv } from "../test-utils/temp-home.js";
|
||||
import {
|
||||
backupVerifyCommandMock,
|
||||
createMockTarStream,
|
||||
createBackupTestRuntime,
|
||||
mockStateOnlyBackupPlan,
|
||||
resetBackupTempHome,
|
||||
@@ -70,7 +71,7 @@ describe("backupCreateCommand atomic archive write", () => {
|
||||
archivePrefix: "openclaw-backup-failure-",
|
||||
});
|
||||
try {
|
||||
tarCreateMock.mockRejectedValueOnce(new Error("disk full"));
|
||||
tarCreateMock.mockReturnValueOnce(createMockTarStream({ error: new Error("disk full") }));
|
||||
|
||||
await expect(
|
||||
backupCreateCommand(runtime, {
|
||||
@@ -93,9 +94,7 @@ describe("backupCreateCommand atomic archive write", () => {
|
||||
const realLink = fs.link.bind(fs);
|
||||
const linkSpy = vi.spyOn(fs, "link");
|
||||
try {
|
||||
tarCreateMock.mockImplementationOnce(async ({ file }: { file: string }) => {
|
||||
await fs.writeFile(file, "archive-bytes", "utf8");
|
||||
});
|
||||
tarCreateMock.mockReturnValueOnce(createMockTarStream());
|
||||
linkSpy.mockImplementationOnce(async (existingPath, newPath) => {
|
||||
await fs.writeFile(newPath, "concurrent-archive", "utf8");
|
||||
return await realLink(existingPath, newPath);
|
||||
@@ -120,9 +119,7 @@ describe("backupCreateCommand atomic archive write", () => {
|
||||
});
|
||||
const linkSpy = vi.spyOn(fs, "link");
|
||||
try {
|
||||
tarCreateMock.mockImplementationOnce(async ({ file }: { file: string }) => {
|
||||
await fs.writeFile(file, "archive-bytes", "utf8");
|
||||
});
|
||||
tarCreateMock.mockReturnValueOnce(createMockTarStream());
|
||||
linkSpy.mockRejectedValueOnce(
|
||||
Object.assign(new Error("hard links not supported"), { code: "EOPNOTSUPP" }),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Backup test support provides temp config/state fixtures and mocked backup runtime helpers.
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { Readable } from "node:stream";
|
||||
import { vi } from "vitest";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { deleteTestEnvValue } from "../test-utils/env.js";
|
||||
@@ -14,6 +15,24 @@ const backupTestMocks = vi.hoisted(() => ({
|
||||
|
||||
export const { backupVerifyCommandMock, tarCreateMock } = backupTestMocks;
|
||||
|
||||
export function createMockTarStream(
|
||||
params: {
|
||||
beforeRead?: () => Promise<void> | void;
|
||||
contents?: string;
|
||||
error?: Error;
|
||||
} = {},
|
||||
): Readable {
|
||||
return Readable.from(
|
||||
(async function* () {
|
||||
await params.beforeRead?.();
|
||||
if (params.error) {
|
||||
throw params.error;
|
||||
}
|
||||
yield params.contents ?? "archive-bytes";
|
||||
})(),
|
||||
);
|
||||
}
|
||||
|
||||
vi.mock("tar", () => ({
|
||||
c: backupTestMocks.tarCreateMock,
|
||||
}));
|
||||
|
||||
+26
-29
@@ -17,6 +17,7 @@ import {
|
||||
} from "./backup-shared.js";
|
||||
import {
|
||||
backupVerifyCommandMock,
|
||||
createMockTarStream,
|
||||
createBackupTestRuntime,
|
||||
mockStateOnlyBackupPlan,
|
||||
resetBackupTempHome,
|
||||
@@ -78,9 +79,7 @@ describe("backup commands", () => {
|
||||
beforeEach(async () => {
|
||||
await resetBackupTempHome(tempHome);
|
||||
tarCreateMock.mockReset();
|
||||
tarCreateMock.mockImplementation(async ({ file }: { file: string }) => {
|
||||
await fs.writeFile(file, "archive-bytes", "utf8");
|
||||
});
|
||||
tarCreateMock.mockImplementation(() => createMockTarStream());
|
||||
backupVerifyCommandMock.mockReset();
|
||||
backupVerifyCommandMock.mockResolvedValue({
|
||||
ok: true,
|
||||
@@ -268,17 +267,16 @@ describe("backup commands", () => {
|
||||
}),
|
||||
);
|
||||
tarCreateMock.mockImplementationOnce(
|
||||
async (
|
||||
options: { file: string; onWriteEntry?: (entry: { path: string }) => void },
|
||||
entryPaths: string[],
|
||||
) => {
|
||||
capturedManifest = JSON.parse(
|
||||
await fs.readFile(entryPaths[0], "utf8"),
|
||||
) as CapturedBackupManifest;
|
||||
capturedEntryPaths = entryPaths;
|
||||
capturedOnWriteEntry = options.onWriteEntry ?? null;
|
||||
await fs.writeFile(options.file, "archive-bytes", "utf8");
|
||||
},
|
||||
(options: { onWriteEntry?: (entry: { path: string }) => void }, entryPaths: string[]) =>
|
||||
createMockTarStream({
|
||||
beforeRead: async () => {
|
||||
capturedManifest = JSON.parse(
|
||||
await fs.readFile(entryPaths[0], "utf8"),
|
||||
) as CapturedBackupManifest;
|
||||
capturedEntryPaths = entryPaths;
|
||||
capturedOnWriteEntry = options.onWriteEntry ?? null;
|
||||
},
|
||||
}),
|
||||
);
|
||||
const result = await backupCreateCommand(runtime, {
|
||||
output: backupDir,
|
||||
@@ -367,21 +365,20 @@ describe("backup commands", () => {
|
||||
const runtime = createBackupTestRuntime();
|
||||
await mockStateOnlyBackupPlan(stateDir);
|
||||
tarCreateMock.mockImplementationOnce(
|
||||
async (
|
||||
options: { file: string; filter?: (entryPath: string) => boolean },
|
||||
entryPaths: string[],
|
||||
) => {
|
||||
const manifestPath = entryPaths[0];
|
||||
const stateRoot = entryPaths[1];
|
||||
if (!manifestPath || !stateRoot) {
|
||||
throw new Error("backup test expected manifest and state entries");
|
||||
}
|
||||
expect(options.filter?.(manifestPath)).toBe(true);
|
||||
expect(
|
||||
options.filter?.(path.join(stateRoot, "agents", "main", "sessions", "s.jsonl")),
|
||||
).toBe(false);
|
||||
await fs.writeFile(options.file, "archive-bytes", "utf8");
|
||||
},
|
||||
(options: { filter?: (entryPath: string) => boolean }, entryPaths: string[]) =>
|
||||
createMockTarStream({
|
||||
beforeRead: () => {
|
||||
const manifestPath = entryPaths[0];
|
||||
const stateRoot = entryPaths[1];
|
||||
if (!manifestPath || !stateRoot) {
|
||||
throw new Error("backup test expected manifest and state entries");
|
||||
}
|
||||
expect(options.filter?.(manifestPath)).toBe(true);
|
||||
expect(
|
||||
options.filter?.(path.join(stateRoot, "agents", "main", "sessions", "s.jsonl")),
|
||||
).toBe(false);
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const result = await backupCreateCommand(runtime, {
|
||||
|
||||
Reference in New Issue
Block a user