From 892ddb75d96419138952b47171410763b3b21bfe Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Fri, 25 Apr 2025 11:46:39 +0200 Subject: [PATCH 1/2] fix: make maven tests immutable Signed-off-by: Ruben Romero Montes --- src/providers/java_maven.js | 2 +- test/providers/java_maven.test.js | 96 ++++++++----------- .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{effectivePom.xml => effective-pom.xml} | 0 .../{effectivePom.xml => effective-pom.xml} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 .../{dep-tree.txt => mvn_deptree.txt} | 0 14 files changed, 40 insertions(+), 58 deletions(-) rename test/providers/tst_manifests/maven/pom_deps_with_ignore_on_artifact/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/pom_deps_with_ignore_on_dependency/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/pom_deps_with_ignore_on_group/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/pom_deps_with_ignore_on_version/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/pom_deps_with_ignore_on_wrong/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/pom_deps_with_no_ignore/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/pom_deps_with_no_ignore_common_paths/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/pom_with_multiple_modules/{effectivePom.xml => effective-pom.xml} (100%) rename test/providers/tst_manifests/maven/pom_with_one_module/{effectivePom.xml => effective-pom.xml} (100%) rename test/providers/tst_manifests/maven/poms_deps_with_2_ignore_long/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/poms_deps_with_ignore_long/{dep-tree.txt => mvn_deptree.txt} (100%) rename test/providers/tst_manifests/maven/poms_deps_with_no_ignore_long/{dep-tree.txt => mvn_deptree.txt} (100%) diff --git a/src/providers/java_maven.js b/src/providers/java_maven.js index 88e6a837..5b1007b3 100644 --- a/src/providers/java_maven.js +++ b/src/providers/java_maven.js @@ -101,7 +101,7 @@ export default class Java_maven extends Base_java { throw new Error(`failed creating maven dependency tree`, {cause: error}) } // read dependency tree from temp file - let content = fs.readFileSync(`${tmpDepTree}`) + let content = fs.readFileSync(tmpDepTree) if (process.env["EXHORT_DEBUG"] === "true") { console.error("Dependency tree that will be used as input for creating the BOM =>" + EOL + EOL + content.toString()) } diff --git a/test/providers/java_maven.test.js b/test/providers/java_maven.test.js index 1704366c..62858d90 100644 --- a/test/providers/java_maven.test.js +++ b/test/providers/java_maven.test.js @@ -2,19 +2,44 @@ import { expect } from 'chai' import fs from 'fs' import sinon from "sinon"; import Java_maven from '../../src/providers/java_maven.js' +import esmock from 'esmock'; +import path from 'path'; let clock -/** this function is parsing the outputfile path from the given command, and write that file the providerContent supplied. - * - * @param {Array}args - the arguments to pass to the binary - * @param {string}providerContent - the content of the mocked data to replace original content in intercepted temp file - * @param {string}outputFileParameter - name of the parameter indicating the output file of the command invocation, including '='. - * @private - */ -function interceptAndOverwriteDataWithMock(args, providerContent, outputFileParameter) { - const interceptedFilePath = args.find(arg => arg.includes(outputFileParameter)).split("=")[1] - fs.writeFileSync(interceptedFilePath, providerContent) +async function mockProvider(cwd) { + + const mockInvokeCommand = () => { + return ''; + }; + + const mockGitRootDir = (cwd) => { + return cwd; + } + + const mockFs = { + mkdtempSync: (pathName) => pathName, + readFileSync: (filePath) => { + const output = path.join(cwd, path.basename(filePath)); + return fs.readFileSync(output); + }, + rmSync: () => {} + } + + return esmock('../../src/providers/java_maven.js', { + fs: mockFs, + '../../src/providers/base_java.js': await esmock('../../src/providers/base_java.js', { + '../../src/tools.js': { + invokeCommand: mockInvokeCommand, + getGitRootDir: mockGitRootDir + } + }) + }); +} + +async function createMockProvider(testPath) { + const Java_maven = await mockProvider(testPath); + return new Java_maven(); } suite('testing the java-maven data provider', () => { @@ -42,42 +67,16 @@ suite('testing the java-maven data provider', () => { "pom_deps_with_no_ignore_common_paths" ].forEach(testCase => { let scenario = testCase.replace('pom_deps_', '').replaceAll('_', ' ') - // test(`custom adhoc test`, async () => { - // - // // let options = { - // // 'EXHORT_SNYK_TOKEN': 'insert-token' - // // } - // // let httpStatus = await exhort.validateToken(options); - // analysisReport = await exhort.stackAnalysis(`/tmp/pom-xml/pom.xml`,false); - // console.log(analysisReport) - // let pom = fs.readFileSync(`/tmp/pom-xml/pom.xml`,).toString().trim() - // let analysisReport = await exhort.componentAnalysis("pom.xml", pom); - // console.log(analysisReport) - // analysisReport = await exhort.stackAnalysis(`/tmp/pom-xml/pom.xml`,true); - // console.log(analysisReport) - // - // }).timeout(process.env.GITHUB_ACTIONS ? 30000 : 5000) test(`verify maven data provided for stack analysis with scenario ${scenario}`, async () => { // load the expected graph for the scenario let expectedSbom = fs.readFileSync(`test/providers/tst_manifests/maven/${testCase}/stack_analysis_expected_sbom.json`,).toString().trim() - let dependencyTreeTextContent = fs.readFileSync(`test/providers/tst_manifests/maven/${testCase}/dep-tree.txt`,).toString() + // let dependencyTreeTextContent = fs.readFileSync(`test/providers/tst_manifests/maven/${testCase}/dep-tree.txt`,).toString() expectedSbom = JSON.stringify(JSON.parse(expectedSbom),null, 4) - let mockedExecFunction = function(bin, args){ - if (args.find(arg => arg.includes(":tree"))) { - interceptAndOverwriteDataWithMock(args, dependencyTreeTextContent, "DoutputFile=") - } - } - let javaMvnProvider = new Java_maven() - Object.getPrototypeOf(Object.getPrototypeOf(javaMvnProvider))._invokeCommand = mockedExecFunction + let javaMvnProvider = await createMockProvider(`test/providers/tst_manifests/maven/${testCase}`); // invoke sut stack analysis for scenario manifest let providedDataForStack = javaMvnProvider.provideStack(`test/providers/tst_manifests/maven/${testCase}/pom.xml`) // verify returned data matches expectation - // expect(providedDataForStack).to.deep.equal({ - // ecosystem: 'maven', - // contentType: 'application/vnd.cyclonedx+json', - // content: expectedSbom - // }) let beautifiedOutput = JSON.stringify(JSON.parse(providedDataForStack.content),null, 4); expect(beautifiedOutput).to.deep.equal(expectedSbom) @@ -89,14 +88,7 @@ suite('testing the java-maven data provider', () => { let expectedSbom = fs.readFileSync(`test/providers/tst_manifests/maven/${testCase}/component_analysis_expected_sbom.json`,).toString().trim() // read target manifest file expectedSbom = JSON.stringify(JSON.parse(expectedSbom)) - let effectivePomContent = fs.readFileSync(`test/providers/tst_manifests/maven/${testCase}/effective-pom.xml`,).toString() - let mockedExecFunction = function(bin, args){ - if (args.find(arg => arg.includes(":effective-pom"))){ - interceptAndOverwriteDataWithMock(args, effectivePomContent, "Doutput="); - } - } - let javaMvnProvider = new Java_maven() - Object.getPrototypeOf(Object.getPrototypeOf(javaMvnProvider))._invokeCommand = mockedExecFunction + let javaMvnProvider = await createMockProvider(`test/providers/tst_manifests/maven/${testCase}`); // invoke sut component analysis for scenario manifest let providedDataForStack = javaMvnProvider.provideComponent(`test/providers/tst_manifests/maven/${testCase}/pom.xml`) // verify returned data matches expectation @@ -124,14 +116,7 @@ suite('testing the java-maven data provider with modules', () => { let expectedSbom = fs.readFileSync(`test/providers/tst_manifests/maven/${testCase}/component_analysis_expected_sbom.json`,).toString().trim() // read target manifest file expectedSbom = JSON.stringify(JSON.parse(expectedSbom)) - let effectivePomContent = fs.readFileSync(`test/providers/tst_manifests/maven/${testCase}/effectivePom.xml`,).toString() - let mockedExecFunction = function(command, args){ - if (args.find(arg => arg.includes(":effective-pom"))){ - interceptAndOverwriteDataWithMock(args, effectivePomContent, "Doutput="); - } - } - let javaMvnProvider = new Java_maven() - Object.getPrototypeOf(Object.getPrototypeOf(javaMvnProvider))._invokeCommand = mockedExecFunction + let javaMvnProvider = await createMockProvider(`test/providers/tst_manifests/maven/${testCase}`); // invoke sut component analysis for scenario manifest let provideDataForComponent = javaMvnProvider.provideComponent(`test/providers/tst_manifests/maven/${testCase}/pom.xml`, {}) // verify returned data matches expectation @@ -140,12 +125,9 @@ suite('testing the java-maven data provider with modules', () => { contentType: 'application/vnd.cyclonedx+json', content: expectedSbom }) - // expect(beautifiedOutput).to.deep.equal(expectedSbom) - // these test cases takes ~2500-2700 ms each pr >10000 in CI (for the first test-case) }).timeout(process.env.GITHUB_ACTIONS ? 40000 : 10000) - // these test cases takes ~1400-2000 ms each pr >10000 in CI (for the first test-case) }) diff --git a/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_artifact/dep-tree.txt b/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_artifact/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/pom_deps_with_ignore_on_artifact/dep-tree.txt rename to test/providers/tst_manifests/maven/pom_deps_with_ignore_on_artifact/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_dependency/dep-tree.txt b/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_dependency/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/pom_deps_with_ignore_on_dependency/dep-tree.txt rename to test/providers/tst_manifests/maven/pom_deps_with_ignore_on_dependency/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_group/dep-tree.txt b/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_group/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/pom_deps_with_ignore_on_group/dep-tree.txt rename to test/providers/tst_manifests/maven/pom_deps_with_ignore_on_group/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_version/dep-tree.txt b/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_version/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/pom_deps_with_ignore_on_version/dep-tree.txt rename to test/providers/tst_manifests/maven/pom_deps_with_ignore_on_version/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_wrong/dep-tree.txt b/test/providers/tst_manifests/maven/pom_deps_with_ignore_on_wrong/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/pom_deps_with_ignore_on_wrong/dep-tree.txt rename to test/providers/tst_manifests/maven/pom_deps_with_ignore_on_wrong/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/pom_deps_with_no_ignore/dep-tree.txt b/test/providers/tst_manifests/maven/pom_deps_with_no_ignore/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/pom_deps_with_no_ignore/dep-tree.txt rename to test/providers/tst_manifests/maven/pom_deps_with_no_ignore/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/pom_deps_with_no_ignore_common_paths/dep-tree.txt b/test/providers/tst_manifests/maven/pom_deps_with_no_ignore_common_paths/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/pom_deps_with_no_ignore_common_paths/dep-tree.txt rename to test/providers/tst_manifests/maven/pom_deps_with_no_ignore_common_paths/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/pom_with_multiple_modules/effectivePom.xml b/test/providers/tst_manifests/maven/pom_with_multiple_modules/effective-pom.xml similarity index 100% rename from test/providers/tst_manifests/maven/pom_with_multiple_modules/effectivePom.xml rename to test/providers/tst_manifests/maven/pom_with_multiple_modules/effective-pom.xml diff --git a/test/providers/tst_manifests/maven/pom_with_one_module/effectivePom.xml b/test/providers/tst_manifests/maven/pom_with_one_module/effective-pom.xml similarity index 100% rename from test/providers/tst_manifests/maven/pom_with_one_module/effectivePom.xml rename to test/providers/tst_manifests/maven/pom_with_one_module/effective-pom.xml diff --git a/test/providers/tst_manifests/maven/poms_deps_with_2_ignore_long/dep-tree.txt b/test/providers/tst_manifests/maven/poms_deps_with_2_ignore_long/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/poms_deps_with_2_ignore_long/dep-tree.txt rename to test/providers/tst_manifests/maven/poms_deps_with_2_ignore_long/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/poms_deps_with_ignore_long/dep-tree.txt b/test/providers/tst_manifests/maven/poms_deps_with_ignore_long/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/poms_deps_with_ignore_long/dep-tree.txt rename to test/providers/tst_manifests/maven/poms_deps_with_ignore_long/mvn_deptree.txt diff --git a/test/providers/tst_manifests/maven/poms_deps_with_no_ignore_long/dep-tree.txt b/test/providers/tst_manifests/maven/poms_deps_with_no_ignore_long/mvn_deptree.txt similarity index 100% rename from test/providers/tst_manifests/maven/poms_deps_with_no_ignore_long/dep-tree.txt rename to test/providers/tst_manifests/maven/poms_deps_with_no_ignore_long/mvn_deptree.txt From 85a2d3a37dcf63f0ca4a67606678ba78d8609052 Mon Sep 17 00:00:00 2001 From: Ruben Romero Montes Date: Fri, 25 Apr 2025 11:47:04 +0200 Subject: [PATCH 2/2] fix: make pnpm tests immutable Signed-off-by: Ruben Romero Montes --- test/it/test_manifests/pnpm/package.json | 4 +- test/it/test_manifests/pnpm/pnpm-lock.yaml | 54 ++++------------------ 2 files changed, 10 insertions(+), 48 deletions(-) diff --git a/test/it/test_manifests/pnpm/package.json b/test/it/test_manifests/pnpm/package.json index 7e26367d..3be1563f 100644 --- a/test/it/test_manifests/pnpm/package.json +++ b/test/it/test_manifests/pnpm/package.json @@ -10,7 +10,7 @@ "keywords": [], "license": "ISC", "dependencies": { - "@hapi/joi": "^17.1.1", - "axios": "^0.19.0" + "axios": "^0.19.0", + "node-json-converter": "0.0.1-security" } } diff --git a/test/it/test_manifests/pnpm/pnpm-lock.yaml b/test/it/test_manifests/pnpm/pnpm-lock.yaml index a7ac6af6..8be47c95 100644 --- a/test/it/test_manifests/pnpm/pnpm-lock.yaml +++ b/test/it/test_manifests/pnpm/pnpm-lock.yaml @@ -8,36 +8,15 @@ importers: .: dependencies: - '@hapi/joi': - specifier: ^17.1.1 - version: 17.1.1 axios: specifier: ^0.19.0 version: 0.19.2 + node-json-converter: + specifier: 0.0.1-security + version: 0.0.1-security packages: - '@hapi/address@4.1.0': - resolution: {integrity: sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==} - deprecated: Moved to 'npm install @sideway/address' - - '@hapi/formula@2.0.0': - resolution: {integrity: sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==} - deprecated: Moved to 'npm install @sideway/formula' - - '@hapi/hoek@9.3.0': - resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} - - '@hapi/joi@17.1.1': - resolution: {integrity: sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==} - deprecated: Switch to 'npm install joi' - - '@hapi/pinpoint@2.0.1': - resolution: {integrity: sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==} - - '@hapi/topo@5.1.0': - resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - axios@0.19.2: resolution: {integrity: sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==} deprecated: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410 @@ -57,29 +36,10 @@ packages: ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} -snapshots: - - '@hapi/address@4.1.0': - dependencies: - '@hapi/hoek': 9.3.0 + node-json-converter@0.0.1-security: + resolution: {integrity: sha512-KxZvcO/m1dly7F8QvHKHq/kTXC/NtEzprCDCEt6ipJasWbT9YetNt0y7kSOblgR/l5sIS1455WQNtzSyu9Qe1Q==} - '@hapi/formula@2.0.0': {} - - '@hapi/hoek@9.3.0': {} - - '@hapi/joi@17.1.1': - dependencies: - '@hapi/address': 4.1.0 - '@hapi/formula': 2.0.0 - '@hapi/hoek': 9.3.0 - '@hapi/pinpoint': 2.0.1 - '@hapi/topo': 5.1.0 - - '@hapi/pinpoint@2.0.1': {} - - '@hapi/topo@5.1.0': - dependencies: - '@hapi/hoek': 9.3.0 +snapshots: axios@0.19.2: dependencies: @@ -98,3 +58,5 @@ snapshots: - supports-color ms@2.0.0: {} + + node-json-converter@0.0.1-security: {}