github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/command/v2/start_command_test.go (about) 1 package v2_test 2 3 import ( 4 "errors" 5 "time" 6 7 "github.com/cloudfoundry/bytefmt" 8 "github.com/liamawhite/cli-with-i18n/actor/actionerror" 9 "github.com/liamawhite/cli-with-i18n/actor/sharedaction" 10 "github.com/liamawhite/cli-with-i18n/actor/v2action" 11 "github.com/liamawhite/cli-with-i18n/api/cloudcontroller/ccv2" 12 "github.com/liamawhite/cli-with-i18n/command/commandfakes" 13 "github.com/liamawhite/cli-with-i18n/command/translatableerror" 14 . "github.com/liamawhite/cli-with-i18n/command/v2" 15 "github.com/liamawhite/cli-with-i18n/command/v2/v2fakes" 16 "github.com/liamawhite/cli-with-i18n/types" 17 "github.com/liamawhite/cli-with-i18n/util/configv3" 18 "github.com/liamawhite/cli-with-i18n/util/ui" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 . "github.com/onsi/gomega/gbytes" 22 ) 23 24 var _ = Describe("Start Command", func() { 25 var ( 26 cmd StartCommand 27 testUI *ui.UI 28 fakeConfig *commandfakes.FakeConfig 29 fakeSharedActor *commandfakes.FakeSharedActor 30 fakeActor *v2fakes.FakeStartActor 31 binaryName string 32 executeErr error 33 ) 34 35 BeforeEach(func() { 36 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 37 fakeConfig = new(commandfakes.FakeConfig) 38 fakeSharedActor = new(commandfakes.FakeSharedActor) 39 fakeActor = new(v2fakes.FakeStartActor) 40 41 cmd = StartCommand{ 42 UI: testUI, 43 Config: fakeConfig, 44 SharedActor: fakeSharedActor, 45 Actor: fakeActor, 46 } 47 48 cmd.RequiredArgs.AppName = "some-app" 49 50 binaryName = "faceman" 51 fakeConfig.BinaryNameReturns(binaryName) 52 53 var err error 54 testUI.TimezoneLocation, err = time.LoadLocation("America/Los_Angeles") 55 Expect(err).NotTo(HaveOccurred()) 56 57 fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient, config v2action.Config) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 58 messages := make(chan *v2action.LogMessage) 59 logErrs := make(chan error) 60 appState := make(chan v2action.ApplicationStateChange) 61 warnings := make(chan string) 62 errs := make(chan error) 63 64 go func() { 65 close(messages) 66 close(logErrs) 67 close(appState) 68 close(warnings) 69 close(errs) 70 }() 71 72 return messages, logErrs, appState, warnings, errs 73 } 74 }) 75 76 JustBeforeEach(func() { 77 executeErr = cmd.Execute(nil) 78 }) 79 80 Context("when checking target fails", func() { 81 BeforeEach(func() { 82 fakeSharedActor.CheckTargetReturns(sharedaction.NotLoggedInError{BinaryName: binaryName}) 83 }) 84 85 It("returns an error if the check fails", func() { 86 Expect(executeErr).To(MatchError(translatableerror.NotLoggedInError{BinaryName: "faceman"})) 87 88 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 89 _, checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0) 90 Expect(checkTargetedOrg).To(BeTrue()) 91 Expect(checkTargetedSpace).To(BeTrue()) 92 }) 93 }) 94 95 Context("when the user is logged in, and org and space are targeted", func() { 96 BeforeEach(func() { 97 fakeConfig.HasTargetedOrganizationReturns(true) 98 fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "some-org"}) 99 fakeConfig.HasTargetedSpaceReturns(true) 100 fakeConfig.TargetedSpaceReturns(configv3.Space{ 101 GUID: "some-space-guid", 102 Name: "some-space"}) 103 fakeConfig.CurrentUserReturns( 104 configv3.User{Name: "some-user"}, 105 nil) 106 }) 107 108 Context("when getting the current user returns an error", func() { 109 var expectedErr error 110 111 BeforeEach(func() { 112 expectedErr = errors.New("getting current user error") 113 fakeConfig.CurrentUserReturns( 114 configv3.User{}, 115 expectedErr) 116 }) 117 118 It("returns the error", func() { 119 Expect(executeErr).To(MatchError(expectedErr)) 120 }) 121 }) 122 123 It("displays flavor text", func() { 124 Expect(testUI.Out).To(Say("Starting app some-app in org some-org / space some-space as some-user...")) 125 }) 126 127 Context("when the app exists", func() { 128 Context("when the app is already started", func() { 129 BeforeEach(func() { 130 fakeActor.GetApplicationByNameAndSpaceReturns( 131 v2action.Application{State: ccv2.ApplicationStarted}, 132 v2action.Warnings{"warning-1", "warning-2"}, 133 nil, 134 ) 135 }) 136 137 It("short circuits and displays message", func() { 138 Expect(executeErr).ToNot(HaveOccurred()) 139 140 Expect(testUI.Out).To(Say("App some-app is already started")) 141 142 Expect(testUI.Err).To(Say("warning-1")) 143 Expect(testUI.Err).To(Say("warning-2")) 144 145 Expect(fakeActor.StartApplicationCallCount()).To(Equal(0)) 146 }) 147 }) 148 149 Context("when the app is not already started", func() { 150 BeforeEach(func() { 151 fakeActor.GetApplicationByNameAndSpaceReturns( 152 v2action.Application{GUID: "app-guid", State: ccv2.ApplicationStopped}, 153 v2action.Warnings{"warning-1", "warning-2"}, 154 nil, 155 ) 156 }) 157 158 It("starts the app", func() { 159 Expect(executeErr).ToNot(HaveOccurred()) 160 161 Expect(testUI.Err).To(Say("warning-1")) 162 Expect(testUI.Err).To(Say("warning-2")) 163 164 Expect(fakeActor.StartApplicationCallCount()).To(Equal(1)) 165 app, _, config := fakeActor.StartApplicationArgsForCall(0) 166 Expect(app.GUID).To(Equal("app-guid")) 167 Expect(config).To(Equal(fakeConfig)) 168 }) 169 170 Context("when passed an ApplicationStateStarting message", func() { 171 BeforeEach(func() { 172 fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient, config v2action.Config) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 173 messages := make(chan *v2action.LogMessage) 174 logErrs := make(chan error) 175 appState := make(chan v2action.ApplicationStateChange) 176 warnings := make(chan string) 177 errs := make(chan error) 178 179 go func() { 180 messages <- v2action.NewLogMessage("log message 1", 1, time.Unix(0, 0), "STG", "1") 181 messages <- v2action.NewLogMessage("log message 2", 1, time.Unix(0, 0), "STG", "1") 182 appState <- v2action.ApplicationStateStarting 183 close(messages) 184 close(logErrs) 185 close(appState) 186 close(warnings) 187 close(errs) 188 }() 189 190 return messages, logErrs, appState, warnings, errs 191 } 192 }) 193 194 It("displays the log", func() { 195 Expect(executeErr).ToNot(HaveOccurred()) 196 Expect(testUI.Out).To(Say("log message 1")) 197 Expect(testUI.Out).To(Say("log message 2")) 198 Expect(testUI.Out).To(Say("Waiting for app to start...")) 199 }) 200 }) 201 202 Context("when passed a log message", func() { 203 BeforeEach(func() { 204 fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient, config v2action.Config) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 205 messages := make(chan *v2action.LogMessage) 206 logErrs := make(chan error) 207 appState := make(chan v2action.ApplicationStateChange) 208 warnings := make(chan string) 209 errs := make(chan error) 210 211 go func() { 212 messages <- v2action.NewLogMessage("log message 1", 1, time.Unix(0, 0), "STG", "1") 213 messages <- v2action.NewLogMessage("log message 2", 1, time.Unix(0, 0), "STG", "1") 214 messages <- v2action.NewLogMessage("log message 3", 1, time.Unix(0, 0), "Something else", "1") 215 close(messages) 216 close(logErrs) 217 close(appState) 218 close(warnings) 219 close(errs) 220 }() 221 222 return messages, logErrs, appState, warnings, errs 223 } 224 }) 225 226 It("displays the log", func() { 227 Expect(executeErr).ToNot(HaveOccurred()) 228 Expect(testUI.Out).To(Say("log message 1")) 229 Expect(testUI.Out).To(Say("log message 2")) 230 Expect(testUI.Out).ToNot(Say("log message 3")) 231 }) 232 }) 233 234 Context("when passed an log err", func() { 235 Context("NOAA connection times out/closes", func() { 236 BeforeEach(func() { 237 fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient, config v2action.Config) (<-chan *v2action.LogMessage, <-chan error, <-chan v2action.ApplicationStateChange, <-chan string, <-chan error) { 238 messages := make(chan *v2action.LogMessage) 239 logErrs := make(chan error) 240 appState := make(chan v2action.ApplicationStateChange) 241 warnings := make(chan string) 242 errs := make(chan error) 243 244 go func() { 245 messages <- v2action.NewLogMessage("log message 1", 1, time.Unix(0, 0), "STG", "1") 246 messages <- v2action.NewLogMessage("log message 2", 1, time.Unix(0, 0), "STG", "1") 247 messages <- v2action.NewLogMessage("log message 3", 1, time.Unix(0, 0), "STG", "1") 248 logErrs <- v2action.NOAATimeoutError{} 249 close(messages) 250 close(logErrs) 251 close(appState) 252 close(warnings) 253 close(errs) 254 }() 255 256 return messages, logErrs, appState, warnings, errs 257 } 258 259 applicationSummary := v2action.ApplicationSummary{ 260 Application: v2action.Application{ 261 Name: "some-app", 262 GUID: "some-app-guid", 263 Instances: types.NullInt{Value: 3, IsSet: true}, 264 Memory: 128, 265 PackageUpdatedAt: time.Unix(0, 0), 266 DetectedBuildpack: types.FilteredString{IsSet: true, Value: "some-buildpack"}, 267 State: "STARTED", 268 DetectedStartCommand: types.FilteredString{IsSet: true, Value: "some start command"}, 269 }, 270 Stack: v2action.Stack{ 271 Name: "potatos", 272 }, 273 Routes: []v2action.Route{ 274 { 275 Host: "banana", 276 Domain: v2action.Domain{ 277 Name: "fruit.com", 278 }, 279 Path: "/hi", 280 }, 281 { 282 Domain: v2action.Domain{ 283 Name: "foobar.com", 284 }, 285 Port: types.NullInt{IsSet: true, Value: 13}, 286 }, 287 }, 288 } 289 warnings := []string{"app-summary-warning"} 290 291 applicationSummary.RunningInstances = []v2action.ApplicationInstanceWithStats{} 292 293 fakeActor.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+some-app")) 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, config v2action.Config) (<-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 Context("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, config v2action.Config) (<-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, config v2action.Config) (<-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 <- v2action.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 Context("when passed an API err", func() { 407 var apiErr error 408 409 BeforeEach(func() { 410 fakeActor.StartApplicationStub = func(app v2action.Application, client v2action.NOAAClient, config v2action.Config) (<-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{Name: "some-app", Timeout: time.Nanosecond} 453 }) 454 455 It("stops logging and returns StagingTimeoutError", func() { 456 Expect(executeErr).To(MatchError(translatableerror.StagingTimeoutError{AppName: "some-app", Timeout: time.Nanosecond})) 457 }) 458 }) 459 460 Context("when the app instance crashes", func() { 461 BeforeEach(func() { 462 apiErr = actionerror.ApplicationInstanceCrashedError{Name: "some-app"} 463 }) 464 465 It("stops logging and returns UnsuccessfulStartError", func() { 466 Expect(executeErr).To(MatchError(translatableerror.UnsuccessfulStartError{AppName: "some-app", BinaryName: "faceman"})) 467 }) 468 }) 469 470 Context("when the app instance flaps", func() { 471 BeforeEach(func() { 472 apiErr = actionerror.ApplicationInstanceFlappingError{Name: "some-app"} 473 }) 474 475 It("stops logging and returns UnsuccessfulStartError", func() { 476 Expect(executeErr).To(MatchError(translatableerror.UnsuccessfulStartError{AppName: "some-app", BinaryName: "faceman"})) 477 }) 478 }) 479 480 Context("starting timeout", func() { 481 BeforeEach(func() { 482 apiErr = actionerror.StartupTimeoutError{Name: "some-app"} 483 }) 484 485 It("stops logging and returns StartupTimeoutError", func() { 486 Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{AppName: "some-app", BinaryName: "faceman"})) 487 }) 488 }) 489 }) 490 491 Context("when the app finishes starting", func() { 492 var ( 493 applicationSummary v2action.ApplicationSummary 494 warnings []string 495 ) 496 497 BeforeEach(func() { 498 applicationSummary = v2action.ApplicationSummary{ 499 Application: v2action.Application{ 500 Name: "some-app", 501 GUID: "some-app-guid", 502 Instances: types.NullInt{Value: 3, IsSet: true}, 503 Memory: 128, 504 PackageUpdatedAt: time.Unix(0, 0), 505 DetectedBuildpack: types.FilteredString{IsSet: true, Value: "some-buildpack"}, 506 State: "STARTED", 507 DetectedStartCommand: types.FilteredString{IsSet: true, Value: "some start command"}, 508 }, 509 IsolationSegment: "some-isolation-segment", 510 Stack: v2action.Stack{ 511 Name: "potatos", 512 }, 513 Routes: []v2action.Route{ 514 { 515 Host: "banana", 516 Domain: v2action.Domain{ 517 Name: "fruit.com", 518 }, 519 Path: "/hi", 520 }, 521 { 522 Domain: v2action.Domain{ 523 Name: "foobar.com", 524 }, 525 Port: types.NullInt{IsSet: true, Value: 13}, 526 }, 527 }, 528 } 529 warnings = []string{"app-summary-warning"} 530 531 applicationSummary.RunningInstances = []v2action.ApplicationInstanceWithStats{ 532 { 533 ID: 0, 534 State: v2action.ApplicationInstanceState(ccv2.ApplicationInstanceRunning), 535 Since: 1403140717.984577, 536 CPU: 0.73, 537 Disk: 50 * bytefmt.MEGABYTE, 538 DiskQuota: 2048 * bytefmt.MEGABYTE, 539 Memory: 100 * bytefmt.MEGABYTE, 540 MemoryQuota: 128 * bytefmt.MEGABYTE, 541 Details: "info from the backend", 542 }, 543 } 544 }) 545 546 Context("when the isolation segment is not empty", func() { 547 BeforeEach(func() { 548 fakeActor.GetApplicationSummaryByNameAndSpaceReturns(applicationSummary, warnings, nil) 549 }) 550 551 It("displays the app summary with isolation segments as well as warnings", func() { 552 Expect(executeErr).ToNot(HaveOccurred()) 553 Expect(testUI.Out).To(Say("name:\\s+some-app")) 554 Expect(testUI.Out).To(Say("requested state:\\s+started")) 555 Expect(testUI.Out).To(Say("instances:\\s+1\\/3")) 556 Expect(testUI.Out).To(Say("isolation segment:\\s+some-isolation-segment")) 557 Expect(testUI.Out).To(Say("usage:\\s+128M x 3 instances")) 558 Expect(testUI.Out).To(Say("routes:\\s+banana.fruit.com/hi, foobar.com:13")) 559 Expect(testUI.Out).To(Say("last uploaded:\\s+\\w{3} [0-3]\\d \\w{3} [0-2]\\d:[0-5]\\d:[0-5]\\d \\w+ \\d{4}")) 560 Expect(testUI.Out).To(Say("stack:\\s+potatos")) 561 Expect(testUI.Out).To(Say("buildpack:\\s+some-buildpack")) 562 Expect(testUI.Out).To(Say("start command:\\s+some start command")) 563 564 Expect(testUI.Err).To(Say("app-summary-warning")) 565 }) 566 567 It("should display the instance table", func() { 568 Expect(executeErr).ToNot(HaveOccurred()) 569 Expect(testUI.Out).To(Say("state\\s+since\\s+cpu\\s+memory\\s+disk")) 570 Expect(testUI.Out).To(Say(`#0\s+running\s+2014-06-19T01:18:37Z\s+73.0%\s+100M of 128M\s+50M of 2G\s+info from the backend`)) 571 }) 572 573 }) 574 575 Context("when the isolation segment is empty", func() { 576 BeforeEach(func() { 577 applicationSummary.IsolationSegment = "" 578 fakeActor.GetApplicationSummaryByNameAndSpaceReturns(applicationSummary, warnings, nil) 579 }) 580 581 It("displays the app summary without isolation segment as well as warnings", func() { 582 Expect(executeErr).ToNot(HaveOccurred()) 583 Expect(testUI.Out).To(Say("name:\\s+some-app")) 584 Expect(testUI.Out).To(Say("requested state:\\s+started")) 585 Expect(testUI.Out).To(Say("instances:\\s+1\\/3")) 586 Expect(testUI.Out).NotTo(Say("isolation segment:")) 587 Expect(testUI.Out).To(Say("usage:\\s+128M x 3 instances")) 588 Expect(testUI.Out).To(Say("routes:\\s+banana.fruit.com/hi, foobar.com:13")) 589 Expect(testUI.Out).To(Say("last uploaded:\\s+\\w{3} [0-3]\\d \\w{3} [0-2]\\d:[0-5]\\d:[0-5]\\d \\w+ \\d{4}")) 590 Expect(testUI.Out).To(Say("stack:\\s+potatos")) 591 Expect(testUI.Out).To(Say("buildpack:\\s+some-buildpack")) 592 Expect(testUI.Out).To(Say("start command:\\s+some start command")) 593 594 Expect(testUI.Err).To(Say("app-summary-warning")) 595 }) 596 597 It("should display the instance table", func() { 598 Expect(executeErr).ToNot(HaveOccurred()) 599 Expect(testUI.Out).To(Say("state\\s+since\\s+cpu\\s+memory\\s+disk")) 600 Expect(testUI.Out).To(Say(`#0\s+running\s+2014-06-19T01:18:37Z\s+73.0%\s+100M of 128M\s+50M of 2G\s+info from the backend`)) 601 }) 602 }) 603 }) 604 }) 605 }) 606 607 Context("when the app does *not* exists", func() { 608 BeforeEach(func() { 609 fakeActor.GetApplicationByNameAndSpaceReturns( 610 v2action.Application{}, 611 v2action.Warnings{"warning-1", "warning-2"}, 612 actionerror.ApplicationNotFoundError{Name: "some-app"}, 613 ) 614 }) 615 616 It("returns back an error", func() { 617 Expect(executeErr).To(MatchError(translatableerror.ApplicationNotFoundError{Name: "some-app"})) 618 619 Expect(testUI.Err).To(Say("warning-1")) 620 Expect(testUI.Err).To(Say("warning-2")) 621 }) 622 }) 623 }) 624 })