github.com/willmadison/cli@v6.40.1-0.20181018160101-29d5937903ff+incompatible/actor/v2action/buildpack_test.go (about) 1 package v2action_test 2 3 import ( 4 "errors" 5 "io" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 14 "code.cloudfoundry.org/cli/actor/actionerror" 15 . "code.cloudfoundry.org/cli/actor/v2action" 16 "code.cloudfoundry.org/cli/actor/v2action/v2actionfakes" 17 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 18 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2" 19 "code.cloudfoundry.org/cli/types" 20 ) 21 22 var _ = Describe("Buildpack", func() { 23 var ( 24 actor *Actor 25 fakeCloudControllerClient *v2actionfakes.FakeCloudControllerClient 26 ) 27 28 BeforeEach(func() { 29 fakeCloudControllerClient = new(v2actionfakes.FakeCloudControllerClient) 30 actor = NewActor(fakeCloudControllerClient, nil, nil) 31 }) 32 33 Describe("Buildpack", func() { 34 Describe("NoStack", func() { 35 var buildpack Buildpack 36 37 When("the stack is empty", func() { 38 BeforeEach(func() { 39 buildpack.Stack = "" 40 }) 41 42 It("returns true", func() { 43 Expect(buildpack.NoStack()).To(BeTrue()) 44 }) 45 }) 46 47 When("the stack is set", func() { 48 BeforeEach(func() { 49 buildpack.Stack = "something i guess" 50 }) 51 52 It("returns false", func() { 53 Expect(buildpack.NoStack()).To(BeFalse()) 54 }) 55 }) 56 }) 57 }) 58 59 Describe("CreateBuildpack", func() { 60 var ( 61 buildpack Buildpack 62 warnings Warnings 63 executeErr error 64 ) 65 66 JustBeforeEach(func() { 67 buildpack, warnings, executeErr = actor.CreateBuildpack("some-bp-name", 42, true) 68 }) 69 70 When("creating the buildpack is successful", func() { 71 BeforeEach(func() { 72 fakeCloudControllerClient.CreateBuildpackReturns(ccv2.Buildpack{GUID: "some-guid"}, ccv2.Warnings{"some-create-warning"}, nil) 73 }) 74 75 It("returns the buildpack and all warnings", func() { 76 Expect(executeErr).ToNot(HaveOccurred()) 77 Expect(fakeCloudControllerClient.CreateBuildpackCallCount()).To(Equal(1)) 78 Expect(fakeCloudControllerClient.CreateBuildpackArgsForCall(0)).To(Equal(ccv2.Buildpack{ 79 Name: "some-bp-name", 80 Position: types.NullInt{IsSet: true, Value: 42}, 81 Enabled: types.NullBool{IsSet: true, Value: true}, 82 })) 83 84 Expect(buildpack).To(Equal(Buildpack{GUID: "some-guid"})) 85 Expect(warnings).To(ConsistOf("some-create-warning")) 86 }) 87 }) 88 89 When("the buildpack already exists with nil stack", func() { 90 BeforeEach(func() { 91 fakeCloudControllerClient.CreateBuildpackReturns(ccv2.Buildpack{}, ccv2.Warnings{"some-create-warning"}, ccerror.BuildpackAlreadyExistsWithoutStackError{Message: ""}) 92 }) 93 94 It("returns a BuildpackAlreadyExistsWithoutStackError error and all warnings", func() { 95 Expect(warnings).To(ConsistOf("some-create-warning")) 96 Expect(executeErr).To(MatchError(actionerror.BuildpackAlreadyExistsWithoutStackError{BuildpackName: "some-bp-name"})) 97 }) 98 }) 99 100 When("the buildpack name is taken", func() { 101 BeforeEach(func() { 102 fakeCloudControllerClient.CreateBuildpackReturns(ccv2.Buildpack{}, ccv2.Warnings{"some-create-warning"}, ccerror.BuildpackNameTakenError{Message: ""}) 103 }) 104 105 It("returns a BuildpackAlreadyExistsWithoutStackError error and all warnings", func() { 106 Expect(warnings).To(ConsistOf("some-create-warning")) 107 Expect(executeErr).To(MatchError(actionerror.BuildpackNameTakenError{Name: "some-bp-name"})) 108 }) 109 }) 110 111 When("a cc create error occurs", func() { 112 BeforeEach(func() { 113 fakeCloudControllerClient.CreateBuildpackReturns(ccv2.Buildpack{}, ccv2.Warnings{"some-create-warning"}, errors.New("kaboom")) 114 }) 115 116 It("returns an error and all warnings", func() { 117 Expect(warnings).To(ConsistOf("some-create-warning")) 118 Expect(executeErr).To(MatchError("kaboom")) 119 }) 120 }) 121 }) 122 123 Describe("GetBuildpackByName", func() { 124 var ( 125 buildpack Buildpack 126 warnings Warnings 127 executeErr error 128 ) 129 130 JustBeforeEach(func() { 131 buildpack, warnings, executeErr = actor.GetBuildpackByName("some-bp-name") 132 }) 133 134 When("one buildpack with the same name exists", func() { 135 When("the buildpack also has no stack", func() { 136 BeforeEach(func() { 137 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 138 { 139 Name: "some-bp-name", 140 GUID: "some-bp-guid", 141 Stack: "", 142 }, 143 }, ccv2.Warnings{"some-warning"}, nil) 144 }) 145 146 It("returns the buildpack", func() { 147 Expect(executeErr).ToNot(HaveOccurred()) 148 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 149 150 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 151 Expect(buildpack).To(Equal(Buildpack{ 152 Name: "some-bp-name", 153 GUID: "some-bp-guid", 154 })) 155 }) 156 }) 157 158 When("the buildpack has a stack", func() { 159 BeforeEach(func() { 160 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 161 { 162 Name: "some-bp-name", 163 GUID: "some-bp-guid", 164 Stack: "some-stack-name", 165 }, 166 }, ccv2.Warnings{"some-warning"}, nil) 167 }) 168 169 It("returns the buildpack", func() { 170 Expect(executeErr).ToNot(HaveOccurred()) 171 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 172 173 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 174 Expect(buildpack).To(Equal(Buildpack{ 175 Name: "some-bp-name", 176 GUID: "some-bp-guid", 177 Stack: "some-stack-name", 178 })) 179 }) 180 }) 181 }) 182 183 When("the client returns an empty set of buildpacks", func() { 184 BeforeEach(func() { 185 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, nil) 186 }) 187 188 It("returns a buildpack not found error", func() { 189 Expect(executeErr).To(MatchError(actionerror.BuildpackNotFoundError{BuildpackName: "some-bp-name"})) 190 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 191 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 192 }) 193 }) 194 195 When("the client returns more than one buildpack", func() { 196 When("one of the buildpacks has no stack", func() { 197 BeforeEach(func() { 198 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 199 { 200 Name: "some-bp-name", 201 GUID: "bp-guid-1", 202 Stack: "some-stack-name", 203 }, 204 { 205 Name: "some-bp-name", 206 GUID: "bp-guid-2", 207 Stack: "", 208 }, 209 }, ccv2.Warnings{"some-warning"}, nil) 210 }) 211 212 It("returns the correct buildpack", func() { 213 Expect(executeErr).ToNot(HaveOccurred()) 214 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 215 216 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 217 Expect(buildpack).To(Equal(Buildpack{ 218 Name: "some-bp-name", 219 GUID: "bp-guid-2", 220 Stack: "", 221 })) 222 }) 223 224 }) 225 Context("none of the buildpacks have no stack", func() { 226 BeforeEach(func() { 227 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 228 { 229 Name: "some-bp-name", 230 GUID: "bp-guid-1", 231 Stack: "some-stack-1", 232 }, 233 { 234 Name: "some-bp-name", 235 GUID: "bp-guid-2", 236 Stack: "some-stack-2", 237 }, 238 }, ccv2.Warnings{"some-warning"}, nil) 239 }) 240 It("returns a multiple buildpacks found error", func() { 241 Expect(executeErr).To(MatchError(actionerror.MultipleBuildpacksFoundError{BuildpackName: "some-bp-name"})) 242 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 243 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 244 }) 245 }) 246 }) 247 248 When("the client errors", func() { 249 BeforeEach(func() { 250 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, ccerror.APINotFoundError{}) 251 }) 252 253 It("returns a buildpack not found error", func() { 254 Expect(executeErr).To(MatchError(ccerror.APINotFoundError{})) 255 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 256 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 257 }) 258 }) 259 }) 260 261 Describe("GetBuildpackByNameAndStack", func() { 262 var ( 263 buildpack Buildpack 264 warnings Warnings 265 executeErr error 266 ) 267 268 JustBeforeEach(func() { 269 buildpack, warnings, executeErr = actor.GetBuildpackByNameAndStack("some-bp-name", "some-stack-name") 270 }) 271 272 When("the client returns a buildpack with the same name and stack", func() { 273 BeforeEach(func() { 274 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 275 { 276 Name: "some-bp-name", 277 GUID: "some-bp-guid", 278 Stack: "some-stack-name", 279 }, 280 }, ccv2.Warnings{"some-warning"}, nil) 281 }) 282 283 It("returns the buildpack", func() { 284 Expect(executeErr).ToNot(HaveOccurred()) 285 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 286 287 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 288 Expect(buildpack).To(Equal(Buildpack{ 289 Name: "some-bp-name", 290 GUID: "some-bp-guid", 291 Stack: "some-stack-name", 292 })) 293 }) 294 }) 295 296 When("the client returns an empty set of buildpacks", func() { 297 BeforeEach(func() { 298 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, nil) 299 }) 300 301 It("returns a buildpack not found error", func() { 302 Expect(executeErr).To(MatchError(actionerror.BuildpackNotFoundError{BuildpackName: "some-bp-name", StackName: "some-stack-name"})) 303 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 304 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 305 }) 306 }) 307 308 When("the client returns more than one buildpack", func() { 309 BeforeEach(func() { 310 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 311 { 312 Name: "some-bp-name", 313 GUID: "bp-guid-1", 314 Stack: "some-stack-name", 315 }, 316 { 317 Name: "some-bp-name", 318 GUID: "bp-guid-2", 319 Stack: "some-stack-name", 320 }, 321 }, ccv2.Warnings{"some-warning"}, nil) 322 }) 323 324 It("returns a multiple buildpacks found error", func() { 325 Expect(executeErr).To(MatchError(actionerror.MultipleBuildpacksFoundError{BuildpackName: "some-bp-name"})) 326 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 327 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 328 }) 329 }) 330 331 When("the client errors", func() { 332 BeforeEach(func() { 333 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, ccerror.APINotFoundError{}) 334 }) 335 336 It("returns the error", func() { 337 Expect(executeErr).To(MatchError(ccerror.APINotFoundError{})) 338 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 339 Expect(fakeCloudControllerClient.GetBuildpacksCallCount()).To(Equal(1)) 340 }) 341 }) 342 }) 343 344 Describe("PrepareBuildpackBits", func() { 345 var ( 346 inPath string 347 outPath string 348 tmpDirPath string 349 fakeDownloader *v2actionfakes.FakeDownloader 350 351 executeErr error 352 ) 353 354 BeforeEach(func() { 355 fakeDownloader = new(v2actionfakes.FakeDownloader) 356 }) 357 358 JustBeforeEach(func() { 359 outPath, executeErr = actor.PrepareBuildpackBits(inPath, tmpDirPath, fakeDownloader) 360 }) 361 362 When("the buildpack path is a url", func() { 363 BeforeEach(func() { 364 inPath = "http://buildpacks.com/a.zip" 365 fakeDownloader = new(v2actionfakes.FakeDownloader) 366 367 var err error 368 tmpDirPath, err = ioutil.TempDir("", "buildpackdir-") 369 Expect(err).ToNot(HaveOccurred()) 370 }) 371 372 AfterEach(func() { 373 Expect(os.RemoveAll(tmpDirPath)).ToNot(HaveOccurred()) 374 }) 375 376 When("downloading the file succeeds", func() { 377 BeforeEach(func() { 378 fakeDownloader.DownloadReturns("/tmp/buildpackdir-100/a.zip", nil) 379 }) 380 381 It("downloads the buildpack to a local file", func() { 382 Expect(executeErr).ToNot(HaveOccurred()) 383 Expect(fakeDownloader.DownloadCallCount()).To(Equal(1)) 384 385 inputPath, inputTmpDirPath := fakeDownloader.DownloadArgsForCall(0) 386 Expect(inputPath).To(Equal("http://buildpacks.com/a.zip")) 387 Expect(inputTmpDirPath).To(Equal(tmpDirPath)) 388 }) 389 }) 390 391 When("downloading the file fails", func() { 392 BeforeEach(func() { 393 fakeDownloader.DownloadReturns("", errors.New("some-download-error")) 394 }) 395 396 It("returns the error", func() { 397 Expect(executeErr).To(MatchError("some-download-error")) 398 }) 399 }) 400 }) 401 402 When("the buildpack path points to a directory", func() { 403 var tempFile *os.File 404 BeforeEach(func() { 405 var err error 406 inPath, err = ioutil.TempDir("", "buildpackdir-") 407 Expect(err).ToNot(HaveOccurred()) 408 409 tempFile, err = ioutil.TempFile(inPath, "foo") 410 Expect(err).ToNot(HaveOccurred()) 411 412 tmpDirPath, err = ioutil.TempDir("", "buildpackdir-") 413 Expect(err).ToNot(HaveOccurred()) 414 }) 415 416 AfterEach(func() { 417 tempFile.Close() 418 Expect(os.RemoveAll(inPath)).ToNot(HaveOccurred()) 419 Expect(os.RemoveAll(tmpDirPath)).ToNot(HaveOccurred()) 420 }) 421 422 It("returns a path to the zipped directory", func() { 423 Expect(executeErr).ToNot(HaveOccurred()) 424 Expect(fakeDownloader.DownloadCallCount()).To(Equal(0)) 425 426 Expect(filepath.Base(outPath)).To(Equal(filepath.Base(inPath) + ".zip")) 427 }) 428 }) 429 430 When("the buildpack path points to an empty directory", func() { 431 BeforeEach(func() { 432 var err error 433 inPath, err = ioutil.TempDir("", "some-empty-dir") 434 Expect(err).ToNot(HaveOccurred()) 435 436 tmpDirPath, err = ioutil.TempDir("", "buildpackdir-") 437 Expect(err).ToNot(HaveOccurred()) 438 }) 439 440 It("returns an error", func() { 441 Expect(executeErr).To(MatchError(actionerror.EmptyBuildpackDirectoryError{Path: inPath})) 442 }) 443 }) 444 445 When("the buildpack path points to a zip file", func() { 446 BeforeEach(func() { 447 inPath = "/foo/buildpacks/a.zip" 448 }) 449 450 It("returns the local filepath", func() { 451 Expect(executeErr).ToNot(HaveOccurred()) 452 Expect(fakeDownloader.DownloadCallCount()).To(Equal(0)) 453 Expect(outPath).To(Equal("/foo/buildpacks/a.zip")) 454 }) 455 }) 456 }) 457 458 Describe("RenameBuildpack", func() { 459 var ( 460 oldName string 461 newName string 462 stackName string 463 warnings Warnings 464 executeErr error 465 ) 466 467 BeforeEach(func() { 468 oldName = "some-old-name" 469 newName = "some-new-name" 470 }) 471 472 JustBeforeEach(func() { 473 warnings, executeErr = actor.RenameBuildpack(oldName, newName, stackName) 474 }) 475 476 When("the lookup succeeds", func() { 477 BeforeEach(func() { 478 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 479 {}, 480 }, 481 ccv2.Warnings{"warning-1", "warning-2"}, 482 nil) 483 }) 484 485 When("the update succeeds", func() { 486 BeforeEach(func() { 487 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{}, 488 ccv2.Warnings{"warning-3", "warning-4"}, 489 nil) 490 }) 491 It("returns warnings", func() { 492 Expect(executeErr).ToNot(HaveOccurred()) 493 Expect(warnings).To(ConsistOf("warning-1", "warning-2", "warning-3", "warning-4")) 494 }) 495 }) 496 497 When("the update errors", func() { 498 BeforeEach(func() { 499 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{}, 500 ccv2.Warnings{"warning-3", "warning-4"}, 501 errors.New("some-error")) 502 }) 503 504 It("returns the error and warnings", func() { 505 Expect(executeErr).To(MatchError("some-error")) 506 Expect(warnings).To(ConsistOf("warning-1", "warning-2", "warning-3", "warning-4")) 507 }) 508 }) 509 }) 510 511 When("the lookup errors", func() { 512 BeforeEach(func() { 513 fakeCloudControllerClient.GetBuildpacksReturns(nil, 514 ccv2.Warnings{"warning-1", "warning-2"}, 515 errors.New("some-lookup-error")) 516 }) 517 It("returns the error and warnings", func() { 518 Expect(executeErr).To(MatchError("some-lookup-error")) 519 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 520 }) 521 }) 522 }) 523 524 Describe("UpdateBuildpack", func() { 525 var ( 526 buildpack Buildpack 527 updatedBuildpack Buildpack 528 warnings Warnings 529 executeErr error 530 ) 531 532 JustBeforeEach(func() { 533 buildpack = Buildpack{ 534 Name: "some-bp-name", 535 GUID: "some-bp-guid", 536 Stack: "some-stack", 537 } 538 updatedBuildpack, warnings, executeErr = actor.UpdateBuildpack(buildpack) 539 }) 540 541 When("there are no errors", func() { 542 BeforeEach(func() { 543 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{ 544 Name: "some-bp-name", 545 GUID: "some-bp-guid", 546 Stack: "some-stack", 547 }, ccv2.Warnings{"some-warning"}, nil) 548 }) 549 550 It("returns the updated buildpack", func() { 551 Expect(executeErr).ToNot(HaveOccurred()) 552 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 553 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 554 555 Expect(updatedBuildpack).To(Equal(buildpack)) 556 }) 557 }) 558 559 When("the client errors", func() { 560 When("the buildpack is not found", func() { 561 BeforeEach(func() { 562 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, ccerror.ResourceNotFoundError{}) 563 }) 564 565 It("returns a buildpack not found error", func() { 566 Expect(executeErr).To(MatchError(actionerror.BuildpackNotFoundError{BuildpackName: "some-bp-name"})) 567 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 568 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 569 }) 570 }) 571 572 When("the buildpack already exists without a stack association", func() { 573 BeforeEach(func() { 574 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, ccerror.BuildpackAlreadyExistsWithoutStackError{}) 575 }) 576 577 It("returns a buildpack already exists without stack error", func() { 578 Expect(executeErr).To(MatchError(actionerror.BuildpackAlreadyExistsWithoutStackError{BuildpackName: "some-bp-name"})) 579 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 580 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 581 }) 582 }) 583 584 When("the buildpack already exists with a stack association", func() { 585 BeforeEach(func() { 586 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, ccerror.BuildpackAlreadyExistsForStackError{Message: "some-message"}) 587 }) 588 589 It("returns a buildpack already exists for stack error", func() { 590 Expect(executeErr).To(MatchError(actionerror.BuildpackAlreadyExistsForStackError{Message: "some-message"})) 591 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 592 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 593 }) 594 }) 595 596 When("the client returns a generic error", func() { 597 BeforeEach(func() { 598 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{}, ccv2.Warnings{"some-warning"}, errors.New("some-error")) 599 }) 600 601 It("returns the error", func() { 602 Expect(executeErr).To(MatchError("some-error")) 603 Expect(warnings).To(ConsistOf(Warnings{"some-warning"})) 604 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 605 }) 606 }) 607 }) 608 }) 609 610 Describe("UpdateBuildpackByNameAndStack", func() { 611 var ( 612 expectedError error 613 warnings Warnings 614 executeErr error 615 newPosition types.NullInt 616 newLocked types.NullBool 617 newEnabled types.NullBool 618 fakeProgressBar *v2actionfakes.FakeSimpleProgressBar 619 updatedBuildpackGuid string 620 stackName string 621 ) 622 623 JustBeforeEach(func() { 624 fakeProgressBar = new(v2actionfakes.FakeSimpleProgressBar) 625 updatedBuildpackGuid, warnings, executeErr = actor.UpdateBuildpackByNameAndStack("some-bp-name", stackName, newPosition, newLocked, newEnabled) 626 }) 627 628 When("stack is an empty string", func() { 629 BeforeEach(func() { 630 stackName = "" 631 }) 632 633 It("gets the buildpack by name only", func() { 634 args := fakeCloudControllerClient.GetBuildpacksArgsForCall(0) 635 Expect(len(args)).To(Equal(1)) 636 Expect(args[0].Values[0]).To(Equal("some-bp-name")) 637 }) 638 }) 639 640 When("a non-empty stack name is passed", func() { 641 BeforeEach(func() { 642 stackName = "some-stack" 643 }) 644 645 It("gets the buildpack by name and stack", func() { 646 args := fakeCloudControllerClient.GetBuildpacksArgsForCall(0) 647 Expect(len(args)).To(Equal(2)) 648 Expect(args[0].Values[0]).To(Equal("some-bp-name")) 649 Expect(args[1].Values[0]).To(Equal(stackName)) 650 }) 651 }) 652 653 When("getting the buildpack fails", func() { 654 BeforeEach(func() { 655 expectedError = errors.New("some-error") 656 fakeCloudControllerClient.GetBuildpacksReturns(nil, nil, expectedError) 657 }) 658 659 It("returns the error", func() { 660 Expect(executeErr).To(MatchError(expectedError)) 661 }) 662 }) 663 664 When("getting the buildpack succeeds", func() { 665 BeforeEach(func() { 666 fakeCloudControllerClient.GetBuildpacksReturns([]ccv2.Buildpack{ 667 ccv2.Buildpack{}}, ccv2.Warnings{"get warning"}, nil) 668 }) 669 670 It("does not return an error", func() { 671 Expect(executeErr).ToNot(HaveOccurred()) 672 }) 673 674 It("returns any warnings", func() { 675 Expect(warnings).To(ConsistOf("get warning")) 676 }) 677 678 When("no changes to the buildpack record are specified", func() { 679 BeforeEach(func() { 680 newPosition = types.NullInt{} 681 newLocked = types.NullBool{} 682 newEnabled = types.NullBool{} 683 }) 684 685 It("doesn't call the CC API", func() { 686 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(0)) 687 }) 688 }) 689 690 When("a new position is specified", func() { 691 BeforeEach(func() { 692 newPosition = types.NullInt{IsSet: true, Value: 3} 693 newLocked = types.NullBool{} 694 newEnabled = types.NullBool{} 695 }) 696 697 It("makes an API call to update the position", func() { 698 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 699 passedBuildpack := fakeCloudControllerClient.UpdateBuildpackArgsForCall(0) 700 Expect(passedBuildpack.Position).To(Equal(newPosition)) 701 }) 702 }) 703 704 When("a new locked state is specified", func() { 705 BeforeEach(func() { 706 newPosition = types.NullInt{} 707 newLocked = types.NullBool{IsSet: true, Value: true} 708 newEnabled = types.NullBool{} 709 }) 710 711 It("makes an API call to update the locked state", func() { 712 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 713 passedBuildpack := fakeCloudControllerClient.UpdateBuildpackArgsForCall(0) 714 Expect(passedBuildpack.Locked).To(Equal(newLocked)) 715 }) 716 }) 717 718 When("a new enabled state is specified", func() { 719 BeforeEach(func() { 720 newPosition = types.NullInt{} 721 newLocked = types.NullBool{} 722 newEnabled = types.NullBool{IsSet: true, Value: true} 723 }) 724 725 It("makes an API call to update the enabled state", func() { 726 Expect(fakeCloudControllerClient.UpdateBuildpackCallCount()).To(Equal(1)) 727 passedBuildpack := fakeCloudControllerClient.UpdateBuildpackArgsForCall(0) 728 Expect(passedBuildpack.Enabled).To(Equal(newEnabled)) 729 }) 730 }) 731 732 When("some arguments are specified and buildpack record update is needed", func() { 733 BeforeEach(func() { 734 newPosition = types.NullInt{IsSet: true, Value: 3} 735 newLocked = types.NullBool{IsSet: true, Value: true} 736 newEnabled = types.NullBool{IsSet: true, Value: true} 737 }) 738 739 When("updating the buildpack record returns an error", func() { 740 BeforeEach(func() { 741 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{}, nil, errors.New("failed")) 742 }) 743 744 It("returns the error", func() { 745 Expect(executeErr).To(MatchError("failed")) 746 }) 747 }) 748 749 When("updating the buildpack record succeeds", func() { 750 BeforeEach(func() { 751 fakeCloudControllerClient.UpdateBuildpackReturns(ccv2.Buildpack{GUID: "some guid"}, ccv2.Warnings{"update warning"}, nil) 752 }) 753 754 It("does not return an error", func() { 755 Expect(executeErr).ToNot(HaveOccurred()) 756 }) 757 758 It("returns any warnings", func() { 759 Expect(warnings).To(ConsistOf("get warning", "update warning")) 760 }) 761 }) 762 }) 763 }) 764 }) 765 766 Describe("UploadBuildpack", func() { 767 var ( 768 bpFile io.Reader 769 bpFilePath string 770 fakePb *v2actionfakes.FakeSimpleProgressBar 771 772 warnings Warnings 773 executeErr error 774 ) 775 776 BeforeEach(func() { 777 bpFile = strings.NewReader("") 778 }) 779 780 JustBeforeEach(func() { 781 fakePb = new(v2actionfakes.FakeSimpleProgressBar) 782 fakePb.InitializeReturns(bpFile, 0, nil) 783 bpFilePath = "tmp/buildpack.zip" 784 warnings, executeErr = actor.UploadBuildpack("some-bp-guid", bpFilePath, fakePb) 785 }) 786 787 It("tracks the progress of the upload", func() { 788 Expect(executeErr).ToNot(HaveOccurred()) 789 Expect(fakePb.InitializeCallCount()).To(Equal(1)) 790 Expect(fakePb.InitializeArgsForCall(0)).To(Equal(bpFilePath)) 791 Expect(fakePb.TerminateCallCount()).To(Equal(1)) 792 }) 793 794 When("the upload errors", func() { 795 BeforeEach(func() { 796 fakeCloudControllerClient.UploadBuildpackReturns(ccv2.Warnings{"some-upload-warning"}, errors.New("some-upload-error")) 797 }) 798 799 It("returns warnings and errors", func() { 800 Expect(warnings).To(ConsistOf("some-upload-warning")) 801 Expect(executeErr).To(MatchError("some-upload-error")) 802 }) 803 }) 804 805 When("the cc returns an error because the buildpack and stack combo already exists", func() { 806 BeforeEach(func() { 807 fakeCloudControllerClient.UploadBuildpackReturns(ccv2.Warnings{"some-upload-warning"}, ccerror.BuildpackAlreadyExistsForStackError{Message: "ya blew it"}) 808 }) 809 810 It("returns warnings and a BuildpackAlreadyExistsForStackError", func() { 811 Expect(warnings).To(ConsistOf("some-upload-warning")) 812 Expect(executeErr).To(MatchError(actionerror.BuildpackAlreadyExistsForStackError{Message: "ya blew it"})) 813 }) 814 }) 815 816 When("the upload is successful", func() { 817 BeforeEach(func() { 818 fakeCloudControllerClient.UploadBuildpackReturns(ccv2.Warnings{"some-create-warning"}, nil) 819 }) 820 821 It("uploads the buildpack and returns any warnings", func() { 822 Expect(executeErr).ToNot(HaveOccurred()) 823 Expect(fakeCloudControllerClient.UploadBuildpackCallCount()).To(Equal(1)) 824 guid, path, pbReader, size := fakeCloudControllerClient.UploadBuildpackArgsForCall(0) 825 Expect(guid).To(Equal("some-bp-guid")) 826 Expect(size).To(Equal(int64(0))) 827 Expect(path).To(Equal(bpFilePath)) 828 Expect(pbReader).To(Equal(bpFile)) 829 Expect(warnings).To(ConsistOf("some-create-warning")) 830 }) 831 }) 832 }) 833 834 Describe("Zipit", func() { 835 //tested in buildpack_linux_test.go and buildpack_windows_test.go 836 var ( 837 source string 838 target string 839 840 executeErr error 841 ) 842 843 JustBeforeEach(func() { 844 executeErr = Zipit(source, target, "testzip-") 845 }) 846 847 When("the source directory does not exist", func() { 848 BeforeEach(func() { 849 source = "" 850 target = "" 851 }) 852 853 It("returns an error", func() { 854 Expect(os.IsNotExist(executeErr)).To(BeTrue()) 855 }) 856 }) 857 }) 858 })