github.com/jfrog/jfrog-cli-go@v1.22.1-0.20200318093948-4826ef344ffd/bintray_test.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "github.com/stretchr/testify/assert" 6 "io/ioutil" 7 "net/http" 8 "os" 9 "path" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/jfrog/jfrog-cli-go/utils/cliutils" 15 "github.com/jfrog/jfrog-cli-go/utils/config" 16 "github.com/jfrog/jfrog-cli-go/utils/ioutils" 17 "github.com/jfrog/jfrog-cli-go/utils/tests" 18 "github.com/jfrog/jfrog-client-go/httpclient" 19 "github.com/jfrog/jfrog-client-go/utils" 20 "github.com/jfrog/jfrog-client-go/utils/errorutils" 21 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 22 "github.com/jfrog/jfrog-client-go/utils/io/httputils" 23 "github.com/jfrog/jfrog-client-go/utils/log" 24 ) 25 26 var bintrayConfig *config.BintrayDetails 27 var bintrayCli *tests.JfrogCli 28 var bintrayOrganization string 29 30 func InitBintrayTests() { 31 initBintrayCredentials() 32 initBintrayOrg() 33 deleteBintrayRepo() 34 createBintrayRepo() 35 bintrayCli = tests.NewJfrogCli(execMain, "jfrog bt", "--user="+bintrayConfig.User+" --key="+bintrayConfig.Key) 36 } 37 38 func initBintrayOrg() { 39 bintrayOrganization = bintrayConfig.User 40 if *tests.BtOrg != "" { 41 bintrayOrganization = *tests.BtOrg 42 } 43 } 44 45 func TestBintrayPackages(t *testing.T) { 46 initBintrayTest(t) 47 48 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/testPackage" 49 bintrayCli.Exec("package-create", packagePath, "--licenses=Apache-2.0", "--vcs-url=vcs.url.com") 50 bintrayCli.Exec("package-show", packagePath) 51 bintrayCli.Exec("package-update", packagePath, "--licenses=GPL-3.0", "--vcs-url=other.url.com") 52 bintrayCli.Exec("package-delete", packagePath) 53 54 cleanBintrayTest() 55 } 56 57 func TestBintrayVersions(t *testing.T) { 58 initBintrayTest(t) 59 60 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/testPackage" 61 versionPath := packagePath + "/1.0" 62 63 bintrayCli.Exec("package-create", packagePath, "--licenses=Apache-2.0", "--vcs-url=vcs.url.com") 64 bintrayCli.Exec("version-create", versionPath, "--desc=versionDescription", "--vcs-tag=vcs.tag") 65 bintrayCli.Exec("version-show", versionPath) 66 bintrayCli.Exec("version-update", versionPath, "--desc=newVersionDescription", "--vcs-tag=new.vcs.tag") 67 bintrayCli.Exec("version-publish", versionPath) 68 bintrayCli.Exec("version-delete", versionPath) 69 bintrayCli.Exec("package-delete", packagePath) 70 71 cleanBintrayTest() 72 } 73 74 func TestBintraySimpleUpload(t *testing.T) { 75 initBintrayTest(t) 76 77 packageName := "simpleUploadPackage" 78 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/" + packageName 79 versionName := "1.0" 80 versionPath := packagePath + "/" + versionName 81 82 createPackageAndVersion(packagePath, versionPath) 83 //Upload file 84 fileName := "a1.in" 85 path := "some/path/in/bintray/" 86 uploadFilePath := tests.GetFilePathForBintray(fileName, tests.GetTestResourcesPath(), "a") 87 bintrayCli.Exec("upload", uploadFilePath, versionPath, path) 88 89 //Check file uploaded 90 expected := []tests.PackageSearchResultItem{{ 91 Repo: tests.BintrayRepo1, 92 Path: path + fileName, 93 Package: packageName, 94 Name: fileName, 95 Version: "1.0", 96 Sha1: "507ac63c6b0f650fb6f36b5621e70ebca3b0965c"}} 97 assertPackageFiles(expected, getPackageFiles(packageName), t) 98 99 bintrayCli.Exec("package-delete", packagePath) 100 cleanBintrayTest() 101 } 102 103 func TestBintrayUploadNoVersion(t *testing.T) { 104 initBintrayTest(t) 105 106 packageName := "simpleUploadPackage" 107 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/" + packageName 108 versionName := "1.0" 109 versionPath := packagePath + "/" + versionName 110 bintrayCli.Exec("package-create", packagePath, "--licenses=Apache-2.0", "--vcs-url=vcs.url.com") 111 112 //Upload file 113 fileName := "a1.in" 114 uploadFilePath := tests.GetFilePathForBintray(fileName, tests.GetTestResourcesPath(), "a") 115 bintrayCli.Exec("upload", uploadFilePath, versionPath) 116 117 //Check file uploaded 118 expected := []tests.PackageSearchResultItem{{ 119 Repo: tests.BintrayRepo1, 120 Path: fileName, 121 Package: packageName, 122 Name: fileName, 123 Version: "1.0", 124 Sha1: "507ac63c6b0f650fb6f36b5621e70ebca3b0965c"}} 125 assertPackageFiles(expected, getPackageFiles(packageName), t) 126 127 bintrayCli.Exec("package-delete", packagePath) 128 cleanBintrayTest() 129 } 130 131 func TestBintrayUploadFromHomeDir(t *testing.T) { 132 initBintrayTest(t) 133 filename := "cliTestFile.txt" 134 testFileRel := filepath.ToSlash(fileutils.GetHomeDir()) + "/cliTestFile.*" 135 testFileAbs := fileutils.GetHomeDir() + fileutils.GetFileSeparator() + filename 136 137 d1 := []byte("test file") 138 assert.NoError(t, ioutil.WriteFile(testFileAbs, d1, 0644), "Couldn't create file") 139 140 packageName := "simpleUploadHomePackage" 141 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/" + packageName 142 versionName := "1.0" 143 versionPath := packagePath + "/" + versionName 144 bintrayCli.Exec("package-create", packagePath, "--licenses=Apache-2.0", "--vcs-url=vcs.url.com") 145 bintrayCli.Exec("upload", testFileRel, versionPath, "--recursive=false") 146 147 //Check file uploaded 148 expected := []tests.PackageSearchResultItem{{ 149 Repo: tests.BintrayRepo1, 150 Path: filename, 151 Package: packageName, 152 Name: filename, 153 Version: "1.0", 154 Sha1: "8f93542443e98f41fe98e97d6d2a147193b1b005"}} 155 assertPackageFiles(expected, getPackageFiles(packageName), t) 156 157 os.Remove(testFileAbs) 158 bintrayCli.Exec("package-delete", packagePath) 159 cleanBintrayTest() 160 } 161 162 func TestBintrayUploadOverride(t *testing.T) { 163 initBintrayTest(t) 164 165 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/" + tests.BintrayUploadTestPackageName 166 versionPath := packagePath + "/" + tests.BintrayUploadTestVersion 167 createPackageAndVersion(packagePath, versionPath) 168 169 testResourcePath := tests.GetTestResourcesPath() 170 path := tests.GetFilePathForBintray("*", testResourcePath, "a") 171 bintrayCli.Exec("upload", path, versionPath, "--flat=true", "--recursive=false", "--publish=true") 172 assertPackageFiles(tests.BintrayExpectedUploadFlatNonRecursive, getPackageFiles(tests.BintrayUploadTestPackageName), t) 173 path = tests.GetFilePathForBintray("b1.in", testResourcePath, "a", "b") 174 bintrayCli.Exec("upload", path, versionPath, "a1.in", "--flat=true", "--recursive=false", "--override=true") 175 assertPackageFiles(tests.BintrayExpectedUploadFlatNonRecursiveModified, getPackageFiles(tests.BintrayUploadTestPackageName), t) 176 177 bintrayCli.Exec("package-delete", packagePath) 178 cleanBintrayTest() 179 } 180 181 func TestBintrayUploads(t *testing.T) { 182 initBintrayTest(t) 183 184 path := tests.GetFilePathForBintray("*", "", "a") 185 186 bintrayExpectedUploadNonFlatRecursive := tests.BintrayExpectedUploadNonFlatRecursive 187 bintrayExpectedUploadNonFlatNonRecursive := tests.BintrayExpectedUploadNonFlatNonRecursive 188 for i := range bintrayExpectedUploadNonFlatRecursive { 189 if strings.HasPrefix(bintrayExpectedUploadNonFlatRecursive[i].Path, "/") { 190 bintrayExpectedUploadNonFlatRecursive[i].Path = bintrayExpectedUploadNonFlatRecursive[i].Path[1:] 191 } 192 } 193 194 for i := range bintrayExpectedUploadNonFlatNonRecursive { 195 if strings.HasPrefix(bintrayExpectedUploadNonFlatNonRecursive[i].Path, "/") { 196 bintrayExpectedUploadNonFlatNonRecursive[i].Path = bintrayExpectedUploadNonFlatNonRecursive[i].Path[1:] 197 } 198 } 199 200 testBintrayUpload(t, path, "--flat=true --recursive=true", tests.BintrayExpectedUploadFlatRecursive) 201 testBintrayUpload(t, path, "--flat=true --recursive=false", tests.BintrayExpectedUploadFlatNonRecursive) 202 testBintrayUpload(t, path, "--flat=false --recursive=true", bintrayExpectedUploadNonFlatRecursive) 203 testBintrayUpload(t, path, "--flat=false --recursive=false", bintrayExpectedUploadNonFlatNonRecursive) 204 205 path = tests.GetFilePathForBintray("(.*)", "", "a") 206 testBintrayUpload(t, path, "--flat=true --recursive=true --regexp=true", tests.BintrayExpectedUploadFlatRecursive) 207 testBintrayUpload(t, path, "--flat=true --recursive=false --regexp=true", tests.BintrayExpectedUploadFlatNonRecursive) 208 testBintrayUpload(t, path, "--flat=false --recursive=true --regexp=true", bintrayExpectedUploadNonFlatRecursive) 209 testBintrayUpload(t, path, "--flat=false --recursive=false --regexp=true", bintrayExpectedUploadNonFlatNonRecursive) 210 211 cleanBintrayTest() 212 } 213 214 func TestBintrayLogs(t *testing.T) { 215 initBintrayTest(t) 216 217 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/" + tests.BintrayUploadTestPackageName 218 versionPath := packagePath + "/" + tests.BintrayUploadTestVersion 219 createPackageAndVersion(packagePath, versionPath) 220 221 path := tests.GetTestResourcesPath() + "a/*" 222 bintrayCli.Exec("upload", path, versionPath, "--flat=true --recursive=true --publish=true") 223 assertPackageFiles(tests.BintrayExpectedUploadFlatRecursive, getPackageFiles(tests.BintrayUploadTestPackageName), t) 224 bintrayCli.Exec("logs", packagePath) 225 226 bintrayCli.Exec("package-delete", packagePath) 227 cleanBintrayTest() 228 } 229 230 func TestBintrayFileDownloads(t *testing.T) { 231 initBintrayTest(t) 232 233 repositoryPath := bintrayOrganization + "/" + tests.BintrayRepo1 234 packagePath := repositoryPath + "/" + tests.BintrayUploadTestPackageName 235 versionPath := packagePath + "/" + tests.BintrayUploadTestVersion 236 createPackageAndVersion(packagePath, versionPath) 237 path := tests.GetFilePathForBintray("*", tests.GetTestResourcesPath(), "a") 238 bintrayCli.Exec("upload", path, versionPath, "--flat=true --recursive=true") 239 path = tests.GetFilePathForBintray("a1.in", tests.GetTestResourcesPath(), "a") 240 bintrayCli.Exec("upload", path, versionPath, "--flat=false") 241 242 // Define executor for testing with retries 243 var args []string 244 retryExecutor := utils.RetryExecutor{ 245 MaxRetries: 25, 246 RetriesInterval: 5, 247 ErrorMessage: "Waiting for bintray to index files...", 248 ExecutionHandler: func() (bool, error) { 249 // Execute Bintray downloads 250 err := bintrayCli.Exec(args...) 251 if err != nil { 252 return true, err 253 } 254 return false, nil 255 }, 256 } 257 258 // File a1.in 259 args = []string{"download-file", repositoryPath + "/a1.in", tests.Out + "/bintray/", "--unpublished=true"} 260 assert.NoError(t, retryExecutor.Execute()) 261 262 // File b1.in 263 args = []string{"download-file", repositoryPath + "/b1.in", tests.Out + "/bintray/x.in", "--unpublished=true"} 264 assert.NoError(t, retryExecutor.Execute()) 265 266 // File c1.in 267 args = []string{"download-file", repositoryPath + "/(c)1.in", tests.Out + "/bintray/z{1}.in", "--unpublished=true"} 268 assert.NoError(t, retryExecutor.Execute()) 269 270 // File a/a1.in 271 args = []string{"download-file", repositoryPath + "/" + tests.GetTestResourcesPath() + "(a)/a1.in", tests.Out + "/bintray/{1}/fullpatha1.in", "--flat=true --unpublished=true"} 272 assert.NoError(t, retryExecutor.Execute()) 273 274 //Validate that files were downloaded as expected 275 expected := []string{ 276 filepath.Join(tests.Out, "bintray", "a1.in"), 277 filepath.Join(tests.Out, "bintray", "x.in"), 278 filepath.Join(tests.Out, "bintray", "zc.in"), 279 filepath.Join(tests.Out, "bintray", "a", "fullpatha1.in"), 280 } 281 paths, _ := fileutils.ListFilesRecursiveWalkIntoDirSymlink(tests.Out+"/bintray/", false) 282 tests.VerifyExistLocally(expected, paths, t) 283 284 // Cleanup 285 bintrayCli.Exec("package-delete", packagePath) 286 cleanBintrayTest() 287 } 288 289 func TestBintrayVersionDownloads(t *testing.T) { 290 initBintrayTest(t) 291 292 repositoryPath := bintrayOrganization + "/" + tests.BintrayRepo1 293 packagePath := repositoryPath + "/" + tests.BintrayUploadTestPackageName 294 versionPath := packagePath + "/" + tests.BintrayUploadTestVersion 295 createPackageAndVersion(packagePath, versionPath) 296 297 path := tests.GetFilePathForBintray("*", tests.GetTestResourcesPath(), "a") 298 bintrayCli.Exec("upload", path, versionPath, "--flat=true --recursive=true") 299 bintrayCli.Exec("download-ver", versionPath, tests.Out+"/bintray/", "--unpublished=true") 300 301 paths, _ := fileutils.ListFilesRecursiveWalkIntoDirSymlink(tests.Out+"/bintray/", false) 302 expected := []string{ 303 filepath.Join(tests.Out, "bintray", "a1.in"), 304 filepath.Join(tests.Out, "bintray", "a2.in"), 305 filepath.Join(tests.Out, "bintray", "a3.in"), 306 filepath.Join(tests.Out, "bintray", "b1.in"), 307 filepath.Join(tests.Out, "bintray", "b2.in"), 308 filepath.Join(tests.Out, "bintray", "b3.in"), 309 filepath.Join(tests.Out, "bintray", "c1.in"), 310 filepath.Join(tests.Out, "bintray", "c2.in"), 311 filepath.Join(tests.Out, "bintray", "c3.in"), 312 } 313 tests.VerifyExistLocally(expected, paths, t) 314 bintrayCli.Exec("package-delete", packagePath) 315 cleanBintrayTest() 316 } 317 318 // Tests compatibility to file paths with windows separators. 319 func TestBintrayUploadWindowsCompatibility(t *testing.T) { 320 initBintrayTest(t) 321 if !cliutils.IsWindows() { 322 t.Skip("Not running on Windows, skipping...") 323 } 324 325 packageName := "simpleUploadPackage" 326 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/" + packageName 327 versionName := "1.0" 328 versionPath := packagePath + "/" + versionName 329 330 createPackageAndVersion(packagePath, versionPath) 331 //Upload file 332 fileName := "a1.in" 333 path := "some/path/in/bintray/" 334 uploadFilePath := ioutils.UnixToWinPathSeparator(tests.GetFilePathForBintray(fileName, tests.GetTestResourcesPath(), "a")) 335 bintrayCli.Exec("upload", uploadFilePath, versionPath, path) 336 337 //Check file uploaded 338 expected := []tests.PackageSearchResultItem{{ 339 Repo: tests.BintrayRepo1, 340 Path: path + fileName, 341 Package: packageName, 342 Name: fileName, 343 Version: "1.0", 344 Sha1: "507ac63c6b0f650fb6f36b5621e70ebca3b0965c"}} 345 assertPackageFiles(expected, getPackageFiles(packageName), t) 346 347 bintrayCli.Exec("package-delete", packagePath) 348 cleanBintrayTest() 349 } 350 351 func CleanBintrayTests() { 352 if !*tests.TestBintray { 353 return 354 } 355 deleteBintrayRepo() 356 } 357 358 func initBintrayTest(t *testing.T) { 359 if !*tests.TestBintray { 360 t.Skip("Bintray is not being tested, skipping...") 361 } 362 } 363 364 func initBintrayCredentials() { 365 if bintrayConfig != nil { 366 return 367 } 368 369 var err error 370 bintrayConfig, err = config.ReadBintrayConf() 371 if errorutils.CheckError(err) != nil { 372 os.Exit(1) 373 } 374 if *tests.BtUser != "" { 375 bintrayConfig.User = *tests.BtUser 376 } 377 if *tests.BtKey != "" { 378 bintrayConfig.Key = *tests.BtKey 379 } 380 381 if bintrayConfig.User == "" || bintrayConfig.Key == "" { 382 log.Error("To test Bintray credentials must be configured.") 383 os.Exit(1) 384 } 385 386 apiUrl := os.Getenv("JFROG_CLI_BINTRAY_API_URL") 387 if apiUrl == "" { 388 apiUrl = "https://bintray.com/api/v1/" 389 } 390 391 downloadServerUrl := os.Getenv("JFROG_CLI_BINTRAY_DOWNLOAD_URL") 392 if downloadServerUrl == "" { 393 downloadServerUrl = "https://dl.bintray.com/" 394 } 395 396 apiUrl = utils.AddTrailingSlashIfNeeded(apiUrl) 397 downloadServerUrl = utils.AddTrailingSlashIfNeeded(downloadServerUrl) 398 399 bintrayConfig.ApiUrl = apiUrl 400 bintrayConfig.DownloadServerUrl = downloadServerUrl 401 } 402 403 func cleanBintrayTest() { 404 tests.CleanFileSystem() 405 } 406 407 func testBintrayUpload(t *testing.T, relPath, flags string, expected []tests.PackageSearchResultItem) { 408 packagePath := bintrayOrganization + "/" + tests.BintrayRepo1 + "/" + tests.BintrayUploadTestPackageName 409 versionPath := packagePath + "/" + tests.BintrayUploadTestVersion 410 createPackageAndVersion(packagePath, versionPath) 411 412 bintrayCli.Exec("upload", tests.GetTestResourcesPath()+relPath, versionPath, flags) 413 assertPackageFiles(expected, getPackageFiles(tests.BintrayUploadTestPackageName), t) 414 bintrayCli.Exec("package-delete", packagePath) 415 } 416 417 func getPackageFiles(packageName string) []tests.PackageSearchResultItem { 418 apiUrl := bintrayConfig.ApiUrl + path.Join("packages", bintrayOrganization, tests.BintrayRepo1, packageName, "files?include_unpublished=1") 419 clientDetails := httputils.HttpClientDetails{ 420 User: bintrayConfig.User, 421 Password: bintrayConfig.Key, 422 Headers: map[string]string{"Content-Type": "application/json"}} 423 424 client, err := httpclient.ClientBuilder().Build() 425 if err != nil { 426 os.Exit(1) 427 } 428 resp, body, _, err := client.SendGet(apiUrl, true, clientDetails) 429 if errorutils.CheckError(err) != nil { 430 os.Exit(1) 431 } 432 if resp.StatusCode != http.StatusOK { 433 log.Error(resp.Status) 434 log.Error(string(body)) 435 os.Exit(1) 436 } 437 438 var result []tests.PackageSearchResultItem 439 err = json.Unmarshal(body, &result) 440 if err != nil { 441 log.Error(err) 442 os.Exit(1) 443 } 444 445 return result 446 } 447 448 func assertPackageFiles(expected, actual []tests.PackageSearchResultItem, t *testing.T) { 449 assert.Equal(t, len(expected), len(actual)) 450 451 expectedMap := make(map[string]tests.PackageSearchResultItem) 452 for _, v := range expected { 453 expectedMap[packageFileHash(v)] = v 454 } 455 456 actualMap := make(map[string]tests.PackageSearchResultItem) 457 for _, v := range actual { 458 actualMap[packageFileHash(v)] = v 459 } 460 461 for _, v := range actual { 462 _, ok := expectedMap[packageFileHash(v)] 463 assert.True(t, ok, "Unexpected file:", v) 464 } 465 for _, v := range expected { 466 _, ok := actualMap[packageFileHash(v)] 467 assert.True(t, ok, "File not found:", v) 468 } 469 } 470 471 func packageFileHash(item tests.PackageSearchResultItem) string { 472 return item.Repo + item.Path + item.Package + item.Version + item.Name + item.Sha1 473 } 474 475 func createPackageAndVersion(packagePath, versionPath string) { 476 bintrayCli.Exec("package-create", packagePath, "--licenses=Apache-2.0 --vcs-url=vcs.url.com") 477 bintrayCli.Exec("version-create", versionPath, "--desc=versionDescription --vcs-tag=vcs.tag") 478 } 479 480 func createBintrayRepo() { 481 content, err := ioutil.ReadFile(tests.GetTestResourcesPath() + tests.BintrayTestRepositoryConfig) 482 if errorutils.CheckError(err) != nil { 483 os.Exit(1) 484 } 485 486 apiUrl := bintrayConfig.ApiUrl + path.Join("repos", bintrayOrganization, tests.BintrayRepo1) 487 clientDetails := httputils.HttpClientDetails{ 488 User: bintrayConfig.User, 489 Password: bintrayConfig.Key, 490 Headers: map[string]string{"Content-Type": "application/json"}} 491 492 client, err := httpclient.ClientBuilder().Build() 493 if err != nil { 494 os.Exit(1) 495 } 496 resp, body, err := client.SendPost(apiUrl, content, clientDetails) 497 if errorutils.CheckError(err) != nil { 498 os.Exit(1) 499 } 500 501 if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusConflict { 502 log.Error(resp.Status) 503 log.Error(string(body)) 504 os.Exit(1) 505 } 506 } 507 508 func deleteBintrayRepo() { 509 apiUrl := bintrayConfig.ApiUrl + path.Join("repos", bintrayOrganization, tests.BintrayRepo1) 510 clientDetails := httputils.HttpClientDetails{ 511 User: bintrayConfig.User, 512 Password: bintrayConfig.Key, 513 Headers: map[string]string{"Content-Type": "application/json"}} 514 515 client, err := httpclient.ClientBuilder().Build() 516 if err != nil { 517 log.Error(err) 518 os.Exit(1) 519 } 520 resp, body, err := client.SendDelete(apiUrl, nil, clientDetails) 521 if errorutils.CheckError(err) != nil { 522 log.Error(err) 523 os.Exit(1) 524 } 525 526 if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNotFound { 527 log.Error(resp.Status) 528 log.Error(string(body)) 529 os.Exit(1) 530 } 531 }