github.com/jfrog/jfrog-cli@v1.54.1/nuget_test.go (about) 1 package main 2 3 import ( 4 "encoding/xml" 5 "os" 6 "path/filepath" 7 "strconv" 8 "testing" 9 10 "github.com/jfrog/jfrog-cli-core/utils/coreutils" 11 12 "github.com/jfrog/jfrog-cli-core/artifactory/commands/dotnet" 13 "github.com/jfrog/jfrog-cli-core/artifactory/utils" 14 dotnetutils "github.com/jfrog/jfrog-cli-core/artifactory/utils/dotnet" 15 "github.com/jfrog/jfrog-cli-core/utils/config" 16 "github.com/jfrog/jfrog-cli/inttestutils" 17 "github.com/jfrog/jfrog-cli/utils/tests" 18 "github.com/jfrog/jfrog-client-go/artifactory/buildinfo" 19 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 ) 23 24 func initNugetTest(t *testing.T) { 25 if !*tests.TestNuget { 26 t.Skip("Skipping NuGet test. To run Nuget test add the '-test.nuget=true' option.") 27 } 28 29 // This is due to Artifactory bug, we cant create remote repository with REST API. 30 require.True(t, isRepoExist(tests.NugetRemoteRepo), "Create nuget remote repository:", tests.NugetRemoteRepo, "in order to run nuget tests") 31 createJfrogHomeConfig(t, true) 32 } 33 34 type testDescriptor struct { 35 name string 36 project string 37 args []string 38 expectedModules []string 39 expectedDependencies []int 40 } 41 42 func TestNugetResolve(t *testing.T) { 43 initNugetTest(t) 44 projects := []testDescriptor{ 45 {"packagesconfigwithoutmodulechnage", "packagesconfig", []string{"nuget", "restore", tests.NugetRemoteRepo}, []string{"packagesconfig"}, []int{6}}, 46 {"packagesconfigwithmodulechnage", "packagesconfig", []string{"nuget", "restore", tests.NugetRemoteRepo, "--module=" + ModuleNameJFrogTest}, []string{ModuleNameJFrogTest}, []int{6}}, 47 {"referencewithoutmodulechnage", "reference", []string{"nuget", "restore", tests.NugetRemoteRepo}, []string{"reference"}, []int{6}}, 48 {"referencewithmodulechnage", "reference", []string{"nuget", "restore", tests.NugetRemoteRepo, "--module=" + ModuleNameJFrogTest}, []string{ModuleNameJFrogTest}, []int{6}}, 49 } 50 for buildNumber, test := range projects { 51 t.Run(test.project, func(t *testing.T) { 52 testNugetCmd(t, createNugetProject(t, test.project), tests.DotnetBuildName, strconv.Itoa(buildNumber), test.expectedModules, test.args, test.expectedDependencies, false) 53 }) 54 } 55 cleanBuildToolsTest() 56 } 57 58 func TestNativeNugetResolve(t *testing.T) { 59 uniqueNugetTests := []testDescriptor{ 60 {"nugetargswithspaces", "packagesconfig", []string{dotnetutils.Nuget.String(), "restore", "-PackagesDirectory", "./packages dir with spaces"}, []string{"packagesconfig"}, []int{6}}, 61 {"packagesconfigwithoutmodulechnage", "packagesconfig", []string{dotnetutils.Nuget.String(), "restore"}, []string{"packagesconfig"}, []int{6}}, 62 {"packagesconfigwithmodulechnage", "packagesconfig", []string{dotnetutils.Nuget.String(), "restore", "--module=" + ModuleNameJFrogTest}, []string{ModuleNameJFrogTest}, []int{6}}, 63 {"packagesconfigwithconfigpath", "packagesconfig", []string{dotnetutils.Nuget.String(), "restore", "./packages.config", "-SolutionDirectory", "."}, []string{"packagesconfig"}, []int{6}}, 64 {"multipackagesconfigwithoutmodulechnage", "multipackagesconfig", []string{dotnetutils.Nuget.String(), "restore"}, []string{"proj1", "proj2", "proj3"}, []int{4, 3, 2}}, 65 {"multipackagesconfigwithmodulechnage", "multipackagesconfig", []string{dotnetutils.Nuget.String(), "restore", "--module=" + ModuleNameJFrogTest}, []string{ModuleNameJFrogTest}, []int{8}}, 66 {"multipackagesconfigwithslnPath", "multipackagesconfig", []string{dotnetutils.Nuget.String(), "restore", "./multipackagesconfig.sln"}, []string{"proj1", "proj2", "proj3"}, []int{4, 3, 2}}, 67 {"multipackagesconfigsingleprojectdir", "multipackagesconfig", []string{dotnetutils.Nuget.String(), "restore", "./proj2/", "-SolutionDirectory", "."}, []string{"proj2"}, []int{3}}, 68 {"multipackagesconfigsingleprojectconfig", "multipackagesconfig", []string{dotnetutils.Nuget.String(), "restore", "./proj1/packages.config", "-SolutionDirectory", "."}, []string{"proj1"}, []int{4}}, 69 } 70 testNativeNugetDotnetResolve(t, uniqueNugetTests, tests.NuGetBuildName, utils.Nuget) 71 } 72 73 func TestDotnetResolve(t *testing.T) { 74 uniqueDotnetTests := []testDescriptor{ 75 {"dotnetargswithspaces", "multireference", []string{dotnetutils.DotnetCore.String(), "restore", "src/multireference.proj1/", "--packages", "./packages dir with spaces"}, []string{"proj1"}, []int{5}}, 76 {"multireferencesingleprojectdir", "multireference", []string{dotnetutils.DotnetCore.String(), "restore", "src/multireference.proj1/"}, []string{"proj1"}, []int{5}}, 77 } 78 testNativeNugetDotnetResolve(t, uniqueDotnetTests, tests.DotnetBuildName, utils.Dotnet) 79 } 80 81 func testNativeNugetDotnetResolve(t *testing.T, uniqueTests []testDescriptor, buildName string, projectType utils.ProjectType) { 82 initNugetTest(t) 83 testDescriptors := append(uniqueTests, []testDescriptor{ 84 {"referencewithoutmodulechnage", "reference", []string{projectType.String(), "restore"}, []string{"reference"}, []int{6}}, 85 {"referencewithmodulechnage", "reference", []string{projectType.String(), "restore", "--module=" + ModuleNameJFrogTest}, []string{ModuleNameJFrogTest}, []int{6}}, 86 {"multireferencewithoutmodulechnage", "multireference", []string{projectType.String(), "restore"}, []string{"proj1", "proj2"}, []int{5, 3}}, 87 {"multireferencewithmodulechnage", "multireference", []string{projectType.String(), "restore", "--module=" + ModuleNameJFrogTest}, []string{ModuleNameJFrogTest}, []int{6}}, 88 {"multireferencewithslnpath", "multireference", []string{projectType.String(), "restore", "src/multireference.sln"}, []string{"proj1", "proj2"}, []int{5, 3}}, 89 {"multireferencewithslndir", "multireference", []string{projectType.String(), "restore", "src/"}, []string{"proj1", "proj2"}, []int{5, 3}}, 90 {"multireferencesingleprojectcsproj", "multireference", []string{projectType.String(), "restore", "src/multireference.proj2/proj2.csproj"}, []string{"proj2"}, []int{3}}, 91 }...) 92 for buildNumber, test := range testDescriptors { 93 projectPath := createNugetProject(t, test.project) 94 err := createConfigFileForTest([]string{projectPath}, tests.NugetRemoteRepo, "", t, projectType, false) 95 if err != nil { 96 assert.NoError(t, err) 97 return 98 } 99 t.Run(test.name, func(t *testing.T) { 100 testNugetCmd(t, projectPath, buildName, strconv.Itoa(buildNumber), test.expectedModules, test.args, test.expectedDependencies, true) 101 }) 102 } 103 cleanBuildToolsTest() 104 } 105 106 func createNugetProject(t *testing.T, projectName string) string { 107 projectSrc := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "nuget", projectName) 108 projectTarget := filepath.Join(tests.Out, projectName) 109 err := fileutils.CreateDirIfNotExist(projectTarget) 110 assert.NoError(t, err) 111 112 err = fileutils.CopyDir(projectSrc, projectTarget, true, nil) 113 assert.NoError(t, err) 114 return projectTarget 115 } 116 117 func TestNuGetWithGlobalConfig(t *testing.T) { 118 initNugetTest(t) 119 projectPath := createNugetProject(t, "packagesconfig") 120 jfrogHomeDir, err := coreutils.GetJfrogHomeDir() 121 assert.NoError(t, err) 122 err = createConfigFileForTest([]string{jfrogHomeDir}, tests.NugetRemoteRepo, "", t, utils.Nuget, true) 123 assert.NoError(t, err) 124 testNugetCmd(t, projectPath, tests.NuGetBuildName, "1", []string{"packagesconfig"}, []string{"nuget", "restore"}, []int{6}, true) 125 126 cleanBuildToolsTest() 127 } 128 129 func testNugetCmd(t *testing.T, projectPath, buildName, buildNumber string, expectedModule, args []string, expectedDependencies []int, native bool) { 130 wd, err := os.Getwd() 131 assert.NoError(t, err) 132 err = os.Chdir(projectPath) 133 assert.NoError(t, err) 134 args = append(args, "--build-name="+buildName, "--build-number="+buildNumber) 135 if native { 136 err = runNuGet(t, args...) 137 if err != nil { 138 return 139 } 140 } else { 141 assert.NoError(t, artifactoryCli.Exec(args...)) 142 } 143 inttestutils.ValidateGeneratedBuildInfoModule(t, buildName, buildNumber, "", expectedModule, buildinfo.Nuget) 144 assert.NoError(t, artifactoryCli.Exec("bp", buildName, buildNumber)) 145 146 publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) 147 if err != nil { 148 assert.NoError(t, err) 149 return 150 } 151 if !found { 152 assert.True(t, found, "build info was expected to be found") 153 return 154 } 155 buildInfo := publishedBuildInfo.BuildInfo 156 require.NotEmpty(t, buildInfo.Modules, buildName+" build info was not generated correctly, no modules were created.") 157 for i, module := range buildInfo.Modules { 158 assert.Equal(t, expectedModule[i], buildInfo.Modules[i].Id, "Unexpected module name") 159 assert.Len(t, module.Dependencies, expectedDependencies[i], "Incorrect number of artifacts found in the build-info") 160 } 161 assert.NoError(t, os.Chdir(wd)) 162 163 // cleanup 164 inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) 165 } 166 167 func runNuGet(t *testing.T, args ...string) error { 168 artifactoryNuGetCli := tests.NewJfrogCli(execMain, "jfrog rt", "") 169 err := artifactoryNuGetCli.Exec(args...) 170 assert.NoError(t, err) 171 return err 172 } 173 174 type testInitNewConfigDescriptor struct { 175 testName string 176 useNugetAddSource bool 177 useNugetV2 bool 178 expectedSourceUrl string 179 } 180 181 func TestInitNewConfig(t *testing.T) { 182 baseRtUrl := "http://some/url" 183 expectedV2Url := baseRtUrl + "/api/nuget" 184 expectedV3Url := baseRtUrl + "/api/nuget/v3" 185 testsSuites := []testInitNewConfigDescriptor{ 186 {"useNugetAddSourceV2", true, true, expectedV2Url}, 187 {"useNugetAddSourceV3", true, false, expectedV3Url}, 188 {"doNotUseNugetAddSourceV2", false, true, expectedV2Url}, 189 {"doNotUseNugetAddSourceV3", false, false, expectedV3Url}, 190 } 191 192 for _, test := range testsSuites { 193 t.Run(test.testName, func(t *testing.T) { 194 runInitNewConfig(t, test, baseRtUrl) 195 }) 196 } 197 } 198 199 func runInitNewConfig(t *testing.T, testSuite testInitNewConfigDescriptor, baseRtUrl string) { 200 initNugetTest(t) 201 202 tempDirPath, err := fileutils.CreateTempDir() 203 if err != nil { 204 assert.NoError(t, err) 205 return 206 } 207 defer fileutils.RemoveTempDir(tempDirPath) 208 209 params := &dotnet.DotnetCommand{} 210 params.SetServerDetails(&config.ServerDetails{ArtifactoryUrl: baseRtUrl, User: "user", Password: "password"}). 211 SetUseNugetAddSource(testSuite.useNugetAddSource).SetUseNugetV2(testSuite.useNugetV2) 212 // Prepare the config file with NuGet authentication 213 configFile, err := params.InitNewConfig(tempDirPath) 214 if err != nil { 215 assert.NoError(t, err) 216 return 217 } 218 219 content, err := os.ReadFile(configFile.Name()) 220 if err != nil { 221 assert.NoError(t, err) 222 return 223 } 224 225 nugetConfig := NugetConfig{} 226 err = xml.Unmarshal(content, &nugetConfig) 227 if err != nil { 228 assert.NoError(t, err, "unmarshalling failed with an error") 229 return 230 } 231 232 assert.Len(t, nugetConfig.PackageSources, 1) 233 234 for _, packageSource := range nugetConfig.PackageSources { 235 assert.Equal(t, dotnet.SourceName, packageSource.Key) 236 assert.Equal(t, testSuite.expectedSourceUrl, packageSource.Value) 237 } 238 assert.Len(t, nugetConfig.PackageSourceCredentials, 1) 239 assert.Len(t, nugetConfig.PackageSourceCredentials[0].JFrogCli, 2) 240 } 241 242 type NugetConfig struct { 243 XMLName xml.Name `xml:"configuration"` 244 PackageSources []PackageSources `xml:"packageSources>add"` 245 PackageSourceCredentials []PackageSourceCredentials `xml:"packageSourceCredentials"` 246 Apikeys []PackageSources `xml:"apikeys>add"` 247 } 248 249 type PackageSources struct { 250 Key string `xml:"key,attr"` 251 Value string `xml:"value,attr"` 252 } 253 254 type PackageSourceCredentials struct { 255 JFrogCli []PackageSources `xml:">add"` 256 }