github.com/jfrog/jfrog-client-go@v1.40.2/tests/distribution_test.go (about) 1 package tests 2 3 import ( 4 "encoding/json" 5 "fmt" 6 artifactoryServices "github.com/jfrog/jfrog-client-go/artifactory/services" 7 "github.com/jfrog/jfrog-client-go/artifactory/services/utils" 8 "github.com/jfrog/jfrog-client-go/distribution/services" 9 distributionServicesUtils "github.com/jfrog/jfrog-client-go/distribution/services/utils" 10 "github.com/jfrog/jfrog-client-go/http/httpclient" 11 "github.com/jfrog/jfrog-client-go/utils/distribution" 12 "github.com/jfrog/jfrog-client-go/utils/io/httputils" 13 "github.com/stretchr/testify/assert" 14 "net/http" 15 "os" 16 "path/filepath" 17 "strings" 18 "testing" 19 "time" 20 ) 21 22 type distributableDistributionStatus string 23 24 const ( 25 // Release bundle created and open for changes: 26 open distributableDistributionStatus = "OPEN" 27 // Release bundle is signed, but not stored: 28 signed distributableDistributionStatus = "SIGNED" 29 // Release bundle is signed and stored, but not scanned by Xray: 30 stored distributableDistributionStatus = "STORED" 31 // Release bundle is signed, stored and scanned by Xray: 32 readyForDistribution distributableDistributionStatus = "READY_FOR_DISTRIBUTION" 33 34 gpgKeyAlias = "client tests distribution key" 35 artifactoryGpgKeyCreatePattern = `{"alias":"` + gpgKeyAlias + `","public_key":"%s"}` 36 bundleVersion = "10" 37 ) 38 39 var httpClient *httpclient.HttpClient 40 var distHttpDetails httputils.HttpClientDetails 41 42 func TestDistributionServices(t *testing.T) { 43 initDistributionTest(t) 44 initClients(t) 45 sendGpgKeys(t) 46 47 // Local release bundle tests 48 t.Run("createDelete", createDelete) 49 t.Run("createUpdate", createUpdate) 50 t.Run("createWithProps", createWithProps) 51 52 // Remote release bundle tests 53 t.Run("createSignDistributeDelete", createSignDistributeDelete) 54 t.Run("createSignSyncDistributeDelete", createSignSyncDistributeDelete) 55 t.Run("createDistributeMapping", createDistributeMapping) 56 t.Run("createDistributeMappingFromPatternAndTarget", createDistributeMappingFromPatternAndTarget) 57 t.Run("createDistributeMappingWithPlaceholder", createDistributeMappingWithPlaceholder) 58 t.Run("createDistributeMappingFromPatternAndTargetWithPlaceholder", createDistributeMappingFromPatternAndTargetWithPlaceholder) 59 60 artifactoryCleanup(t) 61 deleteGpgKeys(t) 62 } 63 64 func initDistributionTest(t *testing.T) { 65 if !*TestDistribution { 66 t.Skip("Skipping distribution test. To run distribution test add the '-test.distribution=true' option.") 67 } 68 } 69 70 func initClients(t *testing.T) { 71 var err error 72 distHttpDetails = GetDistDetails().CreateHttpClientDetails() 73 httpClient, err = httpclient.ClientBuilder().Build() 74 assert.NoError(t, err) 75 } 76 77 func setupDistributionTest(t *testing.T, bundleName string) string { 78 artifactoryCleanup(t) 79 uploadDummyFile(t) 80 return bundleName 81 } 82 83 func initLocalDistributionTest(t *testing.T, bundleName string) string { 84 return setupDistributionTest(t, bundleName) 85 } 86 87 func initRemoteDistributionTest(t *testing.T, bundleName string) string { 88 testsBundleDistributeService.Sync = false 89 return setupDistributionTest(t, bundleName) 90 } 91 92 func createDelete(t *testing.T) { 93 bundleName := initLocalDistributionTest(t, "client-test-bundle-"+getRunId()) 94 95 // Create signed release bundle 96 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 97 createBundleParams.SignImmediately = true 98 createBundleParams.SpecFiles = []*utils.CommonParams{{Pattern: getRtTargetRepo() + "b.in"}} 99 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 100 if !assert.NoError(t, err) { 101 return 102 } 103 defer deleteLocalBundle(t, bundleName, true) 104 assert.NotNil(t, summary) 105 verifyValidSha256(t, summary.GetSha256()) 106 distributionResponse := getLocalBundle(t, bundleName, true) 107 if assert.NotNil(t, distributionResponse) { 108 assertReleaseBundleSigned(t, distributionResponse.State) 109 } 110 } 111 112 func createUpdate(t *testing.T) { 113 bundleName := initLocalDistributionTest(t, "client-test-bundle-"+getRunId()) 114 115 // Create release bundle params 116 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 117 createBundleParams.Description = "Release bundle description 1" 118 createBundleParams.ReleaseNotes = "Release notes 1" 119 createBundleParams.SpecFiles = []*utils.CommonParams{{Pattern: getRtTargetRepo() + "b.in"}} 120 121 // Test DryRun first 122 err := createDryRun(createBundleParams) 123 if !assert.NoError(t, err) { 124 return 125 } 126 // Verify was not created. 127 getLocalBundle(t, bundleName, false) 128 129 // Redefine specFiles to create params from scratch 130 createBundleParams.SpecFiles[0] = &utils.CommonParams{Pattern: getRtTargetRepo() + "b.in"} 131 132 // Create unsigned release bundle 133 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 134 if !assert.NoError(t, err) { 135 return 136 } 137 defer deleteLocalBundle(t, bundleName, true) 138 assert.Nil(t, summary) 139 distributionResponse := assertCreatedLocalBundle(t, bundleName, createBundleParams) 140 spec := distributionResponse.BundleSpec 141 142 // Create update release bundle params 143 updateBundleParams := services.NewUpdateReleaseBundleParams(bundleName, bundleVersion) 144 updateBundleParams.Description = "Release bundle description 2" 145 updateBundleParams.ReleaseNotes = "Release notes 2" 146 updateBundleParams.SpecFiles = []*utils.CommonParams{{Pattern: getRtTargetRepo() + "test/a.in"}} 147 updateBundleParams.SignImmediately = false 148 // Test DryRun first 149 err = updateDryRun(updateBundleParams) 150 if !assert.NoError(t, err) { 151 return 152 } 153 // Verify the release bundle was not updated. 154 assertCreatedLocalBundle(t, bundleName, createBundleParams) 155 156 // Redefine specFiles to create params from scratch 157 updateBundleParams.SpecFiles[0] = &utils.CommonParams{Pattern: getRtTargetRepo() + "test/a.in"} 158 159 summary, err = testsBundleUpdateService.UpdateReleaseBundle(updateBundleParams) 160 if !assert.NoError(t, err) { 161 return 162 } 163 assert.Nil(t, summary) 164 distributionResponse = getLocalBundle(t, bundleName, true) 165 assert.Equal(t, open, distributionResponse.State) 166 assert.Equal(t, updateBundleParams.Description, distributionResponse.Description) 167 assert.Equal(t, updateBundleParams.ReleaseNotes, distributionResponse.ReleaseNotes.Content) 168 assert.NotEqual(t, spec, distributionResponse.BundleSpec) 169 } 170 171 func assertCreatedLocalBundle(t *testing.T, bundleName string, createBundleParams services.CreateReleaseBundleParams) *distributableResponse { 172 distributionResponse := getLocalBundle(t, bundleName, true) 173 assert.Equal(t, open, distributionResponse.State) 174 assert.Equal(t, createBundleParams.Description, distributionResponse.Description) 175 assert.Equal(t, createBundleParams.ReleaseNotes, distributionResponse.ReleaseNotes.Content) 176 return distributionResponse 177 } 178 179 func createDryRun(createBundleParams services.CreateReleaseBundleParams) error { 180 defer setServicesToDryRunFalse() 181 testsBundleCreateService.DryRun = true 182 _, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 183 return err 184 } 185 186 func updateDryRun(updateBundleParams services.UpdateReleaseBundleParams) error { 187 defer setServicesToDryRunFalse() 188 testsBundleUpdateService.DryRun = true 189 _, err := testsBundleUpdateService.UpdateReleaseBundle(updateBundleParams) 190 return err 191 } 192 193 func distributeDryRun(distributionParams distribution.DistributionParams) error { 194 defer setServicesToDryRunFalse() 195 testsBundleDistributeService.DryRun = true 196 testsBundleDistributeService.AutoCreateRepo = true 197 testsBundleDistributeService.DistributeParams = distributionParams 198 return testsBundleDistributeService.Distribute() 199 } 200 201 func setServicesToDryRunFalse() { 202 testsBundleCreateService.DryRun = false 203 testsBundleUpdateService.DryRun = false 204 testsBundleDistributeService.DryRun = false 205 } 206 207 func createWithProps(t *testing.T) { 208 bundleName := initLocalDistributionTest(t, "client-test-bundle-"+getRunId()) 209 210 // Create release bundle with properties 211 targetProps, err := utils.ParseProperties("key1=value1;key2=value2,value3") 212 assert.NoError(t, err) 213 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 214 createBundleParams.SpecFiles = []*utils.CommonParams{{ 215 Pattern: getRtTargetRepo() + "b.in", 216 TargetProps: targetProps, 217 }} 218 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 219 if !assert.NoError(t, err) { 220 return 221 } 222 defer deleteLocalBundle(t, bundleName, true) 223 assert.Nil(t, summary) 224 225 // Check results 226 distributionResponse := getLocalBundle(t, bundleName, true) 227 addedProps := distributionResponse.BundleSpec.Queries[0].AddedProps 228 assert.Len(t, addedProps, 2) 229 230 // Populate prop1Values and prop2Values 231 var prop1Values []string 232 var prop2Values []string 233 switch addedProps[0].Key { 234 case "key1": 235 assert.Equal(t, "key2", addedProps[1].Key) 236 prop1Values = addedProps[0].Values 237 prop2Values = addedProps[1].Values 238 case "key2": 239 assert.Equal(t, "key1", addedProps[1].Key) 240 prop1Values = addedProps[1].Values 241 prop2Values = addedProps[0].Values 242 default: 243 assert.Fail(t, "Unexpected key", addedProps[0].Key) 244 } 245 246 // Check prop1Values and prop2Values 247 assert.Len(t, prop1Values, 1) 248 assert.Len(t, prop2Values, 2) 249 if len(prop1Values) == 1 { 250 assert.Equal(t, "value1", prop1Values[0]) 251 } 252 if len(prop2Values) == 2 { 253 assert.Equal(t, "value2", prop2Values[0]) 254 assert.Equal(t, "value3", prop2Values[1]) 255 } 256 } 257 258 func createSignDistributeDelete(t *testing.T) { 259 bundleName := initRemoteDistributionTest(t, "client-test-bundle-"+getRunId()) 260 261 // Create unsigned release bundle 262 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 263 createBundleParams.SpecFiles = []*utils.CommonParams{{Pattern: getRtTargetRepo() + "b.in"}} 264 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 265 if !assert.NoError(t, err) { 266 return 267 } 268 defer deleteRemoteAndLocalBundle(t, bundleName) 269 assert.Nil(t, summary) 270 distributionResponse := getLocalBundle(t, bundleName, true) 271 assert.Equal(t, open, distributionResponse.State) 272 273 // Sign release bundle 274 signBundleParams := services.NewSignBundleParams(bundleName, bundleVersion) 275 summary, err = testsBundleSignService.SignReleaseBundle(signBundleParams) 276 if !assert.NoError(t, err) { 277 return 278 } 279 assert.NotNil(t, summary) 280 verifyValidSha256(t, summary.GetSha256()) 281 distributionResponse = getLocalBundle(t, bundleName, true) 282 assertReleaseBundleSigned(t, distributionResponse.State) 283 284 // Create distribute params. 285 distributeBundleParams := distribution.NewDistributeReleaseBundleParams(bundleName, bundleVersion) 286 distributeBundleParams.DistributionRules = []*distribution.DistributionCommonParams{{SiteName: "*"}} 287 288 // Create response params. 289 distributionStatusParams := services.DistributionStatusParams{ 290 Name: bundleName, 291 Version: bundleVersion, 292 } 293 294 // Test DryRun first. 295 err = distributeDryRun(distributeBundleParams) 296 if !assert.NoError(t, err) { 297 return 298 } 299 // Assert release bundle not in distribution yet. 300 response, err := testsBundleDistributionStatusService.GetStatus(distributionStatusParams) 301 assert.NoError(t, err) 302 assert.Len(t, *response, 0) 303 304 // Distribute release bundle 305 testsBundleDistributeService.AutoCreateRepo = true 306 testsBundleDistributeService.DistributeParams = distributeBundleParams 307 err = testsBundleDistributeService.Distribute() 308 assert.NoError(t, err) 309 waitForDistribution(t, bundleName) 310 311 // Assert release bundle in "completed" status 312 response, err = testsBundleDistributionStatusService.GetStatus(distributionStatusParams) 313 if assert.NoError(t, err) && assert.NotEmpty(t, *response) { 314 assert.Equal(t, distribution.Completed, (*response)[0].Status) 315 } 316 } 317 318 func createSignSyncDistributeDelete(t *testing.T) { 319 bundleName := initRemoteDistributionTest(t, "client-test-bundle-"+getRunId()) 320 321 // Create unsigned release bundle 322 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 323 createBundleParams.SpecFiles = []*utils.CommonParams{{Pattern: getRtTargetRepo() + "b.in"}} 324 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 325 if !assert.NoError(t, err) { 326 return 327 } 328 defer deleteRemoteAndLocalBundle(t, bundleName) 329 assert.Nil(t, summary) 330 distributionResponse := getLocalBundle(t, bundleName, true) 331 assert.Equal(t, open, distributionResponse.State) 332 333 // Sign release bundle 334 signBundleParams := services.NewSignBundleParams(bundleName, bundleVersion) 335 summary, err = testsBundleSignService.SignReleaseBundle(signBundleParams) 336 if !assert.NoError(t, err) { 337 return 338 } 339 assert.NotNil(t, summary) 340 verifyValidSha256(t, summary.GetSha256()) 341 distributionResponse = getLocalBundle(t, bundleName, true) 342 assertReleaseBundleSigned(t, distributionResponse.State) 343 344 // Distribute release bundle 345 distributeBundleParams := distribution.NewDistributeReleaseBundleParams(bundleName, bundleVersion) 346 distributeBundleParams.DistributionRules = []*distribution.DistributionCommonParams{{SiteName: "*"}} 347 testsBundleDistributeService.Sync = true 348 testsBundleDistributeService.AutoCreateRepo = true 349 testsBundleDistributeService.DistributeParams = distributeBundleParams 350 err = testsBundleDistributeService.Distribute() 351 assert.NoError(t, err) 352 353 // Assert release bundle in "completed" status 354 distributionStatusParams := services.DistributionStatusParams{ 355 Name: bundleName, 356 Version: bundleVersion, 357 } 358 response, err := testsBundleDistributionStatusService.GetStatus(distributionStatusParams) 359 if assert.NoError(t, err) && assert.NotEmpty(t, *response) { 360 assert.Equal(t, distribution.Completed, (*response)[0].Status) 361 } 362 } 363 364 func createDistributeMapping(t *testing.T) { 365 bundleName := initRemoteDistributionTest(t, "client-test-bundle-"+getRunId()) 366 367 // Create release bundle with path mapping from <RtTargetRepo>/b.in to <RtTargetRepo>/b.out 368 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 369 createBundleParams.SpecFiles = []*utils.CommonParams{ 370 { 371 Aql: utils.Aql{ 372 ItemsFind: "{\"$or\":[{\"$and\":[{\"repo\":{\"$match\":\"" + strings.TrimSuffix(getRtTargetRepo(), "/") + "\"},\"name\":{\"$match\":\"b.in\"}}]}]}", 373 }, 374 PathMapping: utils.PathMapping{ 375 Input: getRtTargetRepo() + "b.in", 376 Output: getRtTargetRepo() + "b.out", 377 }, 378 }, 379 } 380 createBundleParams.SignImmediately = true 381 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 382 assert.NoError(t, err) 383 384 defer deleteRemoteAndLocalBundle(t, bundleName) 385 assert.NotNil(t, summary) 386 verifyValidSha256(t, summary.GetSha256()) 387 388 // Distribute release bundle 389 distributeBundleParams := distribution.NewDistributeReleaseBundleParams(bundleName, bundleVersion) 390 distributeBundleParams.DistributionRules = []*distribution.DistributionCommonParams{{SiteName: "*"}} 391 testsBundleDistributeService.Sync = true 392 // On distribution with path mapping, the target repository cannot be auto-created 393 testsBundleDistributeService.AutoCreateRepo = false 394 testsBundleDistributeService.DistributeParams = distributeBundleParams 395 err = testsBundleDistributeService.Distribute() 396 assert.NoError(t, err) 397 398 // Distribute release bundle 399 assertReleaseBundleDistribution(t, bundleName) 400 401 // Make sure <RtTargetRepo>/b.out does exist in Artifactory 402 assertFileExistsInArtifactory(t, getRtTargetRepo()+"b.out") 403 } 404 405 func createDistributeMappingFromPatternAndTarget(t *testing.T) { 406 bundleName := initRemoteDistributionTest(t, "client-test-bundle-"+getRunId()) 407 408 // Create release bundle with path mapping from <RtTargetRepo>/b.in to <RtTargetRepo>/b.out 409 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 410 createBundleParams.SpecFiles = []*utils.CommonParams{{Pattern: getRtTargetRepo() + "b.in", Target: getRtTargetRepo() + "b.out"}} 411 createBundleParams.SignImmediately = true 412 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 413 assert.NoError(t, err) 414 415 defer deleteRemoteAndLocalBundle(t, bundleName) 416 assert.NotNil(t, summary) 417 verifyValidSha256(t, summary.GetSha256()) 418 419 // Distribute release bundle 420 assertReleaseBundleDistribution(t, bundleName) 421 422 // Make sure <RtTargetRepo>/b.out does exist in Artifactory 423 assertFileExistsInArtifactory(t, getRtTargetRepo()+"b.out") 424 } 425 426 func createDistributeMappingWithPlaceholder(t *testing.T) { 427 bundleName := initRemoteDistributionTest(t, "client-test-bundle-"+getRunId()) 428 429 // Create release bundle with path mapping from <RtTargetRepo>/b.in to <RtTargetRepo>/b.out 430 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 431 createBundleParams.SpecFiles = []*utils.CommonParams{ 432 { 433 Aql: utils.Aql{ 434 ItemsFind: "{\"$or\":[{\"$and\":[{\"repo\":{\"$match\":\"" + strings.TrimSuffix(getRtTargetRepo(), "/") + "\"},\"name\":{\"$match\":\"*.in\"}}]}]}", 435 }, 436 PathMapping: utils.PathMapping{ 437 Input: "(" + getRtTargetRepo() + ")" + "(.*).in", 438 Output: "$1$2.out", 439 }, 440 }, 441 } 442 443 createBundleParams.SignImmediately = true 444 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 445 assert.NoError(t, err) 446 447 defer deleteRemoteAndLocalBundle(t, bundleName) 448 assert.NotNil(t, summary) 449 verifyValidSha256(t, summary.GetSha256()) 450 451 // Distribute release bundle 452 assertReleaseBundleDistribution(t, bundleName) 453 454 // Make sure <RtTargetRepo>/b.out does exist in Artifactory 455 assertFileExistsInArtifactory(t, getRtTargetRepo()+"b.out") 456 } 457 458 func createDistributeMappingFromPatternAndTargetWithPlaceholder(t *testing.T) { 459 bundleName := initRemoteDistributionTest(t, "client-test-bundle-"+getRunId()) 460 461 // Create release bundle with path mapping from <RtTargetRepo>/b.in to <RtTargetRepo>/b.out 462 createBundleParams := services.NewCreateReleaseBundleParams(bundleName, bundleVersion) 463 createBundleParams.SpecFiles = []*utils.CommonParams{{Pattern: "(" + getRtTargetRepo() + ")" + "(*).in", Target: "{1}{2}.out"}} 464 createBundleParams.SignImmediately = true 465 summary, err := testsBundleCreateService.CreateReleaseBundle(createBundleParams) 466 assert.NoError(t, err) 467 468 defer deleteRemoteAndLocalBundle(t, bundleName) 469 assert.NotNil(t, summary) 470 verifyValidSha256(t, summary.GetSha256()) 471 472 // Distribute release bundle 473 assertReleaseBundleDistribution(t, bundleName) 474 475 // Make sure <RtTargetRepo>/b.out does exist in Artifactory 476 assertFileExistsInArtifactory(t, getRtTargetRepo()+"b.out") 477 } 478 479 // Send GPG keys to Distribution and Artifactory to allow signing of release bundles 480 func sendGpgKeys(t *testing.T) { 481 // Read gpg public and private key 482 publicKey, err := os.ReadFile(filepath.Join(getTestDataPath(), "public.key")) 483 assert.NoError(t, err) 484 privateKey, err := os.ReadFile(filepath.Join(getTestDataPath(), "private.key")) 485 assert.NoError(t, err) 486 487 err = testsBundleSetSigningKeyService.SetSigningKey(services.NewSetSigningKeyParams(string(publicKey), string(privateKey))) 488 assert.NoError(t, err) 489 490 // Send public key to Artifactory 491 content := fmt.Sprintf(artifactoryGpgKeyCreatePattern, publicKey) 492 resp, body, err := httpClient.SendPost(GetRtDetails().GetUrl()+"api/security/keys/trusted", []byte(content), distHttpDetails, "") 493 assert.NoError(t, err) 494 if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusConflict { 495 t.Error(resp.Status) 496 t.Error(string(body)) 497 } 498 } 499 500 // Delete GPG key from Artifactory to clean up the test environment 501 func deleteGpgKeys(t *testing.T) { 502 // Delete public key from Artifactory 503 gpgKeyId := getGpgKeyId(t) 504 if gpgKeyId == "" { 505 return 506 } 507 resp, body, err := httpClient.SendDelete(GetRtDetails().GetUrl()+"api/security/keys/trusted/"+gpgKeyId, nil, distHttpDetails, "") 508 assert.NoError(t, err) 509 if resp.StatusCode != http.StatusNoContent { 510 t.Error(resp.Status) 511 t.Error(string(body)) 512 } 513 } 514 515 // Get GPG key ID created in the tests 516 func getGpgKeyId(t *testing.T) string { 517 resp, body, _, err := httpClient.SendGet(GetRtDetails().GetUrl()+"api/security/keys/trusted", true, distHttpDetails, "") 518 assert.NoError(t, err) 519 if resp.StatusCode != http.StatusOK { 520 t.Error(resp.Status) 521 t.Error(string(body)) 522 return "" 523 } 524 responses := &gpgKeysResponse{} 525 err = json.Unmarshal(body, &responses) 526 assert.NoError(t, err) 527 for _, gpgKeyResponse := range responses.Keys { 528 if gpgKeyResponse.Alias == gpgKeyAlias { 529 return gpgKeyResponse.Kid 530 } 531 } 532 return "" 533 } 534 535 func assertReleaseBundleSigned(t *testing.T, status distributableDistributionStatus) { 536 assert.Contains(t, []distributableDistributionStatus{signed, stored, readyForDistribution}, status) 537 } 538 539 // Wait for distribution of a release bundle 540 func waitForDistribution(t *testing.T, bundleName string) { 541 distributionStatusParams := services.DistributionStatusParams{ 542 Name: bundleName, 543 Version: bundleVersion, 544 } 545 for i := 0; i < 120; i++ { 546 response, err := testsBundleDistributionStatusService.GetStatus(distributionStatusParams) 547 if assert.NoError(t, err) { 548 assert.Len(t, *response, 1) 549 550 switch (*response)[0].Status { 551 case distribution.Completed: 552 return 553 case distribution.Failed: 554 t.Error("Distribution failed for " + bundleName + "/" + bundleVersion) 555 return 556 case distribution.InProgress, distribution.NotDistributed: 557 // Wait 558 } 559 t.Log("Waiting for " + bundleName + "/" + bundleVersion + "...") 560 time.Sleep(time.Second) 561 } 562 } 563 t.Error("Timeout for release bundle distribution " + bundleName + "/" + bundleVersion) 564 } 565 566 type distributableResponse struct { 567 distributionServicesUtils.ReleaseBundleBody 568 Name string `json:"name,omitempty"` 569 Version string `json:"version,omitempty"` 570 State distributableDistributionStatus `json:"state,omitempty"` 571 } 572 573 type gpgKeysResponse struct { 574 Keys []gpgKeyResponse `json:"keys,omitempty"` 575 } 576 577 type gpgKeyResponse struct { 578 Kid string `json:"kid,omitempty"` 579 Alias string `json:"alias,omitempty"` 580 } 581 582 func getLocalBundle(t *testing.T, bundleName string, expectExist bool) *distributableResponse { 583 resp, body, _, err := httpClient.SendGet(GetDistDetails().GetUrl()+"api/v1/release_bundle/"+bundleName+"/"+bundleVersion, true, distHttpDetails, "") 584 assert.NoError(t, err) 585 if !expectExist { 586 assert.Equal(t, http.StatusNotFound, resp.StatusCode) 587 return nil 588 } 589 if resp.StatusCode != http.StatusOK { 590 t.Error(resp.Status) 591 t.Error(string(body)) 592 return nil 593 } 594 response := &distributableResponse{} 595 err = json.Unmarshal(body, &response) 596 assert.NoError(t, err) 597 return response 598 } 599 600 func deleteLocalBundle(t *testing.T, bundleName string, assertDeletion bool) { 601 deleteLocalBundleParams := services.NewDeleteReleaseBundleParams(bundleName, bundleVersion) 602 testsBundleDeleteLocalService.Sync = true 603 err := testsBundleDeleteLocalService.DeleteDistribution(deleteLocalBundleParams) 604 if !assertDeletion { 605 return 606 } 607 assert.NoError(t, err) 608 distributionResponse := getLocalBundle(t, bundleName, false) 609 assert.Nil(t, distributionResponse) 610 } 611 612 func deleteRemoteAndLocalBundle(t *testing.T, bundleName string) { 613 deleteBundleParams := services.NewDeleteReleaseBundleParams(bundleName, bundleVersion) 614 // Delete also local release bundle 615 deleteBundleParams.DeleteFromDistribution = true 616 deleteBundleParams.DistributionRules = []*distribution.DistributionCommonParams{{SiteName: "*"}} 617 deleteBundleParams.Sync = true 618 err := testsBundleDeleteRemoteService.DeleteDistribution(deleteBundleParams) 619 artifactoryCleanup(t) 620 assert.NoError(t, err) 621 } 622 623 func assertFileExistsInArtifactory(t *testing.T, filePath string) { 624 searchParams := artifactoryServices.NewSearchParams() 625 searchParams.Pattern = filePath 626 reader, err := testsSearchService.Search(searchParams) 627 assert.NoError(t, err) 628 readerCloseAndAssert(t, reader) 629 length, err := reader.Length() 630 assert.NoError(t, err) 631 assert.Equal(t, 1, length) 632 } 633 634 func assertReleaseBundleDistribution(t *testing.T, bundleName string) { 635 // Distribute release bundle 636 distributeBundleParams := distribution.NewDistributeReleaseBundleParams(bundleName, bundleVersion) 637 distributeBundleParams.DistributionRules = []*distribution.DistributionCommonParams{{SiteName: "*"}} 638 testsBundleDistributeService.Sync = true 639 // On distribution with path mapping, the target repository cannot be auto-created 640 testsBundleDistributeService.AutoCreateRepo = false 641 testsBundleDistributeService.DistributeParams = distributeBundleParams 642 err := testsBundleDistributeService.Distribute() 643 assert.NoError(t, err) 644 }