github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/command/v6/start_command_test.go (about)

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