🎉 init: 小龙的工作空间
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* PR-A Baseline Test 10: Session Crash Recovery
|
||||
* Verifies: session state survives restart/reload scenarios
|
||||
* Freezes: session persistence contract
|
||||
*/
|
||||
import { describe, it } from "node:test";
|
||||
import assert from "node:assert";
|
||||
import { existsSync, readFileSync, writeFileSync, unlinkSync, statSync, mkdirSync, readdirSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { randomUUID } from "node:crypto";
|
||||
|
||||
const WORKSPACE = join(homedir(), ".openclaw", "workspace");
|
||||
const TEMP_DIR = join(WORKSPACE, "test", "baseline", "tmp");
|
||||
try { mkdirSync(TEMP_DIR, { recursive: true }); } catch {}
|
||||
|
||||
describe("test-10: Session Crash Recovery Baseline", () => {
|
||||
it("10.01 - written data survives simulated crash (no fsync)", () => {
|
||||
const path = join(TEMP_DIR, "crash-test.json");
|
||||
const data = { id: randomUUID(), state: "running", timestamp: Date.now() };
|
||||
writeFileSync(path, JSON.stringify(data), "utf8");
|
||||
const recovered = JSON.parse(readFileSync(path, "utf8"));
|
||||
assert.equal(recovered.id, data.id, "data must survive 'crash'");
|
||||
assert.equal(recovered.state, "running", "state must be preserved");
|
||||
try { unlinkSync(path); } catch {}
|
||||
console.log("[BASELINE] crash recovery: data survives write");
|
||||
});
|
||||
|
||||
it("10.02 - partial writes don't produce valid JSON (atomicity check)", () => {
|
||||
const path = join(TEMP_DIR, "partial-crash.json");
|
||||
writeFileSync(path, '{"id":"test","state":"runn', "utf8");
|
||||
try {
|
||||
JSON.parse(readFileSync(path, "utf8"));
|
||||
assert.fail("partial JSON should not parse");
|
||||
} catch (e) {
|
||||
console.log("[BASELINE] partial write detected:", e.message.substring(0, 80));
|
||||
assert.ok(e instanceof SyntaxError, "partial write must cause parse error");
|
||||
}
|
||||
try { unlinkSync(path); } catch {}
|
||||
});
|
||||
|
||||
it("10.03 - session state file format is JSON", () => {
|
||||
const sessionsDir = join(homedir(), ".openclaw", "agents", "main", "sessions");
|
||||
if (existsSync(sessionsDir)) {
|
||||
const files = readdirSync(sessionsDir);
|
||||
const jsonFiles = files.filter(f => f.endsWith(".json"));
|
||||
console.log("[BASELINE] session JSON files count:", jsonFiles.length);
|
||||
if (jsonFiles.length > 0) {
|
||||
for (const f of jsonFiles.slice(0, 3)) {
|
||||
try {
|
||||
const content = readFileSync(join(sessionsDir, f), "utf8");
|
||||
JSON.parse(content);
|
||||
console.log(`[BASELINE] ${f}: valid JSON, size=${content.length}`);
|
||||
} catch (e) {
|
||||
console.log(`[BASELINE] ${f}: invalid JSON — ${e.message.substring(0, 80)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.ok(true, "baseline frozen: session file format");
|
||||
});
|
||||
|
||||
it("10.04 - memory index survives process restart simulation", () => {
|
||||
const memoryDb = join(homedir(), ".openclaw", "memory", "main.sqlite");
|
||||
if (existsSync(memoryDb)) {
|
||||
const stat1 = statSync(memoryDb);
|
||||
console.log("[BASELINE] memory DB before 'restart': size=%d, mtime=%s",
|
||||
stat1.size, stat1.mtime.toISOString());
|
||||
const stat2 = statSync(memoryDb);
|
||||
assert.equal(stat2.size, stat1.size, "memory DB must survive re-read");
|
||||
} else {
|
||||
console.log("[BASELINE] no memory DB to check (valid baseline)");
|
||||
}
|
||||
assert.ok(true, "baseline frozen: memory index survival");
|
||||
});
|
||||
|
||||
it("10.05 - workspace files survive across reads (persistence check)", () => {
|
||||
const criticalFiles = ["MEMORY.md", "AGENTS.md"];
|
||||
for (const f of criticalFiles) {
|
||||
const path = join(WORKSPACE, f);
|
||||
if (existsSync(path)) {
|
||||
const content1 = readFileSync(path, "utf8");
|
||||
const content2 = readFileSync(path, "utf8");
|
||||
assert.equal(content1.length, content2.length,
|
||||
`${f} must be identical across reads`);
|
||||
console.log(`[BASELINE] ${f}: persistent read OK, len=${content1.length}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user