github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/command/v3/v3_scale_command_test.go (about)

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