diff --git a/packages/backend-test-utils/src/filesystem/MockDirectory.test.ts b/packages/backend-test-utils/src/filesystem/MockDirectory.test.ts index 45a206d7df..9e3efdaec0 100644 --- a/packages/backend-test-utils/src/filesystem/MockDirectory.test.ts +++ b/packages/backend-test-utils/src/filesystem/MockDirectory.test.ts @@ -278,6 +278,12 @@ describe('createMockDirectory', () => { it('should mock os.tmpdir()', () => { expect(os.tmpdir()).toBe(tmpDirMock.path); }); + + it('should refuce to mock os.tmpdir() again', () => { + expect(() => createMockDirectory({ mockOsTmpDir: true })).toThrow( + 'Cannot mock os.tmpdir() when it has already been mocked', + ); + }); }); it('should restore os.tmpdir()', () => { diff --git a/packages/backend-test-utils/src/filesystem/MockDirectory.ts b/packages/backend-test-utils/src/filesystem/MockDirectory.ts index 4ca66f2b68..20345e4ff9 100644 --- a/packages/backend-test-utils/src/filesystem/MockDirectory.ts +++ b/packages/backend-test-utils/src/filesystem/MockDirectory.ts @@ -18,7 +18,6 @@ import os from 'os'; import { isChildPath } from '@backstage/backend-common'; import fs from 'fs-extra'; import textextensions from 'textextensions'; -import { tmpdir as getTmpDir } from 'os'; import { dirname, extname, @@ -29,6 +28,8 @@ import { posix, } from 'path'; +const tmpdirMarker = Symbol('os-tmpdir-mock'); + /** * The content of a mock directory represented by a nested object structure. * @@ -347,16 +348,20 @@ export interface MockDirectoryOptions { export function createMockDirectory( options?: MockDirectoryOptions, ): MockDirectory { - const tmpDir = process.env.RUNNER_TEMP; // GitHub Actions - const root = fs.mkdtempSync( - joinPath(tmpDir || getTmpDir(), 'backstage-tmp-test-dir-'), - ); + const tmpDir = process.env.RUNNER_TEMP || os.tmpdir(); // GitHub Actions + const root = fs.mkdtempSync(joinPath(tmpDir, 'backstage-tmp-test-dir-')); const mocker = new MockDirectoryImpl(root); const origTmpdir = options?.mockOsTmpDir ? os.tmpdir : undefined; if (origTmpdir) { - os.tmpdir = () => mocker.path; + if (Object.hasOwn(origTmpdir, tmpdirMarker)) { + throw new Error( + 'Cannot mock os.tmpdir() when it has already been mocked', + ); + } + const mock = Object.assign(() => mocker.path, { [tmpdirMarker]: true }); + os.tmpdir = mock; } // In CI we expect there to be no need to clean up temporary directories