github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v7/restart_command_test.go (about) 1 package v7_test 2 3 import ( 4 "errors" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 "code.cloudfoundry.org/cli/actor/v7action" 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 9 "code.cloudfoundry.org/cli/command/commandfakes" 10 "code.cloudfoundry.org/cli/command/flag" 11 v7 "code.cloudfoundry.org/cli/command/v7" 12 "code.cloudfoundry.org/cli/command/v7/v7fakes" 13 "code.cloudfoundry.org/cli/types" 14 "code.cloudfoundry.org/cli/util/configv3" 15 "code.cloudfoundry.org/cli/util/ui" 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 . "github.com/onsi/gomega/gbytes" 19 ) 20 21 var _ = Describe("restart Command", func() { 22 var ( 23 cmd v7.RestartCommand 24 testUI *ui.UI 25 fakeConfig *commandfakes.FakeConfig 26 fakeSharedActor *commandfakes.FakeSharedActor 27 fakeActor *v7fakes.FakeRestartActor 28 binaryName string 29 executeErr error 30 app string 31 ) 32 33 BeforeEach(func() { 34 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 35 fakeConfig = new(commandfakes.FakeConfig) 36 fakeSharedActor = new(commandfakes.FakeSharedActor) 37 fakeActor = new(v7fakes.FakeRestartActor) 38 39 binaryName = "faceman" 40 fakeConfig.BinaryNameReturns(binaryName) 41 app = "some-app" 42 43 cmd = v7.RestartCommand{ 44 RequiredArgs: flag.AppName{AppName: app}, 45 46 UI: testUI, 47 Config: fakeConfig, 48 SharedActor: fakeSharedActor, 49 Actor: fakeActor, 50 } 51 }) 52 53 JustBeforeEach(func() { 54 executeErr = cmd.Execute(nil) 55 }) 56 57 When("checking target fails", func() { 58 BeforeEach(func() { 59 fakeSharedActor.CheckTargetReturns(actionerror.NoOrganizationTargetedError{BinaryName: binaryName}) 60 }) 61 62 It("returns an error", func() { 63 Expect(executeErr).To(MatchError(actionerror.NoOrganizationTargetedError{BinaryName: binaryName})) 64 65 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 66 checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0) 67 Expect(checkTargetedOrg).To(BeTrue()) 68 Expect(checkTargetedSpace).To(BeTrue()) 69 }) 70 }) 71 72 When("the user is not logged in", func() { 73 var expectedErr error 74 75 BeforeEach(func() { 76 expectedErr = errors.New("some current user error") 77 fakeConfig.CurrentUserReturns(configv3.User{}, expectedErr) 78 }) 79 80 It("return an error", func() { 81 Expect(executeErr).To(Equal(expectedErr)) 82 }) 83 }) 84 85 When("the user is logged in", func() { 86 BeforeEach(func() { 87 fakeConfig.TargetedOrganizationReturns(configv3.Organization{ 88 Name: "some-org", 89 }) 90 fakeConfig.TargetedSpaceReturns(configv3.Space{ 91 Name: "some-space", 92 GUID: "some-space-guid", 93 }) 94 fakeConfig.CurrentUserReturns(configv3.User{Name: "steve"}, nil) 95 }) 96 97 It("delegates to actor.GetApplicationByNameAndSpace", func() { 98 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 99 actualAppName, actualSpaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 100 Expect(actualAppName).To(Equal(app)) 101 Expect(actualSpaceGUID).To(Equal("some-space-guid")) 102 }) 103 104 When("Getting the application fails", func() { 105 BeforeEach(func() { 106 fakeActor.GetApplicationByNameAndSpaceReturns( 107 v7action.Application{}, 108 v7action.Warnings{"get-app-warning"}, 109 errors.New("get-app-error"), 110 ) 111 }) 112 113 It("displays all warnings and returns an error", func() { 114 Expect(executeErr).To(MatchError("get-app-error")) 115 Expect(testUI.Err).To(Say("get-app-warning")) 116 }) 117 }) 118 119 When("getting the application succeeds", func() { 120 BeforeEach(func() { 121 fakeActor.GetApplicationByNameAndSpaceReturns( 122 v7action.Application{GUID: "app-guid"}, 123 v7action.Warnings{"get-app-warning"}, 124 nil, 125 ) 126 }) 127 128 When("The deployment strategy is set to rolling", func() { 129 BeforeEach(func() { 130 cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyRolling} 131 }) 132 133 It("does not stop and start the app", func() { 134 Expect(fakeActor.StopApplicationCallCount()).To(Equal(0)) 135 Expect(fakeActor.StartApplicationCallCount()).To(Equal(0)) 136 }) 137 138 It("delegates to actor.CreateDeployment", func() { 139 Expect(fakeActor.CreateDeploymentCallCount()).To(Equal(1)) 140 actualAppGUID, actualDropletGUID := fakeActor.CreateDeploymentArgsForCall(0) 141 Expect(actualAppGUID).To(Equal("app-guid")) 142 Expect(actualDropletGUID).To(BeEmpty()) 143 }) 144 145 When("Creating the deployment fails", func() { 146 BeforeEach(func() { 147 fakeActor.CreateDeploymentReturns("", v7action.Warnings{"create-deployment-warning"}, errors.New("create deployment failed")) 148 }) 149 150 It("returns an error and displays warnings", func() { 151 Expect(executeErr).To(MatchError("create deployment failed")) 152 Expect(testUI.Err).To(Say("get-app-warning")) 153 Expect(testUI.Err).To(Say("create-deployment-warning")) 154 }) 155 }) 156 157 When("creating the deployment succeeds", func() { 158 BeforeEach(func() { 159 fakeActor.CreateDeploymentReturns( 160 "deployment-guid", 161 v7action.Warnings{"create-deployment-warning"}, 162 nil, 163 ) 164 }) 165 166 When("the no wait flag is set", func() { 167 BeforeEach(func() { 168 cmd.NoWait = true 169 }) 170 171 It("calls poll start for rolling with no wait true", func() { 172 Expect(fakeActor.PollStartForRollingCallCount()).To(Equal(1)) 173 actualAppGUID, actualDeploymentGUID, actualNoWait := fakeActor.PollStartForRollingArgsForCall(0) 174 Expect(actualAppGUID).To(Equal("app-guid")) 175 Expect(actualDeploymentGUID).To(Equal("deployment-guid")) 176 Expect(actualNoWait).To(BeTrue()) 177 }) 178 }) 179 180 It("calls poll start for rolling with no wait true", func() { 181 Expect(fakeActor.PollStartForRollingCallCount()).To(Equal(1)) 182 actualAppGUID, actualDeploymentGUID, actualNoWait := fakeActor.PollStartForRollingArgsForCall(0) 183 Expect(actualAppGUID).To(Equal("app-guid")) 184 Expect(actualDeploymentGUID).To(Equal("deployment-guid")) 185 Expect(actualNoWait).To(BeFalse()) 186 }) 187 188 When("polling start fails", func() { 189 BeforeEach(func() { 190 fakeActor.PollStartForRollingReturns( 191 v7action.Warnings{"rolling-poll-warning"}, 192 errors.New("rolling-poll-error"), 193 ) 194 }) 195 196 It("displays all warnings and errors", func() { 197 Expect(executeErr).To(MatchError("rolling-poll-error")) 198 Expect(testUI.Err).To(Say("get-app-warning")) 199 Expect(testUI.Err).To(Say("create-deployment-warning")) 200 Expect(testUI.Err).To(Say("rolling-poll-warning")) 201 }) 202 }) 203 204 When("polling start succeeds", func() { 205 BeforeEach(func() { 206 fakeActor.PollStartForRollingReturns( 207 v7action.Warnings{"rolling-poll-warning"}, 208 nil, 209 ) 210 }) 211 212 It("succeeds and prints warnings", func() { 213 Expect(executeErr).NotTo(HaveOccurred()) 214 Expect(testUI.Err).To(Say("get-app-warning")) 215 Expect(testUI.Err).To(Say("create-deployment-warning")) 216 Expect(testUI.Err).To(Say("rolling-poll-warning")) 217 }) 218 219 }) 220 }) 221 222 }) 223 224 When("stop app does not return an error", func() { 225 BeforeEach(func() { 226 fakeActor.StopApplicationReturns(v7action.Warnings{"stop-warning-1", "stop-warning-2"}, nil) 227 }) 228 229 When("start app does not return an error", func() { 230 BeforeEach(func() { 231 fakeActor.StartApplicationReturns(v7action.Warnings{"start-warning-1", "start-warning-2"}, nil) 232 }) 233 234 When("polling the app does not return an error", func() { 235 BeforeEach(func() { 236 fakeActor.PollStartReturns(v7action.Warnings{"poll-warning-1", "poll-warning-2"}, nil) 237 }) 238 239 When("get app does not return an error", func() { 240 Context("if the app was already started", func() { 241 BeforeEach(func() { 242 fakeActor.GetApplicationByNameAndSpaceReturns(v7action.Application{GUID: "some-app-guid", State: constant.ApplicationStarted}, v7action.Warnings{"get-warning-1", "get-warning-2"}, nil) 243 }) 244 245 It("says that the app was stopped, then started, and outputs warnings", func() { 246 Expect(executeErr).ToNot(HaveOccurred()) 247 248 Expect(testUI.Err).To(Say("get-warning-1")) 249 Expect(testUI.Err).To(Say("get-warning-2")) 250 251 Expect(testUI.Out).To(Say(`Restarting app some-app in org some-org / space some-space as steve\.\.\.`)) 252 Expect(testUI.Err).To(Say("stop-warning-1")) 253 Expect(testUI.Err).To(Say("stop-warning-2")) 254 Expect(testUI.Out).To(Say(`Stopping app\.\.\.`)) 255 256 Expect(testUI.Err).To(Say("start-warning-1")) 257 Expect(testUI.Err).To(Say("start-warning-2")) 258 259 Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`)) 260 261 Expect(testUI.Err).To(Say("poll-warning-1")) 262 Expect(testUI.Err).To(Say("poll-warning-2")) 263 264 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 265 appName, spaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 266 Expect(appName).To(Equal("some-app")) 267 Expect(spaceGUID).To(Equal("some-space-guid")) 268 269 Expect(fakeActor.StopApplicationCallCount()).To(Equal(1)) 270 appGUID := fakeActor.StopApplicationArgsForCall(0) 271 Expect(appGUID).To(Equal("some-app-guid")) 272 273 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 274 appGUID = fakeActor.StartApplicationArgsForCall(0) 275 Expect(appGUID).To(Equal("some-app-guid")) 276 277 Expect(fakeActor.PollStartCallCount()).To(Equal(1)) 278 appGUID, noWait := fakeActor.PollStartArgsForCall(0) 279 Expect(appGUID).To(Equal("some-app-guid")) 280 Expect(noWait).To(Equal(false)) 281 }) 282 }) 283 284 Context("if the app was not already started", func() { 285 BeforeEach(func() { 286 fakeActor.GetApplicationByNameAndSpaceReturns(v7action.Application{GUID: "some-app-guid", State: constant.ApplicationStopped}, v7action.Warnings{"get-warning-1", "get-warning-2"}, nil) 287 }) 288 289 It("says that the app was stopped, then started, and outputs warnings", func() { 290 Expect(executeErr).ToNot(HaveOccurred()) 291 292 Expect(testUI.Err).To(Say("get-warning-1")) 293 Expect(testUI.Err).To(Say("get-warning-2")) 294 295 Expect(testUI.Out).To(Say(`Restarting app some-app in org some-org / space some-space as steve\.\.\.`)) 296 Expect(testUI.Out).ToNot(Say("Stopping")) 297 Expect(testUI.Err).ToNot(Say("stop-warning")) 298 299 Expect(testUI.Err).To(Say("start-warning-1")) 300 Expect(testUI.Err).To(Say("start-warning-2")) 301 302 Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`)) 303 Expect(testUI.Err).To(Say("poll-warning-1")) 304 Expect(testUI.Err).To(Say("poll-warning-2")) 305 306 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 307 appName, spaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 308 Expect(appName).To(Equal("some-app")) 309 Expect(spaceGUID).To(Equal("some-space-guid")) 310 311 Expect(fakeActor.StopApplicationCallCount()).To(BeZero(), "Expected StopApplication to not be called") 312 313 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 314 appGUID := fakeActor.StartApplicationArgsForCall(0) 315 Expect(appGUID).To(Equal("some-app-guid")) 316 317 Expect(fakeActor.PollStartCallCount()).To(Equal(1)) 318 appGUID, noWait := fakeActor.PollStartArgsForCall(0) 319 Expect(appGUID).To(Equal("some-app-guid")) 320 Expect(noWait).To(Equal(false)) 321 }) 322 }) 323 }) 324 325 When("the get app call returns an error", func() { 326 Context("which is an ApplicationNotFoundError", func() { 327 BeforeEach(func() { 328 fakeActor.GetApplicationByNameAndSpaceReturns(v7action.Application{}, v7action.Warnings{"get-warning-1", "get-warning-2"}, actionerror.ApplicationNotFoundError{Name: app}) 329 }) 330 331 It("says that the app wasn't found", func() { 332 Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app})) 333 Expect(testUI.Out).ToNot(Say("Stopping")) 334 Expect(testUI.Out).ToNot(Say("Waiting for app to start")) 335 336 Expect(testUI.Err).To(Say("get-warning-1")) 337 Expect(testUI.Err).To(Say("get-warning-2")) 338 339 Expect(fakeActor.StopApplicationCallCount()).To(BeZero(), "Expected StopApplication to not be called") 340 Expect(fakeActor.StartApplicationCallCount()).To(BeZero(), "Expected StartApplication to not be called") 341 }) 342 343 When("it is an unknown error", func() { 344 var expectedErr error 345 346 BeforeEach(func() { 347 expectedErr = errors.New("some get app error") 348 fakeActor.GetApplicationByNameAndSpaceReturns(v7action.Application{State: constant.ApplicationStopped}, v7action.Warnings{"get-warning-1", "get-warning-2"}, expectedErr) 349 }) 350 351 It("says that the app failed to start", func() { 352 Expect(executeErr).To(Equal(expectedErr)) 353 Expect(testUI.Out).ToNot(Say("Stopping")) 354 Expect(testUI.Out).ToNot(Say("Waiting for app to start")) 355 356 Expect(testUI.Err).To(Say("get-warning-1")) 357 Expect(testUI.Err).To(Say("get-warning-2")) 358 359 Expect(fakeActor.StopApplicationCallCount()).To(BeZero(), "Expected StopApplication to not be called") 360 Expect(fakeActor.StartApplicationCallCount()).To(BeZero(), "Expected StartApplication to not be called") 361 }) 362 }) 363 }) 364 }) 365 }) 366 }) 367 368 When("the start app call returns an error", func() { 369 BeforeEach(func() { 370 fakeActor.GetApplicationByNameAndSpaceReturns(v7action.Application{GUID: "some-app-guid", State: constant.ApplicationStarted}, v7action.Warnings{"get-warning-1", "get-warning-2"}, nil) 371 }) 372 373 Context("and the error is some random error", func() { 374 var expectedErr error 375 376 BeforeEach(func() { 377 expectedErr = errors.New("some start error") 378 fakeActor.StartApplicationReturns(v7action.Warnings{"start-warning-1", "start-warning-2"}, expectedErr) 379 }) 380 381 It("says that the app failed to start", func() { 382 Expect(executeErr).To(Equal(expectedErr)) 383 Expect(testUI.Out).To(Say(`Restarting app some-app in org some-org / space some-space as steve\.\.\.`)) 384 Expect(testUI.Out).NotTo(Say(`Waiting for app to start\.\.\.`)) 385 386 Expect(testUI.Err).To(Say("get-warning-1")) 387 Expect(testUI.Err).To(Say("get-warning-2")) 388 Expect(testUI.Err).To(Say("start-warning-1")) 389 Expect(testUI.Err).To(Say("start-warning-2")) 390 391 Expect(fakeActor.PollStartCallCount()).To(BeZero(), "Expected PollStart to not be called") 392 }) 393 }) 394 395 When("the start app call returns an ApplicationNotFoundError (someone else deleted app after we fetched app)", func() { 396 BeforeEach(func() { 397 fakeActor.StartApplicationReturns(v7action.Warnings{"start-warning-1", "start-warning-2"}, actionerror.ApplicationNotFoundError{Name: app}) 398 }) 399 400 It("says that the app failed to start", func() { 401 Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app})) 402 Expect(testUI.Out).To(Say(`Restarting app some-app in org some-org / space some-space as steve\.\.\.`)) 403 Expect(testUI.Out).NotTo(Say(`Waiting for app to start\.\.\.`)) 404 405 Expect(testUI.Err).To(Say("get-warning-1")) 406 Expect(testUI.Err).To(Say("get-warning-2")) 407 Expect(testUI.Err).To(Say("start-warning-1")) 408 Expect(testUI.Err).To(Say("start-warning-2")) 409 410 Expect(fakeActor.PollStartCallCount()).To(BeZero(), "Expected PollStart to not be called") 411 }) 412 }) 413 }) 414 }) 415 416 When("the stop app call returns an error", func() { 417 BeforeEach(func() { 418 fakeActor.GetApplicationByNameAndSpaceReturns(v7action.Application{GUID: "some-app-guid", State: constant.ApplicationStarted}, v7action.Warnings{"get-warning-1", "get-warning-2"}, nil) 419 }) 420 421 Context("and the error is some random error", func() { 422 var expectedErr error 423 424 BeforeEach(func() { 425 expectedErr = errors.New("some stop error") 426 fakeActor.StopApplicationReturns(v7action.Warnings{"stop-warning-1", "stop-warning-2"}, expectedErr) 427 }) 428 429 It("says that the app failed to start", func() { 430 Expect(executeErr).To(Equal(expectedErr)) 431 Expect(testUI.Out).To(Say(`Restarting app some-app in org some-org / space some-space as steve\.\.\.`)) 432 Expect(testUI.Out).To(Say(`Stopping app\.\.\.`)) 433 Expect(testUI.Err).To(Say("get-warning-1")) 434 Expect(testUI.Err).To(Say("get-warning-2")) 435 Expect(testUI.Err).To(Say("stop-warning-1")) 436 Expect(testUI.Err).To(Say("stop-warning-2")) 437 438 Expect(fakeActor.StartApplicationCallCount()).To(BeZero(), "Expected StartApplication to not be called") 439 }) 440 }) 441 442 When("the stop app call returns a ApplicationNotFoundError (someone else deleted app after we fetched summary)", func() { 443 BeforeEach(func() { 444 fakeActor.StopApplicationReturns(v7action.Warnings{"stop-warning-1", "stop-warning-2"}, actionerror.ApplicationNotFoundError{Name: app}) 445 }) 446 447 It("says that the app failed to start", func() { 448 Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app})) 449 Expect(testUI.Out).To(Say(`Restarting app some-app in org some-org / space some-space as steve\.\.\.`)) 450 451 Expect(testUI.Err).To(Say("get-warning-1")) 452 Expect(testUI.Err).To(Say("get-warning-2")) 453 Expect(testUI.Err).To(Say("stop-warning-1")) 454 Expect(testUI.Err).To(Say("stop-warning-2")) 455 456 Expect(fakeActor.StartApplicationCallCount()).To(BeZero(), "Expected StartApplication to not be called") 457 }) 458 }) 459 }) 460 461 }) 462 }) 463 464 When("getting the application summary returns an error", func() { 465 var expectedErr error 466 467 BeforeEach(func() { 468 expectedErr = actionerror.ApplicationNotFoundError{Name: app} 469 fakeActor.GetDetailedAppSummaryReturns(v7action.DetailedApplicationSummary{}, v7action.Warnings{"warning-1", "warning-2"}, expectedErr) 470 }) 471 472 It("returns the error and prints warnings", func() { 473 Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app})) 474 475 Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`)) 476 477 Expect(testUI.Err).To(Say("warning-1")) 478 Expect(testUI.Err).To(Say("warning-2")) 479 }) 480 }) 481 482 When("getting the application summary is successful", func() { 483 BeforeEach(func() { 484 fakeConfig.TargetedSpaceReturns(configv3.Space{ 485 Name: "some-space", 486 GUID: "some-space-guid", 487 }) 488 summary := v7action.DetailedApplicationSummary{ 489 ApplicationSummary: v7action.ApplicationSummary{ 490 Application: v7action.Application{ 491 Name: "some-app", 492 State: constant.ApplicationStarted, 493 }, 494 ProcessSummaries: v7action.ProcessSummaries{ 495 { 496 Process: v7action.Process{ 497 Type: constant.ProcessTypeWeb, 498 Command: *types.NewFilteredString("some-command-1"), 499 }, 500 }, 501 { 502 Process: v7action.Process{ 503 Type: "console", 504 Command: *types.NewFilteredString("some-command-2"), 505 }, 506 }, 507 }, 508 }, 509 CurrentDroplet: v7action.Droplet{ 510 Stack: "cflinuxfs2", 511 Buildpacks: []v7action.DropletBuildpack{ 512 { 513 Name: "ruby_buildpack", 514 DetectOutput: "some-detect-output", 515 }, 516 { 517 Name: "some-buildpack", 518 DetectOutput: "", 519 }, 520 }, 521 }, 522 } 523 fakeActor.GetDetailedAppSummaryReturns(summary, v7action.Warnings{"warning-1", "warning-2"}, nil) 524 }) 525 526 It("prints the application summary and outputs warnings", func() { 527 Expect(executeErr).ToNot(HaveOccurred()) 528 529 Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`)) 530 Expect(testUI.Out).To(Say(`name:\s+some-app`)) 531 Expect(testUI.Out).To(Say(`requested state:\s+started`)) 532 Expect(testUI.Out).ToNot(Say("start command:")) 533 534 Expect(testUI.Err).To(Say("warning-1")) 535 Expect(testUI.Err).To(Say("warning-2")) 536 537 Expect(fakeActor.GetDetailedAppSummaryCallCount()).To(Equal(1)) 538 appName, spaceGUID, withObfuscatedValues := fakeActor.GetDetailedAppSummaryArgsForCall(0) 539 Expect(appName).To(Equal("some-app")) 540 Expect(spaceGUID).To(Equal("some-space-guid")) 541 Expect(withObfuscatedValues).To(BeFalse()) 542 }) 543 }) 544 })