github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v6/start_command_test.go (about)

     1  package v6_test
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	"code.cloudfoundry.org/cli/actor/actionerror"
     8  	"code.cloudfoundry.org/cli/actor/v2action"
     9  	"code.cloudfoundry.org/cli/actor/v2v3action"
    10  	"code.cloudfoundry.org/cli/actor/v3action"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant"
    12  	"code.cloudfoundry.org/cli/command/commandfakes"
    13  	"code.cloudfoundry.org/cli/command/translatableerror"
    14  	. "code.cloudfoundry.org/cli/command/v6"
    15  	"code.cloudfoundry.org/cli/command/v6/shared/sharedfakes"
    16  	"code.cloudfoundry.org/cli/command/v6/v6fakes"
    17  	"code.cloudfoundry.org/cli/types"
    18  	"code.cloudfoundry.org/cli/util/configv3"
    19  	"code.cloudfoundry.org/cli/util/ui"
    20  	. "github.com/onsi/ginkgo"
    21  	. "github.com/onsi/gomega"
    22  	. "github.com/onsi/gomega/gbytes"
    23  )
    24  
    25  var _ = Describe("Start Command", func() {
    26  	var (
    27  		cmd                         StartCommand
    28  		testUI                      *ui.UI
    29  		fakeConfig                  *commandfakes.FakeConfig
    30  		fakeSharedActor             *commandfakes.FakeSharedActor
    31  		fakeActor                   *v6fakes.FakeStartActor
    32  		fakeApplicationSummaryActor *sharedfakes.FakeApplicationSummaryActor
    33  		binaryName                  string
    34  		appName                     string
    35  		executeErr                  error
    36  	)
    37  
    38  	BeforeEach(func() {
    39  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    40  		fakeConfig = new(commandfakes.FakeConfig)
    41  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    42  		fakeActor = new(v6fakes.FakeStartActor)
    43  		fakeApplicationSummaryActor = new(sharedfakes.FakeApplicationSummaryActor)
    44  
    45  		cmd = StartCommand{
    46  			UI:                      testUI,
    47  			Config:                  fakeConfig,
    48  			SharedActor:             fakeSharedActor,
    49  			Actor:                   fakeActor,
    50  			ApplicationSummaryActor: fakeApplicationSummaryActor,
    51  		}
    52  
    53  		appName = "some-app"
    54  		cmd.RequiredArgs.AppName = appName
    55  
    56  		binaryName = "faceman"
    57  		fakeConfig.BinaryNameReturns(binaryName)
    58  
    59  		var err error
    60  		testUI.TimezoneLocation, err = time.LoadLocation("America/Los_Angeles")
    61  		Expect(err).NotTo(HaveOccurred())
    62  
    63  		fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
    64  			messages := make(chan *v2action.LogMessage)
    65  			logErrs := make(chan error)
    66  			appState := make(chan v2action.ApplicationStateChange)
    67  			warnings := make(chan string)
    68  			errs := make(chan error)
    69  
    70  			go func() {
    71  				close(messages)
    72  				close(logErrs)
    73  				close(appState)
    74  				close(warnings)
    75  				close(errs)
    76  			}()
    77  
    78  			return messages, logErrs, appState, warnings, errs
    79  		}
    80  	})
    81  
    82  	JustBeforeEach(func() {
    83  		executeErr = cmd.Execute(nil)
    84  	})
    85  
    86  	When("checking target fails", func() {
    87  		BeforeEach(func() {
    88  			fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
    89  		})
    90  
    91  		It("returns an error if the check fails", func() {
    92  			Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: "faceman"}))
    93  
    94  			Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
    95  			checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
    96  			Expect(checkTargetedOrg).To(BeTrue())
    97  			Expect(checkTargetedSpace).To(BeTrue())
    98  		})
    99  	})
   100  
   101  	When("the user is logged in, and org and space are targeted", func() {
   102  		BeforeEach(func() {
   103  			fakeConfig.HasTargetedOrganizationReturns(true)
   104  			fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "some-org"})
   105  			fakeConfig.HasTargetedSpaceReturns(true)
   106  			fakeConfig.TargetedSpaceReturns(configv3.Space{
   107  				GUID: "some-space-guid",
   108  				Name: "some-space"})
   109  			fakeConfig.CurrentUserReturns(
   110  				configv3.User{Name: "some-user"},
   111  				nil)
   112  		})
   113  
   114  		When("getting the current user returns an error", func() {
   115  			var expectedErr error
   116  
   117  			BeforeEach(func() {
   118  				expectedErr = errors.New("getting current user error")
   119  				fakeConfig.CurrentUserReturns(
   120  					configv3.User{},
   121  					expectedErr)
   122  			})
   123  
   124  			It("returns the error", func() {
   125  				Expect(executeErr).To(MatchError(expectedErr))
   126  			})
   127  		})
   128  
   129  		It("displays flavor text", func() {
   130  			Expect(testUI.Out).To(Say("Starting app %s in org some-org / space some-space as some-user...", appName))
   131  		})
   132  
   133  		When("the app exists", func() {
   134  			When("the app is already started", func() {
   135  				BeforeEach(func() {
   136  					fakeActor.GetApplicationByNameAndSpaceReturns(
   137  						v2action.Application{State: constant.ApplicationStarted},
   138  						v2action.Warnings{"warning-1", "warning-2"},
   139  						nil,
   140  					)
   141  				})
   142  
   143  				It("short circuits and displays message", func() {
   144  					Expect(executeErr).ToNot(HaveOccurred())
   145  
   146  					Expect(testUI.Out).To(Say("App %s is already started", appName))
   147  
   148  					Expect(testUI.Err).To(Say("warning-1"))
   149  					Expect(testUI.Err).To(Say("warning-2"))
   150  
   151  					Expect(fakeActor.StartApplicationCallCount()).To(Equal(0))
   152  				})
   153  			})
   154  
   155  			When("the app is not already started", func() {
   156  				BeforeEach(func() {
   157  					fakeActor.GetApplicationByNameAndSpaceReturns(
   158  						v2action.Application{GUID: "app-guid", State: constant.ApplicationStopped},
   159  						v2action.Warnings{"warning-1", "warning-2"},
   160  						nil,
   161  					)
   162  				})
   163  
   164  				It("starts the app", func() {
   165  					Expect(executeErr).ToNot(HaveOccurred())
   166  
   167  					Expect(testUI.Err).To(Say("warning-1"))
   168  					Expect(testUI.Err).To(Say("warning-2"))
   169  
   170  					Expect(fakeActor.StartApplicationCallCount()).To(Equal(1))
   171  					app, _ := fakeActor.StartApplicationArgsForCall(0)
   172  					Expect(app.GUID).To(Equal("app-guid"))
   173  				})
   174  
   175  				When("passed an ApplicationStateStarting message", func() {
   176  					BeforeEach(func() {
   177  						fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
   178  							messages := make(chan *v2action.LogMessage)
   179  							logErrs := make(chan error)
   180  							appState := make(chan v2action.ApplicationStateChange)
   181  							warnings := make(chan string)
   182  							errs := make(chan error)
   183  
   184  							go func() {
   185  								messages <- v2action.NewLogMessage("log message 1", 1, time.Unix(0, 0), "STG", "1")
   186  								messages <- v2action.NewLogMessage("log message 2", 1, time.Unix(0, 0), "STG", "1")
   187  								appState <- v2action.ApplicationStateStarting
   188  								close(messages)
   189  								close(logErrs)
   190  								close(appState)
   191  								close(warnings)
   192  								close(errs)
   193  							}()
   194  
   195  							return messages, logErrs, appState, warnings, errs
   196  						}
   197  					})
   198  
   199  					It("displays the log", func() {
   200  						Expect(executeErr).ToNot(HaveOccurred())
   201  						Expect(testUI.Out).To(Say("log message 1"))
   202  						Expect(testUI.Out).To(Say("log message 2"))
   203  						Expect(testUI.Out).To(Say("Waiting for app to start..."))
   204  					})
   205  				})
   206  
   207  				When("passed a log message", func() {
   208  					BeforeEach(func() {
   209  						fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
   210  							messages := make(chan *v2action.LogMessage)
   211  							logErrs := make(chan error)
   212  							appState := make(chan v2action.ApplicationStateChange)
   213  							warnings := make(chan string)
   214  							errs := make(chan error)
   215  
   216  							go func() {
   217  								messages <- v2action.NewLogMessage("log message 1", 1, time.Unix(0, 0), "STG", "1")
   218  								messages <- v2action.NewLogMessage("log message 2", 1, time.Unix(0, 0), "STG", "1")
   219  								messages <- v2action.NewLogMessage("log message 3", 1, time.Unix(0, 0), "Something else", "1")
   220  								close(messages)
   221  								close(logErrs)
   222  								close(appState)
   223  								close(warnings)
   224  								close(errs)
   225  							}()
   226  
   227  							return messages, logErrs, appState, warnings, errs
   228  						}
   229  					})
   230  
   231  					It("displays the log", func() {
   232  						Expect(executeErr).ToNot(HaveOccurred())
   233  						Expect(testUI.Out).To(Say("log message 1"))
   234  						Expect(testUI.Out).To(Say("log message 2"))
   235  						Expect(testUI.Out).ToNot(Say("log message 3"))
   236  					})
   237  				})
   238  
   239  				When("passed an log err", func() {
   240  					Context("NOAA connection times out/closes", func() {
   241  						BeforeEach(func() {
   242  							fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
   243  								messages := make(chan *v2action.LogMessage)
   244  								logErrs := make(chan error)
   245  								appState := make(chan v2action.ApplicationStateChange)
   246  								warnings := make(chan string)
   247  								errs := make(chan error)
   248  
   249  								go func() {
   250  									messages <- v2action.NewLogMessage("log message 1", 1, time.Unix(0, 0), "STG", "1")
   251  									messages <- v2action.NewLogMessage("log message 2", 1, time.Unix(0, 0), "STG", "1")
   252  									messages <- v2action.NewLogMessage("log message 3", 1, time.Unix(0, 0), "STG", "1")
   253  									logErrs <- actionerror.NOAATimeoutError{}
   254  									close(messages)
   255  									close(logErrs)
   256  									close(appState)
   257  									close(warnings)
   258  									close(errs)
   259  								}()
   260  
   261  								return messages, logErrs, appState, warnings, errs
   262  							}
   263  							v3ApplicationSummary := v3action.ApplicationSummary{
   264  								Application: v3action.Application{
   265  									Name: appName,
   266  								},
   267  								ProcessSummaries: v3action.ProcessSummaries{
   268  									{
   269  										Process: v3action.Process{
   270  											Type:       "aba",
   271  											Command:    *types.NewFilteredString("some-command-1"),
   272  											MemoryInMB: types.NullUint64{Value: 32, IsSet: true},
   273  											DiskInMB:   types.NullUint64{Value: 1024, IsSet: true},
   274  										},
   275  									},
   276  									{
   277  										Process: v3action.Process{
   278  											Type:       "console",
   279  											Command:    *types.NewFilteredString("some-command-2"),
   280  											MemoryInMB: types.NullUint64{Value: 16, IsSet: true},
   281  											DiskInMB:   types.NullUint64{Value: 512, IsSet: true},
   282  										},
   283  									},
   284  								},
   285  							}
   286  
   287  							applicationSummary := v2v3action.ApplicationSummary{
   288  								ApplicationSummary: v3ApplicationSummary,
   289  							}
   290  
   291  							warnings := []string{"app-summary-warning"}
   292  
   293  							fakeApplicationSummaryActor.GetApplicationSummaryByNameAndSpaceReturns(applicationSummary, warnings, nil)
   294  						})
   295  
   296  						It("displays a warning and continues until app has started", func() {
   297  							Expect(executeErr).To(BeNil())
   298  							Expect(testUI.Out).To(Say("message 1"))
   299  							Expect(testUI.Out).To(Say("message 2"))
   300  							Expect(testUI.Out).To(Say("message 3"))
   301  							Expect(testUI.Err).To(Say("timeout connecting to log server, no log will be shown"))
   302  							Expect(testUI.Out).To(Say(`name:\s+%s`, appName))
   303  						})
   304  					})
   305  
   306  					Context("an unexpected error occurs", func() {
   307  						var expectedErr error
   308  
   309  						BeforeEach(func() {
   310  							expectedErr = errors.New("err log message")
   311  							fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
   312  								messages := make(chan *v2action.LogMessage)
   313  								logErrs := make(chan error)
   314  								appState := make(chan v2action.ApplicationStateChange)
   315  								warnings := make(chan string)
   316  								errs := make(chan error)
   317  
   318  								go func() {
   319  									logErrs <- expectedErr
   320  									close(messages)
   321  									close(logErrs)
   322  									close(appState)
   323  									close(warnings)
   324  									close(errs)
   325  								}()
   326  
   327  								return messages, logErrs, appState, warnings, errs
   328  							}
   329  						})
   330  
   331  						It("displays the error and continues to poll", func() {
   332  							Expect(executeErr).NotTo(HaveOccurred())
   333  							Expect(testUI.Err).To(Say(expectedErr.Error()))
   334  						})
   335  					})
   336  				})
   337  
   338  				When("passed a warning", func() {
   339  					Context("while NOAA is still logging", func() {
   340  						BeforeEach(func() {
   341  							fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
   342  								messages := make(chan *v2action.LogMessage)
   343  								logErrs := make(chan error)
   344  								appState := make(chan v2action.ApplicationStateChange)
   345  								warnings := make(chan string)
   346  								errs := make(chan error)
   347  
   348  								go func() {
   349  									warnings <- "warning 1"
   350  									warnings <- "warning 2"
   351  									close(messages)
   352  									close(logErrs)
   353  									close(appState)
   354  									close(warnings)
   355  									close(errs)
   356  								}()
   357  
   358  								return messages, logErrs, appState, warnings, errs
   359  							}
   360  						})
   361  
   362  						It("displays the warnings to STDERR", func() {
   363  							Expect(executeErr).ToNot(HaveOccurred())
   364  							Expect(testUI.Err).To(Say("warning 1"))
   365  							Expect(testUI.Err).To(Say("warning 2"))
   366  						})
   367  					})
   368  
   369  					Context("while NOAA is no longer logging", func() {
   370  						BeforeEach(func() {
   371  							fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
   372  								messages := make(chan *v2action.LogMessage)
   373  								logErrs := make(chan error)
   374  								appState := make(chan v2action.ApplicationStateChange)
   375  								warnings := make(chan string)
   376  								errs := make(chan error)
   377  
   378  								go func() {
   379  									warnings <- "warning 1"
   380  									warnings <- "warning 2"
   381  									logErrs <- actionerror.NOAATimeoutError{}
   382  									close(messages)
   383  									close(logErrs)
   384  									warnings <- "warning 3"
   385  									warnings <- "warning 4"
   386  									close(appState)
   387  									close(warnings)
   388  									close(errs)
   389  								}()
   390  
   391  								return messages, logErrs, appState, warnings, errs
   392  							}
   393  						})
   394  
   395  						It("displays the warnings to STDERR", func() {
   396  							Expect(executeErr).ToNot(HaveOccurred())
   397  							Expect(testUI.Err).To(Say("warning 1"))
   398  							Expect(testUI.Err).To(Say("warning 2"))
   399  							Expect(testUI.Err).To(Say("timeout connecting to log server, no log will be shown"))
   400  							Expect(testUI.Err).To(Say("warning 3"))
   401  							Expect(testUI.Err).To(Say("warning 4"))
   402  						})
   403  					})
   404  				})
   405  
   406  				When("passed an API err", func() {
   407  					var apiErr error
   408  
   409  					BeforeEach(func() {
   410  						fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) {
   411  							messages := make(chan *v2action.LogMessage)
   412  							logErrs := make(chan error)
   413  							appState := make(chan v2action.ApplicationStateChange)
   414  							warnings := make(chan string)
   415  							errs := make(chan error)
   416  
   417  							go func() {
   418  								errs <- apiErr
   419  								close(messages)
   420  								close(logErrs)
   421  								close(appState)
   422  								close(warnings)
   423  								close(errs)
   424  							}()
   425  
   426  							return messages, logErrs, appState, warnings, errs
   427  						}
   428  					})
   429  
   430  					Context("an unexpected error", func() {
   431  						BeforeEach(func() {
   432  							apiErr = errors.New("err log message")
   433  						})
   434  
   435  						It("stops logging and returns the error", func() {
   436  							Expect(executeErr).To(MatchError(apiErr))
   437  						})
   438  					})
   439  
   440  					Context("staging failed", func() {
   441  						BeforeEach(func() {
   442  							apiErr = actionerror.StagingFailedError{Reason: "Something, but not nothing"}
   443  						})
   444  
   445  						It("stops logging and returns StagingFailedError", func() {
   446  							Expect(executeErr).To(MatchError(translatableerror.StagingFailedError{Message: "Something, but not nothing"}))
   447  						})
   448  					})
   449  
   450  					Context("staging timed out", func() {
   451  						BeforeEach(func() {
   452  							apiErr = actionerror.StagingTimeoutError{AppName: appName, Timeout: time.Nanosecond}
   453  						})
   454  
   455  						It("stops logging and returns StagingTimeoutError", func() {
   456  							Expect(executeErr).To(MatchError(translatableerror.StagingTimeoutError{AppName: appName, Timeout: time.Nanosecond}))
   457  						})
   458  					})
   459  
   460  					When("the app instance crashes", func() {
   461  						BeforeEach(func() {
   462  							apiErr = actionerror.ApplicationInstanceCrashedError{Name: appName}
   463  						})
   464  
   465  						It("stops logging and returns ApplicationUnableToStartError", func() {
   466  							Expect(executeErr).To(MatchError(translatableerror.ApplicationUnableToStartError{AppName: appName, BinaryName: "faceman"}))
   467  						})
   468  					})
   469  
   470  					When("the app instance flaps", func() {
   471  						BeforeEach(func() {
   472  							apiErr = actionerror.ApplicationInstanceFlappingError{Name: appName}
   473  						})
   474  
   475  						It("stops logging and returns ApplicationUnableToStartError", func() {
   476  							Expect(executeErr).To(MatchError(translatableerror.ApplicationUnableToStartError{AppName: appName, BinaryName: "faceman"}))
   477  						})
   478  					})
   479  
   480  					Context("starting timeout", func() {
   481  						BeforeEach(func() {
   482  							apiErr = actionerror.StartupTimeoutError{Name: appName}
   483  						})
   484  
   485  						It("stops logging and returns StartupTimeoutError", func() {
   486  							Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{AppName: appName, BinaryName: "faceman"}))
   487  						})
   488  					})
   489  				})
   490  
   491  				When("the app finishes starting", func() {
   492  					Describe("version-dependent display", func() {
   493  						When("CC API >= 3.27.0", func() {
   494  							var (
   495  								applicationSummary v2v3action.ApplicationSummary
   496  							)
   497  
   498  							BeforeEach(func() {
   499  								fakeApplicationSummaryActor.CloudControllerV3APIVersionReturns("3.50.0")
   500  								v3ApplicationSummary := v3action.ApplicationSummary{
   501  									Application: v3action.Application{
   502  										Name: appName,
   503  									},
   504  									ProcessSummaries: v3action.ProcessSummaries{
   505  										{
   506  											Process: v3action.Process{
   507  												Type:       "aba",
   508  												Command:    *types.NewFilteredString("some-command-1"),
   509  												MemoryInMB: types.NullUint64{Value: 32, IsSet: true},
   510  												DiskInMB:   types.NullUint64{Value: 1024, IsSet: true},
   511  											},
   512  										},
   513  										{
   514  											Process: v3action.Process{
   515  												Type:       "console",
   516  												Command:    *types.NewFilteredString("some-command-2"),
   517  												MemoryInMB: types.NullUint64{Value: 16, IsSet: true},
   518  												DiskInMB:   types.NullUint64{Value: 512, IsSet: true},
   519  											},
   520  										},
   521  									},
   522  								}
   523  								applicationSummary = v2v3action.ApplicationSummary{
   524  									ApplicationSummary: v3ApplicationSummary,
   525  								}
   526  
   527  								fakeApplicationSummaryActor.GetApplicationSummaryByNameAndSpaceReturns(
   528  									applicationSummary,
   529  									v2v3action.Warnings{"combo-summary-warning"},
   530  									nil)
   531  
   532  							})
   533  
   534  							It("uses the multiprocess display", func() {
   535  								Expect(executeErr).ToNot(HaveOccurred())
   536  
   537  								Expect(fakeApplicationSummaryActor.GetApplicationSummaryByNameAndSpaceCallCount()).To(Equal(1))
   538  								passedAppName, spaceGUID, withObfuscatedValues := fakeApplicationSummaryActor.GetApplicationSummaryByNameAndSpaceArgsForCall(0)
   539  								Expect(passedAppName).To(Equal(appName))
   540  								Expect(spaceGUID).To(Equal("some-space-guid"))
   541  								Expect(withObfuscatedValues).To(BeTrue())
   542  
   543  								Expect(testUI.Out).To(Say(`name:\s+%s`, appName))
   544  								Expect(testUI.Out).To(Say(`type:\s+aba`))
   545  								Expect(testUI.Out).To(Say(`instances:\s+0/0`))
   546  								Expect(testUI.Out).To(Say(`memory usage:\s+32M`))
   547  								Expect(testUI.Out).To(Say(`start command:\s+some-command-1`))
   548  								Expect(testUI.Out).To(Say(`type:\s+console`))
   549  								Expect(testUI.Out).To(Say(`instances:\s+0/0`))
   550  								Expect(testUI.Out).To(Say(`memory usage:\s+16M`))
   551  								Expect(testUI.Out).To(Say(`start command:\s+some-command-2`))
   552  
   553  								Expect(testUI.Err).To(Say("combo-summary-warning"))
   554  							})
   555  						})
   556  					})
   557  				})
   558  			})
   559  		})
   560  
   561  		When("the app does *not* exists", func() {
   562  			BeforeEach(func() {
   563  				fakeActor.GetApplicationByNameAndSpaceReturns(
   564  					v2action.Application{},
   565  					v2action.Warnings{"warning-1", "warning-2"},
   566  					actionerror.ApplicationNotFoundError{Name: appName},
   567  				)
   568  			})
   569  
   570  			It("returns back an error", func() {
   571  				Expect(executeErr).To(MatchError(actionerror.ApplicationNotFoundError{Name: "some-app"}))
   572  
   573  				Expect(testUI.Err).To(Say("warning-1"))
   574  				Expect(testUI.Err).To(Say("warning-2"))
   575  			})
   576  		})
   577  	})
   578  })