From bb61a527ed40e83c861a78805a884274761a7854 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Sun, 17 May 2026 11:44:40 -0700 Subject: [PATCH] fix: resolve test failures on macOS - docker-manager-utils: Read actual root home from /etc/passwd instead of hardcoding /root (macOS uses /var/root) - docker-manager-cleanup: Mock getSafeHostUid/Gid to use real uid/gid so chownSync doesn't fail with EPERM on macOS (gid 501 gets clamped to 1000, which the current user can't chown to) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/docker-manager-cleanup.test.ts | 11 +++++++++++ src/docker-manager-utils.test.ts | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/docker-manager-cleanup.test.ts b/src/docker-manager-cleanup.test.ts index 04e6a25dc..160c097e3 100644 --- a/src/docker-manager-cleanup.test.ts +++ b/src/docker-manager-cleanup.test.ts @@ -11,6 +11,17 @@ import { mockExecaFn, mockExecaSync } from './test-helpers/mock-execa.test-utils // eslint-disable-next-line @typescript-eslint/no-require-imports jest.mock('execa', () => require('./test-helpers/mock-execa.test-utils').execaMockFactory()); +// Mock host identity functions so chownSync uses the real uid/gid +// (on macOS, gid < 1000 gets clamped to 1000 which causes EPERM) +jest.mock('./host-env', () => { + const actual = jest.requireActual('./host-env'); + return { + ...actual, + getSafeHostUid: () => String(process.getuid?.() ?? 1000), + getSafeHostGid: () => String(process.getgid?.() ?? 1000), + }; +}); + describe('docker-manager writeConfigs and cleanup', () => { describe('writeConfigs', () => { let testDir: string; diff --git a/src/docker-manager-utils.test.ts b/src/docker-manager-utils.test.ts index a1bb41789..0837ca407 100644 --- a/src/docker-manager-utils.test.ts +++ b/src/docker-manager-utils.test.ts @@ -217,8 +217,12 @@ describe('docker-manager utilities', () => { process.env.SUDO_USER = 'root'; process.env.HOME = '/some/other/path'; - // Should find root's home directory from /etc/passwd - expect(getRealUserHome()).toBe('/root'); + // Read actual root home from /etc/passwd (differs by platform: /root on Linux, /var/root on macOS) + const passwd = fs.readFileSync('/etc/passwd', 'utf-8'); + const rootLine = passwd.split('\n').find(line => line.startsWith('root:')); + const expectedRootHome = rootLine ? rootLine.split(':')[5] : '/root'; + + expect(getRealUserHome()).toBe(expectedRootHome); }); it('should fall back to HOME when SUDO_USER not found in /etc/passwd', () => { @@ -236,9 +240,13 @@ describe('docker-manager utilities', () => { process.env.SUDO_USER = 'root'; process.env.HOME = '/custom/home'; + // Read actual root home from /etc/passwd (differs by platform) + const passwd = fs.readFileSync('/etc/passwd', 'utf-8'); + const rootLine = passwd.split('\n').find(line => line.startsWith('root:')); + const expectedRootHome = rootLine ? rootLine.split(':')[5] : '/root'; + // With getuid undefined, uid is undefined (falsy), so it attempts passwd lookup - // Should find root's home directory from /etc/passwd - expect(getRealUserHome()).toBe('/root'); + expect(getRealUserHome()).toBe(expectedRootHome); }); });