github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/actor/pushaction/application_test.go (about) 1 package pushaction_test 2 3 import ( 4 "errors" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 . "code.cloudfoundry.org/cli/actor/pushaction" 8 "code.cloudfoundry.org/cli/actor/pushaction/pushactionfakes" 9 "code.cloudfoundry.org/cli/actor/v2action" 10 "code.cloudfoundry.org/cli/actor/v3action" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 12 "code.cloudfoundry.org/cli/types" 13 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 . "github.com/onsi/gomega/gstruct" 17 ) 18 19 var _ = Describe("Applications", func() { 20 var ( 21 actor *Actor 22 fakeV2Actor *pushactionfakes.FakeV2Actor 23 fakeV3Actor *pushactionfakes.FakeV3Actor 24 ) 25 26 BeforeEach(func() { 27 fakeV2Actor = new(pushactionfakes.FakeV2Actor) 28 fakeV3Actor = new(pushactionfakes.FakeV3Actor) 29 actor = NewActor(fakeV2Actor, fakeV3Actor, nil) 30 }) 31 32 Describe("UpdateApplication", func() { 33 var ( 34 config ApplicationConfig 35 36 returnedConfig ApplicationConfig 37 event Event 38 warnings Warnings 39 executeErr error 40 41 updatedApplication v2action.Application 42 ) 43 44 BeforeEach(func() { 45 config = ApplicationConfig{ 46 DesiredApplication: Application{ 47 Application: v2action.Application{ 48 Name: "some-app-name", 49 GUID: "some-app-guid", 50 SpaceGUID: "some-space-guid", 51 }, 52 }, 53 CurrentApplication: Application{ 54 Application: v2action.Application{ 55 Name: "some-app-name", 56 GUID: "some-app-guid", 57 SpaceGUID: "some-space-guid", 58 }, 59 }, 60 Path: "some-path", 61 } 62 }) 63 64 JustBeforeEach(func() { 65 returnedConfig, event, warnings, executeErr = actor.UpdateApplication(config) 66 }) 67 68 Context("when the update is successful", func() { 69 BeforeEach(func() { 70 updatedApplication = v2action.Application{ 71 Name: "some-app-name", 72 GUID: "some-app-guid", 73 SpaceGUID: "some-space-guid", 74 Buildpack: types.FilteredString{Value: "ruby", IsSet: true}, 75 } 76 fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil) 77 }) 78 79 It("updates the application", func() { 80 Expect(executeErr).ToNot(HaveOccurred()) 81 Expect(warnings).To(ConsistOf("update-warning")) 82 Expect(event).To(Equal(UpdatedApplication)) 83 84 Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication)) 85 Expect(returnedConfig.CurrentApplication).To(Equal(returnedConfig.DesiredApplication)) 86 87 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 88 submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0) 89 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 90 "Name": Equal("some-app-name"), 91 "GUID": Equal("some-app-guid"), 92 "SpaceGUID": Equal("some-space-guid"), 93 })) 94 }) 95 }) 96 97 Context("when the update errors", func() { 98 var expectedErr error 99 BeforeEach(func() { 100 expectedErr = errors.New("oh my") 101 fakeV2Actor.UpdateApplicationReturns(v2action.Application{}, v2action.Warnings{"update-warning"}, expectedErr) 102 }) 103 104 It("returns warnings and error and stops", func() { 105 Expect(executeErr).To(MatchError(expectedErr)) 106 Expect(warnings).To(ConsistOf("update-warning")) 107 }) 108 }) 109 110 Context("State", func() { 111 Context("when the state is not being updated", func() { 112 BeforeEach(func() { 113 config.CurrentApplication.State = "some-state" 114 config.DesiredApplication.State = "some-state" 115 }) 116 117 It("does not send the state on update", func() { 118 Expect(executeErr).ToNot(HaveOccurred()) 119 120 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 121 Expect(fakeV2Actor.UpdateApplicationArgsForCall(0)).To(MatchFields(IgnoreExtras, Fields{ 122 "Name": Equal("some-app-name"), 123 "GUID": Equal("some-app-guid"), 124 "SpaceGUID": Equal("some-space-guid"), 125 })) 126 }) 127 }) 128 }) 129 130 Context("StackGUID", func() { 131 Context("when the stack guid is not being updated", func() { 132 BeforeEach(func() { 133 config.CurrentApplication.StackGUID = "some-stack-guid" 134 config.DesiredApplication.StackGUID = "some-stack-guid" 135 }) 136 137 It("does not send the stack guid on update", func() { 138 Expect(executeErr).ToNot(HaveOccurred()) 139 140 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 141 Expect(fakeV2Actor.UpdateApplicationArgsForCall(0)).To(MatchFields(IgnoreExtras, Fields{ 142 "Name": Equal("some-app-name"), 143 "GUID": Equal("some-app-guid"), 144 "SpaceGUID": Equal("some-space-guid"), 145 })) 146 }) 147 }) 148 }) 149 150 Context("Buildpack(s)", func() { 151 var ( 152 buildpack types.FilteredString 153 buildpacks []string 154 ) 155 156 BeforeEach(func() { 157 buildpack = types.FilteredString{} 158 buildpacks = nil 159 }) 160 161 Context("when buildpack is set", func() { 162 BeforeEach(func() { 163 buildpack = types.FilteredString{Value: "ruby", IsSet: true} 164 config.DesiredApplication.Buildpack = buildpack 165 166 updatedApplication = v2action.Application{Buildpack: buildpack} 167 fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil) 168 }) 169 170 It("keeps buildpack in the desired application", func() { 171 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 172 submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0) 173 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 174 "Buildpack": Equal(buildpack), 175 })) 176 177 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0)) 178 Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication)) 179 }) 180 }) 181 182 Context("when builpacks is set as an empty array (autodetect)", func() { 183 BeforeEach(func() { 184 buildpacks = []string{} 185 config.DesiredApplication.Buildpacks = buildpacks 186 187 updatedApplication = v2action.Application{Buildpack: types.FilteredString{ 188 Value: "", 189 IsSet: true, 190 }} 191 fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil) 192 }) 193 194 It("sets buildpack to the only provided buildpack in buildpacks", func() { 195 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 196 submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0) 197 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 198 "Buildpack": Equal(types.FilteredString{Value: "", IsSet: true}), 199 })) 200 201 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0)) 202 Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication)) 203 }) 204 }) 205 206 Context("when buildpacks is set with one buildpack", func() { 207 BeforeEach(func() { 208 buildpacks = []string{"ruby"} 209 config.DesiredApplication.Buildpacks = buildpacks 210 211 updatedApplication = v2action.Application{Buildpack: types.FilteredString{ 212 Value: buildpacks[0], 213 IsSet: true, 214 }} 215 fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil) 216 }) 217 218 It("sets buildpack to the only provided buildpack in buildpacks", func() { 219 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 220 submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0) 221 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 222 "Buildpack": Equal(types.FilteredString{Value: buildpacks[0], IsSet: true}), 223 })) 224 225 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0)) 226 Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication)) 227 }) 228 229 Context("when that buildpack is default/null", func() { 230 BeforeEach(func() { 231 buildpacks = []string{"default"} 232 config.DesiredApplication.Buildpacks = buildpacks 233 234 updatedApplication = v2action.Application{Buildpack: types.FilteredString{ 235 Value: buildpacks[0], 236 IsSet: true, 237 }} 238 fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil) 239 }) 240 241 It("sets buildpack with the empty string", func() { 242 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 243 submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0) 244 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 245 "Buildpack": Equal(types.FilteredString{IsSet: true}), 246 })) 247 }) 248 }) 249 }) 250 251 Context("when buildpacks is set with more than one buildpack", func() { 252 BeforeEach(func() { 253 buildpacks = []string{"ruby", "java"} 254 config.DesiredApplication.Buildpacks = buildpacks 255 256 updatedApplication = v2action.Application{} 257 fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil) 258 }) 259 260 It("does not set buildpack", func() { 261 Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1)) 262 submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0) 263 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 264 "Buildpack": Equal(types.FilteredString{}), 265 })) 266 267 Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication)) 268 }) 269 270 Context("when the v3 update is successful", func() { 271 var submitApp v3action.Application 272 273 BeforeEach(func() { 274 updatedApplication = config.DesiredApplication.Application 275 updatedApplication.GUID = "yay-im-a-guid" 276 submitApp = v3action.Application{ 277 Name: updatedApplication.Name, 278 GUID: updatedApplication.GUID, 279 LifecycleBuildpacks: []string{"ruby", "java"}, 280 LifecycleType: constant.AppLifecycleTypeBuildpack, 281 } 282 283 fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"v2-create-application-warnings"}, nil) 284 fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, nil) 285 }) 286 287 It("updates only the buildpacks in ccv3", func() { 288 Expect(executeErr).ToNot(HaveOccurred()) 289 Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings")) 290 291 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1)) 292 Expect(fakeV3Actor.UpdateApplicationArgsForCall(0)).To(Equal(submitApp)) 293 294 Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication)) 295 }) 296 }) 297 298 Context("when the v3 update fails", func() { 299 BeforeEach(func() { 300 fakeV2Actor.UpdateApplicationReturns(v2action.Application{}, v2action.Warnings{"v2-create-application-warnings"}, nil) 301 fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, errors.New("boom")) 302 }) 303 304 It("raises an error", func() { 305 Expect(executeErr).To(MatchError("boom")) 306 Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings")) 307 308 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1)) 309 }) 310 }) 311 }) 312 }) 313 }) 314 315 Describe("CreateApplication", func() { 316 var ( 317 config ApplicationConfig 318 319 returnedConfig ApplicationConfig 320 event Event 321 warnings Warnings 322 executeErr error 323 324 createdApplication v2action.Application 325 ) 326 327 BeforeEach(func() { 328 config = ApplicationConfig{ 329 DesiredApplication: Application{ 330 Application: v2action.Application{ 331 Name: "some-app-name", 332 SpaceGUID: "some-space-guid", 333 }, 334 }, 335 Path: "some-path", 336 } 337 }) 338 339 JustBeforeEach(func() { 340 returnedConfig, event, warnings, executeErr = actor.CreateApplication(config) 341 }) 342 343 Context("when the creation is successful", func() { 344 BeforeEach(func() { 345 createdApplication = v2action.Application{ 346 Name: "some-app-name", 347 GUID: "some-app-guid", 348 SpaceGUID: "some-space-guid", 349 } 350 351 fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil) 352 }) 353 354 It("creates the application", func() { 355 Expect(executeErr).ToNot(HaveOccurred()) 356 Expect(warnings).To(ConsistOf("create-warning")) 357 Expect(event).To(Equal(CreatedApplication)) 358 359 Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication)) 360 Expect(returnedConfig.CurrentApplication).To(Equal(returnedConfig.DesiredApplication)) 361 362 Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1)) 363 submitApp := fakeV2Actor.CreateApplicationArgsForCall(0) 364 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 365 "Name": Equal("some-app-name"), 366 "SpaceGUID": Equal("some-space-guid"), 367 })) 368 }) 369 }) 370 371 Context("when the creation errors", func() { 372 var expectedErr error 373 374 BeforeEach(func() { 375 expectedErr = errors.New("oh my") 376 fakeV2Actor.CreateApplicationReturns(v2action.Application{}, v2action.Warnings{"create-warning"}, expectedErr) 377 }) 378 379 It("sends the warnings and errors and returns true", func() { 380 Expect(executeErr).To(MatchError(expectedErr)) 381 Expect(warnings).To(ConsistOf("create-warning")) 382 }) 383 }) 384 385 Context("Buildpack(s)", func() { 386 var ( 387 buildpack types.FilteredString 388 buildpacks []string 389 ) 390 391 Context("when buildpack is set", func() { 392 BeforeEach(func() { 393 buildpack = types.FilteredString{Value: "ruby", IsSet: true} 394 config.DesiredApplication.Buildpack = buildpack 395 396 createdApplication = v2action.Application{Buildpack: buildpack} 397 fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil) 398 }) 399 400 It("keeps buildpack in the desired application", func() { 401 Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1)) 402 submitApp := fakeV2Actor.CreateApplicationArgsForCall(0) 403 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 404 "Buildpack": Equal(buildpack), 405 })) 406 407 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0)) 408 Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication)) 409 }) 410 }) 411 412 Context("when buildpacks is set with one buildpack", func() { 413 BeforeEach(func() { 414 buildpacks = []string{"ruby"} 415 config.DesiredApplication.Buildpacks = buildpacks 416 417 createdApplication = v2action.Application{Buildpack: types.FilteredString{ 418 Value: buildpacks[0], 419 IsSet: true, 420 }} 421 fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil) 422 }) 423 424 It("sets buildpack to the set buildpack in buildpacks", func() { 425 Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1)) 426 submitApp := fakeV2Actor.CreateApplicationArgsForCall(0) 427 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 428 "Buildpack": Equal(types.FilteredString{Value: buildpacks[0], IsSet: true}), 429 })) 430 431 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0)) 432 Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication)) 433 }) 434 }) 435 436 Context("when buildpacks is set with more than one buildpack", func() { 437 BeforeEach(func() { 438 buildpacks = []string{"ruby", "java"} 439 config.DesiredApplication.Buildpacks = buildpacks 440 441 createdApplication = v2action.Application{} 442 fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil) 443 }) 444 445 It("does not set buildpack", func() { 446 Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1)) 447 submitApp := fakeV2Actor.CreateApplicationArgsForCall(0) 448 Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{ 449 "Buildpack": Equal(types.FilteredString{}), 450 })) 451 452 Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication)) 453 }) 454 455 Context("when the v3 update is successful", func() { 456 var submitApp v3action.Application 457 458 BeforeEach(func() { 459 createdApplication = config.DesiredApplication.Application 460 createdApplication.GUID = "yay-im-a-guid" 461 submitApp = v3action.Application{ 462 Name: createdApplication.Name, 463 GUID: createdApplication.GUID, 464 LifecycleBuildpacks: []string{"ruby", "java"}, 465 LifecycleType: constant.AppLifecycleTypeBuildpack, 466 } 467 468 fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"v2-create-application-warnings"}, nil) 469 fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, nil) 470 }) 471 472 It("updates only the buildpacks in ccv3", func() { 473 Expect(executeErr).ToNot(HaveOccurred()) 474 Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings")) 475 476 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1)) 477 Expect(fakeV3Actor.UpdateApplicationArgsForCall(0)).To(Equal(submitApp)) 478 479 Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication)) 480 }) 481 }) 482 483 Context("when the v3 update fails", func() { 484 BeforeEach(func() { 485 fakeV2Actor.CreateApplicationReturns(v2action.Application{}, v2action.Warnings{"v2-create-application-warnings"}, nil) 486 fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, errors.New("boom")) 487 }) 488 489 It("raises an error", func() { 490 Expect(executeErr).To(MatchError("boom")) 491 Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings")) 492 493 Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1)) 494 }) 495 }) 496 }) 497 }) 498 }) 499 500 Describe("FindOrReturnPartialApp", func() { 501 var expectedStack v2action.Stack 502 var expectedApp v2action.Application 503 504 Context("when the app exists", func() { 505 Context("when retrieving the stack is successful", func() { 506 BeforeEach(func() { 507 expectedStack = v2action.Stack{ 508 Name: "some-stack", 509 GUID: "some-stack-guid", 510 } 511 fakeV2Actor.GetStackReturns(expectedStack, v2action.Warnings{"stack-warnings"}, nil) 512 513 expectedApp = v2action.Application{ 514 GUID: "some-app-guid", 515 Name: "some-app", 516 StackGUID: expectedStack.GUID, 517 } 518 fakeV2Actor.GetApplicationByNameAndSpaceReturns(expectedApp, v2action.Warnings{"app-warnings"}, nil) 519 }) 520 521 It("fills in the stack", func() { 522 found, app, warnings, err := actor.FindOrReturnPartialApp("some-app", "some-space-guid") 523 Expect(err).ToNot(HaveOccurred()) 524 Expect(warnings).To(ConsistOf("app-warnings", "stack-warnings")) 525 Expect(found).To(BeTrue()) 526 Expect(app).To(Equal(Application{ 527 Application: expectedApp, 528 Stack: expectedStack, 529 })) 530 }) 531 }) 532 533 Context("when retrieving the stack errors", func() { 534 var expectedErr error 535 536 BeforeEach(func() { 537 expectedErr = errors.New("stack stack stack em up") 538 fakeV2Actor.GetStackReturns(v2action.Stack{}, v2action.Warnings{"stack-warnings"}, expectedErr) 539 540 expectedApp = v2action.Application{ 541 GUID: "some-app-guid", 542 Name: "some-app", 543 StackGUID: "some-stack-guid", 544 } 545 fakeV2Actor.GetApplicationByNameAndSpaceReturns(expectedApp, v2action.Warnings{"app-warnings"}, nil) 546 }) 547 548 It("returns error and warnings", func() { 549 found, _, warnings, err := actor.FindOrReturnPartialApp("some-app", "some-space-guid") 550 Expect(err).To(MatchError(expectedErr)) 551 Expect(warnings).To(ConsistOf("app-warnings", "stack-warnings")) 552 Expect(found).To(BeFalse()) 553 }) 554 }) 555 }) 556 557 Context("when the app does not exist", func() { 558 BeforeEach(func() { 559 fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, actionerror.ApplicationNotFoundError{}) 560 }) 561 562 It("returns a partial app and warnings", func() { 563 found, app, warnings, err := actor.FindOrReturnPartialApp("some-app", "some-space-guid") 564 Expect(err).ToNot(HaveOccurred()) 565 Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2")) 566 Expect(found).To(BeFalse()) 567 Expect(app).To(Equal(Application{ 568 Application: v2action.Application{ 569 Name: "some-app", 570 SpaceGUID: "some-space-guid", 571 }, 572 })) 573 }) 574 }) 575 576 Context("when retrieving the app errors", func() { 577 var expectedErr error 578 BeforeEach(func() { 579 expectedErr = errors.New("dios mio") 580 fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, expectedErr) 581 }) 582 583 It("returns a errors and warnings", func() { 584 found, _, warnings, err := actor.FindOrReturnPartialApp("some-app", "some-space-guid") 585 Expect(err).To(MatchError(expectedErr)) 586 Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2")) 587 Expect(found).To(BeFalse()) 588 }) 589 }) 590 }) 591 })