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