github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/command/v7/scale_command_test.go (about) 1 package v7_test 2 3 import ( 4 "errors" 5 "time" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 "code.cloudfoundry.org/cli/actor/v7action" 9 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 10 "code.cloudfoundry.org/cli/command/commandfakes" 11 "code.cloudfoundry.org/cli/command/translatableerror" 12 . "code.cloudfoundry.org/cli/command/v7" 13 "code.cloudfoundry.org/cli/command/v7/v7fakes" 14 "code.cloudfoundry.org/cli/integration/helpers" 15 "code.cloudfoundry.org/cli/resources" 16 "code.cloudfoundry.org/cli/types" 17 "code.cloudfoundry.org/cli/util/configv3" 18 "code.cloudfoundry.org/cli/util/ui" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 . "github.com/onsi/gomega/gbytes" 22 ) 23 24 var _ = Describe("scale Command", func() { 25 var ( 26 cmd ScaleCommand 27 input *Buffer 28 output *Buffer 29 testUI *ui.UI 30 fakeConfig *commandfakes.FakeConfig 31 fakeSharedActor *commandfakes.FakeSharedActor 32 fakeActor *v7fakes.FakeActor 33 app resources.Application 34 binaryName string 35 executeErr error 36 ) 37 38 BeforeEach(func() { 39 input = NewBuffer() 40 output = NewBuffer() 41 testUI = ui.NewTestUI(input, output, NewBuffer()) 42 fakeConfig = new(commandfakes.FakeConfig) 43 fakeSharedActor = new(commandfakes.FakeSharedActor) 44 fakeActor = new(v7fakes.FakeActor) 45 app = resources.Application{Name: "some-app", GUID: "some-app-guid"} 46 47 cmd = ScaleCommand{ 48 BaseCommand: BaseCommand{ 49 UI: testUI, 50 Config: fakeConfig, 51 SharedActor: fakeSharedActor, 52 Actor: fakeActor, 53 }, 54 } 55 56 binaryName = "faceman" 57 fakeConfig.BinaryNameReturns(binaryName) 58 59 cmd.RequiredArgs.AppName = app.Name 60 cmd.ProcessType = constant.ProcessTypeWeb 61 }) 62 63 JustBeforeEach(func() { 64 executeErr = cmd.Execute(nil) 65 }) 66 67 When("checking target fails", func() { 68 BeforeEach(func() { 69 fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName}) 70 }) 71 72 It("returns an error", func() { 73 Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName})) 74 75 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 76 checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0) 77 Expect(checkTargetedOrg).To(BeTrue()) 78 Expect(checkTargetedSpace).To(BeTrue()) 79 }) 80 }) 81 82 When("the user is logged in, and org and space are targeted", func() { 83 BeforeEach(func() { 84 fakeConfig.HasTargetedOrganizationReturns(true) 85 fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "some-org"}) 86 fakeConfig.HasTargetedSpaceReturns(true) 87 fakeConfig.TargetedSpaceReturns(configv3.Space{ 88 GUID: "some-space-guid", 89 Name: "some-space"}) 90 fakeActor.GetCurrentUserReturns( 91 configv3.User{Name: "some-user"}, 92 nil) 93 }) 94 95 When("getting the current user returns an error", func() { 96 var expectedErr error 97 98 BeforeEach(func() { 99 expectedErr = errors.New("getting current user error") 100 fakeActor.GetCurrentUserReturns( 101 configv3.User{}, 102 expectedErr) 103 }) 104 105 It("returns the error", func() { 106 Expect(executeErr).To(MatchError(expectedErr)) 107 }) 108 }) 109 110 When("the application does not exist", func() { 111 BeforeEach(func() { 112 fakeActor.GetApplicationByNameAndSpaceReturns( 113 resources.Application{}, 114 v7action.Warnings{"get-app-warning"}, 115 actionerror.ApplicationNotFoundError{Name: app.Name}) 116 }) 117 118 It("returns an ApplicationNotFoundError and all warnings", func() { 119 Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app.Name})) 120 121 Expect(testUI.Out).ToNot(Say("Showing | Scaling")) 122 Expect(testUI.Err).To(Say("get-app-warning")) 123 124 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 125 appNameArg, spaceGUIDArg := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 126 Expect(appNameArg).To(Equal(app.Name)) 127 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 128 }) 129 }) 130 131 When("an error occurs getting the application", func() { 132 var expectedErr error 133 134 BeforeEach(func() { 135 expectedErr = errors.New("get app error") 136 fakeActor.GetApplicationByNameAndSpaceReturns( 137 resources.Application{}, 138 v7action.Warnings{"get-app-warning"}, 139 expectedErr) 140 }) 141 142 It("returns the error and displays all warnings", func() { 143 Expect(executeErr).To(Equal(expectedErr)) 144 Expect(testUI.Err).To(Say("get-app-warning")) 145 }) 146 }) 147 148 When("the application exists", func() { 149 var appSummary v7action.DetailedApplicationSummary 150 151 BeforeEach(func() { 152 appSummary = v7action.DetailedApplicationSummary{ 153 ApplicationSummary: v7action.ApplicationSummary{ 154 ProcessSummaries: v7action.ProcessSummaries{ 155 { 156 Process: resources.Process{ 157 Type: constant.ProcessTypeWeb, 158 MemoryInMB: types.NullUint64{Value: 32, IsSet: true}, 159 DiskInMB: types.NullUint64{Value: 1024, IsSet: true}, 160 LogRateLimitInBPS: types.NullInt{Value: 1024 * 10, IsSet: true}, 161 }, 162 InstanceDetails: []v7action.ProcessInstance{ 163 v7action.ProcessInstance{ 164 Index: 0, 165 State: constant.ProcessInstanceRunning, 166 MemoryUsage: 1000000, 167 DiskUsage: 1000000, 168 LogRate: 1024 * 5, 169 MemoryQuota: 33554432, 170 DiskQuota: 2000000, 171 LogRateLimit: 1024 * 10, 172 Uptime: time.Since(time.Unix(267321600, 0)), 173 }, 174 v7action.ProcessInstance{ 175 Index: 1, 176 State: constant.ProcessInstanceRunning, 177 MemoryUsage: 2000000, 178 DiskUsage: 2000000, 179 LogRate: 1024 * 3, 180 MemoryQuota: 33554432, 181 DiskQuota: 4000000, 182 LogRateLimit: 1024 * 10, 183 Uptime: time.Since(time.Unix(330480000, 0)), 184 }, 185 v7action.ProcessInstance{ 186 Index: 2, 187 State: constant.ProcessInstanceRunning, 188 MemoryUsage: 3000000, 189 DiskUsage: 3000000, 190 LogRate: 1024 * 4, 191 MemoryQuota: 33554432, 192 DiskQuota: 6000000, 193 LogRateLimit: 1024 * 10, 194 Uptime: time.Since(time.Unix(1277164800, 0)), 195 }, 196 }, 197 }, 198 { 199 Process: resources.Process{ 200 Type: "console", 201 MemoryInMB: types.NullUint64{Value: 16, IsSet: true}, 202 DiskInMB: types.NullUint64{Value: 512, IsSet: true}, 203 LogRateLimitInBPS: types.NullInt{Value: 1024 * 5, IsSet: true}, 204 }, 205 InstanceDetails: []v7action.ProcessInstance{ 206 v7action.ProcessInstance{ 207 Index: 0, 208 State: constant.ProcessInstanceRunning, 209 MemoryUsage: 1000000, 210 DiskUsage: 1000000, 211 LogRate: 1024, 212 MemoryQuota: 33554432, 213 DiskQuota: 8000000, 214 LogRateLimit: 1024 * 5, 215 Uptime: time.Since(time.Unix(167572800, 0)), 216 }, 217 }, 218 }, 219 }, 220 }, 221 } 222 223 fakeActor.GetApplicationByNameAndSpaceReturns( 224 app, 225 v7action.Warnings{"get-app-warning"}, 226 nil) 227 }) 228 229 When("no flag options are provided", func() { 230 BeforeEach(func() { 231 fakeActor.GetDetailedAppSummaryReturns( 232 appSummary, 233 v7action.Warnings{"get-app-summary-warning"}, 234 nil) 235 }) 236 237 It("displays current scale properties and all warnings", func() { 238 Expect(executeErr).ToNot(HaveOccurred()) 239 240 Expect(testUI.Out).To(Say(`Showing current scale of app some-app in org some-org / space some-space as some-user\.\.\.`)) 241 Expect(testUI.Out).ToNot(Say("Scaling | This will cause the app to restart | Stopping | Starting | Waiting")) 242 243 firstAppTable := helpers.ParseV3AppProcessTable(output.Contents()) 244 Expect(len(firstAppTable.Processes)).To(Equal(2)) 245 246 webProcessSummary := firstAppTable.Processes[0] 247 Expect(webProcessSummary.Type).To(Equal("web")) 248 Expect(webProcessSummary.InstanceCount).To(Equal("3/3")) 249 Expect(webProcessSummary.MemUsage).To(Equal("32M")) 250 251 Expect(webProcessSummary.Instances[0].Memory).To(Equal("976.6K of 32M")) 252 Expect(webProcessSummary.Instances[0].Disk).To(Equal("976.6K of 1.9M")) 253 Expect(webProcessSummary.Instances[0].CPU).To(Equal("0.0%")) 254 Expect(webProcessSummary.Instances[0].LogRate).To(Equal("5K/s of 10K/s")) 255 256 Expect(webProcessSummary.Instances[1].Memory).To(Equal("1.9M of 32M")) 257 Expect(webProcessSummary.Instances[1].Disk).To(Equal("1.9M of 3.8M")) 258 Expect(webProcessSummary.Instances[1].CPU).To(Equal("0.0%")) 259 Expect(webProcessSummary.Instances[1].LogRate).To(Equal("3K/s of 10K/s")) 260 261 Expect(webProcessSummary.Instances[2].Memory).To(Equal("2.9M of 32M")) 262 Expect(webProcessSummary.Instances[2].Disk).To(Equal("2.9M of 5.7M")) 263 Expect(webProcessSummary.Instances[2].CPU).To(Equal("0.0%")) 264 Expect(webProcessSummary.Instances[2].LogRate).To(Equal("4K/s of 10K/s")) 265 266 consoleProcessSummary := firstAppTable.Processes[1] 267 Expect(consoleProcessSummary.Type).To(Equal("console")) 268 Expect(consoleProcessSummary.InstanceCount).To(Equal("1/1")) 269 Expect(consoleProcessSummary.MemUsage).To(Equal("16M")) 270 271 Expect(consoleProcessSummary.Instances[0].Memory).To(Equal("976.6K of 32M")) 272 Expect(consoleProcessSummary.Instances[0].Disk).To(Equal("976.6K of 7.6M")) 273 Expect(consoleProcessSummary.Instances[0].CPU).To(Equal("0.0%")) 274 Expect(consoleProcessSummary.Instances[0].LogRate).To(Equal("1K/s of 5K/s")) 275 276 Expect(testUI.Err).To(Say("get-app-warning")) 277 Expect(testUI.Err).To(Say("get-app-summary-warning")) 278 279 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(0)) 280 }) 281 282 When("an error is encountered getting process information", func() { 283 var expectedErr error 284 285 BeforeEach(func() { 286 expectedErr = errors.New("get process error") 287 fakeActor.GetDetailedAppSummaryReturns( 288 v7action.DetailedApplicationSummary{}, 289 v7action.Warnings{"get-process-warning"}, 290 expectedErr, 291 ) 292 }) 293 294 It("returns the error and displays all warnings", func() { 295 Expect(executeErr).To(Equal(expectedErr)) 296 Expect(testUI.Err).To(Say("get-process-warning")) 297 }) 298 }) 299 }) 300 301 When("all flag options are provided", func() { 302 BeforeEach(func() { 303 cmd.Instances.Value = 2 304 cmd.Instances.IsSet = true 305 cmd.DiskLimit.Value = 50 306 cmd.DiskLimit.IsSet = true 307 cmd.MemoryLimit.Value = 100 308 cmd.MemoryLimit.IsSet = true 309 cmd.LogRateLimit.Value = 1024 310 cmd.LogRateLimit.IsSet = true 311 fakeActor.ScaleProcessByApplicationReturns( 312 v7action.Warnings{"scale-warning"}, 313 nil) 314 fakeActor.GetDetailedAppSummaryReturns( 315 appSummary, 316 v7action.Warnings{"get-instances-warning"}, 317 nil) 318 }) 319 320 When("force flag is not provided", func() { 321 When("the user chooses default", func() { 322 BeforeEach(func() { 323 _, err := input.Write([]byte("\n")) 324 Expect(err).ToNot(HaveOccurred()) 325 }) 326 327 It("does not scale the app", func() { 328 Expect(executeErr).ToNot(HaveOccurred()) 329 330 Expect(testUI.Out).To(Say(`Scaling app some-app in org some-org / space some-space as some-user\.\.\.`)) 331 Expect(testUI.Out).To(Say(`This will cause the app to restart\. Are you sure you want to scale some-app\? \[yN\]:`)) 332 Expect(testUI.Out).To(Say("Scaling cancelled")) 333 Expect(testUI.Out).ToNot(Say("Showing | Stopping | Starting | Waiting")) 334 335 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(0)) 336 }) 337 }) 338 339 When("the user chooses no", func() { 340 BeforeEach(func() { 341 _, err := input.Write([]byte("n\n")) 342 Expect(err).ToNot(HaveOccurred()) 343 }) 344 345 It("does not scale the app", func() { 346 Expect(executeErr).ToNot(HaveOccurred()) 347 348 Expect(testUI.Out).To(Say(`Scaling app some-app in org some-org / space some-space as some-user\.\.\.`)) 349 Expect(testUI.Out).To(Say(`This will cause the app to restart\. Are you sure you want to scale some-app\? \[yN\]:`)) 350 Expect(testUI.Out).To(Say("Scaling cancelled")) 351 Expect(testUI.Out).ToNot(Say("Showing | Stopping | Starting | Waiting")) 352 353 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(0)) 354 }) 355 }) 356 357 When("the user chooses yes", func() { 358 BeforeEach(func() { 359 _, err := input.Write([]byte("y\n")) 360 Expect(err).ToNot(HaveOccurred()) 361 }) 362 363 When("polling succeeds and the app has running instances", func() { 364 BeforeEach(func() { 365 fakeActor.PollStartReturns(v7action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}, nil) 366 }) 367 368 It("delegates the right appGUID", func() { 369 actualApp, _, handleInstanceDetails := fakeActor.PollStartArgsForCall(0) 370 Expect(actualApp).To(Equal(app)) 371 handleInstanceDetails("instance details") 372 Expect(testUI.Out).To(Say("instance details")) 373 }) 374 375 When("Restarting the app fails to stop the app", func() { 376 BeforeEach(func() { 377 fakeActor.StopApplicationReturns(v7action.Warnings{"some-restart-warning"}, errors.New("stop-error")) 378 }) 379 380 It("Prints warnings and returns an error", func() { 381 Expect(executeErr).To(MatchError("stop-error")) 382 383 Expect(testUI.Err).To(Say("some-restart-warning")) 384 }) 385 }) 386 387 When("Restarting the app fails to start the app", func() { 388 BeforeEach(func() { 389 fakeActor.StartApplicationReturns(v7action.Warnings{"some-start-warning"}, errors.New("start-error")) 390 }) 391 392 It("Delegates the correct appGUID", func() { 393 actualAppGUID := fakeActor.StartApplicationArgsForCall(0) 394 Expect(actualAppGUID).To(Equal("some-app-guid")) 395 }) 396 397 It("Prints warnings and returns an error", func() { 398 Expect(executeErr).To(MatchError("start-error")) 399 400 Expect(testUI.Err).To(Say("some-start-warning")) 401 }) 402 }) 403 404 It("scales, restarts, and displays scale properties", func() { 405 Expect(executeErr).ToNot(HaveOccurred()) 406 407 Expect(testUI.Out).To(Say(`Scaling app some-app in org some-org / space some-space as some-user\.\.\.`)) 408 Expect(testUI.Out).To(Say(`This will cause the app to restart\. Are you sure you want to scale some-app\? \[yN\]:`)) 409 Expect(testUI.Out).To(Say(`Stopping app some-app in org some-org / space some-space as some-user\.\.\.`)) 410 Expect(testUI.Out).To(Say(`Starting app some-app in org some-org / space some-space as some-user\.\.\.`)) 411 412 // Note that this does test that the disk quota was scaled to 96M, 413 // it is tested below when we check the arguments 414 // passed to ScaleProcessByApplication 415 firstAppTable := helpers.ParseV3AppProcessTable(output.Contents()) 416 Expect(len(firstAppTable.Processes)).To(Equal(2)) 417 418 webProcessSummary := firstAppTable.Processes[0] 419 Expect(webProcessSummary.Type).To(Equal("web")) 420 Expect(webProcessSummary.InstanceCount).To(Equal("3/3")) 421 Expect(webProcessSummary.MemUsage).To(Equal("32M")) 422 423 Expect(webProcessSummary.Instances[0].Memory).To(Equal("976.6K of 32M")) 424 Expect(webProcessSummary.Instances[0].Disk).To(Equal("976.6K of 1.9M")) 425 Expect(webProcessSummary.Instances[0].CPU).To(Equal("0.0%")) 426 Expect(webProcessSummary.Instances[0].LogRate).To(Equal("5K/s of 10K/s")) 427 428 Expect(webProcessSummary.Instances[1].Memory).To(Equal("1.9M of 32M")) 429 Expect(webProcessSummary.Instances[1].Disk).To(Equal("1.9M of 3.8M")) 430 Expect(webProcessSummary.Instances[1].CPU).To(Equal("0.0%")) 431 Expect(webProcessSummary.Instances[1].LogRate).To(Equal("3K/s of 10K/s")) 432 433 Expect(webProcessSummary.Instances[2].Memory).To(Equal("2.9M of 32M")) 434 Expect(webProcessSummary.Instances[2].Disk).To(Equal("2.9M of 5.7M")) 435 Expect(webProcessSummary.Instances[2].CPU).To(Equal("0.0%")) 436 Expect(webProcessSummary.Instances[2].LogRate).To(Equal("4K/s of 10K/s")) 437 438 consoleProcessSummary := firstAppTable.Processes[1] 439 Expect(consoleProcessSummary.Type).To(Equal("console")) 440 Expect(consoleProcessSummary.InstanceCount).To(Equal("1/1")) 441 Expect(consoleProcessSummary.MemUsage).To(Equal("16M")) 442 443 Expect(consoleProcessSummary.Instances[0].Memory).To(Equal("976.6K of 32M")) 444 Expect(consoleProcessSummary.Instances[0].Disk).To(Equal("976.6K of 7.6M")) 445 Expect(consoleProcessSummary.Instances[0].CPU).To(Equal("0.0%")) 446 Expect(consoleProcessSummary.Instances[0].LogRate).To(Equal("1K/s of 5K/s")) 447 448 Expect(testUI.Err).To(Say("get-app-warning")) 449 Expect(testUI.Err).To(Say("scale-warning")) 450 Expect(testUI.Err).To(Say("some-poll-warning-1")) 451 Expect(testUI.Err).To(Say("some-poll-warning-2")) 452 Expect(testUI.Err).To(Say("get-instances-warning")) 453 454 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 455 appNameArg, spaceGUIDArg := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 456 Expect(appNameArg).To(Equal(app.Name)) 457 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 458 459 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(1)) 460 appGUIDArg, scaleProcess := fakeActor.ScaleProcessByApplicationArgsForCall(0) 461 Expect(appGUIDArg).To(Equal("some-app-guid")) 462 Expect(scaleProcess).To(Equal(resources.Process{ 463 Type: constant.ProcessTypeWeb, 464 Instances: types.NullInt{Value: 2, IsSet: true}, 465 DiskInMB: types.NullUint64{Value: 50, IsSet: true}, 466 MemoryInMB: types.NullUint64{Value: 100, IsSet: true}, 467 LogRateLimitInBPS: types.NullInt{Value: 1024, IsSet: true}, 468 })) 469 470 Expect(fakeActor.StopApplicationCallCount()).To(Equal(1)) 471 Expect(fakeActor.StopApplicationArgsForCall(0)).To(Equal("some-app-guid")) 472 473 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 474 Expect(fakeActor.StartApplicationArgsForCall(0)).To(Equal("some-app-guid")) 475 }) 476 }) 477 478 When("polling succeeds but all the app's instances have crashed", func() { 479 BeforeEach(func() { 480 fakeActor.PollStartReturns(v7action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}, actionerror.AllInstancesCrashedError{}) 481 }) 482 483 It("delegates the right appGUID", func() { 484 actualApp, _, handleInstanceDetails := fakeActor.PollStartArgsForCall(0) 485 Expect(actualApp).To(Equal(app)) 486 handleInstanceDetails("instance details") 487 Expect(testUI.Out).To(Say("instance details")) 488 }) 489 490 It("displays the process table", func() { 491 Expect(testUI.Out).To(Say("Showing current scale of app " + app.Name)) 492 }) 493 494 It("displays all warnings and fails", func() { 495 Expect(testUI.Err).To(Say("some-poll-warning-1")) 496 Expect(testUI.Err).To(Say("some-poll-warning-2")) 497 498 Expect(executeErr).To(MatchError(translatableerror.ApplicationUnableToStartError{ 499 AppName: app.Name, 500 BinaryName: binaryName, 501 })) 502 }) 503 }) 504 505 When("polling the start fails", func() { 506 BeforeEach(func() { 507 fakeActor.PollStartReturns(v7action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}, errors.New("some-error")) 508 }) 509 510 It("delegates the right appGUID", func() { 511 actualApp, _, handleInstanceDetails := fakeActor.PollStartArgsForCall(0) 512 Expect(actualApp).To(Equal(app)) 513 handleInstanceDetails("instance details") 514 Expect(testUI.Out).To(Say("instance details")) 515 }) 516 517 It("displays all warnings and fails", func() { 518 Expect(testUI.Err).To(Say("some-poll-warning-1")) 519 Expect(testUI.Err).To(Say("some-poll-warning-2")) 520 521 Expect(executeErr).To(MatchError("some-error")) 522 }) 523 }) 524 525 When("polling times out", func() { 526 BeforeEach(func() { 527 fakeActor.PollStartReturns(nil, actionerror.StartupTimeoutError{}) 528 }) 529 530 It("delegates the right appGUID", func() { 531 actualApp, _, handleInstanceDetails := fakeActor.PollStartArgsForCall(0) 532 Expect(actualApp).To(Equal(app)) 533 handleInstanceDetails("instance details") 534 Expect(testUI.Out).To(Say("instance details")) 535 }) 536 537 It("returns the StartupTimeoutError", func() { 538 Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{ 539 AppName: "some-app", 540 BinaryName: binaryName, 541 })) 542 }) 543 }) 544 }) 545 }) 546 547 When("force flag is provided", func() { 548 BeforeEach(func() { 549 cmd.Force = true 550 }) 551 552 It("does not prompt user to confirm app restart", func() { 553 Expect(executeErr).ToNot(HaveOccurred()) 554 555 Expect(testUI.Out).To(Say(`Scaling app some-app in org some-org / space some-space as some-user\.\.\.`)) 556 Expect(testUI.Out).To(Say(`Stopping app some-app in org some-org / space some-space as some-user\.\.\.`)) 557 Expect(testUI.Out).To(Say(`Starting app some-app in org some-org / space some-space as some-user\.\.\.`)) 558 Expect(testUI.Out).NotTo(Say(`This will cause the app to restart\. Are you sure you want to scale some-app\? \[yN\]:`)) 559 560 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 561 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(1)) 562 Expect(fakeActor.StopApplicationCallCount()).To(Equal(1)) 563 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 564 Expect(fakeActor.GetDetailedAppSummaryCallCount()).To(Equal(1)) 565 }) 566 }) 567 }) 568 569 When("only the instances flag option is provided", func() { 570 BeforeEach(func() { 571 cmd.Instances.Value = 3 572 cmd.Instances.IsSet = true 573 fakeActor.ScaleProcessByApplicationReturns( 574 v7action.Warnings{"scale-warning"}, 575 nil) 576 fakeActor.GetDetailedAppSummaryReturns( 577 appSummary, 578 v7action.Warnings{"get-instances-warning"}, 579 nil) 580 }) 581 582 It("scales the number of instances, displays scale properties, and does not restart the application", func() { 583 Expect(executeErr).ToNot(HaveOccurred()) 584 585 Expect(testUI.Out).To(Say("Scaling")) 586 Expect(testUI.Out).NotTo(Say("This will cause the app to restart | Stopping | Starting")) 587 588 Expect(testUI.Err).To(Say("get-app-warning")) 589 Expect(testUI.Err).To(Say("scale-warning")) 590 Expect(testUI.Err).To(Say("get-instances-warning")) 591 592 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 593 appNameArg, spaceGUIDArg := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 594 Expect(appNameArg).To(Equal(app.Name)) 595 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 596 597 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(1)) 598 appGUIDArg, scaleProcess := fakeActor.ScaleProcessByApplicationArgsForCall(0) 599 Expect(appGUIDArg).To(Equal("some-app-guid")) 600 Expect(scaleProcess).To(Equal(resources.Process{ 601 Type: constant.ProcessTypeWeb, 602 Instances: types.NullInt{Value: 3, IsSet: true}, 603 })) 604 605 Expect(fakeActor.StopApplicationCallCount()).To(Equal(0)) 606 Expect(fakeActor.StartApplicationCallCount()).To(Equal(0)) 607 }) 608 609 When("the app is started", func() { 610 BeforeEach(func() { 611 app.State = constant.ApplicationStarted 612 fakeActor.GetApplicationByNameAndSpaceReturns( 613 app, nil, nil) 614 }) 615 616 It("polls for the app being started", func() { 617 Expect(fakeActor.PollStartCallCount()).To(Equal(1)) 618 }) 619 }) 620 621 When("the app is stopped", func() { 622 BeforeEach(func() { 623 app.State = constant.ApplicationStopped 624 fakeActor.GetApplicationByNameAndSpaceReturns( 625 app, nil, nil) 626 }) 627 It("does not poll for the app being started", func() { 628 Expect(fakeActor.PollStartCallCount()).To(Equal(0)) 629 }) 630 }) 631 }) 632 633 When("only the memory flag option is provided", func() { 634 BeforeEach(func() { 635 cmd.MemoryLimit.Value = 256 636 cmd.MemoryLimit.IsSet = true 637 fakeActor.ScaleProcessByApplicationReturns( 638 v7action.Warnings{"scale-warning"}, 639 nil) 640 fakeActor.GetDetailedAppSummaryReturns( 641 appSummary, 642 v7action.Warnings{"get-instances-warning"}, 643 nil) 644 645 _, err := input.Write([]byte("y\n")) 646 Expect(err).ToNot(HaveOccurred()) 647 }) 648 649 It("scales, restarts, and displays scale properties", func() { 650 Expect(executeErr).ToNot(HaveOccurred()) 651 652 Expect(testUI.Out).To(Say("Scaling")) 653 Expect(testUI.Out).To(Say("This will cause the app to restart")) 654 Expect(testUI.Out).To(Say("Stopping")) 655 Expect(testUI.Out).To(Say("Starting")) 656 657 Expect(testUI.Err).To(Say("get-app-warning")) 658 Expect(testUI.Err).To(Say("scale-warning")) 659 Expect(testUI.Err).To(Say("get-instances-warning")) 660 661 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 662 appNameArg, spaceGUIDArg := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 663 Expect(appNameArg).To(Equal(app.Name)) 664 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 665 666 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(1)) 667 appGUIDArg, scaleProcess := fakeActor.ScaleProcessByApplicationArgsForCall(0) 668 Expect(appGUIDArg).To(Equal("some-app-guid")) 669 Expect(scaleProcess).To(Equal(resources.Process{ 670 Type: constant.ProcessTypeWeb, 671 MemoryInMB: types.NullUint64{Value: 256, IsSet: true}, 672 })) 673 674 Expect(fakeActor.StopApplicationCallCount()).To(Equal(1)) 675 appGUID := fakeActor.StopApplicationArgsForCall(0) 676 Expect(appGUID).To(Equal("some-app-guid")) 677 678 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 679 appGUID = fakeActor.StartApplicationArgsForCall(0) 680 Expect(appGUID).To(Equal("some-app-guid")) 681 682 Expect(fakeActor.GetDetailedAppSummaryCallCount()).To(Equal(1)) 683 }) 684 }) 685 686 When("only the disk flag option is provided", func() { 687 BeforeEach(func() { 688 cmd.DiskLimit.Value = 1025 689 cmd.DiskLimit.IsSet = true 690 fakeActor.ScaleProcessByApplicationReturns( 691 v7action.Warnings{"scale-warning"}, 692 nil) 693 fakeActor.GetDetailedAppSummaryReturns( 694 appSummary, 695 v7action.Warnings{"get-instances-warning"}, 696 nil) 697 _, err := input.Write([]byte("y\n")) 698 Expect(err).ToNot(HaveOccurred()) 699 }) 700 701 It("scales the number of instances, displays scale properties, and restarts the application", func() { 702 Expect(executeErr).ToNot(HaveOccurred()) 703 704 Expect(testUI.Out).To(Say("Scaling")) 705 Expect(testUI.Out).To(Say("This will cause the app to restart")) 706 Expect(testUI.Out).To(Say("Stopping")) 707 Expect(testUI.Out).To(Say("Starting")) 708 709 Expect(testUI.Err).To(Say("get-app-warning")) 710 Expect(testUI.Err).To(Say("scale-warning")) 711 Expect(testUI.Err).To(Say("get-instances-warning")) 712 713 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 714 appNameArg, spaceGUIDArg := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 715 Expect(appNameArg).To(Equal(app.Name)) 716 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 717 718 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(1)) 719 appGUIDArg, scaleProcess := fakeActor.ScaleProcessByApplicationArgsForCall(0) 720 Expect(appGUIDArg).To(Equal("some-app-guid")) 721 Expect(scaleProcess).To(Equal(resources.Process{ 722 Type: constant.ProcessTypeWeb, 723 DiskInMB: types.NullUint64{Value: 1025, IsSet: true}, 724 })) 725 726 Expect(fakeActor.StopApplicationCallCount()).To(Equal(1)) 727 appGUID := fakeActor.StopApplicationArgsForCall(0) 728 Expect(appGUID).To(Equal("some-app-guid")) 729 730 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 731 appGUID = fakeActor.StartApplicationArgsForCall(0) 732 Expect(appGUID).To(Equal("some-app-guid")) 733 }) 734 }) 735 736 When("process flag is provided", func() { 737 BeforeEach(func() { 738 cmd.ProcessType = "some-process-type" 739 cmd.Instances.Value = 2 740 cmd.Instances.IsSet = true 741 fakeActor.ScaleProcessByApplicationReturns( 742 v7action.Warnings{"scale-warning"}, 743 nil) 744 fakeActor.GetDetailedAppSummaryReturns( 745 appSummary, 746 v7action.Warnings{"get-instances-warning"}, 747 nil) 748 _, err := input.Write([]byte("y\n")) 749 Expect(err).ToNot(HaveOccurred()) 750 }) 751 752 It("scales the specified process", func() { 753 Expect(executeErr).ToNot(HaveOccurred()) 754 755 Expect(testUI.Out).To(Say("Scaling")) 756 757 Expect(testUI.Err).To(Say("get-app-warning")) 758 Expect(testUI.Err).To(Say("scale-warning")) 759 Expect(testUI.Err).To(Say("get-instances-warning")) 760 761 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 762 appNameArg, spaceGUIDArg := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 763 Expect(appNameArg).To(Equal(app.Name)) 764 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 765 766 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(1)) 767 appGUIDArg, scaleProcess := fakeActor.ScaleProcessByApplicationArgsForCall(0) 768 Expect(appGUIDArg).To(Equal("some-app-guid")) 769 Expect(scaleProcess).To(Equal(resources.Process{ 770 Type: "some-process-type", 771 Instances: types.NullInt{Value: 2, IsSet: true}, 772 })) 773 }) 774 }) 775 776 When("only the log rate limit option is provided", func() { 777 BeforeEach(func() { 778 cmd.LogRateLimit.Value = 2048 779 cmd.LogRateLimit.IsSet = true 780 fakeActor.ScaleProcessByApplicationReturns( 781 v7action.Warnings{"scale-warning"}, 782 nil) 783 fakeActor.GetDetailedAppSummaryReturns( 784 appSummary, 785 v7action.Warnings{"get-instances-warning"}, 786 nil) 787 788 _, err := input.Write([]byte("y\n")) 789 Expect(err).ToNot(HaveOccurred()) 790 }) 791 792 It("scales, restarts, and displays scale properties", func() { 793 Expect(executeErr).ToNot(HaveOccurred()) 794 795 Expect(testUI.Out).To(Say("Scaling")) 796 Expect(testUI.Out).To(Say("This will cause the app to restart")) 797 Expect(testUI.Out).To(Say("Stopping")) 798 Expect(testUI.Out).To(Say("Starting")) 799 800 Expect(testUI.Err).To(Say("get-app-warning")) 801 Expect(testUI.Err).To(Say("scale-warning")) 802 Expect(testUI.Err).To(Say("get-instances-warning")) 803 804 Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(1)) 805 appNameArg, spaceGUIDArg := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0) 806 Expect(appNameArg).To(Equal(app.Name)) 807 Expect(spaceGUIDArg).To(Equal("some-space-guid")) 808 809 Expect(fakeActor.ScaleProcessByApplicationCallCount()).To(Equal(1)) 810 appGUIDArg, scaleProcess := fakeActor.ScaleProcessByApplicationArgsForCall(0) 811 Expect(appGUIDArg).To(Equal("some-app-guid")) 812 Expect(scaleProcess).To(Equal(resources.Process{ 813 Type: constant.ProcessTypeWeb, 814 LogRateLimitInBPS: types.NullInt{Value: 2048, IsSet: true}, 815 })) 816 817 Expect(fakeActor.StopApplicationCallCount()).To(Equal(1)) 818 appGUID := fakeActor.StopApplicationArgsForCall(0) 819 Expect(appGUID).To(Equal("some-app-guid")) 820 821 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 822 appGUID = fakeActor.StartApplicationArgsForCall(0) 823 Expect(appGUID).To(Equal("some-app-guid")) 824 825 Expect(fakeActor.GetDetailedAppSummaryCallCount()).To(Equal(1)) 826 }) 827 }) 828 829 When("an error is encountered scaling the application", func() { 830 var expectedErr error 831 832 BeforeEach(func() { 833 cmd.Instances.Value = 3 834 cmd.Instances.IsSet = true 835 expectedErr = errors.New("scale process error") 836 fakeActor.ScaleProcessByApplicationReturns( 837 v7action.Warnings{"scale-process-warning"}, 838 expectedErr, 839 ) 840 }) 841 842 It("returns the error and displays all warnings", func() { 843 Expect(executeErr).To(Equal(expectedErr)) 844 Expect(testUI.Err).To(Say("scale-process-warning")) 845 }) 846 }) 847 }) 848 }) 849 })