From cee0ba4e0f50b96f80b2a2f017b206f5993c28eb Mon Sep 17 00:00:00 2001 From: Eran Turgeman <81029514+eranturgeman@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:41:58 +0200 Subject: [PATCH] Artifactory resolution tests (#2347) --- go.mod | 2 +- go.sum | 4 +- main_test.go | 3 + testdata/nuget/simple-dotnet/Class1.cs | 6 ++ testdata/nuget/simple-dotnet/nuget1.csproj | 16 ++++ testdata/yarn_remote_repository_config.json | 6 ++ utils/tests/consts.go | 2 + utils/tests/utils.go | 5 +- xray_test.go | 82 +++++++++++++++++++++ 9 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 testdata/nuget/simple-dotnet/Class1.cs create mode 100644 testdata/nuget/simple-dotnet/nuget1.csproj create mode 100644 testdata/yarn_remote_repository_config.json diff --git a/go.mod b/go.mod index e57e0f700..997652832 100644 --- a/go.mod +++ b/go.mod @@ -132,7 +132,7 @@ require ( // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20231130093251-25c79868c10c -// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20231130101652-2aaa8c0c51ec +replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20231207140254-799876947bac // replace github.com/jfrog/gofrog => github.com/jfrog/gofrog v1.3.2-0.20231130091721-6d742be8bc7a diff --git a/go.sum b/go.sum index e07c31904..8256f20a4 100644 --- a/go.sum +++ b/go.sum @@ -243,8 +243,8 @@ github.com/jfrog/gofrog v1.3.2 h1:TktKP+PdZdxjkYZxWWIq4DkTGSYtr9Slsy+egZpEhUY= github.com/jfrog/gofrog v1.3.2/go.mod h1:AQo5Fq0G9nDEF6icH7MYQK0iohR4HuEAXl8jaxRuT6Q= github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY= github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= -github.com/jfrog/jfrog-cli-core/v2 v2.47.2 h1:2tHkYY5ZdLkX3IsyGAfCDLQASMO4jrqd5WsNQP6d3PY= -github.com/jfrog/jfrog-cli-core/v2 v2.47.2/go.mod h1:RFQwrZ1qXAQ+X0xfuzxBBDIYuRnDsPy12xlyjuOpUog= +github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20231207140254-799876947bac h1:nb9wfr/o8e31l7Kv7Rc9++3EITpZhtYQnzT+U7rdsIA= +github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20231207140254-799876947bac/go.mod h1:RFQwrZ1qXAQ+X0xfuzxBBDIYuRnDsPy12xlyjuOpUog= github.com/jfrog/jfrog-client-go v1.35.0 h1:VTyrR/jFlWInRdGYswa2fwFc1Thsh6eGMnHuqhDVh7s= github.com/jfrog/jfrog-client-go v1.35.0/go.mod h1:cG0vdKXbyfupKgSYmwA5FZPco6zSfyJi3eEYOxuqm/k= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= diff --git a/main_test.go b/main_test.go index f9d4fb07b..4d42e6107 100644 --- a/main_test.go +++ b/main_test.go @@ -88,6 +88,9 @@ func tearDownIntegrationTests() { if *tests.TestNpm || *tests.TestGradle || *tests.TestMaven || *tests.TestGo || *tests.TestNuget || *tests.TestPip || *tests.TestPipenv || *tests.TestDocker || *tests.TestPodman || *tests.TestDockerScan { CleanBuildToolsTests() } + if *tests.TestXray { + CleanXrayTests() + } if *tests.TestDistribution { CleanDistributionTests() } diff --git a/testdata/nuget/simple-dotnet/Class1.cs b/testdata/nuget/simple-dotnet/Class1.cs new file mode 100644 index 000000000..af05eece0 --- /dev/null +++ b/testdata/nuget/simple-dotnet/Class1.cs @@ -0,0 +1,6 @@ +namespace nuget1; + +public class Class1 +{ + +} diff --git a/testdata/nuget/simple-dotnet/nuget1.csproj b/testdata/nuget/simple-dotnet/nuget1.csproj new file mode 100644 index 000000000..0b5a60de8 --- /dev/null +++ b/testdata/nuget/simple-dotnet/nuget1.csproj @@ -0,0 +1,16 @@ + + + + net7.0 + enable + enable + + + + + + + + + + diff --git a/testdata/yarn_remote_repository_config.json b/testdata/yarn_remote_repository_config.json new file mode 100644 index 000000000..1474dc89d --- /dev/null +++ b/testdata/yarn_remote_repository_config.json @@ -0,0 +1,6 @@ +{ + "key": "${YARN_REMOTE_REPO}", + "rclass": "remote", + "packageType": "npm", + "url": "https://registry.npmjs.org" +} diff --git a/utils/tests/consts.go b/utils/tests/consts.go index 8b3b93a6b..160ef87a3 100644 --- a/utils/tests/consts.go +++ b/utils/tests/consts.go @@ -78,6 +78,7 @@ const ( NpmLocalRepositoryConfig = "npm_local_repository_config.json" NpmRemoteRepositoryConfig = "npm_remote_repository_config.json" NugetRemoteRepositoryConfig = "nuget_remote_repository_config.json" + YarnRemoteRepositoryConfig = "yarn_remote_repository_config.json" Out = "out" PypiRemoteRepositoryConfig = "pypi_remote_repository_config.json" PypiVirtualRepositoryConfig = "pypi_virtual_repository_config.json" @@ -171,6 +172,7 @@ var ( NpmRepo = "cli-npm" NpmRemoteRepo = "cli-npm-remote" NugetRemoteRepo = "cli-nuget-remote" + YarnRemoteRepo = "cli-yarn-remote" PypiRemoteRepo = "cli-pypi-remote" PypiVirtualRepo = "cli-pypi-virtual" PipenvRemoteRepo = "cli-pipenv-pypi-remote" diff --git a/utils/tests/utils.go b/utils/tests/utils.go index b3eeb3950..00d738513 100644 --- a/utils/tests/utils.go +++ b/utils/tests/utils.go @@ -335,6 +335,7 @@ var reposConfigMap = map[*string]string{ &NpmRepo: NpmLocalRepositoryConfig, &NpmRemoteRepo: NpmRemoteRepositoryConfig, &NugetRemoteRepo: NugetRemoteRepositoryConfig, + &YarnRemoteRepo: YarnRemoteRepositoryConfig, &PypiRemoteRepo: PypiRemoteRepositoryConfig, &PypiVirtualRepo: PypiVirtualRepositoryConfig, &PipenvRemoteRepo: PipenvRemoteRepositoryConfig, @@ -397,7 +398,7 @@ func GetNonVirtualRepositories() map[*string]string { TestPip: {&PypiRemoteRepo}, TestPipenv: {&PipenvRemoteRepo}, TestPlugins: {&RtRepo1}, - TestXray: {}, + TestXray: {&NpmRemoteRepo, &NugetRemoteRepo, &YarnRemoteRepo}, TestAccess: {&RtRepo1}, TestTransfer: {&RtRepo1, &RtRepo2, &MvnRepo1, &MvnRemoteRepo, &DockerRemoteRepo}, TestLifecycle: {&RtDevRepo, &RtProdRepo}, @@ -488,6 +489,7 @@ func getSubstitutionMap() map[string]string { "${NPM_REPO}": NpmRepo, "${NPM_REMOTE_REPO}": NpmRemoteRepo, "${NUGET_REMOTE_REPO}": NugetRemoteRepo, + "${YARN_REMOTE_REPO}": YarnRemoteRepo, "${GO_REPO}": GoRepo, "${GO_REMOTE_REPO}": GoRemoteRepo, "${GO_VIRTUAL_REPO}": GoVirtualRepo, @@ -554,6 +556,7 @@ func AddTimestampToGlobalVars() { NpmRepo += uniqueSuffix NpmRemoteRepo += uniqueSuffix NugetRemoteRepo += uniqueSuffix + YarnRemoteRepo += uniqueSuffix PypiRemoteRepo += uniqueSuffix PypiVirtualRepo += uniqueSuffix PipenvRemoteRepo += uniqueSuffix diff --git a/xray_test.go b/xray_test.go index 0b5ae975a..1415f2f02 100644 --- a/xray_test.go +++ b/xray_test.go @@ -56,6 +56,14 @@ var ( func InitXrayTests() { initXrayCli() + initArtifactoryCli() + cleanUpOldRepositories() + tests.AddTimestampToGlobalVars() + createRequiredRepos() +} + +func CleanXrayTests() { + deleteCreatedRepos() } func authenticateXray() string { @@ -950,3 +958,77 @@ func setStringFlags(flagSet *flag.FlagSet, flags ...string) []string { } return cmdFlags } + +// We perform validation on dependency resolution from an Artifactory server during the construction of the dependency tree during 'audit' flow. +// This process involves resolving all dependencies required by the project. +func TestDependencyResolutionFromArtifactory(t *testing.T) { + initXrayTest(t, "") + + testCases := []struct { + testProjectPath []string + resolveRepoName string + cacheRepoName string + projectType artUtils.ProjectType + }{ + { + testProjectPath: []string{"npm", "npmproject"}, + resolveRepoName: tests.NpmRemoteRepo, + cacheRepoName: tests.NpmRemoteRepo, + projectType: artUtils.Npm, + }, + { + testProjectPath: []string{"nuget", "simple-dotnet"}, + resolveRepoName: tests.NugetRemoteRepo, + cacheRepoName: tests.NugetRemoteRepo, + projectType: artUtils.Dotnet, + }, + { + testProjectPath: []string{"yarn", "yarnproject"}, + resolveRepoName: tests.YarnRemoteRepo, + cacheRepoName: tests.YarnRemoteRepo, + projectType: artUtils.Yarn, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.projectType.String(), func(t *testing.T) { + testSingleTechDependencyResolution(t, testCase.testProjectPath, testCase.resolveRepoName, testCase.cacheRepoName, testCase.projectType) + }) + } +} + +func testSingleTechDependencyResolution(t *testing.T, testProjectPartialPath []string, resolveRepoName string, cacheRepoName string, projectType artUtils.ProjectType) { + tempDirPath, createTempDirCallback := coretests.CreateTempDirWithCallbackAndAssert(t) + defer createTempDirCallback() + testProjectPath := filepath.Join(append([]string{filepath.FromSlash(tests.GetTestResourcesPath())}, testProjectPartialPath...)...) + assert.NoError(t, biutils.CopyDir(testProjectPath, tempDirPath, true, nil)) + rootDir, err := os.Getwd() + assert.NoError(t, err) + assert.NoError(t, os.Chdir(tempDirPath)) + defer func() { + assert.NoError(t, os.Chdir(rootDir)) + }() + createJfrogHomeConfig(t, true) + context := createContext(t, "repo-resolve="+resolveRepoName) + err = artCmdUtils.CreateBuildConfig(context, projectType) + assert.NoError(t, err) + + artifactoryPathToSearch := cacheRepoName + "-cache/*" + output := artifactoryCli.RunCliCmdWithOutput(t, "s", artifactoryPathToSearch) + // Before the resolution from Artifactory, we verify whether the repository's cache is empty. + assert.Equal(t, "[]\n", output) + + if projectType == artUtils.Dotnet { + // In Nuget/Dotnet projects we need to clear local caches so we will resolve dependencies from Artifactory + _, err = exec.Command("dotnet", "nuget", "locals", "all", "--clear").CombinedOutput() + assert.NoError(t, err) + } + + // We execute 'audit' command on a project that hasn't been installed. With the Artifactory server and repository configuration, our expectation is that dependencies will be resolved from there + assert.NoError(t, xrayCli.Exec("audit")) + + // Following resolution from Artifactory, we anticipate the repository's cache to contain data. + output = artifactoryCli.RunCliCmdWithOutput(t, "s", artifactoryPathToSearch, "--fail-no-op") + // After the resolution from Artifactory, we verify whether the repository's cache is filled with artifacts. + assert.NotEqual(t, "[]\n", output) +}