diff --git a/src/client/testing/testController/common/utils.ts b/src/client/testing/testController/common/utils.ts index e3b37bf74e40..9923d7ec3e12 100644 --- a/src/client/testing/testController/common/utils.ts +++ b/src/client/testing/testController/common/utils.ts @@ -38,6 +38,22 @@ interface ExecutionResultMessage extends Message { params: ExecutionTestPayload; } +/** + * Retrieves the path to the temporary directory. + * + * On Windows, it returns the default temporary directory. + * On macOS/Linux, it prefers the `XDG_RUNTIME_DIR` environment variable if set, + * otherwise, it falls back to the default temporary directory. + * + * @returns {string} The path to the temporary directory. + */ +function getTempDir(): string { + if (process.platform === 'win32') { + return os.tmpdir(); // Default Windows behavior + } + return process.env.XDG_RUNTIME_DIR || os.tmpdir(); // Prefer XDG_RUNTIME_DIR on macOS/Linux +} + /** * Writes an array of test IDs to a temporary file. * @@ -50,11 +66,12 @@ export async function writeTestIdsFile(testIds: string[]): Promise { const tempName = `test-ids-${randomSuffix}.txt`; // create temp file let tempFileName: string; + const tempDir: string = getTempDir(); try { traceLog('Attempting to use temp directory for test ids file, file name:', tempName); - tempFileName = path.join(os.tmpdir(), tempName); + tempFileName = path.join(tempDir, tempName); // attempt access to written file to check permissions - await fs.promises.access(os.tmpdir()); + await fs.promises.access(tempDir); } catch (error) { // Handle the error when accessing the temp directory traceError('Error accessing temp directory:', error, ' Attempt to use extension root dir instead'); diff --git a/src/test/testing/testController/utils.unit.test.ts b/src/test/testing/testController/utils.unit.test.ts index ff1a0c707678..4d2af9da3d5a 100644 --- a/src/test/testing/testController/utils.unit.test.ts +++ b/src/test/testing/testController/utils.unit.test.ts @@ -2,7 +2,6 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import * as fs from 'fs'; import * as path from 'path'; -import * as os from 'os'; import { writeTestIdsFile } from '../../../client/testing/testController/common/utils'; import { EXTENSION_ROOT_DIR } from '../../../client/constants'; @@ -21,11 +20,13 @@ suite('writeTestIdsFile tests', () => { const testIds = ['test1', 'test2', 'test3']; const writeFileStub = sandbox.stub(fs.promises, 'writeFile').resolves(); - const result = await writeTestIdsFile(testIds); - - const tmpDir = os.tmpdir(); + // Set up XDG_RUNTIME_DIR + process.env = { + ...process.env, + XDG_RUNTIME_DIR: '/xdg/runtime/dir', + }; - assert.ok(result.startsWith(tmpDir)); + await writeTestIdsFile(testIds); assert.ok(writeFileStub.calledOnceWith(sinon.match.string, testIds.join('\n'))); }); @@ -48,3 +49,41 @@ suite('writeTestIdsFile tests', () => { assert.ok(writeFileStub.calledOnceWith(sinon.match.string, testIds.join('\n'))); }); }); + +suite('getTempDir tests', () => { + let sandbox: sinon.SinonSandbox; + let originalPlatform: NodeJS.Platform; + let originalEnv: NodeJS.ProcessEnv; + + setup(() => { + sandbox = sinon.createSandbox(); + originalPlatform = process.platform; + originalEnv = process.env; + }); + + teardown(() => { + sandbox.restore(); + Object.defineProperty(process, 'platform', { value: originalPlatform }); + process.env = originalEnv; + }); + + test('should use XDG_RUNTIME_DIR on non-Windows if available', async () => { + if (process.platform === 'win32') { + return; + } + // Force platform to be Linux + Object.defineProperty(process, 'platform', { value: 'linux' }); + + // Set up XDG_RUNTIME_DIR + process.env = { ...process.env, XDG_RUNTIME_DIR: '/xdg/runtime/dir' }; + + const testIds = ['test1', 'test2', 'test3']; + sandbox.stub(fs.promises, 'access').resolves(); + sandbox.stub(fs.promises, 'writeFile').resolves(); + + // This will use getTempDir internally + const result = await writeTestIdsFile(testIds); + + assert.ok(result.startsWith('/xdg/runtime/dir')); + }); +});