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