github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/command/v2/start_command_test.go (about)

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