github.com/randomtask1155/cli@v6.41.1-0.20181227003417-a98eed78cbde+incompatible/command/v6/restart_command_test.go (about)

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