github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/actor/v2action/application_test.go (about) 1 package v2action_test 2 3 import ( 4 "errors" 5 "time" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 . "code.cloudfoundry.org/cli/actor/v2action" 9 "code.cloudfoundry.org/cli/actor/v2action/v2actionfakes" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2" 12 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 13 "code.cloudfoundry.org/cli/types" 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("Application Actions", func() { 19 var ( 20 actor *Actor 21 fakeCloudControllerClient *v2actionfakes.FakeCloudControllerClient 22 fakeConfig *v2actionfakes.FakeConfig 23 ) 24 25 BeforeEach(func() { 26 actor, fakeCloudControllerClient, _, fakeConfig = NewTestActor() 27 fakeConfig.DialTimeoutReturns(time.Millisecond) 28 }) 29 30 Describe("Application", func() { 31 var app Application 32 BeforeEach(func() { 33 app = Application{} 34 }) 35 36 Describe("CalculatedCommand", func() { 37 When("command is set", func() { 38 BeforeEach(func() { 39 app.Command = types.FilteredString{IsSet: true, Value: "foo"} 40 app.DetectedStartCommand = types.FilteredString{IsSet: true, Value: "bar"} 41 }) 42 43 It("returns back the command", func() { 44 Expect(app.CalculatedCommand()).To(Equal("foo")) 45 }) 46 }) 47 48 Context("only detected start command is set", func() { 49 BeforeEach(func() { 50 app.DetectedStartCommand = types.FilteredString{IsSet: true, Value: "bar"} 51 }) 52 53 It("returns back the detected start command", func() { 54 Expect(app.CalculatedCommand()).To(Equal("bar")) 55 }) 56 }) 57 58 Context("neither command nor detected start command are set", func() { 59 It("returns an empty string", func() { 60 Expect(app.CalculatedCommand()).To(BeEmpty()) 61 }) 62 }) 63 }) 64 65 Describe("CalculatedBuildpack", func() { 66 When("buildpack is set", func() { 67 BeforeEach(func() { 68 app.Buildpack = types.FilteredString{IsSet: true, Value: "foo"} 69 app.DetectedBuildpack = types.FilteredString{IsSet: true, Value: "bar"} 70 }) 71 72 It("returns back the buildpack", func() { 73 Expect(app.CalculatedBuildpack()).To(Equal("foo")) 74 }) 75 }) 76 77 Context("only detected buildpack is set", func() { 78 BeforeEach(func() { 79 app.DetectedBuildpack = types.FilteredString{IsSet: true, Value: "bar"} 80 }) 81 82 It("returns back the detected buildpack", func() { 83 Expect(app.CalculatedBuildpack()).To(Equal("bar")) 84 }) 85 }) 86 87 Context("neither buildpack nor detected buildpack are set", func() { 88 It("returns an empty string", func() { 89 Expect(app.CalculatedBuildpack()).To(BeEmpty()) 90 }) 91 }) 92 }) 93 94 Describe("CalculatedHealthCheckEndpoint", func() { 95 When("the health check type is http", func() { 96 BeforeEach(func() { 97 app.HealthCheckType = constant.ApplicationHealthCheckHTTP 98 app.HealthCheckHTTPEndpoint = "/some-endpoint" 99 }) 100 101 It("returns the endpoint field", func() { 102 Expect(app.CalculatedHealthCheckEndpoint()).To(Equal( 103 "/some-endpoint")) 104 }) 105 }) 106 107 When("the health check type is not http", func() { 108 BeforeEach(func() { 109 app.HealthCheckType = constant.ApplicationHealthCheckProcess 110 app.HealthCheckHTTPEndpoint = "/some-endpoint" 111 }) 112 113 It("returns the empty string", func() { 114 Expect(app.CalculatedHealthCheckEndpoint()).To(Equal("")) 115 }) 116 }) 117 }) 118 119 Describe("StagingCompleted", func() { 120 When("staging the application completes", func() { 121 It("returns true", func() { 122 app.PackageState = constant.ApplicationPackageStaged 123 Expect(app.StagingCompleted()).To(BeTrue()) 124 }) 125 }) 126 127 When("the application is *not* staged", func() { 128 It("returns false", func() { 129 app.PackageState = constant.ApplicationPackageFailed 130 Expect(app.StagingCompleted()).To(BeFalse()) 131 }) 132 }) 133 }) 134 135 Describe("StagingFailed", func() { 136 When("staging the application fails", func() { 137 It("returns true", func() { 138 app.PackageState = constant.ApplicationPackageFailed 139 Expect(app.StagingFailed()).To(BeTrue()) 140 }) 141 }) 142 143 When("staging the application does *not* fail", func() { 144 It("returns false", func() { 145 app.PackageState = constant.ApplicationPackageStaged 146 Expect(app.StagingFailed()).To(BeFalse()) 147 }) 148 }) 149 }) 150 151 Describe("StagingFailedMessage", func() { 152 When("the application has a staging failed description", func() { 153 BeforeEach(func() { 154 app.StagingFailedDescription = "An app was not successfully detected by any available buildpack" 155 app.StagingFailedReason = "NoAppDetectedError" 156 }) 157 It("returns that description", func() { 158 Expect(app.StagingFailedMessage()).To(Equal("An app was not successfully detected by any available buildpack")) 159 }) 160 }) 161 162 When("the application does not have a staging failed description", func() { 163 BeforeEach(func() { 164 app.StagingFailedDescription = "" 165 app.StagingFailedReason = "NoAppDetectedError" 166 }) 167 It("returns the staging failed code", func() { 168 Expect(app.StagingFailedMessage()).To(Equal("NoAppDetectedError")) 169 }) 170 }) 171 }) 172 173 Describe("StagingFailedNoAppDetected", func() { 174 When("staging the application fails due to a no app detected error", func() { 175 It("returns true", func() { 176 app.StagingFailedReason = "NoAppDetectedError" 177 Expect(app.StagingFailedNoAppDetected()).To(BeTrue()) 178 }) 179 }) 180 181 When("staging the application fails due to any other reason", func() { 182 It("returns false", func() { 183 app.StagingFailedReason = "InsufficientResources" 184 Expect(app.StagingFailedNoAppDetected()).To(BeFalse()) 185 }) 186 }) 187 }) 188 189 Describe("Started", func() { 190 When("app is started", func() { 191 It("returns true", func() { 192 Expect(Application{State: constant.ApplicationStarted}.Started()).To(BeTrue()) 193 }) 194 }) 195 196 When("app is stopped", func() { 197 It("returns false", func() { 198 Expect(Application{State: constant.ApplicationStopped}.Started()).To(BeFalse()) 199 }) 200 }) 201 }) 202 203 Describe("Stopped", func() { 204 When("app is started", func() { 205 It("returns true", func() { 206 Expect(Application{State: constant.ApplicationStopped}.Stopped()).To(BeTrue()) 207 }) 208 }) 209 210 When("app is stopped", func() { 211 It("returns false", func() { 212 Expect(Application{State: constant.ApplicationStarted}.Stopped()).To(BeFalse()) 213 }) 214 }) 215 }) 216 }) 217 218 Describe("CreateApplication", func() { 219 When("the create is successful", func() { 220 var expectedApp ccv2.Application 221 BeforeEach(func() { 222 expectedApp = ccv2.Application{ 223 GUID: "some-app-guid", 224 Name: "some-app-name", 225 SpaceGUID: "some-space-guid", 226 } 227 fakeCloudControllerClient.CreateApplicationReturns(expectedApp, ccv2.Warnings{"some-app-warning-1"}, nil) 228 }) 229 230 It("creates and returns the application", func() { 231 newApp := Application{ 232 Name: "some-app-name", 233 SpaceGUID: "some-space-guid", 234 } 235 app, warnings, err := actor.CreateApplication(newApp) 236 Expect(err).ToNot(HaveOccurred()) 237 Expect(warnings).To(ConsistOf("some-app-warning-1")) 238 Expect(app).To(Equal(Application(expectedApp))) 239 240 Expect(fakeCloudControllerClient.CreateApplicationCallCount()).To(Equal(1)) 241 Expect(fakeCloudControllerClient.CreateApplicationArgsForCall(0)).To(Equal(ccv2.Application(newApp))) 242 }) 243 }) 244 245 When("the client returns back an error", func() { 246 var expectedErr error 247 BeforeEach(func() { 248 expectedErr = errors.New("some create app error") 249 fakeCloudControllerClient.CreateApplicationReturns(ccv2.Application{}, ccv2.Warnings{"some-app-warning-1"}, expectedErr) 250 }) 251 252 It("returns warnings and an error", func() { 253 newApp := Application{ 254 Name: "some-app-name", 255 SpaceGUID: "some-space-guid", 256 } 257 _, warnings, err := actor.CreateApplication(newApp) 258 Expect(warnings).To(ConsistOf("some-app-warning-1")) 259 Expect(err).To(MatchError(expectedErr)) 260 }) 261 }) 262 }) 263 264 Describe("GetApplication", func() { 265 When("the application exists", func() { 266 BeforeEach(func() { 267 fakeCloudControllerClient.GetApplicationReturns( 268 ccv2.Application{ 269 GUID: "some-app-guid", 270 Name: "some-app", 271 }, 272 ccv2.Warnings{"foo"}, 273 nil, 274 ) 275 }) 276 277 It("returns the application and warnings", func() { 278 app, warnings, err := actor.GetApplication("some-app-guid") 279 Expect(err).ToNot(HaveOccurred()) 280 Expect(app).To(Equal(Application{ 281 GUID: "some-app-guid", 282 Name: "some-app", 283 })) 284 Expect(warnings).To(ConsistOf("foo")) 285 286 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(1)) 287 Expect(fakeCloudControllerClient.GetApplicationArgsForCall(0)).To(Equal("some-app-guid")) 288 }) 289 }) 290 291 When("the application does not exist", func() { 292 BeforeEach(func() { 293 fakeCloudControllerClient.GetApplicationReturns(ccv2.Application{}, nil, ccerror.ResourceNotFoundError{}) 294 }) 295 296 It("returns an ApplicationNotFoundError", func() { 297 _, _, err := actor.GetApplication("some-app-guid") 298 Expect(err).To(MatchError(actionerror.ApplicationNotFoundError{GUID: "some-app-guid"})) 299 }) 300 }) 301 }) 302 303 Describe("GetApplicationByNameAndSpace", func() { 304 When("the application exists", func() { 305 BeforeEach(func() { 306 fakeCloudControllerClient.GetApplicationsReturns( 307 []ccv2.Application{ 308 { 309 GUID: "some-app-guid", 310 Name: "some-app", 311 }, 312 }, 313 ccv2.Warnings{"foo"}, 314 nil, 315 ) 316 }) 317 318 It("returns the application and warnings", func() { 319 app, warnings, err := actor.GetApplicationByNameAndSpace("some-app", "some-space-guid") 320 Expect(err).ToNot(HaveOccurred()) 321 Expect(app).To(Equal(Application{ 322 GUID: "some-app-guid", 323 Name: "some-app", 324 })) 325 Expect(warnings).To(ConsistOf("foo")) 326 327 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 328 Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf([]ccv2.Filter{ 329 ccv2.Filter{ 330 Type: constant.NameFilter, 331 Operator: constant.EqualOperator, 332 Values: []string{"some-app"}, 333 }, 334 ccv2.Filter{ 335 Type: constant.SpaceGUIDFilter, 336 Operator: constant.EqualOperator, 337 Values: []string{"some-space-guid"}, 338 }, 339 })) 340 }) 341 }) 342 343 When("the application does not exists", func() { 344 BeforeEach(func() { 345 fakeCloudControllerClient.GetApplicationsReturns([]ccv2.Application{}, nil, nil) 346 }) 347 348 It("returns an ApplicationNotFoundError", func() { 349 _, _, err := actor.GetApplicationByNameAndSpace("some-app", "some-space-guid") 350 Expect(err).To(MatchError(actionerror.ApplicationNotFoundError{Name: "some-app"})) 351 }) 352 }) 353 354 When("the cloud controller client returns an error", func() { 355 var expectedError error 356 357 BeforeEach(func() { 358 expectedError = errors.New("I am a CloudControllerClient Error") 359 fakeCloudControllerClient.GetApplicationsReturns([]ccv2.Application{}, nil, expectedError) 360 }) 361 362 It("returns the error", func() { 363 _, _, err := actor.GetApplicationByNameAndSpace("some-app", "some-space-guid") 364 Expect(err).To(MatchError(expectedError)) 365 }) 366 }) 367 }) 368 369 Describe("GetApplicationsBySpace", func() { 370 When("the there are applications in the space", func() { 371 BeforeEach(func() { 372 fakeCloudControllerClient.GetApplicationsReturns( 373 []ccv2.Application{ 374 { 375 GUID: "some-app-guid-1", 376 Name: "some-app-1", 377 }, 378 { 379 GUID: "some-app-guid-2", 380 Name: "some-app-2", 381 }, 382 }, 383 ccv2.Warnings{"warning-1", "warning-2"}, 384 nil, 385 ) 386 }) 387 388 It("returns the application and warnings", func() { 389 apps, warnings, err := actor.GetApplicationsBySpace("some-space-guid") 390 Expect(err).ToNot(HaveOccurred()) 391 Expect(apps).To(ConsistOf( 392 Application{ 393 GUID: "some-app-guid-1", 394 Name: "some-app-1", 395 }, 396 Application{ 397 GUID: "some-app-guid-2", 398 Name: "some-app-2", 399 }, 400 )) 401 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 402 403 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 404 Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf([]ccv2.Filter{ 405 ccv2.Filter{ 406 Type: constant.SpaceGUIDFilter, 407 Operator: constant.EqualOperator, 408 Values: []string{"some-space-guid"}, 409 }, 410 })) 411 }) 412 }) 413 414 When("the cloud controller client returns an error", func() { 415 var expectedError error 416 417 BeforeEach(func() { 418 expectedError = errors.New("some cc error") 419 fakeCloudControllerClient.GetApplicationsReturns( 420 []ccv2.Application{}, 421 ccv2.Warnings{"warning-1", "warning-2"}, 422 expectedError) 423 }) 424 425 It("returns the error and warnings", func() { 426 _, warnings, err := actor.GetApplicationsBySpace("some-space-guid") 427 Expect(warnings).To(ConsistOf("warning-1", "warning-2")) 428 Expect(err).To(MatchError(expectedError)) 429 }) 430 }) 431 }) 432 433 Describe("GetRouteApplications", func() { 434 When("the CC client returns no errors", func() { 435 BeforeEach(func() { 436 fakeCloudControllerClient.GetRouteApplicationsReturns( 437 []ccv2.Application{ 438 { 439 GUID: "application-guid", 440 Name: "application-name", 441 }, 442 }, ccv2.Warnings{"route-applications-warning"}, nil) 443 }) 444 It("returns the applications bound to the route and warnings", func() { 445 applications, warnings, err := actor.GetRouteApplications("route-guid") 446 Expect(fakeCloudControllerClient.GetRouteApplicationsCallCount()).To(Equal(1)) 447 Expect(fakeCloudControllerClient.GetRouteApplicationsArgsForCall(0)).To(Equal("route-guid")) 448 449 Expect(err).ToNot(HaveOccurred()) 450 Expect(warnings).To(ConsistOf("route-applications-warning")) 451 Expect(applications).To(ConsistOf( 452 Application{ 453 GUID: "application-guid", 454 Name: "application-name", 455 }, 456 )) 457 }) 458 }) 459 460 When("the CC client returns an error", func() { 461 BeforeEach(func() { 462 fakeCloudControllerClient.GetRouteApplicationsReturns( 463 []ccv2.Application{}, ccv2.Warnings{"route-applications-warning"}, errors.New("get-route-applications-error")) 464 }) 465 466 It("returns the error and warnings", func() { 467 apps, warnings, err := actor.GetRouteApplications("route-guid") 468 Expect(fakeCloudControllerClient.GetRouteApplicationsCallCount()).To(Equal(1)) 469 Expect(fakeCloudControllerClient.GetRouteApplicationsArgsForCall(0)).To(Equal("route-guid")) 470 471 Expect(err).To(MatchError("get-route-applications-error")) 472 Expect(warnings).To(ConsistOf("route-applications-warning")) 473 Expect(apps).To(BeNil()) 474 }) 475 }) 476 }) 477 478 Describe("SetApplicationHealthCheckTypeByNameAndSpace", func() { 479 When("setting an http endpoint with a health check that is not http", func() { 480 It("returns an http health check invalid error", func() { 481 _, _, err := actor.SetApplicationHealthCheckTypeByNameAndSpace( 482 "some-app", "some-space-guid", "some-health-check-type", "/foo") 483 Expect(err).To(MatchError(actionerror.HTTPHealthCheckInvalidError{})) 484 }) 485 }) 486 487 When("the app exists", func() { 488 When("the desired health check type is different", func() { 489 BeforeEach(func() { 490 fakeCloudControllerClient.GetApplicationsReturns( 491 []ccv2.Application{ 492 {GUID: "some-app-guid"}, 493 }, 494 ccv2.Warnings{"get application warning"}, 495 nil, 496 ) 497 fakeCloudControllerClient.UpdateApplicationReturns( 498 ccv2.Application{ 499 GUID: "some-app-guid", 500 HealthCheckType: constant.ApplicationHealthCheckProcess, 501 }, 502 ccv2.Warnings{"update warnings"}, 503 nil, 504 ) 505 }) 506 507 It("sets the desired health check type and returns the warnings", func() { 508 returnedApp, warnings, err := actor.SetApplicationHealthCheckTypeByNameAndSpace( 509 "some-app", "some-space-guid", "process", "/") 510 Expect(err).ToNot(HaveOccurred()) 511 Expect(warnings).To(ConsistOf("get application warning", "update warnings")) 512 513 Expect(returnedApp).To(Equal(Application{ 514 GUID: "some-app-guid", 515 HealthCheckType: constant.ApplicationHealthCheckProcess, 516 })) 517 518 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 519 app := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 520 Expect(app).To(Equal(ccv2.Application{ 521 GUID: "some-app-guid", 522 HealthCheckType: constant.ApplicationHealthCheckProcess, 523 })) 524 }) 525 }) 526 527 When("the desired health check type is 'http'", func() { 528 When("the desired http endpoint is already set", func() { 529 BeforeEach(func() { 530 fakeCloudControllerClient.GetApplicationsReturns( 531 []ccv2.Application{ 532 {GUID: "some-app-guid", HealthCheckType: constant.ApplicationHealthCheckHTTP, HealthCheckHTTPEndpoint: "/"}, 533 }, 534 ccv2.Warnings{"get application warning"}, 535 nil, 536 ) 537 }) 538 539 It("does not send the update", func() { 540 _, warnings, err := actor.SetApplicationHealthCheckTypeByNameAndSpace( 541 "some-app", "some-space-guid", "http", "/") 542 Expect(err).ToNot(HaveOccurred()) 543 Expect(warnings).To(ConsistOf("get application warning")) 544 545 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(0)) 546 }) 547 }) 548 549 When("the desired http endpoint is not set", func() { 550 BeforeEach(func() { 551 fakeCloudControllerClient.GetApplicationsReturns( 552 []ccv2.Application{ 553 {GUID: "some-app-guid", HealthCheckType: constant.ApplicationHealthCheckHTTP, HealthCheckHTTPEndpoint: "/"}, 554 }, 555 ccv2.Warnings{"get application warning"}, 556 nil, 557 ) 558 fakeCloudControllerClient.UpdateApplicationReturns( 559 ccv2.Application{}, 560 ccv2.Warnings{"update warnings"}, 561 nil, 562 ) 563 }) 564 565 It("sets the desired health check type and returns the warnings", func() { 566 _, warnings, err := actor.SetApplicationHealthCheckTypeByNameAndSpace( 567 "some-app", "some-space-guid", "http", "/v2/anything") 568 Expect(err).ToNot(HaveOccurred()) 569 570 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 571 app := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 572 Expect(app).To(Equal(ccv2.Application{ 573 GUID: "some-app-guid", 574 HealthCheckType: constant.ApplicationHealthCheckHTTP, 575 HealthCheckHTTPEndpoint: "/v2/anything", 576 })) 577 578 Expect(warnings).To(ConsistOf("get application warning", "update warnings")) 579 }) 580 }) 581 }) 582 583 When("the application health check type is already set to the desired type", func() { 584 BeforeEach(func() { 585 fakeCloudControllerClient.GetApplicationsReturns( 586 []ccv2.Application{ 587 { 588 GUID: "some-app-guid", 589 HealthCheckType: constant.ApplicationHealthCheckProcess, 590 }, 591 }, 592 ccv2.Warnings{"get application warning"}, 593 nil, 594 ) 595 }) 596 597 It("does not update the health check type", func() { 598 returnedApp, warnings, err := actor.SetApplicationHealthCheckTypeByNameAndSpace( 599 "some-app", "some-space-guid", "process", "/") 600 Expect(err).ToNot(HaveOccurred()) 601 Expect(warnings).To(ConsistOf("get application warning")) 602 Expect(returnedApp).To(Equal(Application{ 603 GUID: "some-app-guid", 604 HealthCheckType: constant.ApplicationHealthCheckProcess, 605 })) 606 607 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(0)) 608 }) 609 }) 610 }) 611 612 When("getting the application returns an error", func() { 613 BeforeEach(func() { 614 fakeCloudControllerClient.GetApplicationsReturns( 615 []ccv2.Application{}, ccv2.Warnings{"get application warning"}, errors.New("get application error")) 616 }) 617 618 It("returns the error and warnings", func() { 619 _, warnings, err := actor.SetApplicationHealthCheckTypeByNameAndSpace( 620 "some-app", "some-space-guid", "process", "/") 621 622 Expect(warnings).To(ConsistOf("get application warning")) 623 Expect(err).To(MatchError("get application error")) 624 }) 625 }) 626 627 When("updating the application returns an error", func() { 628 var expectedErr error 629 630 BeforeEach(func() { 631 expectedErr = errors.New("foo bar") 632 fakeCloudControllerClient.GetApplicationsReturns( 633 []ccv2.Application{ 634 {GUID: "some-app-guid"}, 635 }, 636 ccv2.Warnings{"get application warning"}, 637 nil, 638 ) 639 fakeCloudControllerClient.UpdateApplicationReturns( 640 ccv2.Application{}, 641 ccv2.Warnings{"update warnings"}, 642 expectedErr, 643 ) 644 }) 645 646 It("returns the error and warnings", func() { 647 _, warnings, err := actor.SetApplicationHealthCheckTypeByNameAndSpace( 648 "some-app", "some-space-guid", "process", "/") 649 Expect(err).To(MatchError(expectedErr)) 650 Expect(warnings).To(ConsistOf("get application warning", "update warnings")) 651 }) 652 }) 653 }) 654 655 Describe("StartApplication/RestartApplication", func() { 656 var ( 657 app Application 658 659 appState <-chan ApplicationStateChange 660 warnings <-chan string 661 errs <-chan error 662 ) 663 664 BeforeEach(func() { 665 fakeConfig.StagingTimeoutReturns(time.Minute) 666 fakeConfig.StartupTimeoutReturns(time.Minute) 667 668 app = Application{ 669 GUID: "some-app-guid", 670 Name: "some-app", 671 Instances: types.NullInt{Value: 2, IsSet: true}, 672 } 673 appCount := 0 674 fakeCloudControllerClient.GetApplicationStub = func(appGUID string) (ccv2.Application, ccv2.Warnings, error) { 675 if appCount == 0 { 676 appCount++ 677 return ccv2.Application{ 678 GUID: "some-app-guid", 679 Instances: types.NullInt{Value: 2, IsSet: true}, 680 Name: "some-app", 681 PackageState: constant.ApplicationPackagePending, 682 }, ccv2.Warnings{"app-warnings-1"}, nil 683 } 684 685 return ccv2.Application{ 686 GUID: "some-app-guid", 687 Name: "some-app", 688 Instances: types.NullInt{Value: 2, IsSet: true}, 689 PackageState: constant.ApplicationPackageStaged, 690 }, ccv2.Warnings{"app-warnings-2"}, nil 691 } 692 693 instanceCount := 0 694 fakeCloudControllerClient.GetApplicationApplicationInstancesStub = func(guid string) (map[int]ccv2.ApplicationInstance, ccv2.Warnings, error) { 695 if instanceCount == 0 { 696 instanceCount++ 697 return map[int]ccv2.ApplicationInstance{ 698 0: {State: constant.ApplicationInstanceStarting}, 699 1: {State: constant.ApplicationInstanceStarting}, 700 }, ccv2.Warnings{"app-instance-warnings-1"}, nil 701 } 702 703 return map[int]ccv2.ApplicationInstance{ 704 0: {State: constant.ApplicationInstanceStarting}, 705 1: {State: constant.ApplicationInstanceRunning}, 706 }, ccv2.Warnings{"app-instance-warnings-2"}, nil 707 } 708 }) 709 710 AfterEach(func() { 711 Eventually(appState).Should(BeClosed()) 712 Eventually(warnings).Should(BeClosed()) 713 Eventually(errs).Should(BeClosed()) 714 }) 715 716 var ItHandlesStagingIssues = func() { 717 Context("staging issues", func() { 718 When("polling fails", func() { 719 var expectedErr error 720 BeforeEach(func() { 721 expectedErr = errors.New("I am a banana!!!!") 722 fakeCloudControllerClient.GetApplicationStub = func(appGUID string) (ccv2.Application, ccv2.Warnings, error) { 723 return ccv2.Application{}, ccv2.Warnings{"app-warnings-1"}, expectedErr 724 } 725 }) 726 727 It("sends the error and stops polling", func() { 728 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 729 Eventually(warnings).Should(Receive(Equal("state-warning"))) 730 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 731 Eventually(errs).Should(Receive(MatchError(expectedErr))) 732 733 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(0)) 734 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(1)) 735 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 736 }) 737 }) 738 739 When("the application fails to stage", func() { 740 Context("due to a NoAppDetectedError", func() { 741 BeforeEach(func() { 742 fakeCloudControllerClient.GetApplicationStub = func(appGUID string) (ccv2.Application, ccv2.Warnings, error) { 743 return ccv2.Application{ 744 GUID: "some-app-guid", 745 Name: "some-app", 746 Instances: types.NullInt{Value: 2, IsSet: true}, 747 PackageState: constant.ApplicationPackageFailed, 748 StagingFailedReason: "NoAppDetectedError", 749 }, ccv2.Warnings{"app-warnings-1"}, nil 750 } 751 }) 752 753 It("sends a StagingFailedNoAppDetectedError and stops polling", func() { 754 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 755 Eventually(warnings).Should(Receive(Equal("state-warning"))) 756 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 757 Eventually(errs).Should(Receive(MatchError(actionerror.StagingFailedNoAppDetectedError{Reason: "NoAppDetectedError"}))) 758 759 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(0)) 760 Expect(fakeConfig.StagingTimeoutCallCount()).To(Equal(1)) 761 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(1)) 762 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 763 }) 764 }) 765 766 Context("due to any other error", func() { 767 BeforeEach(func() { 768 fakeCloudControllerClient.GetApplicationStub = func(appGUID string) (ccv2.Application, ccv2.Warnings, error) { 769 return ccv2.Application{ 770 GUID: "some-app-guid", 771 Name: "some-app", 772 Instances: types.NullInt{Value: 2, IsSet: true}, 773 PackageState: constant.ApplicationPackageFailed, 774 StagingFailedReason: "OhNoes", 775 }, ccv2.Warnings{"app-warnings-1"}, nil 776 } 777 }) 778 779 It("sends a StagingFailedError and stops polling", func() { 780 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 781 Eventually(warnings).Should(Receive(Equal("state-warning"))) 782 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 783 Eventually(errs).Should(Receive(MatchError(actionerror.StagingFailedError{Reason: "OhNoes"}))) 784 785 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(0)) 786 Expect(fakeConfig.StagingTimeoutCallCount()).To(Equal(1)) 787 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(1)) 788 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 789 }) 790 }) 791 }) 792 793 When("the application takes too long to stage", func() { 794 BeforeEach(func() { 795 fakeConfig.StagingTimeoutReturns(0) 796 fakeCloudControllerClient.GetApplicationApplicationInstancesStub = nil 797 }) 798 799 It("sends a timeout error and stops polling", func() { 800 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 801 Eventually(warnings).Should(Receive(Equal("state-warning"))) 802 Eventually(errs).Should(Receive(MatchError(actionerror.StagingTimeoutError{AppName: "some-app", Timeout: 0}))) 803 804 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(0)) 805 Expect(fakeConfig.StagingTimeoutCallCount()).To(Equal(2)) 806 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(0)) 807 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 808 }) 809 }) 810 }) 811 } 812 813 var ItHandlesStartingIssues = func() { 814 Context("starting issues", func() { 815 When("polling fails", func() { 816 var expectedErr error 817 BeforeEach(func() { 818 expectedErr = errors.New("I am a banana!!!!") 819 fakeCloudControllerClient.GetApplicationApplicationInstancesStub = func(guid string) (map[int]ccv2.ApplicationInstance, ccv2.Warnings, error) { 820 return nil, ccv2.Warnings{"app-instance-warnings-1"}, expectedErr 821 } 822 }) 823 824 It("sends the error and stops polling", func() { 825 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 826 Eventually(warnings).Should(Receive(Equal("state-warning"))) 827 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 828 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 829 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 830 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 831 Eventually(errs).Should(Receive(MatchError(expectedErr))) 832 833 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(1)) 834 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(1)) 835 }) 836 }) 837 838 When("the application takes too long to start", func() { 839 BeforeEach(func() { 840 fakeConfig.StartupTimeoutReturns(0) 841 }) 842 843 It("sends a timeout error and stops polling", func() { 844 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 845 Eventually(warnings).Should(Receive(Equal("state-warning"))) 846 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 847 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 848 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 849 Eventually(errs).Should(Receive(MatchError(actionerror.StartupTimeoutError{Name: "some-app"}))) 850 851 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(1)) 852 Expect(fakeConfig.StartupTimeoutCallCount()).To(Equal(1)) 853 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 854 }) 855 }) 856 857 When("the application crashes", func() { 858 BeforeEach(func() { 859 fakeCloudControllerClient.GetApplicationApplicationInstancesStub = func(guid string) (map[int]ccv2.ApplicationInstance, ccv2.Warnings, error) { 860 return map[int]ccv2.ApplicationInstance{ 861 0: {State: constant.ApplicationInstanceCrashed}, 862 }, ccv2.Warnings{"app-instance-warnings-1"}, nil 863 } 864 }) 865 866 It("returns an ApplicationInstanceCrashedError and stops polling", func() { 867 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 868 Eventually(warnings).Should(Receive(Equal("state-warning"))) 869 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 870 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 871 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 872 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 873 Eventually(errs).Should(Receive(MatchError(actionerror.ApplicationInstanceCrashedError{Name: "some-app"}))) 874 875 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(1)) 876 Expect(fakeConfig.StartupTimeoutCallCount()).To(Equal(1)) 877 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(1)) 878 }) 879 }) 880 881 When("the application flaps", func() { 882 BeforeEach(func() { 883 fakeCloudControllerClient.GetApplicationApplicationInstancesStub = func(guid string) (map[int]ccv2.ApplicationInstance, ccv2.Warnings, error) { 884 return map[int]ccv2.ApplicationInstance{ 885 0: {State: constant.ApplicationInstanceFlapping}, 886 }, ccv2.Warnings{"app-instance-warnings-1"}, nil 887 } 888 }) 889 890 It("returns an ApplicationInstanceFlappingError and stops polling", func() { 891 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 892 Eventually(warnings).Should(Receive(Equal("state-warning"))) 893 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 894 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 895 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 896 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 897 Eventually(errs).Should(Receive(MatchError(actionerror.ApplicationInstanceFlappingError{Name: "some-app"}))) 898 899 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(1)) 900 Expect(fakeConfig.StartupTimeoutCallCount()).To(Equal(1)) 901 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(1)) 902 }) 903 }) 904 }) 905 } 906 907 var ItStartsApplication = func() { 908 When("the app is not running", func() { 909 It("starts and polls for an app instance", func() { 910 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 911 Eventually(warnings).Should(Receive(Equal("state-warning"))) 912 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 913 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 914 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 915 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 916 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-2"))) 917 918 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(2)) 919 920 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 921 passedApp := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 922 Expect(passedApp).To(Equal(ccv2.Application{ 923 GUID: "some-app-guid", 924 State: constant.ApplicationStarted, 925 })) 926 927 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(2)) 928 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(2)) 929 }) 930 }) 931 932 When("the app has zero instances", func() { 933 BeforeEach(func() { 934 fakeCloudControllerClient.UpdateApplicationReturns(ccv2.Application{GUID: "some-app-guid", 935 Instances: types.NullInt{Value: 0, IsSet: true}, 936 Name: "some-app", 937 }, ccv2.Warnings{"state-warning"}, nil) 938 }) 939 940 It("starts and only polls for staging to finish", func() { 941 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 942 Eventually(warnings).Should(Receive(Equal("state-warning"))) 943 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 944 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 945 Consistently(appState).ShouldNot(Receive(Equal(ApplicationStateStarting))) 946 947 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(1)) 948 949 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 950 passedApp := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 951 Expect(passedApp).To(Equal(ccv2.Application{ 952 GUID: "some-app-guid", 953 State: constant.ApplicationStarted, 954 })) 955 956 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(2)) 957 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 958 }) 959 }) 960 961 When("updating the application fails", func() { 962 var expectedErr error 963 BeforeEach(func() { 964 expectedErr = errors.New("I am a banana!!!!") 965 fakeCloudControllerClient.UpdateApplicationReturns(ccv2.Application{}, ccv2.Warnings{"state-warning"}, expectedErr) 966 }) 967 968 It("sends the update error and never polls", func() { 969 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 970 Eventually(warnings).Should(Receive(Equal("state-warning"))) 971 Eventually(errs).Should(Receive(MatchError(expectedErr))) 972 973 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(0)) 974 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(0)) 975 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 976 }) 977 }) 978 979 ItHandlesStagingIssues() 980 981 ItHandlesStartingIssues() 982 } 983 984 Describe("StartApplication", func() { 985 BeforeEach(func() { 986 fakeCloudControllerClient.UpdateApplicationReturns(ccv2.Application{GUID: "some-app-guid", 987 Instances: types.NullInt{Value: 2, IsSet: true}, 988 Name: "some-app", 989 }, ccv2.Warnings{"state-warning"}, nil) 990 }) 991 992 JustBeforeEach(func() { 993 appState, warnings, errs = actor.StartApplication(app) 994 }) 995 996 When("the app is already staged", func() { 997 BeforeEach(func() { 998 app.PackageState = constant.ApplicationPackageStaged 999 }) 1000 1001 It("does not send ApplicationStateStaging", func() { 1002 Consistently(appState).ShouldNot(Receive(Equal(ApplicationStateStaging))) 1003 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1004 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 1005 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 1006 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 1007 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 1008 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-2"))) 1009 1010 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 1011 passedApp := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 1012 Expect(passedApp).To(Equal(ccv2.Application{ 1013 GUID: "some-app-guid", 1014 State: constant.ApplicationStarted, 1015 })) 1016 }) 1017 }) 1018 1019 ItStartsApplication() 1020 }) 1021 1022 Describe("RestartApplication", func() { 1023 BeforeEach(func() { 1024 fakeCloudControllerClient.UpdateApplicationReturns(ccv2.Application{GUID: "some-app-guid", 1025 Instances: types.NullInt{Value: 2, IsSet: true}, 1026 Name: "some-app", 1027 }, ccv2.Warnings{"state-warning"}, nil) 1028 }) 1029 1030 JustBeforeEach(func() { 1031 appState, warnings, errs = actor.RestartApplication(app) 1032 }) 1033 1034 When("application is running", func() { 1035 BeforeEach(func() { 1036 app.State = constant.ApplicationStarted 1037 }) 1038 1039 It("stops, starts and polls for an app instance", func() { 1040 Eventually(appState).Should(Receive(Equal(ApplicationStateStopping))) 1041 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1042 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 1043 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1044 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 1045 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 1046 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 1047 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 1048 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-2"))) 1049 1050 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(2)) 1051 1052 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(2)) 1053 passedApp := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 1054 Expect(passedApp).To(Equal(ccv2.Application{ 1055 GUID: "some-app-guid", 1056 State: constant.ApplicationStopped, 1057 })) 1058 1059 passedApp = fakeCloudControllerClient.UpdateApplicationArgsForCall(1) 1060 Expect(passedApp).To(Equal(ccv2.Application{ 1061 GUID: "some-app-guid", 1062 State: constant.ApplicationStarted, 1063 })) 1064 1065 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(2)) 1066 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(2)) 1067 }) 1068 1069 When("updating the application to stop fails", func() { 1070 var expectedErr error 1071 BeforeEach(func() { 1072 expectedErr = errors.New("I am a banana!!!!") 1073 updateApplicationCalled := false 1074 fakeCloudControllerClient.UpdateApplicationStub = func(app ccv2.Application) (ccv2.Application, ccv2.Warnings, error) { 1075 if !updateApplicationCalled { 1076 return ccv2.Application{}, ccv2.Warnings{"state-warning"}, expectedErr 1077 } 1078 1079 updateApplicationCalled = true 1080 return ccv2.Application{GUID: "some-app-guid", 1081 Instances: types.NullInt{Value: 2, IsSet: true}, 1082 Name: "some-app", 1083 }, ccv2.Warnings{"state-warning"}, nil 1084 } 1085 }) 1086 1087 It("sends the update error and never polls", func() { 1088 Eventually(appState).Should(Receive(Equal(ApplicationStateStopping))) 1089 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1090 Eventually(errs).Should(Receive(MatchError(expectedErr))) 1091 Eventually(appState).ShouldNot(Receive(Equal(ApplicationStateStaging))) 1092 1093 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(0)) 1094 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(0)) 1095 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 1096 }) 1097 }) 1098 }) 1099 1100 When("the app is not running", func() { 1101 BeforeEach(func() { 1102 app.State = constant.ApplicationStopped 1103 }) 1104 1105 It("does not stop an app instance", func() { 1106 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 1107 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1108 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 1109 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 1110 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 1111 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 1112 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-2"))) 1113 1114 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 1115 passedApp := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 1116 Expect(passedApp).To(Equal(ccv2.Application{ 1117 GUID: "some-app-guid", 1118 State: constant.ApplicationStarted, 1119 })) 1120 }) 1121 }) 1122 1123 When("the app is already staged", func() { 1124 BeforeEach(func() { 1125 app.PackageState = constant.ApplicationPackageStaged 1126 }) 1127 1128 It("does not send ApplicationStateStaging", func() { 1129 Consistently(appState).ShouldNot(Receive(Equal(ApplicationStateStaging))) 1130 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1131 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 1132 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 1133 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 1134 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 1135 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-2"))) 1136 1137 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 1138 passedApp := fakeCloudControllerClient.UpdateApplicationArgsForCall(0) 1139 Expect(passedApp).To(Equal(ccv2.Application{ 1140 GUID: "some-app-guid", 1141 State: constant.ApplicationStarted, 1142 })) 1143 }) 1144 }) 1145 1146 ItStartsApplication() 1147 }) 1148 1149 Describe("RestageApplication", func() { 1150 JustBeforeEach(func() { 1151 appState, warnings, errs = actor.RestageApplication(app) 1152 }) 1153 1154 When("restaging succeeds", func() { 1155 BeforeEach(func() { 1156 fakeCloudControllerClient.RestageApplicationReturns(ccv2.Application{GUID: "some-app-guid", 1157 Instances: types.NullInt{Value: 2, IsSet: true}, 1158 Name: "some-app", 1159 }, ccv2.Warnings{"state-warning"}, nil) 1160 }) 1161 1162 It("restages and polls for app instances", func() { 1163 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 1164 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1165 Eventually(warnings).Should(Receive(Equal("app-warnings-1"))) 1166 Eventually(warnings).Should(Receive(Equal("app-warnings-2"))) 1167 Eventually(appState).Should(Receive(Equal(ApplicationStateStarting))) 1168 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-1"))) 1169 Eventually(warnings).Should(Receive(Equal("app-instance-warnings-2"))) 1170 1171 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(2)) 1172 1173 Expect(fakeCloudControllerClient.RestageApplicationCallCount()).To(Equal(1)) 1174 app := fakeCloudControllerClient.RestageApplicationArgsForCall(0) 1175 Expect(app).To(Equal(ccv2.Application{ 1176 GUID: "some-app-guid", 1177 })) 1178 1179 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(2)) 1180 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(2)) 1181 }) 1182 1183 ItHandlesStagingIssues() 1184 1185 ItHandlesStartingIssues() 1186 }) 1187 1188 When("restaging errors", func() { 1189 BeforeEach(func() { 1190 fakeCloudControllerClient.RestageApplicationReturns(ccv2.Application{GUID: "some-app-guid", 1191 Instances: types.NullInt{Value: 2, IsSet: true}, 1192 Name: "some-app", 1193 }, ccv2.Warnings{"state-warning"}, errors.New("some-error")) 1194 }) 1195 1196 It("sends the restage error and never polls", func() { 1197 Eventually(appState).Should(Receive(Equal(ApplicationStateStaging))) 1198 Eventually(warnings).Should(Receive(Equal("state-warning"))) 1199 Eventually(errs).Should(Receive(MatchError("some-error"))) 1200 1201 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(0)) 1202 Expect(fakeCloudControllerClient.GetApplicationCallCount()).To(Equal(0)) 1203 Expect(fakeCloudControllerClient.GetApplicationApplicationInstancesCallCount()).To(Equal(0)) 1204 }) 1205 }) 1206 }) 1207 }) 1208 1209 Describe("UpdateApplication", func() { 1210 When("the update is successful", func() { 1211 var expectedApp ccv2.Application 1212 BeforeEach(func() { 1213 expectedApp = ccv2.Application{ 1214 GUID: "some-app-guid", 1215 Name: "some-app-name", 1216 SpaceGUID: "some-space-guid", 1217 } 1218 fakeCloudControllerClient.UpdateApplicationReturns(expectedApp, ccv2.Warnings{"some-app-warning-1"}, nil) 1219 }) 1220 1221 It("updates and returns the application", func() { 1222 newApp := Application{ 1223 Name: "some-app-name", 1224 SpaceGUID: "some-space-guid", 1225 } 1226 app, warnings, err := actor.UpdateApplication(newApp) 1227 Expect(err).ToNot(HaveOccurred()) 1228 Expect(warnings).To(ConsistOf("some-app-warning-1")) 1229 Expect(app).To(Equal(Application(expectedApp))) 1230 1231 Expect(fakeCloudControllerClient.UpdateApplicationCallCount()).To(Equal(1)) 1232 Expect(fakeCloudControllerClient.UpdateApplicationArgsForCall(0)).To(Equal(ccv2.Application(newApp))) 1233 }) 1234 }) 1235 1236 When("the client returns back an error", func() { 1237 var expectedErr error 1238 BeforeEach(func() { 1239 expectedErr = errors.New("some update app error") 1240 fakeCloudControllerClient.UpdateApplicationReturns(ccv2.Application{}, ccv2.Warnings{"some-app-warning-1"}, expectedErr) 1241 }) 1242 1243 It("returns warnings and an error", func() { 1244 newApp := Application{ 1245 Name: "some-app-name", 1246 SpaceGUID: "some-space-guid", 1247 } 1248 _, warnings, err := actor.UpdateApplication(newApp) 1249 Expect(warnings).To(ConsistOf("some-app-warning-1")) 1250 Expect(err).To(MatchError(expectedErr)) 1251 }) 1252 }) 1253 }) 1254 })