From 0ec2482ea095bf9d99b2ef0c4a3365fee20e3a4e Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Fri, 7 Feb 2025 11:35:25 -0800 Subject: [PATCH] add check for tmp dir access error on testIds file --- .../testing/testController/common/utils.ts | 2 + .../testing/testController/utils.unit.test.ts | 226 +++--------------- 2 files changed, 39 insertions(+), 189 deletions(-) diff --git a/src/client/testing/testController/common/utils.ts b/src/client/testing/testController/common/utils.ts index 68e10a2213d6..e3b37bf74e40 100644 --- a/src/client/testing/testController/common/utils.ts +++ b/src/client/testing/testController/common/utils.ts @@ -53,6 +53,8 @@ export async function writeTestIdsFile(testIds: string[]): Promise { try { traceLog('Attempting to use temp directory for test ids file, file name:', tempName); tempFileName = path.join(os.tmpdir(), tempName); + // attempt access to written file to check permissions + await fs.promises.access(os.tmpdir()); } 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 b871d18348e2..ff1a0c707678 100644 --- a/src/test/testing/testController/utils.unit.test.ts +++ b/src/test/testing/testController/utils.unit.test.ts @@ -1,202 +1,50 @@ -// // Copyright (c) Microsoft Corporation. All rights reserved. -// // Licensed under the MIT License. +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'; -// import * as assert from 'assert'; -// import { -// JSONRPC_CONTENT_LENGTH_HEADER, -// JSONRPC_CONTENT_TYPE_HEADER, -// JSONRPC_UUID_HEADER, -// ExtractJsonRPCData, -// parseJsonRPCHeadersAndData, -// splitTestNameWithRegex, -// argKeyExists, -// addValueIfKeyNotExist, -// } from '../../../client/testing/testController/common/utils'; +suite('writeTestIdsFile tests', () => { + let sandbox: sinon.SinonSandbox; -// suite('Test Controller Utils: JSON RPC', () => { -// test('Empty raw data string', async () => { -// const rawDataString = ''; + setup(() => { + sandbox = sinon.createSandbox(); + }); -// const output = parseJsonRPCHeadersAndData(rawDataString); -// assert.deepStrictEqual(output.headers.size, 0); -// assert.deepStrictEqual(output.remainingRawData, ''); -// }); + teardown(() => { + sandbox.restore(); + }); -// test('Valid data empty JSON', async () => { -// const rawDataString = `${JSONRPC_CONTENT_LENGTH_HEADER}: 2\n${JSONRPC_CONTENT_TYPE_HEADER}: application/json\n${JSONRPC_UUID_HEADER}: 1234\n\n{}`; + test('should write test IDs to a temporary file', async () => { + const testIds = ['test1', 'test2', 'test3']; + const writeFileStub = sandbox.stub(fs.promises, 'writeFile').resolves(); -// const rpcHeaders = parseJsonRPCHeadersAndData(rawDataString); -// assert.deepStrictEqual(rpcHeaders.headers.size, 3); -// assert.deepStrictEqual(rpcHeaders.remainingRawData, '{}'); -// const rpcContent = ExtractJsonRPCData(rpcHeaders.headers.get('Content-Length'), rpcHeaders.remainingRawData); -// assert.deepStrictEqual(rpcContent.extractedJSON, '{}'); -// }); + const result = await writeTestIdsFile(testIds); -// test('Valid data NO JSON', async () => { -// const rawDataString = `${JSONRPC_CONTENT_LENGTH_HEADER}: 0\n${JSONRPC_CONTENT_TYPE_HEADER}: application/json\n${JSONRPC_UUID_HEADER}: 1234\n\n`; + const tmpDir = os.tmpdir(); -// const rpcHeaders = parseJsonRPCHeadersAndData(rawDataString); -// assert.deepStrictEqual(rpcHeaders.headers.size, 3); -// assert.deepStrictEqual(rpcHeaders.remainingRawData, ''); -// const rpcContent = ExtractJsonRPCData(rpcHeaders.headers.get('Content-Length'), rpcHeaders.remainingRawData); -// assert.deepStrictEqual(rpcContent.extractedJSON, ''); -// }); + assert.ok(result.startsWith(tmpDir)); -// test('Valid data with full JSON', async () => { -// // this is just some random JSON -// const json = -// '{"jsonrpc": "2.0", "method": "initialize", "params": {"processId": 1234, "rootPath": "/home/user/project", "rootUri": "file:///home/user/project", "capabilities": {}}, "id": 0}'; -// const rawDataString = `${JSONRPC_CONTENT_LENGTH_HEADER}: ${json.length}\n${JSONRPC_CONTENT_TYPE_HEADER}: application/json\n${JSONRPC_UUID_HEADER}: 1234\n\n${json}`; + assert.ok(writeFileStub.calledOnceWith(sinon.match.string, testIds.join('\n'))); + }); -// const rpcHeaders = parseJsonRPCHeadersAndData(rawDataString); -// assert.deepStrictEqual(rpcHeaders.headers.size, 3); -// assert.deepStrictEqual(rpcHeaders.remainingRawData, json); -// const rpcContent = ExtractJsonRPCData(rpcHeaders.headers.get('Content-Length'), rpcHeaders.remainingRawData); -// assert.deepStrictEqual(rpcContent.extractedJSON, json); -// }); + test('should handle error when accessing temp directory', async () => { + const testIds = ['test1', 'test2', 'test3']; + const error = new Error('Access error'); + const accessStub = sandbox.stub(fs.promises, 'access').rejects(error); + const writeFileStub = sandbox.stub(fs.promises, 'writeFile').resolves(); + const mkdirStub = sandbox.stub(fs.promises, 'mkdir').resolves(); -// test('Valid data with multiple JSON', async () => { -// const json = -// '{"jsonrpc": "2.0", "method": "initialize", "params": {"processId": 1234, "rootPath": "/home/user/project", "rootUri": "file:///home/user/project", "capabilities": {}}, "id": 0}'; -// const rawDataString = `${JSONRPC_CONTENT_LENGTH_HEADER}: ${json.length}\n${JSONRPC_CONTENT_TYPE_HEADER}: application/json\n${JSONRPC_UUID_HEADER}: 1234\n\n${json}`; -// const rawDataString2 = rawDataString + rawDataString; + const result = await writeTestIdsFile(testIds); -// const rpcHeaders = parseJsonRPCHeadersAndData(rawDataString2); -// assert.deepStrictEqual(rpcHeaders.headers.size, 3); -// const rpcContent = ExtractJsonRPCData(rpcHeaders.headers.get('Content-Length'), rpcHeaders.remainingRawData); -// assert.deepStrictEqual(rpcContent.extractedJSON, json); -// assert.deepStrictEqual(rpcContent.remainingRawData, rawDataString); -// }); + const tempFileFolder = path.join(EXTENSION_ROOT_DIR, '.temp'); -// test('Valid constant', async () => { -// const data = `{"cwd": "/Users/eleanorboyd/testingFiles/inc_dec_example", "status": "success", "result": {"test_dup_class.test_a.TestSomething.test_a": {"test": "test_dup_class.test_a.TestSomething.test_a", "outcome": "success", "message": "None", "traceback": null, "subtest": null}}}`; -// const secondPayload = `Content-Length: 270 -// Content-Type: application/json -// Request-uuid: 496c86b1-608f-4886-9436-ec00538e144c + assert.ok(result.startsWith(tempFileFolder)); -// ${data}`; -// const payload = `Content-Length: 270 -// Content-Type: application/json -// Request-uuid: 496c86b1-608f-4886-9436-ec00538e144c - -// ${data}${secondPayload}`; - -// const rpcHeaders = parseJsonRPCHeadersAndData(payload); -// assert.deepStrictEqual(rpcHeaders.headers.size, 3); -// const rpcContent = ExtractJsonRPCData(rpcHeaders.headers.get('Content-Length'), rpcHeaders.remainingRawData); -// assert.deepStrictEqual(rpcContent.extractedJSON, data); -// assert.deepStrictEqual(rpcContent.remainingRawData, secondPayload); -// }); -// test('Valid content length as only header with carriage return', async () => { -// const payload = `Content-Length: 7 -// `; - -// const rpcHeaders = parseJsonRPCHeadersAndData(payload); -// assert.deepStrictEqual(rpcHeaders.headers.size, 1); -// const rpcContent = ExtractJsonRPCData(rpcHeaders.headers.get('Content-Length'), rpcHeaders.remainingRawData); -// assert.deepStrictEqual(rpcContent.extractedJSON, ''); -// assert.deepStrictEqual(rpcContent.remainingRawData, ''); -// }); -// test('Valid content length header with no value', async () => { -// const payload = `Content-Length:`; - -// const rpcHeaders = parseJsonRPCHeadersAndData(payload); -// const rpcContent = ExtractJsonRPCData(rpcHeaders.headers.get('Content-Length'), rpcHeaders.remainingRawData); -// assert.deepStrictEqual(rpcContent.extractedJSON, ''); -// assert.deepStrictEqual(rpcContent.remainingRawData, ''); -// }); - -// suite('Test Controller Utils: Other', () => { -// interface TestCase { -// name: string; -// input: string; -// expectedParent: string; -// expectedSubtest: string; -// } - -// const testCases: Array = [ -// { -// name: 'Single parameter, named', -// input: 'test_package.ClassName.test_method (param=value)', -// expectedParent: 'test_package.ClassName.test_method', -// expectedSubtest: '(param=value)', -// }, -// { -// name: 'Single parameter, unnamed', -// input: 'test_package.ClassName.test_method [value]', -// expectedParent: 'test_package.ClassName.test_method', -// expectedSubtest: '[value]', -// }, -// { -// name: 'Multiple parameters, named', -// input: 'test_package.ClassName.test_method (param1=value1, param2=value2)', -// expectedParent: 'test_package.ClassName.test_method', -// expectedSubtest: '(param1=value1, param2=value2)', -// }, -// { -// name: 'Multiple parameters, unnamed', -// input: 'test_package.ClassName.test_method [value1, value2]', -// expectedParent: 'test_package.ClassName.test_method', -// expectedSubtest: '[value1, value2]', -// }, -// { -// name: 'Names with special characters', -// input: 'test_package.ClassName.test_method (param1=value/1, param2=value+2)', -// expectedParent: 'test_package.ClassName.test_method', -// expectedSubtest: '(param1=value/1, param2=value+2)', -// }, -// { -// name: 'Names with spaces', -// input: 'test_package.ClassName.test_method ["a b c d"]', -// expectedParent: 'test_package.ClassName.test_method', -// expectedSubtest: '["a b c d"]', -// }, -// ]; - -// testCases.forEach((testCase) => { -// test(`splitTestNameWithRegex: ${testCase.name}`, () => { -// const splitResult = splitTestNameWithRegex(testCase.input); -// assert.deepStrictEqual(splitResult, [testCase.expectedParent, testCase.expectedSubtest]); -// }); -// }); -// }); -// suite('Test Controller Utils: Args Mapping', () => { -// suite('addValueIfKeyNotExist', () => { -// test('should add key-value pair if key does not exist', () => { -// const args = ['key1=value1', 'key2=value2']; -// const result = addValueIfKeyNotExist(args, 'key3', 'value3'); -// assert.deepEqual(result, ['key1=value1', 'key2=value2', 'key3=value3']); -// }); - -// test('should not add key-value pair if key already exists', () => { -// const args = ['key1=value1', 'key2=value2']; -// const result = addValueIfKeyNotExist(args, 'key1', 'value3'); -// assert.deepEqual(result, ['key1=value1', 'key2=value2']); -// }); -// test('should not add key-value pair if key exists as a solo element', () => { -// const args = ['key1=value1', 'key2']; -// const result = addValueIfKeyNotExist(args, 'key2', 'yellow'); -// assert.deepEqual(result, ['key1=value1', 'key2']); -// }); -// test('add just key if value is null', () => { -// const args = ['key1=value1', 'key2']; -// const result = addValueIfKeyNotExist(args, 'key3', null); -// assert.deepEqual(result, ['key1=value1', 'key2', 'key3']); -// }); -// }); - -// suite('argKeyExists', () => { -// test('should return true if key exists', () => { -// const args = ['key1=value1', 'key2=value2']; -// const result = argKeyExists(args, 'key1'); -// assert.deepEqual(result, true); -// }); - -// test('should return false if key does not exist', () => { -// const args = ['key1=value1', 'key2=value2']; -// const result = argKeyExists(args, 'key3'); -// assert.deepEqual(result, false); -// }); -// }); -// }); -// }); + assert.ok(accessStub.called); + assert.ok(mkdirStub.called); + assert.ok(writeFileStub.calledOnceWith(sinon.match.string, testIds.join('\n'))); + }); +});