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