diff --git a/.circleci/config.yml b/.circleci/config.yml index f97a8f9e7a..55370e21f5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -931,6 +931,35 @@ workflows: pre_test_cmds: | if (Test-Path '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>') { . '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>' } + - acceptance-tests: + name: acceptance-tests windows unmanaged pre-prod + go_target_os: windows + go_os: windows + go_arch: amd64 + go_download_base_url: << pipeline.parameters.go_download_base_url >> + context: + - nodejs-install + - team_hammerhead-cli + filters: + branches: + ignore: + - main + - '/release.*/' + requires: + - build windows amd64 + executor: win-server2022-amd64 + test_snyk_command: binary-releases\\snyk-win.exe + install_deps_extension: windows-native-build + dont_skip_tests: 0 + shards: 1 + shard_calc_cmd: '$([int]$env:CIRCLE_NODE_INDEX + 1)' + additional_test_args: --runTestsByPath test/jest/acceptance/snyk-test/unmanaged-pre-prod.spec.ts + pre_test_cmds: | + if (Test-Path '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>') { . '<< pipeline.parameters.windows_cache_dir >>/<< pipeline.parameters.windows_env_script >>' } + $env:TEST_SNYK_API = $env:TEST_SNYK_API_DEV + $env:TEST_SNYK_TOKEN = $env:TEST_SNYK_TOKEN_DEV + $env:TEST_SNYK_TOKEN_2 = $env:TEST_SNYK_TOKEN_DEV + - sign: name: sign windows amd64 context: snyk-windows-signing @@ -1559,6 +1588,9 @@ jobs: pre_test_cmds: type: string default: 'echo Running tests' + additional_test_args: + type: string + default: '' shards: type: integer default: 4 @@ -1593,7 +1625,7 @@ jobs: no_output_timeout: 30m command: | << parameters.pre_test_cmds >> - npm run test:acceptance -- --selectProjects coreCli --shard=<< parameters.shard_calc_cmd >>/<< parameters.shards >> + npm run test:acceptance -- --selectProjects coreCli << parameters.additional_test_args >> --shard=<< parameters.shard_calc_cmd >>/<< parameters.shards >> environment: TEST_SNYK_FIPS: << parameters.fips >> TEST_SNYK_COMMAND: << parameters.test_snyk_command >> diff --git a/test/jest/acceptance/snyk-test/unmanaged-pre-prod.spec.ts b/test/jest/acceptance/snyk-test/unmanaged-pre-prod.spec.ts new file mode 100644 index 0000000000..24aa37da23 --- /dev/null +++ b/test/jest/acceptance/snyk-test/unmanaged-pre-prod.spec.ts @@ -0,0 +1,97 @@ +import { describeIf } from '../../../utils'; +import { + createProjectFromFixture, + createProjectFromWorkspace, +} from '../../util/createProject'; +import { runSnykCLI } from '../../util/runSnykCLI'; +import * as path from 'path'; + +jest.setTimeout(1000 * 60 * 5); + +const hasPreProdCredentials = Boolean( + process.env.TEST_SNYK_API_DEV && process.env.TEST_SNYK_TOKEN_DEV, +); + +const env = { + ...process.env, + SNYK_API: process.env.TEST_SNYK_API_DEV, + SNYK_TOKEN: process.env.TEST_SNYK_TOKEN_DEV, +}; + +describeIf(hasPreProdCredentials)('unmanaged pre-prod user journey', () => { + test('runs `snyk test --unmanaged` against pre-prod', async () => { + const project = await createProjectFromWorkspace('unmanaged'); + const { code, stdout, stderr } = await runSnykCLI('test --unmanaged -d', { + cwd: project.path(), + env, + }); + + if (code !== 1) { + console.debug(stderr); + console.debug('---------------------------'); + console.debug(stdout); + } + + expect(code).toEqual(1); + expect(stdout).toContain('madler/zlib@1.2.11'); + expect(stdout).toContain( + 'Tested 1 dependency for known issues, found 2 issues.', + ); + }); + + test('runs `snyk test --unmanaged --json` against pre-prod', async () => { + const project = await createProjectFromWorkspace('unmanaged'); + const { code, stdout, stderr } = await runSnykCLI( + 'test --unmanaged -d --json', + { + cwd: project.path(), + env, + }, + ); + + console.debug(stderr); + console.debug('---------------------------'); + console.debug(stdout); + + const parsed = JSON.parse(stdout); + expect(parsed).toEqual(expect.any(Array)); + expect(parsed.length).toBeGreaterThanOrEqual(1); + expect(parsed[0].vulnerabilities.length).toBeGreaterThanOrEqual(1); + expect(stdout).toContain('"purl": "pkg:generic/zlib@'); + + // Verify file paths are present in the response to confirm the + // backend correctly handles OS-specific path separators (e.g. Windows backslashes). + expect(parsed[0].depsFilePaths).toBeDefined(); + const filePaths = Object.values(parsed[0].depsFilePaths).flat() as string[]; + expect(filePaths.length).toBeGreaterThanOrEqual(1); + }); + + test('runs `snyk sbom --unmanaged --max-depth=1` against pre-prod', async () => { + const project = await createProjectFromFixture( + path.join('unmanaged', 'extraction'), + ); + const { code, stdout, stderr } = await runSnykCLI( + `sbom --unmanaged --max-depth=1 --format=cyclonedx1.4+json --org=${process.env.TEST_SNYK_ORG_SLUGNAME} --debug`, + { + cwd: project.path(), + env, + }, + ); + + if (code !== 0) { + console.debug(stderr); + console.debug('---------------------------'); + console.debug(stdout); + } + + expect(code).toEqual(0); + + let sbom; + expect(() => { + sbom = JSON.parse(stdout); + }).not.toThrow(); + + expect(sbom.metadata.component.name).toEqual('root-node'); + expect(sbom.components.length).toBeGreaterThanOrEqual(1); + }); +});