From ed8467bb6271ade5251497ba4697ff0a54253db7 Mon Sep 17 00:00:00 2001 From: Eran Turgeman Date: Thu, 7 Dec 2023 13:08:02 +0200 Subject: [PATCH] added Artifactory tests for: yarn, dotnet, npm --- go.mod | 2 +- go.sum | 4 +- 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 | 98 +++++++++++++-------- 8 files changed, 98 insertions(+), 41 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..c53fdbbee 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/eranturgeman/jfrog-cli-core/v2 v2.0.0-20231207102413-b244ea08b1ec // 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..24288c725 100644 --- a/go.sum +++ b/go.sum @@ -135,6 +135,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/eranturgeman/jfrog-cli-core/v2 v2.0.0-20231207102413-b244ea08b1ec h1:dfwCBrhK7hpeQWJTf550fYagMkcsTM7Hu+twHJTWkpI= +github.com/eranturgeman/jfrog-cli-core/v2 v2.0.0-20231207102413-b244ea08b1ec/go.mod h1:RFQwrZ1qXAQ+X0xfuzxBBDIYuRnDsPy12xlyjuOpUog= github.com/forPelevin/gomoji v1.1.8 h1:JElzDdt0TyiUlecy6PfITDL6eGvIaxqYH1V52zrd0qQ= github.com/forPelevin/gomoji v1.1.8/go.mod h1:8+Z3KNGkdslmeGZBC3tCrwMrcPy5GRzAD+gL9NAwMXg= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -243,8 +245,6 @@ 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-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/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 61f748793..3e960ed97 100644 --- a/xray_test.go +++ b/xray_test.go @@ -7,7 +7,10 @@ import ( "fmt" biutils "github.com/jfrog/build-info-go/utils" "github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/sca/npm" + "github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/sca/nuget" + "github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/sca/yarn" "github.com/jfrog/jfrog-cli-core/v2/xray/scangraph" + "github.com/jfrog/jfrog-client-go/utils/log" "net/http" "net/http/httptest" "os" @@ -841,27 +844,24 @@ func TestCurationAudit(t *testing.T) { } serverMock, config := curationServer(t, expectedRequest, requestToFail) - cleanUpJfrogHome, err := coretests.SetJfrogHome() //TODO dont forget to create jfrog home in the test + cleanUpJfrogHome, err := coretests.SetJfrogHome() assert.NoError(t, err) defer cleanUpJfrogHome() config.User = "admin" config.Password = "password" config.ServerId = "test" - //TODO this creates the server, but a mock server configCmd := coreCmd.NewConfigCommand(coreCmd.AddOrEdit, "test").SetDetails(config).SetUseBasicAuthOnly(true).SetInteractive(false) assert.NoError(t, configCmd.Run()) - // todo make sure that the artifactory repo that is created for the test is also deleted after the test - //todo remember that in GO we must download from virtualExample defer serverMock.Close() // Create build config - resolutionServerId := "server-id-resolve" //todo no need + resolutionServerId := "server-id-resolve" deploymentServerId := "server-id-deploy" resolutionRepo := "repo-resolve" - deploymentRepo := "repo-deploy" //todo no need + deploymentRepo := "repo-deploy" context := createContext(t, resolutionServerId+"="+config.ServerId, resolutionRepo+"=npms", deploymentServerId+"="+config.ServerId, deploymentRepo+"=npm-local", "global=false") - err = artCmdUtils.CreateBuildConfig(context, artUtils.Npm) // TODO look here for artifactory tests + err = artCmdUtils.CreateBuildConfig(context, artUtils.Npm) assert.NoError(t, err) localXrayCli := xrayCli.WithoutCredentials() @@ -961,26 +961,44 @@ func setStringFlags(flagSet *flag.FlagSet, flags ...string) []string { // We test resolution from an Artifactory server using BuildDependencyTree that resolves dependencies before building the tree func TestDependencyResolutionFromArtifactory(t *testing.T) { - /* - testCases := []struct { - testProjectPath []string - repoName string - projectType artUtils.ProjectType - }{ - { - testProjectPath: []string{"npm", "npmproject"}, - repoName: tests.NpmRemoteRepo, - projectType: artUtils.Npm, - }, - } + 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, + }, + } - initXrayTest(t, "") // checks for the -test.xray flag and for minVersion if needed + for _, testcase := range testCases { + testSingleTechDependencyResolution(t, testcase.testProjectPath, testcase.resolveRepoName, testcase.cacheRepoName, testcase.projectType) + } +} +func testSingleTechDependencyResolution(t *testing.T, testProjectPartialPath []string, resolveRepoName string, cacheRepoName string, projectType artUtils.ProjectType) { + log.Info(fmt.Sprintf("--- Starting %s test ---", projectType.String())) tempDirPath, createTempDirCallback := coretests.CreateTempDirWithCallbackAndAssert(t) defer createTempDirCallback() - testProjectPath := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "npm", "npmproject") //TODO here + testProjectPath := filepath.Join(append([]string{filepath.FromSlash(tests.GetTestResourcesPath())}, testProjectPartialPath...)...) assert.NoError(t, biutils.CopyDir(testProjectPath, tempDirPath, true, nil)) rootDir, err := os.Getwd() require.NoError(t, err) @@ -989,12 +1007,9 @@ func TestDependencyResolutionFromArtifactory(t *testing.T) { assert.NoError(t, os.Chdir(rootDir)) }() - // use SetJfrogHome and then revert it with defer - this is needed so the tests will not change the home path for jfrog cleanUpJfrogHome, err := coretests.SetJfrogHome() assert.NoError(t, err) defer cleanUpJfrogHome() - - // Create config command using NewConfigCommand. this replaces running the command of jf config that should run with a prompt server := &config.ServerDetails{ Url: *tests.JfrogUrl, ArtifactoryUrl: *tests.JfrogUrl + tests.ArtifactoryEndpoint, @@ -1004,28 +1019,37 @@ func TestDependencyResolutionFromArtifactory(t *testing.T) { configCmd := coreCmd.NewConfigCommand(coreCmd.AddOrEdit, "test").SetDetails(serverDetails).SetUseBasicAuthOnly(true).SetInteractive(false) assert.NoError(t, configCmd.Run()) - - // Create build config using createContext. this replaces jf npm-config that should run with a prompt - context := createContext(t, "repo-resolve="+tests.NpmRemoteRepo, "server-id-resolve="+serverDetails.ServerId, "global=false") //TODO here - err = artCmdUtils.CreateBuildConfig(context, artUtils.Npm) //TODO here + context := createContext(t, "repo-resolve="+resolveRepoName, "server-id-resolve="+serverDetails.ServerId, "global=false") + err = artCmdUtils.CreateBuildConfig(context, projectType) assert.NoError(t, err) - // make a search command on the repo's cache and check that it is empty. use --fail-no-op flag - artifactoryPathToSearch := tests.NpmRemoteRepo + "-cache/*" //TODO here + artifactoryPathToSearch := cacheRepoName + "-cache/*" output := artifactoryCli.RunCliCmdWithOutput(t, "s", artifactoryPathToSearch) // We check the repo's cache is empty before resolving from artifactory assert.Equal(t, "[]\n", output) - // run the install command that should fill the cache (see about flag that should ignore cache). - // We run BuildDependencyTree on an un-installed project. Since we set an Artifactory server and repository we expect the dependencies will be resolved from there - auditParams := (&utils.AuditBasicParams{}).SetServerDetails(server).SetDepsRepo(tests.NpmRemoteRepo) //TODO here - _, _, err = npm.BuildDependencyTree(auditParams) //TODO here - assert.NoError(t, err) + auditParams := (&utils.AuditBasicParams{}).SetServerDetails(server).SetDepsRepo(resolveRepoName) + err = runBuildDependencyTreeAccordingToTech(t, auditParams, projectType) + require.NoError(t, err) - // make another search to make sure the cache if filled with the resolved dependencies. use --fail-no-op flag // After resolving from Artifactory we expect the repo's cache to be non-empty output = artifactoryCli.RunCliCmdWithOutput(t, "s", artifactoryPathToSearch) // We check the repo's cache is empty before resolving from artifactory assert.NotEqual(t, "[]\n", output) } + +func runBuildDependencyTreeAccordingToTech(t *testing.T, auditParams *utils.AuditBasicParams, projectType artUtils.ProjectType) (err error) { + switch projectType { + case artUtils.Npm: + _, _, err = npm.BuildDependencyTree(auditParams) + case artUtils.Dotnet: + // Clearing local caches so we resolve from Artifactory + _, err = exec.Command("dotnet", "nuget", "locals", "all", "--clear").CombinedOutput() + assert.NoError(t, err) + _, _, err = nuget.BuildDependencyTree(auditParams) + case artUtils.Yarn: + _, _, err = yarn.BuildDependencyTree(auditParams) + } + return +}