github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/actor/v3action/package_test.go (about) 1 package v3action_test 2 3 import ( 4 "errors" 5 "io" 6 "io/ioutil" 7 "os" 8 "strings" 9 10 "code.cloudfoundry.org/cli/actor/actionerror" 11 "code.cloudfoundry.org/cli/actor/sharedaction" 12 . "code.cloudfoundry.org/cli/actor/v3action" 13 "code.cloudfoundry.org/cli/actor/v3action/v3actionfakes" 14 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 15 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 16 17 . "github.com/onsi/ginkgo" 18 . "github.com/onsi/ginkgo/extensions/table" 19 . "github.com/onsi/gomega" 20 . "github.com/onsi/gomega/gstruct" 21 ) 22 23 var _ = Describe("Package Actions", func() { 24 var ( 25 actor *Actor 26 fakeCloudControllerClient *v3actionfakes.FakeCloudControllerClient 27 fakeSharedActor *v3actionfakes.FakeSharedActor 28 fakeConfig *v3actionfakes.FakeConfig 29 ) 30 31 BeforeEach(func() { 32 fakeCloudControllerClient = new(v3actionfakes.FakeCloudControllerClient) 33 fakeConfig = new(v3actionfakes.FakeConfig) 34 fakeSharedActor = new(v3actionfakes.FakeSharedActor) 35 actor = NewActor(fakeCloudControllerClient, fakeConfig, fakeSharedActor, nil) 36 }) 37 38 Describe("GetApplicationPackages", func() { 39 When("there are no client errors", func() { 40 BeforeEach(func() { 41 fakeCloudControllerClient.GetApplicationsReturns( 42 []ccv3.Application{ 43 {GUID: "some-app-guid"}, 44 }, 45 ccv3.Warnings{"get-applications-warning"}, 46 nil, 47 ) 48 49 fakeCloudControllerClient.GetPackagesReturns( 50 []ccv3.Package{ 51 { 52 GUID: "some-package-guid-1", 53 State: constant.PackageReady, 54 CreatedAt: "2017-08-14T21:16:42Z", 55 }, 56 { 57 GUID: "some-package-guid-2", 58 State: constant.PackageFailed, 59 CreatedAt: "2017-08-16T00:18:24Z", 60 }, 61 }, 62 ccv3.Warnings{"get-application-packages-warning"}, 63 nil, 64 ) 65 }) 66 67 It("gets the app's packages", func() { 68 packages, warnings, err := actor.GetApplicationPackages("some-app-name", "some-space-guid") 69 70 Expect(err).ToNot(HaveOccurred()) 71 Expect(warnings).To(ConsistOf("get-applications-warning", "get-application-packages-warning")) 72 Expect(packages).To(Equal([]Package{ 73 { 74 GUID: "some-package-guid-1", 75 State: constant.PackageReady, 76 CreatedAt: "2017-08-14T21:16:42Z", 77 }, 78 { 79 GUID: "some-package-guid-2", 80 State: constant.PackageFailed, 81 CreatedAt: "2017-08-16T00:18:24Z", 82 }, 83 })) 84 85 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 86 Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf( 87 ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app-name"}}, 88 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}}, 89 )) 90 91 Expect(fakeCloudControllerClient.GetPackagesCallCount()).To(Equal(1)) 92 Expect(fakeCloudControllerClient.GetPackagesArgsForCall(0)).To(ConsistOf( 93 ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{"some-app-guid"}}, 94 )) 95 }) 96 }) 97 98 When("getting the application fails", func() { 99 var expectedErr error 100 101 BeforeEach(func() { 102 expectedErr = errors.New("some get application error") 103 104 fakeCloudControllerClient.GetApplicationsReturns( 105 []ccv3.Application{}, 106 ccv3.Warnings{"get-applications-warning"}, 107 expectedErr, 108 ) 109 }) 110 111 It("returns the error", func() { 112 _, warnings, err := actor.GetApplicationPackages("some-app-name", "some-space-guid") 113 114 Expect(err).To(Equal(expectedErr)) 115 Expect(warnings).To(ConsistOf("get-applications-warning")) 116 }) 117 }) 118 119 When("getting the application packages fails", func() { 120 var expectedErr error 121 122 BeforeEach(func() { 123 expectedErr = errors.New("some get application error") 124 125 fakeCloudControllerClient.GetApplicationsReturns( 126 []ccv3.Application{ 127 {GUID: "some-app-guid"}, 128 }, 129 ccv3.Warnings{"get-applications-warning"}, 130 nil, 131 ) 132 133 fakeCloudControllerClient.GetPackagesReturns( 134 []ccv3.Package{}, 135 ccv3.Warnings{"get-application-packages-warning"}, 136 expectedErr, 137 ) 138 }) 139 140 It("returns the error", func() { 141 _, warnings, err := actor.GetApplicationPackages("some-app-name", "some-space-guid") 142 143 Expect(err).To(Equal(expectedErr)) 144 Expect(warnings).To(ConsistOf("get-applications-warning", "get-application-packages-warning")) 145 }) 146 }) 147 }) 148 149 Describe("CreateDockerPackageByApplicationNameAndSpace", func() { 150 var ( 151 dockerPackage Package 152 warnings Warnings 153 executeErr error 154 ) 155 156 JustBeforeEach(func() { 157 dockerPackage, warnings, executeErr = actor.CreateDockerPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", DockerImageCredentials{Path: "some-docker-image", Password: "some-password", Username: "some-username"}) 158 }) 159 160 When("the application can't be retrieved", func() { 161 BeforeEach(func() { 162 fakeCloudControllerClient.GetApplicationsReturns( 163 []ccv3.Application{}, 164 ccv3.Warnings{"some-app-warning"}, 165 errors.New("some-app-error"), 166 ) 167 }) 168 169 It("returns the error and all warnings", func() { 170 Expect(executeErr).To(MatchError("some-app-error")) 171 Expect(warnings).To(ConsistOf("some-app-warning")) 172 }) 173 }) 174 175 When("the application can be retrieved", func() { 176 BeforeEach(func() { 177 fakeCloudControllerClient.GetApplicationsReturns( 178 []ccv3.Application{ 179 { 180 Name: "some-app-name", 181 GUID: "some-app-guid", 182 }, 183 }, 184 ccv3.Warnings{"some-app-warning"}, 185 nil, 186 ) 187 }) 188 189 When("creating the package fails", func() { 190 BeforeEach(func() { 191 fakeCloudControllerClient.CreatePackageReturns( 192 ccv3.Package{}, 193 ccv3.Warnings{"some-create-package-warning"}, 194 errors.New("some-create-package-error"), 195 ) 196 }) 197 It("fails to create the package", func() { 198 Expect(executeErr).To(MatchError("some-create-package-error")) 199 Expect(warnings).To(ConsistOf("some-app-warning", "some-create-package-warning")) 200 }) 201 }) 202 203 When("creating the package succeeds", func() { 204 BeforeEach(func() { 205 createdPackage := ccv3.Package{ 206 DockerImage: "some-docker-image", 207 DockerUsername: "some-username", 208 DockerPassword: "some-password", 209 GUID: "some-pkg-guid", 210 State: constant.PackageReady, 211 Relationships: ccv3.Relationships{ 212 constant.RelationshipTypeApplication: ccv3.Relationship{ 213 GUID: "some-app-guid", 214 }, 215 }, 216 } 217 218 fakeCloudControllerClient.CreatePackageReturns( 219 createdPackage, 220 ccv3.Warnings{"some-create-package-warning"}, 221 nil, 222 ) 223 }) 224 225 It("calls CC to create the package and returns the package", func() { 226 Expect(executeErr).ToNot(HaveOccurred()) 227 Expect(warnings).To(ConsistOf("some-app-warning", "some-create-package-warning")) 228 229 expectedPackage := ccv3.Package{ 230 DockerImage: "some-docker-image", 231 DockerUsername: "some-username", 232 DockerPassword: "some-password", 233 GUID: "some-pkg-guid", 234 State: constant.PackageReady, 235 Relationships: ccv3.Relationships{ 236 constant.RelationshipTypeApplication: ccv3.Relationship{ 237 GUID: "some-app-guid", 238 }, 239 }, 240 } 241 Expect(dockerPackage).To(Equal(Package(expectedPackage))) 242 243 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 244 Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf( 245 ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app-name"}}, 246 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}}, 247 )) 248 249 Expect(fakeCloudControllerClient.CreatePackageCallCount()).To(Equal(1)) 250 Expect(fakeCloudControllerClient.CreatePackageArgsForCall(0)).To(Equal(ccv3.Package{ 251 Type: constant.PackageTypeDocker, 252 DockerImage: "some-docker-image", 253 DockerUsername: "some-username", 254 DockerPassword: "some-password", 255 Relationships: ccv3.Relationships{ 256 constant.RelationshipTypeApplication: ccv3.Relationship{GUID: "some-app-guid"}, 257 }, 258 })) 259 }) 260 }) 261 }) 262 }) 263 264 Describe("CreateAndUploadBitsPackageByApplicationNameAndSpace", func() { 265 var ( 266 bitsPath string 267 pkg Package 268 warnings Warnings 269 executeErr error 270 ) 271 272 BeforeEach(func() { 273 bitsPath = "" 274 pkg = Package{} 275 warnings = nil 276 executeErr = nil 277 278 // putting this here so the tests don't hang on polling 279 fakeCloudControllerClient.GetPackageReturns( 280 ccv3.Package{GUID: "some-pkg-guid", State: constant.PackageReady}, 281 ccv3.Warnings{}, 282 nil, 283 ) 284 }) 285 286 JustBeforeEach(func() { 287 pkg, warnings, executeErr = actor.CreateAndUploadBitsPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 288 }) 289 290 When("retrieving the application errors", func() { 291 BeforeEach(func() { 292 fakeCloudControllerClient.GetApplicationsReturns( 293 []ccv3.Application{}, 294 ccv3.Warnings{"some-app-warning"}, 295 errors.New("some-get-error"), 296 ) 297 }) 298 299 It("returns the warnings and the error", func() { 300 Expect(executeErr).To(MatchError("some-get-error")) 301 Expect(warnings).To(ConsistOf("some-app-warning")) 302 }) 303 }) 304 305 When("the application can be retrieved", func() { 306 BeforeEach(func() { 307 fakeCloudControllerClient.GetApplicationsReturns( 308 []ccv3.Application{ 309 { 310 Name: "some-app-name", 311 GUID: "some-app-guid", 312 }, 313 }, 314 ccv3.Warnings{"some-app-warning"}, 315 nil, 316 ) 317 }) 318 319 When("bits path is a directory", func() { 320 BeforeEach(func() { 321 var err error 322 bitsPath, err = ioutil.TempDir("", "example") 323 Expect(err).ToNot(HaveOccurred()) 324 }) 325 326 AfterEach(func() { 327 if bitsPath != "" { 328 err := os.RemoveAll(bitsPath) 329 Expect(err).ToNot(HaveOccurred()) 330 } 331 }) 332 333 It("calls GatherDirectoryResources and ZipDirectoryResources", func() { 334 Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(1)) 335 Expect(fakeSharedActor.ZipDirectoryResourcesCallCount()).To(Equal(1)) 336 }) 337 338 When("gathering resources fails", func() { 339 BeforeEach(func() { 340 fakeSharedActor.GatherDirectoryResourcesReturns(nil, errors.New("some-gather-error")) 341 }) 342 343 It("returns the error", func() { 344 Expect(executeErr).To(MatchError("some-gather-error")) 345 Expect(warnings).To(ConsistOf("some-app-warning")) 346 }) 347 }) 348 349 When("gathering resources succeeds", func() { 350 BeforeEach(func() { 351 fakeSharedActor.GatherDirectoryResourcesReturns([]sharedaction.Resource{{Filename: "file-1"}, {Filename: "file-2"}}, nil) 352 }) 353 354 When("zipping gathered resources fails", func() { 355 BeforeEach(func() { 356 fakeSharedActor.ZipDirectoryResourcesReturns("", errors.New("some-archive-error")) 357 }) 358 359 It("returns the error", func() { 360 Expect(executeErr).To(MatchError("some-archive-error")) 361 Expect(warnings).To(ConsistOf("some-app-warning")) 362 }) 363 }) 364 365 When("zipping gathered resources succeeds", func() { 366 BeforeEach(func() { 367 fakeSharedActor.ZipDirectoryResourcesReturns("zipped-archive", nil) 368 }) 369 370 When("creating the package fails", func() { 371 BeforeEach(func() { 372 fakeCloudControllerClient.CreatePackageReturns( 373 ccv3.Package{}, 374 ccv3.Warnings{"create-package-warning"}, 375 errors.New("some-create-error"), 376 ) 377 }) 378 379 It("returns the error", func() { 380 Expect(executeErr).To(MatchError("some-create-error")) 381 Expect(warnings).To(ConsistOf("some-app-warning", "create-package-warning")) 382 }) 383 }) 384 385 When("creating the package succeeds", func() { 386 var createdPackage ccv3.Package 387 388 BeforeEach(func() { 389 createdPackage = ccv3.Package{ 390 GUID: "some-pkg-guid", 391 State: constant.PackageAwaitingUpload, 392 Relationships: ccv3.Relationships{ 393 constant.RelationshipTypeApplication: ccv3.Relationship{ 394 GUID: "some-app-guid", 395 }, 396 }, 397 } 398 399 fakeCloudControllerClient.CreatePackageReturns( 400 createdPackage, 401 ccv3.Warnings{"some-package-warning"}, 402 nil, 403 ) 404 }) 405 406 It("uploads the package with the path to the zip", func() { 407 Expect(fakeCloudControllerClient.UploadPackageCallCount()).To(Equal(1)) 408 _, zippedArchive := fakeCloudControllerClient.UploadPackageArgsForCall(0) 409 Expect(zippedArchive).To(Equal("zipped-archive")) 410 }) 411 412 When("uploading fails", func() { 413 BeforeEach(func() { 414 fakeCloudControllerClient.UploadPackageReturns( 415 ccv3.Package{}, 416 ccv3.Warnings{"upload-package-warning"}, 417 errors.New("some-error"), 418 ) 419 }) 420 421 It("returns the error", func() { 422 Expect(executeErr).To(MatchError("some-error")) 423 Expect(warnings).To(ConsistOf("some-app-warning", "some-package-warning", "upload-package-warning")) 424 }) 425 }) 426 427 When("uploading succeeds", func() { 428 BeforeEach(func() { 429 fakeCloudControllerClient.UploadPackageReturns( 430 ccv3.Package{}, 431 ccv3.Warnings{"upload-package-warning"}, 432 nil, 433 ) 434 }) 435 436 When("the polling errors", func() { 437 var expectedErr error 438 439 BeforeEach(func() { 440 expectedErr = errors.New("Fake error during polling") 441 fakeCloudControllerClient.GetPackageReturns( 442 ccv3.Package{}, 443 ccv3.Warnings{"some-get-pkg-warning"}, 444 expectedErr, 445 ) 446 }) 447 448 It("returns the error and warnings", func() { 449 Expect(executeErr).To(MatchError(expectedErr)) 450 Expect(warnings).To(ConsistOf("some-app-warning", "some-package-warning", "upload-package-warning", "some-get-pkg-warning")) 451 }) 452 }) 453 454 When("the polling is successful", func() { 455 It("collects all warnings", func() { 456 Expect(executeErr).NotTo(HaveOccurred()) 457 Expect(warnings).To(ConsistOf("some-app-warning", "some-package-warning", "upload-package-warning")) 458 }) 459 460 It("successfully resolves the app name", func() { 461 Expect(executeErr).ToNot(HaveOccurred()) 462 463 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 464 Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf( 465 ccv3.Query{Key: ccv3.NameFilter, Values: []string{"some-app-name"}}, 466 ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"some-space-guid"}}, 467 )) 468 }) 469 470 It("successfully creates the Package", func() { 471 Expect(executeErr).ToNot(HaveOccurred()) 472 473 Expect(fakeCloudControllerClient.CreatePackageCallCount()).To(Equal(1)) 474 inputPackage := fakeCloudControllerClient.CreatePackageArgsForCall(0) 475 Expect(inputPackage).To(Equal(ccv3.Package{ 476 Type: constant.PackageTypeBits, 477 Relationships: ccv3.Relationships{ 478 constant.RelationshipTypeApplication: ccv3.Relationship{GUID: "some-app-guid"}, 479 }, 480 })) 481 }) 482 483 It("returns the package", func() { 484 Expect(executeErr).ToNot(HaveOccurred()) 485 486 expectedPackage := ccv3.Package{ 487 GUID: "some-pkg-guid", 488 State: constant.PackageReady, 489 } 490 Expect(pkg).To(Equal(Package(expectedPackage))) 491 492 Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(1)) 493 Expect(fakeCloudControllerClient.GetPackageArgsForCall(0)).To(Equal("some-pkg-guid")) 494 }) 495 496 DescribeTable("polls until terminal state is reached", 497 func(finalState constant.PackageState, expectedErr error) { 498 fakeCloudControllerClient.GetPackageReturns( 499 ccv3.Package{GUID: "some-pkg-guid", State: constant.PackageAwaitingUpload}, 500 ccv3.Warnings{"poll-package-warning"}, 501 nil, 502 ) 503 fakeCloudControllerClient.GetPackageReturnsOnCall( 504 2, 505 ccv3.Package{State: finalState}, 506 ccv3.Warnings{"poll-package-warning"}, 507 nil, 508 ) 509 510 _, tableWarnings, err := actor.CreateAndUploadBitsPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 511 512 if expectedErr == nil { 513 Expect(err).ToNot(HaveOccurred()) 514 } else { 515 Expect(err).To(MatchError(expectedErr)) 516 } 517 518 Expect(tableWarnings).To(ConsistOf("some-app-warning", "some-package-warning", "upload-package-warning", "poll-package-warning", "poll-package-warning")) 519 520 // hacky, get packages is called an extry time cause the 521 // JustBeforeEach executes everything once as well 522 Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(3)) 523 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(3)) 524 }, 525 526 Entry("READY", constant.PackageReady, nil), 527 Entry("FAILED", constant.PackageFailed, actionerror.PackageProcessingFailedError{}), 528 Entry("EXPIRED", constant.PackageExpired, actionerror.PackageProcessingExpiredError{}), 529 ) 530 }) 531 }) 532 }) 533 }) 534 }) 535 }) 536 537 When("bitsPath is blank", func() { 538 var oldCurrentDir, appDir string 539 BeforeEach(func() { 540 var err error 541 oldCurrentDir, err = os.Getwd() 542 Expect(err).NotTo(HaveOccurred()) 543 544 appDir, err = ioutil.TempDir("", "example") 545 Expect(err).ToNot(HaveOccurred()) 546 547 Expect(os.Chdir(appDir)).NotTo(HaveOccurred()) 548 appDir, err = os.Getwd() 549 Expect(err).ToNot(HaveOccurred()) 550 }) 551 552 AfterEach(func() { 553 Expect(os.Chdir(oldCurrentDir)).NotTo(HaveOccurred()) 554 err := os.RemoveAll(appDir) 555 Expect(err).ToNot(HaveOccurred()) 556 }) 557 558 It("uses the current working directory", func() { 559 Expect(executeErr).NotTo(HaveOccurred()) 560 561 Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(1)) 562 Expect(fakeSharedActor.GatherDirectoryResourcesArgsForCall(0)).To(Equal(appDir)) 563 564 Expect(fakeSharedActor.ZipDirectoryResourcesCallCount()).To(Equal(1)) 565 pathArg, _ := fakeSharedActor.ZipDirectoryResourcesArgsForCall(0) 566 Expect(pathArg).To(Equal(appDir)) 567 }) 568 }) 569 570 When("bits path is an archive", func() { 571 BeforeEach(func() { 572 var err error 573 tempFile, err := ioutil.TempFile("", "bits-zip-test") 574 Expect(err).ToNot(HaveOccurred()) 575 Expect(tempFile.Close()).To(Succeed()) 576 tempFilePath := tempFile.Name() 577 578 bitsPathFile, err := ioutil.TempFile("", "example") 579 Expect(err).ToNot(HaveOccurred()) 580 Expect(bitsPathFile.Close()).To(Succeed()) 581 bitsPath = bitsPathFile.Name() 582 583 zipit(tempFilePath, bitsPath, "") 584 Expect(os.Remove(tempFilePath)).To(Succeed()) 585 }) 586 587 AfterEach(func() { 588 err := os.RemoveAll(bitsPath) 589 Expect(err).ToNot(HaveOccurred()) 590 }) 591 592 It("calls GatherArchiveResources and ZipArchiveResources", func() { 593 Expect(fakeSharedActor.GatherArchiveResourcesCallCount()).To(Equal(1)) 594 Expect(fakeSharedActor.ZipArchiveResourcesCallCount()).To(Equal(1)) 595 }) 596 597 When("gathering archive resources fails", func() { 598 BeforeEach(func() { 599 fakeSharedActor.GatherArchiveResourcesReturns(nil, errors.New("some-archive-resource-error")) 600 }) 601 It("should return an error", func() { 602 Expect(executeErr).To(MatchError("some-archive-resource-error")) 603 Expect(warnings).To(ConsistOf("some-app-warning")) 604 }) 605 606 }) 607 608 When("gathering resources succeeds", func() { 609 BeforeEach(func() { 610 fakeSharedActor.GatherArchiveResourcesReturns([]sharedaction.Resource{{Filename: "file-1"}, {Filename: "file-2"}}, nil) 611 }) 612 613 When("zipping gathered resources fails", func() { 614 BeforeEach(func() { 615 fakeSharedActor.ZipArchiveResourcesReturns("", errors.New("some-archive-error")) 616 }) 617 618 It("returns the error", func() { 619 Expect(executeErr).To(MatchError("some-archive-error")) 620 Expect(warnings).To(ConsistOf("some-app-warning")) 621 }) 622 }) 623 624 When("zipping gathered resources succeeds", func() { 625 BeforeEach(func() { 626 fakeSharedActor.ZipArchiveResourcesReturns("zipped-archive", nil) 627 }) 628 629 It("uploads the package", func() { 630 Expect(executeErr).ToNot(HaveOccurred()) 631 Expect(warnings).To(ConsistOf("some-app-warning")) 632 633 Expect(fakeCloudControllerClient.UploadPackageCallCount()).To(Equal(1)) 634 _, archivePathArg := fakeCloudControllerClient.UploadPackageArgsForCall(0) 635 Expect(archivePathArg).To(Equal("zipped-archive")) 636 }) 637 }) 638 }) 639 }) 640 641 When("bits path is a symlink to a directory", func() { 642 var tempDir string 643 644 BeforeEach(func() { 645 var err error 646 tempDir, err = ioutil.TempDir("", "example") 647 Expect(err).ToNot(HaveOccurred()) 648 649 tempFile, err := ioutil.TempFile("", "example-file-") 650 Expect(err).ToNot(HaveOccurred()) 651 Expect(tempFile.Close()).To(Succeed()) 652 653 bitsPath = tempFile.Name() 654 Expect(os.Remove(bitsPath)).To(Succeed()) 655 Expect(os.Symlink(tempDir, bitsPath)).To(Succeed()) 656 }) 657 658 AfterEach(func() { 659 Expect(os.RemoveAll(tempDir)).To(Succeed()) 660 Expect(os.Remove(bitsPath)).To(Succeed()) 661 }) 662 663 It("calls GatherDirectoryResources and returns without an error", func() { 664 Expect(fakeSharedActor.GatherDirectoryResourcesCallCount()).To(Equal(1)) 665 Expect(fakeSharedActor.GatherDirectoryResourcesArgsForCall(0)).To(Equal(bitsPath)) 666 Expect(executeErr).ToNot(HaveOccurred()) 667 }) 668 }) 669 670 When("bits path is symlink to an archive", func() { 671 var archivePath string 672 673 BeforeEach(func() { 674 var err error 675 tempArchiveFile, err := ioutil.TempFile("", "bits-zip-test") 676 Expect(err).ToNot(HaveOccurred()) 677 Expect(tempArchiveFile.Close()).To(Succeed()) 678 tempArchiveFilePath := tempArchiveFile.Name() 679 680 archivePathFile, err := ioutil.TempFile("", "example") 681 Expect(err).ToNot(HaveOccurred()) 682 Expect(archivePathFile.Close()).To(Succeed()) 683 archivePath = archivePathFile.Name() 684 685 zipit(tempArchiveFilePath, archivePath, "") 686 Expect(os.Remove(tempArchiveFilePath)).To(Succeed()) 687 688 tempFile, err := ioutil.TempFile("", "example-file-") 689 Expect(err).ToNot(HaveOccurred()) 690 Expect(tempFile.Close()).To(Succeed()) 691 692 bitsPath = tempFile.Name() 693 Expect(os.Remove(bitsPath)).To(Succeed()) 694 Expect(os.Symlink(archivePath, bitsPath)).To(Succeed()) 695 }) 696 697 AfterEach(func() { 698 Expect(os.Remove(archivePath)).To(Succeed()) 699 Expect(os.Remove(bitsPath)).To(Succeed()) 700 }) 701 702 It("calls GatherArchiveResources and returns without an error", func() { 703 Expect(fakeSharedActor.GatherArchiveResourcesCallCount()).To(Equal(1)) 704 Expect(fakeSharedActor.GatherArchiveResourcesArgsForCall(0)).To(Equal(bitsPath)) 705 Expect(executeErr).ToNot(HaveOccurred()) 706 }) 707 }) 708 }) 709 }) 710 711 Describe("CreateBitsPackageByApplication", func() { 712 var ( 713 appGUID string 714 715 pkg Package 716 executeErr error 717 warnings Warnings 718 ) 719 720 JustBeforeEach(func() { 721 pkg, warnings, executeErr = actor.CreateBitsPackageByApplication(appGUID) 722 }) 723 724 When("creating the package fails", func() { 725 BeforeEach(func() { 726 fakeCloudControllerClient.CreatePackageReturns( 727 ccv3.Package{}, 728 ccv3.Warnings{"create-package-warning"}, 729 errors.New("some-create-error"), 730 ) 731 }) 732 733 It("returns the error", func() { 734 Expect(executeErr).To(MatchError("some-create-error")) 735 Expect(warnings).To(ConsistOf("create-package-warning")) 736 }) 737 }) 738 739 When("creating the package succeeds", func() { 740 var createdPackage ccv3.Package 741 742 BeforeEach(func() { 743 createdPackage = ccv3.Package{GUID: "some-pkg-guid"} 744 fakeCloudControllerClient.CreatePackageReturns( 745 createdPackage, 746 ccv3.Warnings{"create-package-warning"}, 747 nil, 748 ) 749 }) 750 751 It("returns all warnings and the package", func() { 752 Expect(executeErr).ToNot(HaveOccurred()) 753 754 Expect(fakeCloudControllerClient.CreatePackageCallCount()).To(Equal(1)) 755 Expect(fakeCloudControllerClient.CreatePackageArgsForCall(0)).To(Equal(ccv3.Package{ 756 Type: constant.PackageTypeBits, 757 Relationships: ccv3.Relationships{ 758 constant.RelationshipTypeApplication: ccv3.Relationship{GUID: appGUID}, 759 }, 760 })) 761 762 Expect(warnings).To(ConsistOf("create-package-warning")) 763 Expect(pkg).To(MatchFields(IgnoreExtras, Fields{ 764 "GUID": Equal("some-pkg-guid"), 765 })) 766 }) 767 }) 768 }) 769 770 Describe("UploadBitsPackage", func() { 771 var ( 772 pkg Package 773 matchedResources []sharedaction.Resource 774 reader io.Reader 775 readerLength int64 776 777 appPkg Package 778 warnings Warnings 779 executeErr error 780 ) 781 782 BeforeEach(func() { 783 pkg = Package{GUID: "some-package-guid"} 784 785 matchedResources = []sharedaction.Resource{{Filename: "some-resource"}, {Filename: "another-resource"}} 786 someString := "who reads these days" 787 reader = strings.NewReader(someString) 788 readerLength = int64(len([]byte(someString))) 789 }) 790 791 JustBeforeEach(func() { 792 appPkg, warnings, executeErr = actor.UploadBitsPackage(pkg, matchedResources, reader, readerLength) 793 }) 794 795 When("the upload is successful", func() { 796 BeforeEach(func() { 797 fakeCloudControllerClient.UploadBitsPackageReturns(ccv3.Package{GUID: "some-package-guid"}, ccv3.Warnings{"upload-warning-1", "upload-warning-2"}, nil) 798 }) 799 800 It("passes a ccv3 Resource to the client", func() { 801 passedPackage, passedMatchedResources, passedReader, passedReaderLength := fakeCloudControllerClient.UploadBitsPackageArgsForCall(0) 802 Expect(passedPackage).To(Equal(ccv3.Package(appPkg))) 803 Expect(passedMatchedResources).To(ConsistOf(ccv3.Resource{FilePath: "some-resource"}, ccv3.Resource{FilePath: "another-resource"})) 804 Expect(passedReader).To(Equal(reader)) 805 Expect(passedReaderLength).To(Equal(readerLength)) 806 }) 807 808 It("returns all warnings", func() { 809 Expect(executeErr).ToNot(HaveOccurred()) 810 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2")) 811 Expect(appPkg).To(Equal(Package{GUID: "some-package-guid"})) 812 813 Expect(fakeCloudControllerClient.UploadBitsPackageCallCount()).To(Equal(1)) 814 815 }) 816 }) 817 818 When("the upload returns an error", func() { 819 var err error 820 821 BeforeEach(func() { 822 err = errors.New("some-error") 823 fakeCloudControllerClient.UploadBitsPackageReturns(ccv3.Package{}, ccv3.Warnings{"upload-warning-1", "upload-warning-2"}, err) 824 }) 825 826 It("returns the error", func() { 827 Expect(executeErr).To(MatchError(err)) 828 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2")) 829 }) 830 }) 831 }) 832 833 Describe("PollPackage", func() { 834 Context("Polling Behavior", func() { 835 var ( 836 pkg Package 837 838 appPkg Package 839 warnings Warnings 840 executeErr error 841 ) 842 843 BeforeEach(func() { 844 pkg = Package{ 845 GUID: "some-pkg-guid", 846 } 847 848 warnings = nil 849 executeErr = nil 850 851 // putting this here so the tests don't hang on polling 852 fakeCloudControllerClient.GetPackageReturns( 853 ccv3.Package{ 854 GUID: "some-pkg-guid", 855 State: constant.PackageReady, 856 }, 857 ccv3.Warnings{}, 858 nil, 859 ) 860 }) 861 862 JustBeforeEach(func() { 863 appPkg, warnings, executeErr = actor.PollPackage(pkg) 864 }) 865 866 When("the polling errors", func() { 867 var expectedErr error 868 869 BeforeEach(func() { 870 expectedErr = errors.New("Fake error during polling") 871 fakeCloudControllerClient.GetPackageReturns( 872 ccv3.Package{}, 873 ccv3.Warnings{"some-get-pkg-warning"}, 874 expectedErr, 875 ) 876 }) 877 878 It("returns the error and warnings", func() { 879 Expect(executeErr).To(MatchError(expectedErr)) 880 Expect(warnings).To(ConsistOf("some-get-pkg-warning")) 881 }) 882 }) 883 884 When("the polling is successful", func() { 885 It("returns the package", func() { 886 Expect(executeErr).ToNot(HaveOccurred()) 887 888 expectedPackage := ccv3.Package{ 889 GUID: "some-pkg-guid", 890 State: constant.PackageReady, 891 } 892 893 Expect(appPkg).To(Equal(Package(expectedPackage))) 894 Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(1)) 895 Expect(fakeCloudControllerClient.GetPackageArgsForCall(0)).To(Equal("some-pkg-guid")) 896 }) 897 }) 898 }) 899 900 DescribeTable("Polling states", 901 func(finalState constant.PackageState, expectedErr error) { 902 fakeCloudControllerClient.GetPackageReturns( 903 ccv3.Package{GUID: "some-pkg-guid", State: constant.PackageAwaitingUpload}, 904 ccv3.Warnings{"poll-package-warning"}, 905 nil, 906 ) 907 908 fakeCloudControllerClient.GetPackageReturnsOnCall( 909 1, 910 ccv3.Package{State: finalState}, 911 ccv3.Warnings{"poll-package-warning"}, 912 nil, 913 ) 914 915 _, tableWarnings, err := actor.PollPackage(Package{ 916 GUID: "some-pkg-guid", 917 }) 918 919 if expectedErr == nil { 920 Expect(err).ToNot(HaveOccurred()) 921 } else { 922 Expect(err).To(MatchError(expectedErr)) 923 } 924 925 Expect(tableWarnings).To(ConsistOf("poll-package-warning", "poll-package-warning")) 926 927 Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(2)) 928 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(2)) 929 }, 930 931 Entry("READY", constant.PackageReady, nil), 932 Entry("FAILED", constant.PackageFailed, actionerror.PackageProcessingFailedError{}), 933 Entry("EXPIRED", constant.PackageExpired, actionerror.PackageProcessingExpiredError{}), 934 ) 935 }) 936 })