github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v7/update_buildpack_command_test.go (about) 1 package v7_test 2 3 import ( 4 "errors" 5 6 "code.cloudfoundry.org/cli/actor/v7action" 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 8 "code.cloudfoundry.org/cli/command/v7/v7fakes" 9 "code.cloudfoundry.org/cli/types" 10 11 "code.cloudfoundry.org/cli/command/translatableerror" 12 13 "code.cloudfoundry.org/cli/actor/actionerror" 14 "code.cloudfoundry.org/cli/command/commandfakes" 15 "code.cloudfoundry.org/cli/command/flag" 16 . "code.cloudfoundry.org/cli/command/v7" 17 "code.cloudfoundry.org/cli/util/configv3" 18 "code.cloudfoundry.org/cli/util/ui" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 . "github.com/onsi/gomega/gbytes" 22 ) 23 24 var _ = Describe("UpdateBuildpackCommand", func() { 25 var ( 26 cmd UpdateBuildpackCommand 27 fakeSharedActor *commandfakes.FakeSharedActor 28 testUI *ui.UI 29 input *Buffer 30 fakeActor *v7fakes.FakeUpdateBuildpackActor 31 fakeConfig *commandfakes.FakeConfig 32 buildpackGUID = "buildpack-guid" 33 buildpackName = "some-bp" 34 binaryName = "faceman" 35 36 executeErr error 37 expectedErr error 38 ) 39 40 BeforeEach(func() { 41 fakeSharedActor = new(commandfakes.FakeSharedActor) 42 input = NewBuffer() 43 testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer()) 44 fakeActor = new(v7fakes.FakeUpdateBuildpackActor) 45 fakeConfig = new(commandfakes.FakeConfig) 46 buildpackGUID = "some guid" 47 48 cmd = UpdateBuildpackCommand{ 49 RequiredArgs: flag.BuildpackName{Buildpack: buildpackName}, 50 UI: testUI, 51 SharedActor: fakeSharedActor, 52 Actor: fakeActor, 53 Config: fakeConfig, 54 } 55 }) 56 57 JustBeforeEach(func() { 58 executeErr = cmd.Execute(nil) 59 }) 60 61 Describe("invalid flag combinations", func() { 62 When("the --lock and --unlock flags are provided", func() { 63 BeforeEach(func() { 64 cmd.Lock = true 65 cmd.Unlock = true 66 }) 67 68 It("returns an ArgumentCombinationError", func() { 69 Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{ 70 Args: []string{"--lock", "--unlock"}, 71 })) 72 }) 73 }) 74 75 When("the --enable and --disable flags are provided", func() { 76 BeforeEach(func() { 77 cmd.Enable = true 78 cmd.Disable = true 79 }) 80 81 It("returns an ArgumentCombinationError", func() { 82 Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{ 83 Args: []string{"--enable", "--disable"}, 84 })) 85 }) 86 }) 87 88 When("the --path and --lock flags are provided", func() { 89 BeforeEach(func() { 90 cmd.Lock = true 91 cmd.Path = "asdf" 92 }) 93 94 It("returns an ArgumentCombinationError", func() { 95 Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{ 96 Args: []string{"--path", "--lock"}, 97 })) 98 }) 99 }) 100 101 When("the --path and --assign-stack flags are provided", func() { 102 BeforeEach(func() { 103 cmd.Path = "asdf" 104 cmd.NewStack = "some-new-stack" 105 }) 106 107 It("returns an ArgumentCombinationError", func() { 108 Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{ 109 Args: []string{"--path", "--assign-stack"}, 110 })) 111 }) 112 }) 113 114 When("the --stack and --assign-stack flags are provided", func() { 115 BeforeEach(func() { 116 cmd.CurrentStack = "current-stack" 117 cmd.NewStack = "some-new-stack" 118 }) 119 120 It("returns an ArgumentCombinationError", func() { 121 Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{ 122 Args: []string{"--stack", "--assign-stack"}, 123 })) 124 }) 125 }) 126 }) 127 128 When("the environment is not set up correctly", func() { 129 BeforeEach(func() { 130 fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName}) 131 }) 132 133 It("returns an error", func() { 134 Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName})) 135 136 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 137 checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0) 138 Expect(checkTargetedOrg).To(BeFalse()) 139 Expect(checkTargetedSpace).To(BeFalse()) 140 }) 141 }) 142 143 When("the environment is setup correctly", func() { 144 When("getting the current user fails", func() { 145 BeforeEach(func() { 146 expectedErr = errors.New("some-error that happened") 147 fakeConfig.CurrentUserReturns(configv3.User{}, expectedErr) 148 }) 149 150 It("returns the error", func() { 151 Expect(executeErr).To(MatchError(expectedErr)) 152 }) 153 }) 154 155 When("getting the current user succeeds", func() { 156 var userName string 157 158 BeforeEach(func() { 159 userName = "some-user" 160 fakeConfig.CurrentUserReturns(configv3.User{Name: userName}, nil) 161 }) 162 163 When("preparing buildpack bits causes an error", func() { 164 var emptyDirectoryError error 165 BeforeEach(func() { 166 emptyDirectoryError = actionerror.EmptyBuildpackDirectoryError{Path: "some-directory"} 167 fakeActor.PrepareBuildpackBitsReturns("", emptyDirectoryError) 168 cmd.Path = "some empty directory" 169 }) 170 171 It("exits without updating if the path points to an empty directory", func() { 172 Expect(executeErr).To(MatchError(emptyDirectoryError)) 173 Expect(fakeActor.UpdateBuildpackByNameAndStackCallCount()).To(Equal(0)) 174 }) 175 }) 176 177 When("updating the buildpack fails", func() { 178 BeforeEach(func() { 179 cmd.Path = "path/to/buildpack" 180 fakeActor.PrepareBuildpackBitsReturns("path/to/prepared/bits", nil) 181 expectedErr = errors.New("update-error") 182 fakeActor.UpdateBuildpackByNameAndStackReturns( 183 v7action.Buildpack{}, 184 v7action.Warnings{"update-bp-warning1", "update-bp-warning2"}, 185 expectedErr, 186 ) 187 }) 188 189 It("returns the error and prints any warnings", func() { 190 Expect(testUI.Err).To(Say("update-bp-warning1")) 191 Expect(testUI.Err).To(Say("update-bp-warning2")) 192 Expect(executeErr).To(MatchError(expectedErr)) 193 Expect(fakeActor.UploadBuildpackCallCount()).To(Equal(0)) 194 }) 195 }) 196 197 When("the --lock flag is provided", func() { 198 BeforeEach(func() { 199 cmd.Lock = true 200 }) 201 202 It("sets the locked value to true when updating the buildpack", func() { 203 Expect(executeErr).ToNot(HaveOccurred()) 204 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 205 Expect(buildpack.Locked.IsSet).To(Equal(true)) 206 Expect(buildpack.Locked.Value).To(Equal(true)) 207 }) 208 }) 209 210 When("the --unlock flag is provided", func() { 211 BeforeEach(func() { 212 cmd.Unlock = true 213 }) 214 215 It("sets the locked value to false when updating the buildpack", func() { 216 Expect(executeErr).ToNot(HaveOccurred()) 217 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 218 Expect(buildpack.Locked.IsSet).To(Equal(true)) 219 Expect(buildpack.Locked.Value).To(Equal(false)) 220 }) 221 }) 222 223 When("the --enable flag is provided", func() { 224 BeforeEach(func() { 225 cmd.Enable = true 226 }) 227 228 It("sets the enabled value to true when updating the buildpack", func() { 229 Expect(executeErr).ToNot(HaveOccurred()) 230 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 231 Expect(buildpack.Enabled.IsSet).To(Equal(true)) 232 Expect(buildpack.Enabled.Value).To(Equal(true)) 233 }) 234 }) 235 236 When("the --disable flag is provided", func() { 237 BeforeEach(func() { 238 cmd.Disable = true 239 }) 240 241 It("sets the enabled value to false when updating the buildpack", func() { 242 Expect(executeErr).ToNot(HaveOccurred()) 243 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 244 Expect(buildpack.Enabled.IsSet).To(Equal(true)) 245 Expect(buildpack.Enabled.Value).To(Equal(false)) 246 }) 247 }) 248 249 When("the --index flag is provided", func() { 250 BeforeEach(func() { 251 cmd.Position = types.NullInt{IsSet: true, Value: 99} 252 }) 253 254 It("sets the new buildpack order when updating the buildpack", func() { 255 Expect(executeErr).ToNot(HaveOccurred()) 256 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 257 Expect(buildpack.Position.IsSet).To(Equal(true)) 258 Expect(buildpack.Position.Value).To(Equal(99)) 259 }) 260 }) 261 262 When("the --assign-stack flag is provided", func() { 263 BeforeEach(func() { 264 cmd.NewStack = "some-new-stack" 265 }) 266 267 It("sets the new stack on the buildpack", func() { 268 Expect(executeErr).ToNot(HaveOccurred()) 269 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 270 Expect(testUI.Out).ToNot(Say("Updating buildpack %s", buildpackName)) 271 Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName)) 272 Expect(buildpack.Stack).To(Equal("some-new-stack")) 273 }) 274 275 Context("and the --index flag is provided", func() { 276 BeforeEach(func() { 277 cmd.Position = types.NullInt{IsSet: true, Value: 3} 278 }) 279 280 It("sets the new stack and updates the priority of the buildpack", func() { 281 Expect(executeErr).ToNot(HaveOccurred()) 282 Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName)) 283 Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack)) 284 Expect(testUI.Out).To(Say("OK")) 285 }) 286 }) 287 288 Context("and the --lock flag is provided", func() { 289 BeforeEach(func() { 290 cmd.Lock = true 291 }) 292 293 It("sets the new stack and locks the buildpack", func() { 294 Expect(executeErr).ToNot(HaveOccurred()) 295 Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName)) 296 Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack)) 297 Expect(testUI.Out).To(Say("OK")) 298 }) 299 }) 300 301 Context("and the --unlock flag is provided", func() { 302 BeforeEach(func() { 303 cmd.Unlock = true 304 }) 305 306 It("sets the new stack and unlocks the buildpack", func() { 307 Expect(executeErr).ToNot(HaveOccurred()) 308 Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName)) 309 Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack)) 310 Expect(testUI.Out).To(Say("OK")) 311 }) 312 }) 313 314 Context("and the --enable flag is provided", func() { 315 BeforeEach(func() { 316 cmd.Enable = true 317 }) 318 319 It("sets the new stack and enables the buildpack", func() { 320 Expect(executeErr).ToNot(HaveOccurred()) 321 Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName)) 322 Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack)) 323 Expect(testUI.Out).To(Say("OK")) 324 }) 325 }) 326 327 Context("and the --disable flag is provided", func() { 328 BeforeEach(func() { 329 cmd.Disable = true 330 }) 331 332 It("sets the new stack and disables the buildpack", func() { 333 Expect(executeErr).ToNot(HaveOccurred()) 334 Expect(testUI.Out).To(Say("Assigning stack %s to %s as %s...", cmd.NewStack, buildpackName, userName)) 335 Expect(testUI.Out).To(Say("Updating buildpack %s with stack %s...", buildpackName, cmd.NewStack)) 336 Expect(testUI.Out).To(Say("OK")) 337 }) 338 }) 339 340 }) 341 342 When("the --rename flag is provided", func() { 343 BeforeEach(func() { 344 cmd.NewName = "new-buildpack-name" 345 }) 346 347 It("sets the new name on the buildpack", func() { 348 Expect(executeErr).ToNot(HaveOccurred()) 349 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 350 Expect(buildpack.Name).To(Equal("new-buildpack-name")) 351 352 Expect(testUI.Out).ToNot(Say("Updating buildpack %s", buildpackName)) 353 Expect(testUI.Out).To(Say( 354 "Renaming buildpack %s to %s as %s...", buildpackName, cmd.NewName, userName)) 355 Expect(testUI.Out).To(Say("OK")) 356 }) 357 358 Context("and the --assign-stack flag is provided", func() { 359 BeforeEach(func() { 360 cmd.NewStack = "new-stack" 361 }) 362 363 It("sets the new name/stack on the buildpack and refers to the new name going forward", func() { 364 Expect(executeErr).ToNot(HaveOccurred()) 365 _, _, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 366 Expect(buildpack.Name).To(Equal("new-buildpack-name")) 367 Expect(buildpack.Stack).To(Equal("new-stack")) 368 369 Expect(testUI.Out).To(Say( 370 "Renaming buildpack %s to %s as %s...", buildpackName, cmd.NewName, userName)) 371 372 Expect(testUI.Out).To(Say( 373 "Assigning stack %s to %s as %s", cmd.NewStack, cmd.NewName, userName)) 374 375 Expect(testUI.Out).ToNot(Say("Updating buildpack %s", buildpackName)) 376 377 Expect(testUI.Out).To(Say("OK")) 378 }) 379 }) 380 }) 381 382 When("updating the buildpack succeeds", func() { 383 BeforeEach(func() { 384 fakeActor.UpdateBuildpackByNameAndStackReturns( 385 v7action.Buildpack{GUID: buildpackGUID}, 386 v7action.Warnings{"update-bp-warning1", "update-bp-warning2"}, 387 nil, 388 ) 389 }) 390 391 When("no arguments are specified", func() { 392 It("makes the actor call to update the buildpack", func() { 393 Expect(fakeActor.UpdateBuildpackByNameAndStackCallCount()).To(Equal(1)) 394 _, newStack, buildpack := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 395 Expect(buildpack.Name).To(Equal("")) 396 Expect(buildpack.Stack).To(Equal("")) 397 Expect(buildpack.Position.IsSet).To(BeFalse()) 398 Expect(buildpack.Locked.IsSet).To(BeFalse()) 399 Expect(buildpack.Enabled.IsSet).To(BeFalse()) 400 Expect(newStack).To(Equal("")) 401 402 Expect(testUI.Err).To(Say("update-bp-warning1")) 403 Expect(testUI.Err).To(Say("update-bp-warning2")) 404 Expect(testUI.Out).To(Say("Updating buildpack %s as %s...", buildpackName, userName)) 405 Expect(testUI.Out).To(Say("OK")) 406 }) 407 }) 408 409 When("a path is specified", func() { 410 BeforeEach(func() { 411 cmd.Path = "some path" 412 }) 413 414 It("makes the call to update the buildpack", func() { 415 Expect(fakeActor.UpdateBuildpackByNameAndStackCallCount()).To(Equal(1)) 416 buildpackNameArg, _, _ := fakeActor.UpdateBuildpackByNameAndStackArgsForCall(0) 417 Expect(buildpackNameArg).To(Equal(buildpackName)) 418 419 Expect(testUI.Err).To(Say("update-bp-warning1")) 420 Expect(testUI.Err).To(Say("update-bp-warning2")) 421 Expect(testUI.Out).To(Say("Updating buildpack %s as %s...", buildpackName, userName)) 422 Expect(testUI.Out).To(Say("OK")) 423 }) 424 425 When("preparing the bits succeeds", func() { 426 buildpackBitsPath := "some path on the file system" 427 BeforeEach(func() { 428 fakeActor.PrepareBuildpackBitsReturns(buildpackBitsPath, nil) 429 }) 430 431 It("uploads the new buildpack bits", func() { 432 Expect(testUI.Out).To(Say("Uploading buildpack some-bp as some-user...")) 433 Expect(fakeActor.UploadBuildpackCallCount()).To(Equal(1)) 434 buildpackGUIDUsed, pathUsed, _ := fakeActor.UploadBuildpackArgsForCall(0) 435 Expect(buildpackGUIDUsed).To(Equal(buildpackGUID)) 436 Expect(pathUsed).To(Equal(buildpackBitsPath)) 437 }) 438 439 When("uploading the buildpack fails", func() { 440 441 When("the client returns invalid auth token", func() { 442 BeforeEach(func() { 443 fakeActor.UploadBuildpackReturns("", v7action.Warnings{"some-create-bp-with-auth-warning"}, ccerror.InvalidAuthTokenError{Message: "token expired"}) 444 }) 445 446 It("alerts the user and retries the upload", func() { 447 Expect(testUI.Err).To(Say("Failed to upload buildpack due to auth token expiration, retrying...")) 448 Expect(fakeActor.UploadBuildpackCallCount()).To(Equal(2)) 449 }) 450 }) 451 452 When("a non token error occurs", func() { 453 BeforeEach(func() { 454 expectedErr = errors.New("upload error") 455 fakeActor.UploadBuildpackReturns("", v7action.Warnings{"upload-warning1", "upload-warning2"}, expectedErr) 456 }) 457 458 It("returns all warnings and an error", func() { 459 Expect(testUI.Err).To(Say("update-bp-warning1")) 460 Expect(testUI.Err).To(Say("update-bp-warning2")) 461 Expect(testUI.Err).To(Say("upload-warning1")) 462 Expect(testUI.Err).To(Say("upload-warning2")) 463 Expect(executeErr).To(MatchError(expectedErr)) 464 }) 465 }) 466 }) 467 468 When("uploading the buildpack succeeds", func() { 469 BeforeEach(func() { 470 fakeActor.UploadBuildpackReturns( 471 "example.com/job/url/", 472 v7action.Warnings{"upload-warning1", "upload-warning2"}, 473 nil, 474 ) 475 }) 476 477 When("polling the buildpack job fails", func() { 478 BeforeEach(func() { 479 expectedErr = ccerror.JobTimeoutError{JobGUID: "job-guid"} 480 fakeActor.PollUploadBuildpackJobReturns( 481 v7action.Warnings{"poll-warning1", "poll-warning2"}, 482 expectedErr, 483 ) 484 }) 485 486 It("returns all warnings and an error", func() { 487 Expect(testUI.Err).To(Say("update-bp-warning1")) 488 Expect(testUI.Err).To(Say("update-bp-warning2")) 489 Expect(testUI.Err).To(Say("poll-warning1")) 490 Expect(testUI.Err).To(Say("poll-warning2")) 491 Expect(executeErr).To(MatchError(expectedErr)) 492 }) 493 }) 494 495 When("polling the buildpack job succeeds", func() { 496 BeforeEach(func() { 497 fakeActor.PollUploadBuildpackJobReturns( 498 v7action.Warnings{"poll-warning1", "poll-warning2"}, 499 nil, 500 ) 501 }) 502 503 It("displays success test and any warnings", func() { 504 Expect(testUI.Out).To(Say(`Uploading buildpack %s`, buildpackName)) 505 Expect(testUI.Err).To(Say("upload-warning1")) 506 Expect(testUI.Err).To(Say("upload-warning2")) 507 Expect(testUI.Out).To(Say("OK")) 508 509 Expect(testUI.Out).To(Say(`Processing uploaded buildpack %s\.\.\.`, buildpackName)) 510 Expect(testUI.Err).To(Say("poll-warning1")) 511 Expect(testUI.Err).To(Say("poll-warning2")) 512 Expect(testUI.Out).To(Say("OK")) 513 }) 514 }) 515 }) 516 }) 517 }) 518 }) 519 }) 520 }) 521 })