



























@@ -33,6 +33,17 @@ async function expectPathMissing(targetPath: string): Promise<void> {
3333throw new Error(`Expected path to be missing: ${targetPath}`);
3434}
353536+function lockCleanupRecords(
37+locks: Array<{ lockPath: string; removed: boolean; stale: boolean; staleReasons: string[] }>,
38+) {
39+return locks.map((entry) => ({
40+name: path.basename(entry.lockPath),
41+removed: entry.removed,
42+stale: entry.stale,
43+staleReasons: entry.staleReasons,
44+}));
45+}
46+3647async function expectCurrentPidOwnsLock(params: {
3748sessionFile: string;
3849timeoutMs: number;
@@ -411,10 +422,39 @@ describe("acquireSessionWriteLock", () => {
411422});
412423413424expect(result.locks).toHaveLength(3);
414-expect(result.cleaned).toHaveLength(2);
415-expect(result.cleaned.map((entry) => path.basename(entry.lockPath)).toSorted()).toEqual([
416-"dead.jsonl.lock",
417-"old-live.jsonl.lock",
425+expect(lockCleanupRecords(result.locks)).toEqual([
426+{
427+name: "dead.jsonl.lock",
428+removed: true,
429+stale: true,
430+staleReasons: ["dead-pid", "too-old"],
431+},
432+{
433+name: "fresh-live.jsonl.lock",
434+removed: false,
435+stale: false,
436+staleReasons: [],
437+},
438+{
439+name: "old-live.jsonl.lock",
440+removed: true,
441+stale: true,
442+staleReasons: ["too-old"],
443+},
444+]);
445+expect(lockCleanupRecords(result.cleaned)).toEqual([
446+{
447+name: "dead.jsonl.lock",
448+removed: true,
449+stale: true,
450+staleReasons: ["dead-pid", "too-old"],
451+},
452+{
453+name: "old-live.jsonl.lock",
454+removed: true,
455+stale: true,
456+staleReasons: ["too-old"],
457+},
418458]);
419459420460await expectPathMissing(staleDeadLock);
@@ -451,11 +491,22 @@ describe("acquireSessionWriteLock", () => {
451491readOwnerProcessArgs: () => ["python", "worker.py"],
452492});
453493454-expect(result.locks).toHaveLength(1);
455-expect(result.cleaned.map((entry) => path.basename(entry.lockPath))).toEqual([
456-"false-live.jsonl.lock",
494+expect(lockCleanupRecords(result.locks)).toEqual([
495+{
496+name: "false-live.jsonl.lock",
497+removed: true,
498+stale: true,
499+staleReasons: ["non-openclaw-owner"],
500+},
501+]);
502+expect(lockCleanupRecords(result.cleaned)).toEqual([
503+{
504+name: "false-live.jsonl.lock",
505+removed: true,
506+stale: true,
507+staleReasons: ["non-openclaw-owner"],
508+},
457509]);
458-expect(result.cleaned[0]?.staleReasons).toContain("non-openclaw-owner");
459510await expect(fs.access(falseLiveLock)).rejects.toThrow();
460511} finally {
461512await fs.rm(root, { recursive: true, force: true });
@@ -488,10 +539,14 @@ describe("acquireSessionWriteLock", () => {
488539readOwnerProcessArgs: () => ["node", "/srv/app/dist/index.js"],
489540});
490541491-expect(result.cleaned.map((entry) => path.basename(entry.lockPath))).toEqual([
492-"false-live-generic-entry.jsonl.lock",
542+expect(lockCleanupRecords(result.cleaned)).toEqual([
543+{
544+name: "false-live-generic-entry.jsonl.lock",
545+removed: true,
546+stale: true,
547+staleReasons: ["non-openclaw-owner"],
548+},
493549]);
494-expect(result.cleaned[0]?.staleReasons).toContain("non-openclaw-owner");
495550await expect(fs.access(falseLiveLock)).rejects.toThrow();
496551} finally {
497552await fs.rm(root, { recursive: true, force: true });
@@ -599,11 +654,22 @@ describe("acquireSessionWriteLock", () => {
599654removeStale: true,
600655});
601656602-expect(result.locks).toHaveLength(1);
603-expect(result.cleaned.map((entry) => path.basename(entry.lockPath))).toEqual([
604-"orphan-self.jsonl.lock",
657+expect(lockCleanupRecords(result.locks)).toEqual([
658+{
659+name: "orphan-self.jsonl.lock",
660+removed: true,
661+stale: true,
662+staleReasons: ["orphan-self-pid"],
663+},
664+]);
665+expect(lockCleanupRecords(result.cleaned)).toEqual([
666+{
667+name: "orphan-self.jsonl.lock",
668+removed: true,
669+stale: true,
670+staleReasons: ["orphan-self-pid"],
671+},
605672]);
606-expect(result.cleaned[0]?.staleReasons).toContain("orphan-self-pid");
607673await expectPathMissing(orphanSelfLock);
608674} finally {
609675await fs.rm(root, { recursive: true, force: true });
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。