github.com/randomtask1155/cli@v6.41.1-0.20181227003417-a98eed78cbde+incompatible/integration/v6/experimental/v3_scale_command_test.go (about)

     1  package experimental
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccversion"
     8  	"code.cloudfoundry.org/cli/integration/helpers"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/gbytes"
    12  	. "github.com/onsi/gomega/gexec"
    13  	. "github.com/onsi/gomega/ghttp"
    14  )
    15  
    16  var _ = Describe("v3-scale command", func() {
    17  	var (
    18  		orgName   string
    19  		spaceName string
    20  		appName   string
    21  		userName  string
    22  	)
    23  
    24  	BeforeEach(func() {
    25  		orgName = helpers.NewOrgName()
    26  		spaceName = helpers.NewSpaceName()
    27  		appName = helpers.PrefixedRandomName("app")
    28  		userName, _ = helpers.GetCredentials()
    29  	})
    30  
    31  	Describe("help", func() {
    32  		When("--help flag is set", func() {
    33  			It("displays command usage to output", func() {
    34  				session := helpers.CF("v3-scale", "--help")
    35  
    36  				Eventually(session).Should(Say("NAME:"))
    37  				Eventually(session).Should(Say("v3-scale - Change or view the instance count, disk space limit, and memory limit for an app"))
    38  
    39  				Eventually(session).Should(Say("USAGE:"))
    40  				Eventually(session).Should(Say(`cf v3-scale APP_NAME \[--process PROCESS\] \[-i INSTANCES\] \[-k DISK\] \[-m MEMORY\]`))
    41  
    42  				Eventually(session).Should(Say("OPTIONS:"))
    43  				Eventually(session).Should(Say(`-f\s+Force restart of app without prompt`))
    44  				Eventually(session).Should(Say(`-i\s+Number of instances`))
    45  				Eventually(session).Should(Say(`-k\s+Disk limit \(e\.g\. 256M, 1024M, 1G\)`))
    46  				Eventually(session).Should(Say(`-m\s+Memory limit \(e\.g\. 256M, 1024M, 1G\)`))
    47  				Eventually(session).Should(Say(`--process\s+App process to scale \(Default: web\)`))
    48  
    49  				Eventually(session).Should(Say("ENVIRONMENT:"))
    50  				Eventually(session).Should(Say(`CF_STARTUP_TIMEOUT=5\s+Max wait time for app instance startup, in minutes`))
    51  
    52  				Eventually(session).Should(Exit(0))
    53  			})
    54  		})
    55  	})
    56  
    57  	It("displays the experimental warning", func() {
    58  		session := helpers.CF("v3-scale", appName)
    59  		Eventually(session.Err).Should(Say("This command is in EXPERIMENTAL stage and may change without notice"))
    60  		Eventually(session).Should(Exit())
    61  	})
    62  
    63  	When("the environment is not setup correctly", func() {
    64  		When("no API endpoint is set", func() {
    65  			BeforeEach(func() {
    66  				helpers.UnsetAPI()
    67  			})
    68  
    69  			It("fails with no API endpoint set message", func() {
    70  				session := helpers.CF("v3-scale", appName)
    71  				Eventually(session).Should(Say("FAILED"))
    72  				Eventually(session.Err).Should(Say(`No API endpoint set\. Use 'cf login' or 'cf api' to target an endpoint\.`))
    73  				Eventually(session).Should(Exit(1))
    74  			})
    75  		})
    76  
    77  		When("the v3 api version is lower than the minimum version", func() {
    78  			var server *Server
    79  
    80  			BeforeEach(func() {
    81  				server = helpers.StartAndTargetServerWithAPIVersions(helpers.DefaultV2Version, ccversion.MinV3ClientVersion)
    82  			})
    83  
    84  			AfterEach(func() {
    85  				server.Close()
    86  			})
    87  
    88  			It("fails with error message that the minimum version is not met", func() {
    89  				session := helpers.CF("v3-scale", appName)
    90  				Eventually(session).Should(Say("FAILED"))
    91  				Eventually(session.Err).Should(Say(`This command requires CF API version 3\.27\.0 or higher\.`))
    92  				Eventually(session).Should(Exit(1))
    93  			})
    94  		})
    95  
    96  		When("not logged in", func() {
    97  			BeforeEach(func() {
    98  				helpers.LogoutCF()
    99  			})
   100  
   101  			It("fails with not logged in message", func() {
   102  				session := helpers.CF("v3-scale", appName)
   103  				Eventually(session).Should(Say("FAILED"))
   104  				Eventually(session.Err).Should(Say(`Not logged in\. Use 'cf login' to log in\.`))
   105  				Eventually(session).Should(Exit(1))
   106  			})
   107  		})
   108  
   109  		When("there is no org set", func() {
   110  			BeforeEach(func() {
   111  				helpers.LogoutCF()
   112  				helpers.LoginCF()
   113  			})
   114  
   115  			It("fails with no org targeted error message", func() {
   116  				session := helpers.CF("v3-scale", appName)
   117  				Eventually(session).Should(Say("FAILED"))
   118  				Eventually(session.Err).Should(Say(`No org targeted, use 'cf target -o ORG' to target an org\.`))
   119  				Eventually(session).Should(Exit(1))
   120  			})
   121  		})
   122  
   123  		When("there is no space set", func() {
   124  			BeforeEach(func() {
   125  				helpers.LogoutCF()
   126  				helpers.LoginCF()
   127  				helpers.TargetOrg(ReadOnlyOrg)
   128  			})
   129  
   130  			It("fails with no space targeted error message", func() {
   131  				session := helpers.CF("v3-scale", appName)
   132  				Eventually(session).Should(Say("FAILED"))
   133  				Eventually(session.Err).Should(Say(`No space targeted, use 'cf target -s SPACE' to target a space\.`))
   134  				Eventually(session).Should(Exit(1))
   135  			})
   136  		})
   137  	})
   138  
   139  	When("the environment is set up correctly", func() {
   140  		BeforeEach(func() {
   141  			helpers.SetupCF(orgName, spaceName)
   142  		})
   143  
   144  		AfterEach(func() {
   145  			helpers.QuickDeleteOrg(orgName)
   146  		})
   147  
   148  		When("the app name is not provided", func() {
   149  			It("tells the user that the app name is required, prints help text, and exits 1", func() {
   150  				session := helpers.CF("v3-scale")
   151  
   152  				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided"))
   153  				Eventually(session).Should(Say("NAME:"))
   154  				Eventually(session).Should(Exit(1))
   155  			})
   156  		})
   157  
   158  		When("the app does not exist", func() {
   159  			It("displays app not found and exits 1", func() {
   160  				invalidAppName := "invalid-app-name"
   161  				session := helpers.CF("v3-scale", invalidAppName)
   162  				Eventually(session.Err).Should(Say("App %s not found", invalidAppName))
   163  				Eventually(session).Should(Say("FAILED"))
   164  				Eventually(session).Should(Exit(1))
   165  			})
   166  		})
   167  
   168  		When("the app exists", func() {
   169  			BeforeEach(func() {
   170  				helpers.WithProcfileApp(func(appDir string) {
   171  					Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName)).Should(Exit(0))
   172  				})
   173  			})
   174  
   175  			When("scale option flags are not provided", func() {
   176  				It("displays the current scale properties for all processes", func() {
   177  					session := helpers.CF("v3-scale", appName)
   178  
   179  					Eventually(session).Should(Say(`Showing current scale of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   180  					Consistently(session).ShouldNot(Say("Scaling"))
   181  					Consistently(session).ShouldNot(Say("This will cause the app to restart"))
   182  					Consistently(session).ShouldNot(Say("Stopping"))
   183  					Consistently(session).ShouldNot(Say("Starting"))
   184  					Consistently(session).ShouldNot(Say("Waiting"))
   185  					Eventually(session).Should(Exit(0))
   186  
   187  					appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   188  					Expect(len(appTable.Processes)).To(Equal(2))
   189  
   190  					processSummary := appTable.Processes[0]
   191  					Expect(processSummary.Type).To(Equal("web"))
   192  					Expect(processSummary.InstanceCount).To(Equal("1/1"))
   193  
   194  					instanceSummary := processSummary.Instances[0]
   195  					Expect(instanceSummary.Memory).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of \d+[KMG]`))
   196  					Expect(instanceSummary.Disk).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of \d+[KMG]`))
   197  
   198  					Expect(appTable.Processes[1].Type).To(Equal("console"))
   199  					Expect(appTable.Processes[1].InstanceCount).To(Equal("0/0"))
   200  				})
   201  			})
   202  
   203  			When("only one scale option flag is provided", func() {
   204  				It("scales the app accordingly", func() {
   205  					By("verifying we start with a single instance")
   206  					session := helpers.CF("v3-scale", appName)
   207  					Eventually(session).Should(Exit(0))
   208  					appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   209  					Expect(appTable.Processes).To(HaveLen(2))
   210  
   211  					By("scaling to 3 instances")
   212  					session = helpers.CF("v3-scale", appName, "-i", "3")
   213  					Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   214  					Consistently(session).ShouldNot(Say("This will cause the app to restart"))
   215  					Consistently(session).ShouldNot(Say("Stopping"))
   216  					Consistently(session).ShouldNot(Say("Starting"))
   217  					Eventually(session).Should(Exit(0))
   218  
   219  					updatedAppTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   220  					Expect(updatedAppTable.Processes).To(HaveLen(2))
   221  
   222  					processSummary := updatedAppTable.Processes[0]
   223  					instanceSummary := processSummary.Instances[0]
   224  					Expect(processSummary.Type).To(Equal("web"))
   225  					Expect(processSummary.InstanceCount).To(MatchRegexp(`\d/3`))
   226  					Expect(instanceSummary.Disk).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of \d+[KMG]`))
   227  
   228  					Expect(instanceSummary.Memory).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of \d+[KMG]`))
   229  					By("scaling memory to 64M")
   230  					buffer := NewBuffer()
   231  					buffer.Write([]byte("y\n"))
   232  					session = helpers.CFWithStdin(buffer, "v3-scale", appName, "-m", "64M")
   233  					Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   234  					Eventually(session).Should(Say("This will cause the app to restart\\. Are you sure you want to scale %s\\? \\[yN\\]:", appName))
   235  					Eventually(session).Should(Say("Stopping app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   236  					Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   237  					Eventually(session).Should(Exit(0))
   238  
   239  					updatedAppTable = helpers.ParseV3AppProcessTable(session.Out.Contents())
   240  					Expect(updatedAppTable.Processes).To(HaveLen(2))
   241  
   242  					processSummary = updatedAppTable.Processes[0]
   243  					instanceSummary = processSummary.Instances[0]
   244  					Expect(processSummary.Type).To(Equal("web"))
   245  					Expect(processSummary.InstanceCount).To(MatchRegexp(`\d/3`))
   246  					Expect(instanceSummary.Memory).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of 64M`))
   247  					Expect(instanceSummary.Disk).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of \d+[KMG]`))
   248  
   249  					By("scaling disk to 92M")
   250  					buffer = NewBuffer()
   251  					buffer.Write([]byte("y\n"))
   252  					session = helpers.CFWithStdin(buffer, "v3-scale", appName, "-k", "92M")
   253  					Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   254  					Eventually(session).Should(Say("This will cause the app to restart\\. Are you sure you want to scale %s\\? \\[yN\\]:", appName))
   255  					Eventually(session).Should(Say("Stopping app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   256  					Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   257  					Eventually(session).Should(Exit(0))
   258  
   259  					updatedAppTable = helpers.ParseV3AppProcessTable(session.Out.Contents())
   260  					Expect(updatedAppTable.Processes).To(HaveLen(2))
   261  
   262  					processSummary = updatedAppTable.Processes[0]
   263  					instanceSummary = processSummary.Instances[0]
   264  					Expect(processSummary.Type).To(Equal("web"))
   265  					Expect(processSummary.InstanceCount).To(MatchRegexp(`\d/3`))
   266  					Expect(instanceSummary.Memory).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of 64M`))
   267  					Expect(instanceSummary.Disk).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of 92M`))
   268  
   269  					By("scaling to 0 instances")
   270  					session = helpers.CF("v3-scale", appName, "-i", "0")
   271  					Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   272  					Consistently(session).ShouldNot(Say("This will cause the app to restart"))
   273  					Consistently(session).ShouldNot(Say("Stopping"))
   274  					Consistently(session).ShouldNot(Say("Starting"))
   275  					Eventually(session).Should(Exit(0))
   276  
   277  					updatedAppTable = helpers.ParseV3AppProcessTable(session.Out.Contents())
   278  					Expect(updatedAppTable.Processes).To(BeEmpty())
   279  				})
   280  
   281  				When("the user chooses not to restart the app", func() {
   282  					It("cancels the scale", func() {
   283  						buffer := NewBuffer()
   284  						buffer.Write([]byte("n\n"))
   285  						session := helpers.CFWithStdin(buffer, "v3-scale", appName, "-i", "2", "-k", "90M")
   286  						Eventually(session).Should(Say("This will cause the app to restart"))
   287  						Consistently(session).ShouldNot(Say("Stopping"))
   288  						Consistently(session).ShouldNot(Say("Starting"))
   289  						Eventually(session).Should(Say("Scaling cancelled"))
   290  						Consistently(session).ShouldNot(Say("Waiting for app to start\\.\\.\\."))
   291  						Eventually(session).Should(Exit(0))
   292  
   293  						appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   294  						Expect(appTable.Processes).To(BeEmpty())
   295  					})
   296  				})
   297  			})
   298  
   299  			When("all scale option flags are provided", func() {
   300  				When("the app starts successfully", func() {
   301  					It("scales the app accordingly", func() {
   302  						buffer := NewBuffer()
   303  						buffer.Write([]byte("y\n"))
   304  						session := helpers.CFWithStdin(buffer, "v3-scale", appName, "-i", "2", "-k", "120M", "-m", "60M")
   305  						Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   306  						Eventually(session).Should(Say("This will cause the app to restart\\. Are you sure you want to scale %s\\? \\[yN\\]:", appName))
   307  						Eventually(session).Should(Say("Stopping app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   308  						Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   309  						Eventually(session).Should(Exit(0))
   310  
   311  						appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   312  						Expect(appTable.Processes).To(HaveLen(2))
   313  
   314  						processSummary := appTable.Processes[0]
   315  						instanceSummary := processSummary.Instances[0]
   316  						Expect(processSummary.Type).To(Equal("web"))
   317  						Expect(processSummary.InstanceCount).To(MatchRegexp(`\d/2`))
   318  						Expect(instanceSummary.State).To(MatchRegexp(`running|starting`))
   319  						Expect(instanceSummary.Memory).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of 60M`))
   320  						Expect(instanceSummary.Disk).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of 120M`))
   321  					})
   322  				})
   323  
   324  				When("the app does not start successfully", func() {
   325  					It("scales the app and displays the app summary", func() {
   326  						buffer := NewBuffer()
   327  						buffer.Write([]byte("y\n"))
   328  						session := helpers.CFWithStdin(buffer, "v3-scale", appName, "-i", "2", "-k", "120M", "-m", "6M")
   329  						Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   330  						Eventually(session).Should(Say("This will cause the app to restart\\. Are you sure you want to scale %s\\? \\[yN\\]:", appName))
   331  						Eventually(session).Should(Say("Stopping app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   332  						Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   333  						Eventually(session).Should(Exit(0))
   334  
   335  						appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   336  						Expect(appTable.Processes).To(HaveLen(2))
   337  
   338  						processSummary := appTable.Processes[0]
   339  						instanceSummary := processSummary.Instances[0]
   340  						Expect(processSummary.Type).To(Equal("web"))
   341  						Expect(processSummary.InstanceCount).To(MatchRegexp(`\d/2`))
   342  						Expect(instanceSummary.State).To(MatchRegexp(`crashed`))
   343  						Expect(instanceSummary.Memory).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of 6M`))
   344  						Expect(instanceSummary.Disk).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of 120M`))
   345  					})
   346  				})
   347  			})
   348  
   349  			PWhen("the provided scale options are the same as the existing scale properties", func() {
   350  				var (
   351  					session          *Session
   352  					currentInstances string
   353  					maxMemory        string
   354  					maxDiskSize      string
   355  				)
   356  
   357  				BeforeEach(func() {
   358  					session = helpers.CF("v3-scale", appName)
   359  					Eventually(session).Should(Exit(0))
   360  
   361  					appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   362  					instanceSummary := appTable.Processes[0].Instances[0]
   363  					currentInstances = string(len(appTable.Processes[0].Instances))
   364  					maxMemory = strings.Fields(instanceSummary.Memory)[2]
   365  					maxDiskSize = strings.Fields(instanceSummary.Disk)[2]
   366  				})
   367  
   368  				It("the action should be a no-op", func() {
   369  					session = helpers.CF("v3-scale", appName, "-i", currentInstances, "-m", maxMemory, "-k", maxDiskSize)
   370  					Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   371  					Consistently(session).ShouldNot(Say("This will cause the app to restart"))
   372  					Consistently(session).ShouldNot(Say("Stopping"))
   373  					Consistently(session).ShouldNot(Say("Starting"))
   374  					Consistently(session).ShouldNot(Say("Waiting for app to start"))
   375  					Eventually(session).Should(Exit(0))
   376  
   377  					appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   378  					Expect(appTable.Processes).To(HaveLen(1))
   379  
   380  					newProcessSummary := appTable.Processes[0]
   381  					newInstanceSummary := newProcessSummary.Instances[0]
   382  					Expect(newProcessSummary.Type).To(Equal("web"))
   383  					Expect(newProcessSummary.InstanceCount).To(MatchRegexp(fmt.Sprintf(`\d/%s`, currentInstances)))
   384  					Expect(newInstanceSummary.Memory).To(MatchRegexp(fmt.Sprintf(`\d+(\.\d+)?[KMG]? of %s`, maxMemory)))
   385  					Expect(newInstanceSummary.Disk).To(MatchRegexp(fmt.Sprintf(`\d+(\.\d+)?[KMG]? of %s`, maxDiskSize)))
   386  				})
   387  			})
   388  
   389  			When("the process flag is provided", func() {
   390  				It("scales the requested process", func() {
   391  					session := helpers.CF("v3-scale", appName, "-i", "2", "--process", "console")
   392  					Eventually(session).Should(Say("Scaling app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   393  					Eventually(session).Should(Exit(0))
   394  
   395  					appTable := helpers.ParseV3AppProcessTable(session.Out.Contents())
   396  					Expect(appTable.Processes).To(HaveLen(2))
   397  
   398  					processSummary := appTable.Processes[1]
   399  					instanceSummary := processSummary.Instances[0]
   400  					Expect(processSummary.Instances).To(HaveLen(2))
   401  					Expect(processSummary.Type).To(Equal("console"))
   402  					Expect(processSummary.InstanceCount).To(MatchRegexp(`\d/2`))
   403  					Expect(instanceSummary.Memory).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of \d+[KMG]`))
   404  					Expect(instanceSummary.Disk).To(MatchRegexp(`\d+(\.\d+)?[KMG]? of \d+[KMG]`))
   405  				})
   406  			})
   407  		})
   408  	})
   409  
   410  	When("invalid scale option values are provided", func() {
   411  		When("a negative value is passed to a flag argument", func() {
   412  			It("outputs an error message to the user, provides help text, and exits 1", func() {
   413  				session := helpers.CF("v3-scale", "some-app", "-i=-5")
   414  				Eventually(session.Err).Should(Say("Incorrect Usage: invalid argument for flag '-i' \\(expected int > 0\\)"))
   415  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   416  				Eventually(session).Should(Exit(1))
   417  
   418  				session = helpers.CF("v3-scale", "some-app", "-k=-5")
   419  				Eventually(session.Err).Should(Say("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   420  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   421  				Eventually(session).Should(Exit(1))
   422  
   423  				session = helpers.CF("v3-scale", "some-app", "-m=-5")
   424  				Eventually(session.Err).Should(Say("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   425  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   426  				Eventually(session).Should(Exit(1))
   427  			})
   428  		})
   429  
   430  		When("a non-integer value is passed to a flag argument", func() {
   431  			It("outputs an error message to the user, provides help text, and exits 1", func() {
   432  				session := helpers.CF("v3-scale", "some-app", "-i", "not-an-integer")
   433  				Eventually(session.Err).Should(Say("Incorrect Usage: invalid argument for flag '-i' \\(expected int > 0\\)"))
   434  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   435  				Eventually(session).Should(Exit(1))
   436  
   437  				session = helpers.CF("v3-scale", "some-app", "-k", "not-an-integer")
   438  				Eventually(session.Err).Should(Say("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   439  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   440  				Eventually(session).Should(Exit(1))
   441  
   442  				session = helpers.CF("v3-scale", "some-app", "-m", "not-an-integer")
   443  				Eventually(session.Err).Should(Say("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   444  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   445  				Eventually(session).Should(Exit(1))
   446  			})
   447  		})
   448  
   449  		When("the unit of measurement is not provided", func() {
   450  			It("outputs an error message to the user, provides help text, and exits 1", func() {
   451  				session := helpers.CF("v3-scale", "some-app", "-k", "9")
   452  				Eventually(session.Err).Should(Say("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   453  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   454  				Eventually(session).Should(Exit(1))
   455  
   456  				session = helpers.CF("v3-scale", "some-app", "-m", "7")
   457  				Eventually(session.Err).Should(Say("Byte quantity must be an integer with a unit of measurement like M, MB, G, or GB"))
   458  				Eventually(session).Should(Say("cf v3-scale APP_NAME")) // help
   459  				Eventually(session).Should(Exit(1))
   460  			})
   461  		})
   462  	})
   463  })