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