From 65c94df872b969cde994e9ad27209be530bddd43 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 30 Apr 2026 15:37:09 +0100 Subject: [PATCH] test(infra): cover fallback tmp chmod race --- src/infra/tmp-openclaw-dir.test.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/infra/tmp-openclaw-dir.test.ts b/src/infra/tmp-openclaw-dir.test.ts index 4dc27511520..c427007d38a 100644 --- a/src/infra/tmp-openclaw-dir.test.ts +++ b/src/infra/tmp-openclaw-dir.test.ts @@ -470,6 +470,28 @@ describe("resolvePreferredOpenClawTmpDir", () => { expect(warn).not.toHaveBeenCalled(); }); + it("uses fallback when chmod loses a concurrent fallback repair race", () => { + const fallbackPath = fallbackTmp(); + const chmodSync = vi.fn((target: string, mode: number) => { + if (target === fallbackPath && mode === 0o700) { + throw nodeErrorWithCode("EACCES"); + } + }); + const warn = vi.fn(); + const states = [0o40777, 0o40777, 0o40700]; + + const resolved = resolveWithReadOnlyTmpFallback({ + fallbackPath, + fallbackLstatSync: vi.fn(() => makeDirStat({ mode: states.shift() ?? 0o40700 })), + chmodSync, + warn, + }); + + expect(resolved).toBe(fallbackPath); + expect(chmodSync).toHaveBeenCalledWith(fallbackPath, 0o700); + expect(warn).not.toHaveBeenCalled(); + }); + it("throws when the fallback directory cannot be created", () => { expect(() => resolvePreferredOpenClawTmpDir({