github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/command/v6/v3_zdt_push_command_test.go (about)

     1  package v6_test
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	"code.cloudfoundry.org/cli/actor/actionerror"
     8  	"code.cloudfoundry.org/cli/actor/pushaction"
     9  	"code.cloudfoundry.org/cli/actor/v2action"
    10  	"code.cloudfoundry.org/cli/actor/v3action"
    11  	"code.cloudfoundry.org/cli/actor/v3action/v3actionfakes"
    12  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    13  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccversion"
    14  	"code.cloudfoundry.org/cli/command/commandfakes"
    15  	"code.cloudfoundry.org/cli/command/flag"
    16  	"code.cloudfoundry.org/cli/command/translatableerror"
    17  	. "code.cloudfoundry.org/cli/command/v6"
    18  	"code.cloudfoundry.org/cli/command/v6/shared"
    19  	"code.cloudfoundry.org/cli/command/v6/shared/sharedfakes"
    20  	"code.cloudfoundry.org/cli/command/v6/v6fakes"
    21  	"code.cloudfoundry.org/cli/types"
    22  	"code.cloudfoundry.org/cli/util/configv3"
    23  	"code.cloudfoundry.org/cli/util/ui"
    24  	. "github.com/onsi/ginkgo"
    25  	. "github.com/onsi/ginkgo/extensions/table"
    26  	. "github.com/onsi/gomega"
    27  	. "github.com/onsi/gomega/gbytes"
    28  )
    29  
    30  var _ = Describe("v3-zdt-push Command", func() {
    31  	var (
    32  		cmd             V3ZeroDowntimePushCommand
    33  		testUI          *ui.UI
    34  		fakeConfig      *commandfakes.FakeConfig
    35  		fakeSharedActor *commandfakes.FakeSharedActor
    36  		fakeNOAAClient  *v3actionfakes.FakeNOAAClient
    37  		fakeZdtActor    *v6fakes.FakeV3ZeroDowntimeVersionActor
    38  		fakeV3PushActor *v6fakes.FakeOriginalV3PushActor
    39  		fakeV2PushActor *v6fakes.FakeOriginalV2PushActor
    40  		fakeV2AppActor  *sharedfakes.FakeV2AppActor
    41  		binaryName      string
    42  		executeErr      error
    43  		app             string
    44  		userName        string
    45  		spaceName       string
    46  		orgName         string
    47  	)
    48  
    49  	BeforeEach(func() {
    50  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    51  		fakeConfig = new(commandfakes.FakeConfig)
    52  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    53  		fakeZdtActor = new(v6fakes.FakeV3ZeroDowntimeVersionActor)
    54  		fakeV3PushActor = new(v6fakes.FakeOriginalV3PushActor)
    55  		fakeV2PushActor = new(v6fakes.FakeOriginalV2PushActor)
    56  		fakeV2AppActor = new(sharedfakes.FakeV2AppActor)
    57  		fakeNOAAClient = new(v3actionfakes.FakeNOAAClient)
    58  
    59  		fakeConfig.StagingTimeoutReturns(10 * time.Minute)
    60  
    61  		binaryName = "faceman"
    62  		fakeConfig.BinaryNameReturns(binaryName)
    63  		app = "some-app"
    64  		userName = "banana"
    65  		spaceName = "some-space"
    66  		orgName = "some-org"
    67  
    68  		appSummaryDisplayer := shared.AppSummaryDisplayer{
    69  			UI:         testUI,
    70  			Config:     fakeConfig,
    71  			Actor:      fakeV3PushActor,
    72  			V2AppActor: fakeV2AppActor,
    73  			AppName:    app,
    74  		}
    75  		packageDisplayer := shared.NewPackageDisplayer(
    76  			testUI,
    77  			fakeConfig,
    78  		)
    79  
    80  		cmd = V3ZeroDowntimePushCommand{
    81  			RequiredArgs: flag.AppName{AppName: app},
    82  
    83  			UI:                  testUI,
    84  			Config:              fakeConfig,
    85  			SharedActor:         fakeSharedActor,
    86  			ZdtActor:            fakeZdtActor,
    87  			OriginalV2PushActor: fakeV2PushActor,
    88  
    89  			NOAAClient:          fakeNOAAClient,
    90  			AppSummaryDisplayer: appSummaryDisplayer,
    91  			PackageDisplayer:    packageDisplayer,
    92  		}
    93  		fakeZdtActor.CloudControllerAPIVersionReturns(ccversion.MinVersionZeroDowntimePushV3)
    94  
    95  		// we stub out StagePackage out here so the happy paths below don't hang
    96  		fakeZdtActor.StagePackageStub = func(_ string, _ string) (<-chan v3action.Droplet, <-chan v3action.Warnings, <-chan error) {
    97  			dropletStream := make(chan v3action.Droplet)
    98  			warningsStream := make(chan v3action.Warnings)
    99  			errorStream := make(chan error)
   100  
   101  			go func() {
   102  				defer close(dropletStream)
   103  				defer close(warningsStream)
   104  				defer close(errorStream)
   105  			}()
   106  
   107  			return dropletStream, warningsStream, errorStream
   108  		}
   109  	})
   110  
   111  	JustBeforeEach(func() {
   112  		executeErr = cmd.Execute(nil)
   113  	})
   114  
   115  	When("the API version is at the minimum documented version", func() {
   116  		const MinVersionDocumentedZDTPush = "3.55.0" // CAPI docs show that 3.55.0 should work, but it doesn't,
   117  		// so we're using 3.55 as the "version below the version we support" in this test to document this fact.
   118  		BeforeEach(func() {
   119  			fakeZdtActor.CloudControllerAPIVersionReturns(MinVersionDocumentedZDTPush)
   120  		})
   121  
   122  		It("returns a MinimumAPIVersionNotMetError", func() {
   123  			Expect(executeErr).To(MatchError(translatableerror.MinimumCFAPIVersionNotMetError{
   124  				CurrentVersion: MinVersionDocumentedZDTPush,
   125  				MinimumVersion: ccversion.MinVersionZeroDowntimePushV3,
   126  			}))
   127  		})
   128  
   129  		It("displays the experimental warning", func() {
   130  			Expect(testUI.Err).To(Say("This command is in EXPERIMENTAL stage and may change without notice"))
   131  		})
   132  	})
   133  
   134  	When("the API version is the oldest supported by the CLI", func() {
   135  		BeforeEach(func() {
   136  			fakeZdtActor.CloudControllerAPIVersionReturns(ccversion.MinSupportedV3ClientVersion)
   137  		})
   138  
   139  		It("returns a MinimumAPIVersionNotMetError", func() {
   140  			Expect(executeErr).To(MatchError(translatableerror.MinimumCFAPIVersionNotMetError{
   141  				CurrentVersion: ccversion.MinSupportedV3ClientVersion,
   142  				MinimumVersion: ccversion.MinVersionZeroDowntimePushV3,
   143  			}))
   144  		})
   145  
   146  		It("displays the experimental warning", func() {
   147  			Expect(testUI.Err).To(Say("This command is in EXPERIMENTAL stage and may change without notice"))
   148  		})
   149  	})
   150  
   151  	DescribeTable("argument combinations",
   152  		func(dockerImage string, dockerUsername string, dockerPassword string,
   153  			buildpacks []string, appPath string,
   154  			expectedErr error) {
   155  			cmd.DockerImage.Path = dockerImage
   156  			cmd.DockerUsername = dockerUsername
   157  			fakeConfig.DockerPasswordReturns(dockerPassword)
   158  			cmd.Buildpacks = buildpacks
   159  			cmd.AppPath = flag.PathWithExistenceCheck(appPath)
   160  			Expect(cmd.Execute(nil)).To(MatchError(expectedErr))
   161  		},
   162  		Entry("docker username",
   163  			"", "some-docker-username", "", []string{}, "",
   164  			translatableerror.RequiredFlagsError{
   165  				Arg1: "--docker-image, -o",
   166  				Arg2: "--docker-username",
   167  			}),
   168  		Entry("docker username, password",
   169  			"", "some-docker-username", "my-password", []string{}, "",
   170  			translatableerror.RequiredFlagsError{
   171  				Arg1: "--docker-image, -o",
   172  				Arg2: "--docker-username",
   173  			}),
   174  		Entry("docker username, app path",
   175  			"", "some-docker-username", "", []string{}, "some/app/path",
   176  			translatableerror.RequiredFlagsError{
   177  				Arg1: "--docker-image, -o",
   178  				Arg2: "--docker-username",
   179  			}),
   180  		Entry("docker username, buildpacks",
   181  			"", "some-docker-username", "", []string{"ruby_buildpack"}, "",
   182  			translatableerror.RequiredFlagsError{
   183  				Arg1: "--docker-image, -o",
   184  				Arg2: "--docker-username",
   185  			}),
   186  		Entry("docker image, docker username",
   187  			"some-docker-image", "some-docker-username", "", []string{}, "",
   188  			translatableerror.DockerPasswordNotSetError{}),
   189  		Entry("docker image, app path",
   190  			"some-docker-image", "", "", []string{}, "some/app/path",
   191  			translatableerror.ArgumentCombinationError{
   192  				Args: []string{"--docker-image", "-o", "-p"},
   193  			}),
   194  		Entry("docker image, buildpacks",
   195  			"some-docker-image", "", "", []string{"ruby_buildpack"}, "",
   196  			translatableerror.ArgumentCombinationError{
   197  				Args: []string{"-b", "--docker-image", "-o"},
   198  			}),
   199  	)
   200  
   201  	Context("when checking target fails", func() {
   202  		BeforeEach(func() {
   203  			fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
   204  		})
   205  
   206  		It("returns an error", func() {
   207  			Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName}))
   208  
   209  			Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   210  			checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   211  			Expect(checkTargetedOrg).To(BeTrue())
   212  			Expect(checkTargetedSpace).To(BeTrue())
   213  		})
   214  	})
   215  
   216  	Context("when the user is logged in", func() {
   217  		BeforeEach(func() {
   218  			fakeConfig.CurrentUserReturns(configv3.User{Name: userName}, nil)
   219  			fakeConfig.TargetedSpaceReturns(configv3.Space{Name: spaceName, GUID: "some-space-guid"})
   220  			fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: orgName, GUID: "some-org-guid"})
   221  		})
   222  
   223  		Context("when looking up the application returns some api error", func() {
   224  			BeforeEach(func() {
   225  				fakeZdtActor.GetApplicationByNameAndSpaceReturns(v3action.Application{}, v3action.Warnings{"get-warning"}, errors.New("some-error"))
   226  			})
   227  
   228  			It("returns the error and displays all warnings", func() {
   229  				Expect(executeErr).To(MatchError("some-error"))
   230  
   231  				Expect(testUI.Err).To(Say("get-warning"))
   232  			})
   233  		})
   234  
   235  		Context("when the application doesn't exist", func() {
   236  			BeforeEach(func() {
   237  				fakeZdtActor.GetApplicationByNameAndSpaceReturns(v3action.Application{}, v3action.Warnings{"get-warning"}, actionerror.ApplicationNotFoundError{Name: "some-app"})
   238  			})
   239  
   240  			Context("when creating the application returns an error", func() {
   241  				var expectedErr error
   242  
   243  				BeforeEach(func() {
   244  					expectedErr = errors.New("I am an error")
   245  					fakeZdtActor.CreateApplicationInSpaceReturns(v3action.Application{}, v3action.Warnings{"I am a warning", "I am also a warning"}, expectedErr)
   246  				})
   247  
   248  				It("displays the warnings and error", func() {
   249  					Expect(executeErr).To(MatchError(expectedErr))
   250  
   251  					Expect(testUI.Err).To(Say("I am a warning"))
   252  					Expect(testUI.Err).To(Say("I am also a warning"))
   253  					Expect(testUI.Out).ToNot(Say("app some-app in org some-org / space some-space as banana..."))
   254  				})
   255  			})
   256  
   257  			Context("when creating the application does not error", func() {
   258  				BeforeEach(func() {
   259  					fakeZdtActor.CreateApplicationInSpaceReturns(v3action.Application{Name: "some-app", GUID: "some-app-guid", State: constant.ApplicationStopped}, v3action.Warnings{"I am a warning", "I am also a warning"}, nil)
   260  				})
   261  
   262  				It("calls CreateApplication", func() {
   263  					Expect(fakeZdtActor.CreateApplicationInSpaceCallCount()).To(Equal(1), "Expected CreateApplicationInSpace to be called once")
   264  					createApp, createSpaceGUID := fakeZdtActor.CreateApplicationInSpaceArgsForCall(0)
   265  					Expect(createApp).To(Equal(v3action.Application{
   266  						Name:          "some-app",
   267  						LifecycleType: constant.AppLifecycleTypeBuildpack,
   268  					}))
   269  					Expect(createSpaceGUID).To(Equal("some-space-guid"))
   270  				})
   271  
   272  				Context("when creating the package fails", func() {
   273  					var expectedErr error
   274  
   275  					BeforeEach(func() {
   276  						expectedErr = errors.New("I am an error")
   277  						fakeZdtActor.CreateAndUploadBitsPackageByApplicationNameAndSpaceReturns(v3action.Package{}, v3action.Warnings{"I am a package warning", "I am also a package warning"}, expectedErr)
   278  					})
   279  
   280  					It("displays the header and error", func() {
   281  						Expect(executeErr).To(MatchError(expectedErr))
   282  
   283  						Expect(testUI.Out).To(Say("Uploading and creating bits package for app some-app in org some-org / space some-space as banana..."))
   284  
   285  						Expect(testUI.Err).To(Say("I am a package warning"))
   286  						Expect(testUI.Err).To(Say("I am also a package warning"))
   287  
   288  						Expect(testUI.Out).ToNot(Say("Staging package for %s in org some-org / space some-space as banana...", app))
   289  					})
   290  				})
   291  
   292  				Context("when creating the package succeeds", func() {
   293  					BeforeEach(func() {
   294  						fakeZdtActor.CreateAndUploadBitsPackageByApplicationNameAndSpaceReturns(v3action.Package{GUID: "some-guid"}, v3action.Warnings{"I am a package warning", "I am also a package warning"}, nil)
   295  					})
   296  
   297  					Context("when the -p flag is provided", func() {
   298  						BeforeEach(func() {
   299  							cmd.AppPath = "some-app-path"
   300  						})
   301  
   302  						It("creates the package with the provided path", func() {
   303  							Expect(testUI.Out).To(Say("Uploading and creating bits package for app %s in org %s / space %s as %s", app, orgName, spaceName, userName))
   304  							Expect(testUI.Err).To(Say("I am a package warning"))
   305  							Expect(testUI.Err).To(Say("I am also a package warning"))
   306  							Expect(testUI.Out).To(Say("OK"))
   307  							Expect(testUI.Out).To(Say("Staging package for app %s in org some-org / space some-space as banana...", app))
   308  
   309  							Expect(fakeZdtActor.CreateAndUploadBitsPackageByApplicationNameAndSpaceCallCount()).To(Equal(1))
   310  							_, _, appPath := fakeZdtActor.CreateAndUploadBitsPackageByApplicationNameAndSpaceArgsForCall(0)
   311  
   312  							Expect(appPath).To(Equal("some-app-path"))
   313  						})
   314  					})
   315  
   316  					Context("when the -o flag is provided", func() {
   317  						BeforeEach(func() {
   318  							cmd.DockerImage.Path = "example.com/docker/docker/docker:docker"
   319  							fakeZdtActor.CreateDockerPackageByApplicationNameAndSpaceReturns(v3action.Package{GUID: "some-guid"}, v3action.Warnings{"I am a docker package warning", "I am also a docker package warning"}, nil)
   320  						})
   321  
   322  						It("creates a docker package with the provided image path", func() {
   323  
   324  							Expect(testUI.Out).To(Say("Creating docker package for app %s in org %s / space %s as %s", app, orgName, spaceName, userName))
   325  							Expect(testUI.Err).To(Say("I am a docker package warning"))
   326  							Expect(testUI.Err).To(Say("I am also a docker package warning"))
   327  							Expect(testUI.Out).To(Say("OK"))
   328  							Expect(testUI.Out).To(Say("Staging package for app %s in org some-org / space some-space as banana...", app))
   329  
   330  							Expect(fakeZdtActor.CreateDockerPackageByApplicationNameAndSpaceCallCount()).To(Equal(1))
   331  							_, _, dockerImageCredentials := fakeZdtActor.CreateDockerPackageByApplicationNameAndSpaceArgsForCall(0)
   332  
   333  							Expect(dockerImageCredentials.Path).To(Equal("example.com/docker/docker/docker:docker"))
   334  						})
   335  					})
   336  
   337  					Context("when neither -p nor -o flags are provided", func() {
   338  						It("calls CreateAndUploadBitsPackageByApplicationNameAndSpace with empty string", func() {
   339  							Expect(testUI.Out).To(Say("Uploading and creating bits package for app %s in org %s / space %s as %s", app, orgName, spaceName, userName))
   340  
   341  							Expect(fakeZdtActor.CreateAndUploadBitsPackageByApplicationNameAndSpaceCallCount()).To(Equal(1))
   342  							_, _, appPath := fakeZdtActor.CreateAndUploadBitsPackageByApplicationNameAndSpaceArgsForCall(0)
   343  
   344  							Expect(appPath).To(BeEmpty())
   345  						})
   346  					})
   347  
   348  					Context("when getting streaming logs fails", func() {
   349  						var expectedErr error
   350  						BeforeEach(func() {
   351  							expectedErr = errors.New("something is wrong!")
   352  							fakeZdtActor.GetStreamingLogsForApplicationByNameAndSpaceReturns(nil, nil, v3action.Warnings{"some-logging-warning", "some-other-logging-warning"}, expectedErr)
   353  						})
   354  
   355  						It("returns the error and displays warnings", func() {
   356  							Expect(executeErr).To(Equal(expectedErr))
   357  
   358  							Expect(testUI.Out).To(Say("Staging package for app %s in org some-org / space some-space as banana...", app))
   359  
   360  							Expect(testUI.Err).To(Say("some-logging-warning"))
   361  							Expect(testUI.Err).To(Say("some-other-logging-warning"))
   362  
   363  						})
   364  					})
   365  
   366  					Context("when --no-start is provided", func() {
   367  						BeforeEach(func() {
   368  							cmd.NoStart = true
   369  						})
   370  
   371  						It("does not stage the package and returns", func() {
   372  							Expect(testUI.Out).To(Say("Uploading and creating bits package for app %s in org %s / space %s as %s", app, orgName, spaceName, userName))
   373  							Expect(fakeZdtActor.CreateAndUploadBitsPackageByApplicationNameAndSpaceCallCount()).To(Equal(1))
   374  							Expect(fakeZdtActor.GetStreamingLogsForApplicationByNameAndSpaceCallCount()).To(Equal(0))
   375  
   376  							Expect(executeErr).ToNot(HaveOccurred())
   377  						})
   378  					})
   379  
   380  					Context("when the logging does not error", func() {
   381  						var allLogsWritten chan bool
   382  
   383  						BeforeEach(func() {
   384  							allLogsWritten = make(chan bool)
   385  							fakeZdtActor.GetStreamingLogsForApplicationByNameAndSpaceStub = func(appName string, spaceGUID string, client v3action.NOAAClient) (<-chan *v3action.LogMessage, <-chan error, v3action.Warnings, error) {
   386  								logStream := make(chan *v3action.LogMessage)
   387  								errorStream := make(chan error)
   388  
   389  								go func() {
   390  									logStream <- v3action.NewLogMessage("Here are some staging logs!", 1, time.Now(), v3action.StagingLog, "sourceInstance")
   391  									logStream <- v3action.NewLogMessage("Here are some other staging logs!", 1, time.Now(), v3action.StagingLog, "sourceInstance")
   392  									logStream <- v3action.NewLogMessage("not from staging", 1, time.Now(), "potato", "sourceInstance")
   393  									allLogsWritten <- true
   394  								}()
   395  
   396  								return logStream, errorStream, v3action.Warnings{"steve for all I care"}, nil
   397  							}
   398  						})
   399  
   400  						Context("when the staging returns an error", func() {
   401  							var expectedErr error
   402  
   403  							BeforeEach(func() {
   404  								expectedErr = errors.New("any gibberish")
   405  								fakeZdtActor.StagePackageStub = func(packageGUID string, _ string) (<-chan v3action.Droplet, <-chan v3action.Warnings, <-chan error) {
   406  									dropletStream := make(chan v3action.Droplet)
   407  									warningsStream := make(chan v3action.Warnings)
   408  									errorStream := make(chan error)
   409  
   410  									go func() {
   411  										<-allLogsWritten
   412  										defer close(dropletStream)
   413  										defer close(warningsStream)
   414  										defer close(errorStream)
   415  										warningsStream <- v3action.Warnings{"some-staging-warning", "some-other-staging-warning"}
   416  										errorStream <- expectedErr
   417  									}()
   418  
   419  									return dropletStream, warningsStream, errorStream
   420  								}
   421  							})
   422  
   423  							It("returns the error and displays warnings", func() {
   424  								Expect(executeErr).To(Equal(expectedErr))
   425  
   426  								Expect(testUI.Out).To(Say("Staging package for app %s in org some-org / space some-space as banana...", app))
   427  
   428  								Expect(testUI.Err).To(Say("some-staging-warning"))
   429  								Expect(testUI.Err).To(Say("some-other-staging-warning"))
   430  
   431  								Expect(testUI.Out).ToNot(Say("Setting app some-app to droplet some-droplet-guid in org some-org / space some-space as banana..."))
   432  							})
   433  						})
   434  
   435  						Context("when the staging is successful", func() {
   436  							BeforeEach(func() {
   437  								fakeZdtActor.StagePackageStub = func(packageGUID string, _ string) (<-chan v3action.Droplet, <-chan v3action.Warnings, <-chan error) {
   438  									dropletStream := make(chan v3action.Droplet)
   439  									warningsStream := make(chan v3action.Warnings)
   440  									errorStream := make(chan error)
   441  
   442  									go func() {
   443  										<-allLogsWritten
   444  										defer close(dropletStream)
   445  										defer close(warningsStream)
   446  										defer close(errorStream)
   447  										warningsStream <- v3action.Warnings{"some-staging-warning", "some-other-staging-warning"}
   448  										dropletStream <- v3action.Droplet{GUID: "some-droplet-guid"}
   449  									}()
   450  
   451  									return dropletStream, warningsStream, errorStream
   452  								}
   453  							})
   454  
   455  							It("outputs the staging message and warnings", func() {
   456  								Expect(executeErr).ToNot(HaveOccurred())
   457  
   458  								Expect(testUI.Out).To(Say("Staging package for app %s in org some-org / space some-space as banana...", app))
   459  								Expect(testUI.Out).To(Say("OK"))
   460  
   461  								Expect(testUI.Err).To(Say("some-staging-warning"))
   462  								Expect(testUI.Err).To(Say("some-other-staging-warning"))
   463  							})
   464  
   465  							It("stages the package", func() {
   466  								Expect(executeErr).ToNot(HaveOccurred())
   467  								Expect(fakeZdtActor.StagePackageCallCount()).To(Equal(1))
   468  								guidArg, _ := fakeZdtActor.StagePackageArgsForCall(0)
   469  								Expect(guidArg).To(Equal("some-guid"))
   470  							})
   471  
   472  							It("displays staging logs and their warnings", func() {
   473  								Expect(testUI.Out).To(Say("Here are some staging logs!"))
   474  								Expect(testUI.Out).To(Say("Here are some other staging logs!"))
   475  								Expect(testUI.Out).ToNot(Say("not from staging"))
   476  
   477  								Expect(testUI.Err).To(Say("steve for all I care"))
   478  
   479  								Expect(fakeZdtActor.GetStreamingLogsForApplicationByNameAndSpaceCallCount()).To(Equal(1))
   480  								appName, spaceGUID, noaaClient := fakeZdtActor.GetStreamingLogsForApplicationByNameAndSpaceArgsForCall(0)
   481  								Expect(appName).To(Equal(app))
   482  								Expect(spaceGUID).To(Equal("some-space-guid"))
   483  								Expect(noaaClient).To(Equal(fakeNOAAClient))
   484  
   485  								guidArg, _ := fakeZdtActor.StagePackageArgsForCall(0)
   486  								Expect(guidArg).To(Equal("some-guid"))
   487  							})
   488  
   489  							Context("when --no-route flag is set to true", func() {
   490  								BeforeEach(func() {
   491  									cmd.NoRoute = true
   492  								})
   493  
   494  								It("does not create any routes", func() {
   495  									Expect(fakeV2PushActor.CreateAndMapDefaultApplicationRouteCallCount()).To(Equal(0))
   496  
   497  									Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(1))
   498  								})
   499  							})
   500  
   501  							Context("when buildpack(s) are provided via -b flag", func() {
   502  								BeforeEach(func() {
   503  									cmd.Buildpacks = []string{"some-buildpack"}
   504  								})
   505  
   506  								It("creates the app with the specified buildpack and prints the buildpack name in the summary", func() {
   507  									Expect(fakeZdtActor.CreateApplicationInSpaceCallCount()).To(Equal(1), "Expected CreateApplicationInSpace to be called once")
   508  									createApp, createSpaceGUID := fakeZdtActor.CreateApplicationInSpaceArgsForCall(0)
   509  									Expect(createApp).To(Equal(v3action.Application{
   510  										Name:                "some-app",
   511  										LifecycleType:       constant.AppLifecycleTypeBuildpack,
   512  										LifecycleBuildpacks: []string{"some-buildpack"},
   513  									}))
   514  									Expect(createSpaceGUID).To(Equal("some-space-guid"))
   515  								})
   516  							})
   517  
   518  							Context("when a docker image is specified", func() {
   519  								BeforeEach(func() {
   520  									cmd.DockerImage.Path = "example.com/docker/docker/docker:docker"
   521  								})
   522  
   523  								It("creates the app with a docker lifecycle", func() {
   524  									Expect(fakeZdtActor.CreateApplicationInSpaceCallCount()).To(Equal(1), "Expected CreateApplicationInSpace to be called once")
   525  									createApp, createSpaceGUID := fakeZdtActor.CreateApplicationInSpaceArgsForCall(0)
   526  									Expect(createApp).To(Equal(v3action.Application{
   527  										Name:          "some-app",
   528  										LifecycleType: constant.AppLifecycleTypeDocker,
   529  									}))
   530  									Expect(createSpaceGUID).To(Equal("some-space-guid"))
   531  								})
   532  							})
   533  
   534  							Context("when mapping routes fails", func() {
   535  								BeforeEach(func() {
   536  									fakeV2PushActor.CreateAndMapDefaultApplicationRouteReturns(pushaction.Warnings{"route-warning"}, errors.New("some-error"))
   537  								})
   538  
   539  								It("returns the error", func() {
   540  									Expect(executeErr).To(MatchError("some-error"))
   541  									Expect(testUI.Out).To(Say(`Mapping routes\.\.\.`))
   542  									Expect(testUI.Err).To(Say("route-warning"))
   543  
   544  									Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(0))
   545  								})
   546  							})
   547  
   548  							Context("when mapping routes succeeds and the app doesn't have a current droplet", func() {
   549  								BeforeEach(func() {
   550  									fakeV2PushActor.CreateAndMapDefaultApplicationRouteReturns(pushaction.Warnings{"route-warning"}, nil)
   551  									fakeZdtActor.GetCurrentDropletByApplicationReturns(v3action.Droplet{}, v3action.Warnings{}, actionerror.DropletNotFoundError{AppGUID: "some-app-guid"})
   552  								})
   553  
   554  								It("displays the header and OK", func() {
   555  									Expect(testUI.Out).To(Say(`Mapping routes\.\.\.`))
   556  									Expect(testUI.Out).To(Say("OK"))
   557  
   558  									Expect(testUI.Err).To(Say("route-warning"))
   559  
   560  									Expect(fakeV2PushActor.CreateAndMapDefaultApplicationRouteCallCount()).To(Equal(1), "Expected CreateAndMapDefaultApplicationRoute to be called")
   561  									orgArg, spaceArg, appArg := fakeV2PushActor.CreateAndMapDefaultApplicationRouteArgsForCall(0)
   562  									Expect(orgArg).To(Equal("some-org-guid"))
   563  									Expect(spaceArg).To(Equal("some-space-guid"))
   564  									Expect(appArg).To(Equal(v2action.Application{Name: "some-app", GUID: "some-app-guid"}))
   565  
   566  									Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(1))
   567  								})
   568  
   569  								It("restarts the application", func() {
   570  									Expect(executeErr).NotTo(HaveOccurred())
   571  									Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(1))
   572  								})
   573  
   574  								Context("when restarting the application fails", func() {
   575  									BeforeEach(func() {
   576  										fakeZdtActor.RestartApplicationReturns(v3action.Warnings{"start-warning-1", "start-warning-2"}, errors.New("some-error"))
   577  									})
   578  
   579  									It("says that the app failed to start", func() {
   580  										Expect(executeErr).To(Equal(errors.New("some-error")))
   581  										Expect(testUI.Out).To(Say(`Starting app some-app in org some-org / space some-space as banana\.\.\.`))
   582  
   583  										Expect(testUI.Err).To(Say("start-warning-1"))
   584  										Expect(testUI.Err).To(Say("start-warning-2"))
   585  
   586  										Expect(testUI.Out).ToNot(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
   587  									})
   588  								})
   589  
   590  								Context("when restarting the application succeeds", func() {
   591  									BeforeEach(func() {
   592  										fakeZdtActor.RestartApplicationReturns(v3action.Warnings{"start-warning-1", "start-warning-2"}, nil)
   593  									})
   594  
   595  									It("says that the app was started and outputs warnings", func() {
   596  										Expect(testUI.Out).To(Say(`Starting app some-app in org some-org / space some-space as banana\.\.\.`))
   597  
   598  										Expect(testUI.Err).To(Say("start-warning-1"))
   599  										Expect(testUI.Err).To(Say("start-warning-2"))
   600  										Expect(testUI.Out).To(Say("OK"))
   601  
   602  										Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(1))
   603  										appGUID := fakeZdtActor.RestartApplicationArgsForCall(0)
   604  										Expect(appGUID).To(Equal("some-app-guid"))
   605  									})
   606  
   607  								})
   608  
   609  								Context("it polls the application", func() {
   610  									Context("when polling the start fails", func() {
   611  										BeforeEach(func() {
   612  											fakeZdtActor.PollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
   613  												warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
   614  												return errors.New("some-error")
   615  											}
   616  										})
   617  
   618  										It("displays all warnings and fails", func() {
   619  											Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
   620  
   621  											Expect(testUI.Err).To(Say("some-poll-warning-1"))
   622  											Expect(testUI.Err).To(Say("some-poll-warning-2"))
   623  
   624  											Expect(executeErr).To(MatchError("some-error"))
   625  										})
   626  									})
   627  
   628  									Context("when polling times out", func() {
   629  										BeforeEach(func() {
   630  											fakeZdtActor.PollStartReturns(actionerror.StartupTimeoutError{})
   631  										})
   632  
   633  										It("returns the StartupTimeoutError", func() {
   634  											Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{
   635  												AppName:    "some-app",
   636  												BinaryName: binaryName,
   637  											}))
   638  										})
   639  									})
   640  
   641  									Context("when polling the start succeeds", func() {
   642  										BeforeEach(func() {
   643  											fakeZdtActor.PollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
   644  												warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
   645  												return nil
   646  											}
   647  										})
   648  
   649  										It("displays all warnings", func() {
   650  											Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
   651  
   652  											Expect(testUI.Err).To(Say("some-poll-warning-1"))
   653  											Expect(testUI.Err).To(Say("some-poll-warning-2"))
   654  
   655  											Expect(executeErr).ToNot(HaveOccurred())
   656  										})
   657  
   658  										Context("when displaying the application info fails", func() {
   659  											BeforeEach(func() {
   660  												var expectedErr error
   661  												expectedErr = actionerror.ApplicationNotFoundError{Name: app}
   662  												fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(v3action.ApplicationSummary{}, v3action.Warnings{"display-warning-1", "display-warning-2"}, expectedErr)
   663  											})
   664  
   665  											It("returns the error and prints warnings", func() {
   666  												Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app}))
   667  
   668  												Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
   669  
   670  												Expect(testUI.Err).To(Say("display-warning-1"))
   671  												Expect(testUI.Err).To(Say("display-warning-2"))
   672  
   673  												Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
   674  											})
   675  										})
   676  
   677  										Context("when getting the application summary is successful", func() {
   678  											BeforeEach(func() {
   679  												summary := v3action.ApplicationSummary{
   680  													Application: v3action.Application{
   681  														Name:  "some-app",
   682  														GUID:  "some-app-guid",
   683  														State: "started",
   684  													},
   685  													CurrentDroplet: v3action.Droplet{
   686  														Stack: "cflinuxfs2",
   687  														Buildpacks: []v3action.Buildpack{
   688  															{
   689  																Name:         "ruby_buildpack",
   690  																DetectOutput: "some-detect-output",
   691  															},
   692  														},
   693  													},
   694  													ProcessSummaries: []v3action.ProcessSummary{
   695  														{
   696  															Process: v3action.Process{
   697  																Type:       "worker",
   698  																MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
   699  															},
   700  															InstanceDetails: []v3action.ProcessInstance{
   701  																v3action.ProcessInstance{
   702  																	Index:       0,
   703  																	State:       constant.ProcessInstanceRunning,
   704  																	MemoryUsage: 4000000,
   705  																	DiskUsage:   4000000,
   706  																	MemoryQuota: 67108864,
   707  																	DiskQuota:   8000000,
   708  																	Uptime:      time.Now().Sub(time.Unix(1371859200, 0)),
   709  																},
   710  															},
   711  														},
   712  													},
   713  												}
   714  
   715  												fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(summary, v3action.Warnings{"display-warning-1", "display-warning-2"}, nil)
   716  											})
   717  
   718  											Context("when getting the application routes fails", func() {
   719  												BeforeEach(func() {
   720  													fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{},
   721  														v2action.Warnings{"route-warning-1", "route-warning-2"}, errors.New("some-error"))
   722  												})
   723  
   724  												It("displays all warnings and returns the error", func() {
   725  													Expect(executeErr).To(MatchError("some-error"))
   726  
   727  													Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
   728  
   729  													Expect(testUI.Err).To(Say("display-warning-1"))
   730  													Expect(testUI.Err).To(Say("display-warning-2"))
   731  													Expect(testUI.Err).To(Say("route-warning-1"))
   732  													Expect(testUI.Err).To(Say("route-warning-2"))
   733  
   734  													Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
   735  												})
   736  											})
   737  
   738  											Context("when getting the application routes is successful", func() {
   739  												BeforeEach(func() {
   740  													fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{
   741  														{Domain: v2action.Domain{Name: "some-other-domain"}}, {
   742  															Domain: v2action.Domain{Name: "some-domain"}}},
   743  														v2action.Warnings{"route-warning-1", "route-warning-2"}, nil)
   744  												})
   745  
   746  												It("prints the application summary and outputs warnings", func() {
   747  													Expect(executeErr).ToNot(HaveOccurred())
   748  
   749  													Expect(testUI.Out).To(Say(`(?m)Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.\n\n`))
   750  													Expect(testUI.Out).To(Say(`name:\s+some-app`))
   751  													Expect(testUI.Out).To(Say(`requested state:\s+started`))
   752  													Expect(testUI.Out).To(Say(`routes:\s+some-other-domain, some-domain`))
   753  													Expect(testUI.Out).To(Say(`stack:\s+cflinuxfs2`))
   754  													Expect(testUI.Out).To(Say(`(?m)buildpacks:\s+some-detect-output\n\n`))
   755  
   756  													Expect(testUI.Out).To(Say(`type:\s+worker`))
   757  													Expect(testUI.Out).To(Say(`instances:\s+1/1`))
   758  													Expect(testUI.Out).To(Say(`memory usage:\s+64M`))
   759  													Expect(testUI.Out).To(Say(`\s+state\s+since\s+cpu\s+memory\s+disk`))
   760  													Expect(testUI.Out).To(Say(`#0\s+running\s+2013-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [AP]M\s+0.0%\s+3.8M of 64M\s+3.8M of 7.6M`))
   761  
   762  													Expect(testUI.Err).To(Say("display-warning-1"))
   763  													Expect(testUI.Err).To(Say("display-warning-2"))
   764  													Expect(testUI.Err).To(Say("route-warning-1"))
   765  													Expect(testUI.Err).To(Say("route-warning-2"))
   766  
   767  													Expect(fakeV3PushActor.GetApplicationSummaryByNameAndSpaceCallCount()).To(Equal(1))
   768  													appName, spaceGUID, withObfuscatedValues := fakeV3PushActor.GetApplicationSummaryByNameAndSpaceArgsForCall(0)
   769  													Expect(appName).To(Equal("some-app"))
   770  													Expect(spaceGUID).To(Equal("some-space-guid"))
   771  
   772  													Expect(fakeV2AppActor.GetApplicationRoutesCallCount()).To(Equal(1))
   773  													Expect(fakeV2AppActor.GetApplicationRoutesArgsForCall(0)).To(Equal("some-app-guid"))
   774  													Expect(withObfuscatedValues).To(BeFalse())
   775  												})
   776  											})
   777  										})
   778  									})
   779  								})
   780  
   781  							})
   782  						})
   783  					})
   784  				})
   785  			})
   786  		})
   787  
   788  		Context("when looking up the application succeeds", func() {
   789  			BeforeEach(func() {
   790  				fakeZdtActor.GetApplicationByNameAndSpaceReturns(v3action.Application{
   791  					Name:  "some-app",
   792  					GUID:  "some-app-guid",
   793  					State: constant.ApplicationStarted,
   794  				}, v3action.Warnings{"get-warning"}, nil)
   795  			})
   796  
   797  			It("updates the application", func() {
   798  				Expect(fakeZdtActor.CreateApplicationInSpaceCallCount()).To(Equal(0))
   799  				Expect(fakeZdtActor.UpdateApplicationCallCount()).To(Equal(1))
   800  			})
   801  
   802  			Context("when updating the application fails", func() {
   803  				BeforeEach(func() {
   804  					fakeZdtActor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"update-warning-1"}, errors.New("some-error"))
   805  				})
   806  
   807  				It("returns the error and displays warnings", func() {
   808  					Expect(executeErr).To(MatchError("some-error"))
   809  
   810  					Expect(testUI.Err).To(Say("get-warning"))
   811  					Expect(testUI.Err).To(Say("update-warning"))
   812  				})
   813  			})
   814  
   815  			Context("when a docker image is provided", func() {
   816  				BeforeEach(func() {
   817  					cmd.DockerImage.Path = "example.com/docker/docker/docker:docker"
   818  					cmd.DockerUsername = "username"
   819  					fakeConfig.DockerPasswordReturns("password")
   820  				})
   821  
   822  				Context("when a username/password are provided", func() {
   823  					It("updates the app with the provided credentials", func() {
   824  						appName, spaceGuid, dockerImageCredentials := fakeZdtActor.CreateDockerPackageByApplicationNameAndSpaceArgsForCall(0)
   825  						Expect(appName).To(Equal("some-app"))
   826  						Expect(spaceGuid).To(Equal("some-space-guid"))
   827  						Expect(dockerImageCredentials.Path).To(Equal(cmd.DockerImage.Path))
   828  						Expect(dockerImageCredentials.Username).To(Equal("username"))
   829  						Expect(dockerImageCredentials.Password).To(Equal("password"))
   830  					})
   831  				})
   832  
   833  				It("updates the app with a docker lifecycle", func() {
   834  					Expect(fakeZdtActor.UpdateApplicationCallCount()).To(Equal(1), "Expected UpdateApplication to be called once")
   835  					updateApp := fakeZdtActor.UpdateApplicationArgsForCall(0)
   836  					Expect(updateApp).To(Equal(v3action.Application{
   837  						GUID:          "some-app-guid",
   838  						LifecycleType: constant.AppLifecycleTypeDocker,
   839  					}))
   840  				})
   841  			})
   842  
   843  			Context("when the app has a buildpack lifecycle", func() {
   844  				Context("when a buildpack was not provided", func() {
   845  					BeforeEach(func() {
   846  						cmd.Buildpacks = []string{}
   847  					})
   848  
   849  					It("does not update the buildpack", func() {
   850  						appArg := fakeZdtActor.UpdateApplicationArgsForCall(0)
   851  						Expect(appArg).To(Equal(v3action.Application{
   852  							GUID:                "some-app-guid",
   853  							LifecycleType:       constant.AppLifecycleTypeBuildpack,
   854  							LifecycleBuildpacks: []string{},
   855  						}))
   856  					})
   857  				})
   858  
   859  				Context("when a buildpack was provided", func() {
   860  					BeforeEach(func() {
   861  						cmd.Buildpacks = []string{"some-buildpack"}
   862  					})
   863  
   864  					It("updates the buildpack", func() {
   865  						appArg := fakeZdtActor.UpdateApplicationArgsForCall(0)
   866  						Expect(appArg).To(Equal(v3action.Application{
   867  							GUID:                "some-app-guid",
   868  							LifecycleType:       constant.AppLifecycleTypeBuildpack,
   869  							LifecycleBuildpacks: []string{"some-buildpack"},
   870  						}))
   871  					})
   872  				})
   873  
   874  				Context("when a stack was provided", func() {
   875  					BeforeEach(func() {
   876  						cmd.StackName = "cflinuxfs9000"
   877  					})
   878  
   879  					It("updates the stack", func() {
   880  						appArg := fakeZdtActor.UpdateApplicationArgsForCall(0)
   881  						Expect(appArg).To(Equal(v3action.Application{
   882  							GUID:          "some-app-guid",
   883  							LifecycleType: constant.AppLifecycleTypeBuildpack,
   884  							StackName:     "cflinuxfs9000",
   885  						}))
   886  					})
   887  				})
   888  
   889  				Context("when multiple buildpacks are provided", func() {
   890  					BeforeEach(func() {
   891  						cmd.Buildpacks = []string{"some-buildpack-1", "some-buildpack-2"}
   892  					})
   893  
   894  					It("updates the buildpacks", func() {
   895  						appArg := fakeZdtActor.UpdateApplicationArgsForCall(0)
   896  						Expect(appArg).To(Equal(v3action.Application{
   897  							GUID:                "some-app-guid",
   898  							LifecycleType:       constant.AppLifecycleTypeBuildpack,
   899  							LifecycleBuildpacks: []string{"some-buildpack-1", "some-buildpack-2"},
   900  						}))
   901  					})
   902  
   903  					Context("when default was also provided", func() {
   904  						BeforeEach(func() {
   905  							cmd.Buildpacks = []string{"default", "some-buildpack-2"}
   906  						})
   907  
   908  						It("returns the ConflictingBuildpacksError", func() {
   909  							Expect(executeErr).To(Equal(translatableerror.ConflictingBuildpacksError{}))
   910  							Expect(fakeZdtActor.UpdateApplicationCallCount()).To(Equal(0))
   911  						})
   912  					})
   913  
   914  					Context("when null was also provided", func() {
   915  						BeforeEach(func() {
   916  							cmd.Buildpacks = []string{"null", "some-buildpack-2"}
   917  						})
   918  
   919  						It("returns the ConflictingBuildpacksError", func() {
   920  							Expect(executeErr).To(Equal(translatableerror.ConflictingBuildpacksError{}))
   921  							Expect(fakeZdtActor.UpdateApplicationCallCount()).To(Equal(0))
   922  						})
   923  					})
   924  				})
   925  			})
   926  
   927  			Context("when updating the application succeeds", func() {
   928  				Context("when the application is stopped", func() {
   929  					BeforeEach(func() {
   930  						fakeZdtActor.UpdateApplicationReturns(v3action.Application{GUID: "some-app-guid", State: constant.ApplicationStopped}, v3action.Warnings{"update-warning"}, nil)
   931  					})
   932  
   933  					It("sets the droplet and restarts the app", func() {
   934  						Expect(executeErr).ToNot(HaveOccurred())
   935  
   936  						Expect(testUI.Err).To(Say("get-warning"))
   937  						Expect(testUI.Err).To(Say("update-warning"))
   938  
   939  						Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(1))
   940  						Expect(fakeZdtActor.SetApplicationDropletByApplicationNameAndSpaceCallCount()).To(Equal(1))
   941  						Expect(fakeZdtActor.PollStartCallCount()).To(Equal(1))
   942  					})
   943  
   944  					Context("when the wait-for-deploy-complete flag is not provided", func() {
   945  						Context("when polling the start fails", func() {
   946  							BeforeEach(func() {
   947  								fakeZdtActor.PollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
   948  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
   949  									return errors.New("some-error")
   950  								}
   951  							})
   952  
   953  							It("displays all warnings and fails", func() {
   954  								Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
   955  
   956  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
   957  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
   958  
   959  								Expect(executeErr).To(MatchError("some-error"))
   960  							})
   961  						})
   962  
   963  						Context("when polling times out", func() {
   964  							BeforeEach(func() {
   965  								fakeZdtActor.PollStartReturns(actionerror.StartupTimeoutError{})
   966  							})
   967  
   968  							It("returns the StartupTimeoutError", func() {
   969  								Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{
   970  									AppName:    "some-app",
   971  									BinaryName: binaryName,
   972  								}))
   973  							})
   974  						})
   975  
   976  						Context("when polling the start succeeds", func() {
   977  							BeforeEach(func() {
   978  								fakeZdtActor.PollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
   979  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
   980  									return nil
   981  								}
   982  							})
   983  
   984  							It("displays all warnings", func() {
   985  								Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
   986  
   987  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
   988  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
   989  
   990  								Expect(executeErr).ToNot(HaveOccurred())
   991  							})
   992  
   993  							Context("when displaying the application info fails", func() {
   994  								BeforeEach(func() {
   995  									var expectedErr error
   996  									expectedErr = actionerror.ApplicationNotFoundError{Name: app}
   997  									fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(v3action.ApplicationSummary{}, v3action.Warnings{"display-warning-1", "display-warning-2"}, expectedErr)
   998  								})
   999  
  1000  								It("returns the error and prints warnings", func() {
  1001  									Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app}))
  1002  
  1003  									Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
  1004  
  1005  									Expect(testUI.Err).To(Say("display-warning-1"))
  1006  									Expect(testUI.Err).To(Say("display-warning-2"))
  1007  
  1008  									Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
  1009  								})
  1010  							})
  1011  
  1012  							Context("when getting the application summary is successful", func() {
  1013  								BeforeEach(func() {
  1014  									summary := v3action.ApplicationSummary{
  1015  										Application: v3action.Application{
  1016  											Name:  "some-app",
  1017  											GUID:  "some-app-guid",
  1018  											State: "started",
  1019  										},
  1020  										CurrentDroplet: v3action.Droplet{
  1021  											Stack: "cflinuxfs2",
  1022  											Buildpacks: []v3action.Buildpack{
  1023  												{
  1024  													Name:         "ruby_buildpack",
  1025  													DetectOutput: "some-detect-output",
  1026  												},
  1027  											},
  1028  										},
  1029  										ProcessSummaries: []v3action.ProcessSummary{
  1030  											{
  1031  												Process: v3action.Process{
  1032  													Type:       "worker",
  1033  													MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
  1034  												},
  1035  												InstanceDetails: []v3action.ProcessInstance{
  1036  													v3action.ProcessInstance{
  1037  														Index:       0,
  1038  														State:       constant.ProcessInstanceRunning,
  1039  														MemoryUsage: 4000000,
  1040  														DiskUsage:   4000000,
  1041  														MemoryQuota: 67108864,
  1042  														DiskQuota:   8000000,
  1043  														Uptime:      time.Now().Sub(time.Unix(1371859200, 0)),
  1044  													},
  1045  												},
  1046  											},
  1047  										},
  1048  									}
  1049  
  1050  									fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(summary, v3action.Warnings{"display-warning-1", "display-warning-2"}, nil)
  1051  								})
  1052  
  1053  								Context("when getting the application routes fails", func() {
  1054  									BeforeEach(func() {
  1055  										fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{},
  1056  											v2action.Warnings{"route-warning-1", "route-warning-2"}, errors.New("some-error"))
  1057  									})
  1058  
  1059  									It("displays all warnings and returns the error", func() {
  1060  										Expect(executeErr).To(MatchError("some-error"))
  1061  
  1062  										Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
  1063  
  1064  										Expect(testUI.Err).To(Say("display-warning-1"))
  1065  										Expect(testUI.Err).To(Say("display-warning-2"))
  1066  										Expect(testUI.Err).To(Say("route-warning-1"))
  1067  										Expect(testUI.Err).To(Say("route-warning-2"))
  1068  
  1069  										Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
  1070  									})
  1071  								})
  1072  
  1073  								Context("when getting the application routes is successful", func() {
  1074  									BeforeEach(func() {
  1075  										fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{
  1076  											{Domain: v2action.Domain{Name: "some-other-domain"}}, {
  1077  												Domain: v2action.Domain{Name: "some-domain"}}},
  1078  											v2action.Warnings{"route-warning-1", "route-warning-2"}, nil)
  1079  									})
  1080  
  1081  									It("prints the application summary and outputs warnings", func() {
  1082  										Expect(executeErr).ToNot(HaveOccurred())
  1083  
  1084  										Expect(testUI.Out).To(Say(`(?m)Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.\n\n`))
  1085  										Expect(testUI.Out).To(Say(`name:\s+some-app`))
  1086  										Expect(testUI.Out).To(Say(`requested state:\s+started`))
  1087  										Expect(testUI.Out).To(Say(`routes:\s+some-other-domain, some-domain`))
  1088  										Expect(testUI.Out).To(Say(`stack:\s+cflinuxfs2`))
  1089  										Expect(testUI.Out).To(Say(`(?m)buildpacks:\s+some-detect-output\n\n`))
  1090  
  1091  										Expect(testUI.Out).To(Say(`type:\s+worker`))
  1092  										Expect(testUI.Out).To(Say(`instances:\s+1/1`))
  1093  										Expect(testUI.Out).To(Say(`memory usage:\s+64M`))
  1094  										Expect(testUI.Out).To(Say(`\s+state\s+since\s+cpu\s+memory\s+disk`))
  1095  										Expect(testUI.Out).To(Say(`#0\s+running\s+2013-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [AP]M\s+0.0%\s+3.8M of 64M\s+3.8M of 7.6M`))
  1096  
  1097  										Expect(testUI.Err).To(Say("display-warning-1"))
  1098  										Expect(testUI.Err).To(Say("display-warning-2"))
  1099  										Expect(testUI.Err).To(Say("route-warning-1"))
  1100  										Expect(testUI.Err).To(Say("route-warning-2"))
  1101  
  1102  										Expect(fakeV3PushActor.GetApplicationSummaryByNameAndSpaceCallCount()).To(Equal(1))
  1103  										appName, spaceGUID, withObfuscatedValues := fakeV3PushActor.GetApplicationSummaryByNameAndSpaceArgsForCall(0)
  1104  										Expect(appName).To(Equal("some-app"))
  1105  										Expect(spaceGUID).To(Equal("some-space-guid"))
  1106  
  1107  										Expect(fakeV2AppActor.GetApplicationRoutesCallCount()).To(Equal(1))
  1108  										Expect(fakeV2AppActor.GetApplicationRoutesArgsForCall(0)).To(Equal("some-app-guid"))
  1109  										Expect(withObfuscatedValues).To(BeFalse())
  1110  									})
  1111  								})
  1112  							})
  1113  						})
  1114  					})
  1115  				})
  1116  
  1117  				Context("when the application is started", func() {
  1118  					BeforeEach(func() {
  1119  						fakeZdtActor.UpdateApplicationReturns(v3action.Application{GUID: "some-app-guid", State: constant.ApplicationStarted}, nil, nil)
  1120  					})
  1121  
  1122  					It("creates a deployment", func() {
  1123  						Expect(executeErr).ToNot(HaveOccurred())
  1124  						Expect(testUI.Out).To(Say("Starting deployment for app some-app in org some-org / space some-space as banana..."))
  1125  
  1126  						Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(0))
  1127  						Expect(fakeZdtActor.CreateDeploymentCallCount()).To(Equal(1))
  1128  					})
  1129  
  1130  					Context("when the wait-for-deploy-complete flag is not provided", func() {
  1131  						Context("when polling the start fails", func() {
  1132  							BeforeEach(func() {
  1133  								fakeZdtActor.ZeroDowntimePollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
  1134  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
  1135  									return errors.New("some-error")
  1136  								}
  1137  							})
  1138  
  1139  							It("displays all warnings and fails", func() {
  1140  								Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
  1141  
  1142  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
  1143  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
  1144  
  1145  								Expect(executeErr).To(MatchError("some-error"))
  1146  							})
  1147  						})
  1148  
  1149  						Context("when polling times out", func() {
  1150  							BeforeEach(func() {
  1151  								fakeZdtActor.ZeroDowntimePollStartReturns(actionerror.StartupTimeoutError{})
  1152  							})
  1153  
  1154  							It("returns the StartupTimeoutError", func() {
  1155  								Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{
  1156  									AppName:    "some-app",
  1157  									BinaryName: binaryName,
  1158  								}))
  1159  							})
  1160  						})
  1161  
  1162  						Context("when polling the start succeeds", func() {
  1163  							BeforeEach(func() {
  1164  								fakeZdtActor.ZeroDowntimePollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
  1165  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
  1166  									return nil
  1167  								}
  1168  							})
  1169  
  1170  							It("displays all warnings", func() {
  1171  								Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
  1172  
  1173  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
  1174  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
  1175  
  1176  								Expect(executeErr).ToNot(HaveOccurred())
  1177  							})
  1178  
  1179  							Context("when displaying the application info fails", func() {
  1180  								BeforeEach(func() {
  1181  									var expectedErr error
  1182  									expectedErr = actionerror.ApplicationNotFoundError{Name: app}
  1183  									fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(v3action.ApplicationSummary{}, v3action.Warnings{"display-warning-1", "display-warning-2"}, expectedErr)
  1184  								})
  1185  
  1186  								It("returns the error and prints warnings", func() {
  1187  									Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app}))
  1188  
  1189  									Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
  1190  
  1191  									Expect(testUI.Err).To(Say("display-warning-1"))
  1192  									Expect(testUI.Err).To(Say("display-warning-2"))
  1193  
  1194  									Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
  1195  								})
  1196  							})
  1197  
  1198  							Context("when getting the application summary is successful", func() {
  1199  								BeforeEach(func() {
  1200  									summary := v3action.ApplicationSummary{
  1201  										Application: v3action.Application{
  1202  											Name:  "some-app",
  1203  											GUID:  "some-app-guid",
  1204  											State: "started",
  1205  										},
  1206  										CurrentDroplet: v3action.Droplet{
  1207  											Stack: "cflinuxfs2",
  1208  											Buildpacks: []v3action.Buildpack{
  1209  												{
  1210  													Name:         "ruby_buildpack",
  1211  													DetectOutput: "some-detect-output",
  1212  												},
  1213  											},
  1214  										},
  1215  										ProcessSummaries: []v3action.ProcessSummary{
  1216  											{
  1217  												Process: v3action.Process{
  1218  													Type:       "worker",
  1219  													MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
  1220  												},
  1221  												InstanceDetails: []v3action.ProcessInstance{
  1222  													v3action.ProcessInstance{
  1223  														Index:       0,
  1224  														State:       constant.ProcessInstanceRunning,
  1225  														MemoryUsage: 4000000,
  1226  														DiskUsage:   4000000,
  1227  														MemoryQuota: 67108864,
  1228  														DiskQuota:   8000000,
  1229  														Uptime:      time.Now().Sub(time.Unix(1371859200, 0)),
  1230  													},
  1231  												},
  1232  											},
  1233  										},
  1234  									}
  1235  
  1236  									fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(summary, v3action.Warnings{"display-warning-1", "display-warning-2"}, nil)
  1237  								})
  1238  
  1239  								Context("when getting the application routes fails", func() {
  1240  									BeforeEach(func() {
  1241  										fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{},
  1242  											v2action.Warnings{"route-warning-1", "route-warning-2"}, errors.New("some-error"))
  1243  									})
  1244  
  1245  									It("displays all warnings and returns the error", func() {
  1246  										Expect(executeErr).To(MatchError("some-error"))
  1247  
  1248  										Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
  1249  
  1250  										Expect(testUI.Err).To(Say("display-warning-1"))
  1251  										Expect(testUI.Err).To(Say("display-warning-2"))
  1252  										Expect(testUI.Err).To(Say("route-warning-1"))
  1253  										Expect(testUI.Err).To(Say("route-warning-2"))
  1254  
  1255  										Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
  1256  									})
  1257  								})
  1258  
  1259  								Context("when getting the application routes is successful", func() {
  1260  									BeforeEach(func() {
  1261  										fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{
  1262  											{Domain: v2action.Domain{Name: "some-other-domain"}}, {
  1263  												Domain: v2action.Domain{Name: "some-domain"}}},
  1264  											v2action.Warnings{"route-warning-1", "route-warning-2"}, nil)
  1265  									})
  1266  
  1267  									It("prints the application summary and outputs warnings", func() {
  1268  										Expect(executeErr).ToNot(HaveOccurred())
  1269  
  1270  										Expect(testUI.Out).To(Say(`(?m)Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.\n\n`))
  1271  										Expect(testUI.Out).To(Say(`name:\s+some-app`))
  1272  										Expect(testUI.Out).To(Say(`requested state:\s+started`))
  1273  										Expect(testUI.Out).To(Say(`routes:\s+some-other-domain, some-domain`))
  1274  										Expect(testUI.Out).To(Say(`stack:\s+cflinuxfs2`))
  1275  										Expect(testUI.Out).To(Say(`(?m)buildpacks:\s+some-detect-output\n\n`))
  1276  
  1277  										Expect(testUI.Out).To(Say(`type:\s+worker`))
  1278  										Expect(testUI.Out).To(Say(`instances:\s+1/1`))
  1279  										Expect(testUI.Out).To(Say(`memory usage:\s+64M`))
  1280  										Expect(testUI.Out).To(Say(`\s+state\s+since\s+cpu\s+memory\s+disk`))
  1281  										Expect(testUI.Out).To(Say(`#0\s+running\s+2013-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [AP]M\s+0.0%\s+3.8M of 64M\s+3.8M of 7.6M`))
  1282  
  1283  										Expect(testUI.Err).To(Say("display-warning-1"))
  1284  										Expect(testUI.Err).To(Say("display-warning-2"))
  1285  										Expect(testUI.Err).To(Say("route-warning-1"))
  1286  										Expect(testUI.Err).To(Say("route-warning-2"))
  1287  
  1288  										Expect(fakeV3PushActor.GetApplicationSummaryByNameAndSpaceCallCount()).To(Equal(1))
  1289  										appName, spaceGUID, withObfuscatedValues := fakeV3PushActor.GetApplicationSummaryByNameAndSpaceArgsForCall(0)
  1290  										Expect(appName).To(Equal("some-app"))
  1291  										Expect(spaceGUID).To(Equal("some-space-guid"))
  1292  
  1293  										Expect(fakeV2AppActor.GetApplicationRoutesCallCount()).To(Equal(1))
  1294  										Expect(fakeV2AppActor.GetApplicationRoutesArgsForCall(0)).To(Equal("some-app-guid"))
  1295  										Expect(withObfuscatedValues).To(BeFalse())
  1296  									})
  1297  								})
  1298  							})
  1299  						})
  1300  					})
  1301  
  1302  					Context("when the wait-for-deploy-complete is provided", func() {
  1303  						BeforeEach(func() {
  1304  							cmd.WaitUntilDeployed = true
  1305  						})
  1306  
  1307  						Context("When polling the deployment fails", func() {
  1308  							BeforeEach(func() {
  1309  								fakeZdtActor.PollDeploymentStub = func(deploymentGUID string, warnings chan<- v3action.Warnings) error {
  1310  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
  1311  									return errors.New("some-polling-error")
  1312  								}
  1313  							})
  1314  
  1315  							It("Displays all warnings and fails", func() {
  1316  								Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
  1317  
  1318  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
  1319  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
  1320  
  1321  								Expect(executeErr).To(MatchError("some-polling-error"))
  1322  							})
  1323  						})
  1324  
  1325  						Context("When polling the deployment timesout", func() {
  1326  							BeforeEach(func() {
  1327  								fakeZdtActor.PollDeploymentReturns(actionerror.StartupTimeoutError{})
  1328  							})
  1329  
  1330  							It("Returns the StartupTimeoutError", func() {
  1331  								Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{
  1332  									AppName:    "some-app",
  1333  									BinaryName: binaryName,
  1334  								}))
  1335  							})
  1336  						})
  1337  
  1338  						Context("When polling the deployment succeeds", func() {
  1339  							BeforeEach(func() {
  1340  								fakeZdtActor.PollDeploymentStub = func(deploymentGUID string, warnings chan<- v3action.Warnings) error {
  1341  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
  1342  									return nil
  1343  								}
  1344  							})
  1345  
  1346  							It("displays all warnings", func() {
  1347  								Expect(testUI.Out).To(Say(`Waiting for app to start\.\.\.`))
  1348  
  1349  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
  1350  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
  1351  
  1352  								Expect(executeErr).ToNot(HaveOccurred())
  1353  							})
  1354  
  1355  							Context("when displaying the application info fails", func() {
  1356  								BeforeEach(func() {
  1357  									var expectedErr error
  1358  									expectedErr = actionerror.ApplicationNotFoundError{Name: app}
  1359  									fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(v3action.ApplicationSummary{}, v3action.Warnings{"display-warning-1", "display-warning-2"}, expectedErr)
  1360  								})
  1361  
  1362  								It("returns the error and prints warnings", func() {
  1363  									Expect(executeErr).To(Equal(actionerror.ApplicationNotFoundError{Name: app}))
  1364  
  1365  									Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
  1366  
  1367  									Expect(testUI.Err).To(Say("display-warning-1"))
  1368  									Expect(testUI.Err).To(Say("display-warning-2"))
  1369  
  1370  									Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
  1371  								})
  1372  							})
  1373  
  1374  							Context("when getting the application summary is successful", func() {
  1375  								BeforeEach(func() {
  1376  									summary := v3action.ApplicationSummary{
  1377  										Application: v3action.Application{
  1378  											Name:  "some-app",
  1379  											GUID:  "some-app-guid",
  1380  											State: "started",
  1381  										},
  1382  										CurrentDroplet: v3action.Droplet{
  1383  											Stack: "cflinuxfs2",
  1384  											Buildpacks: []v3action.Buildpack{
  1385  												{
  1386  													Name:         "ruby_buildpack",
  1387  													DetectOutput: "some-detect-output",
  1388  												},
  1389  											},
  1390  										},
  1391  										ProcessSummaries: []v3action.ProcessSummary{
  1392  											{
  1393  												Process: v3action.Process{
  1394  													Type:       "worker",
  1395  													MemoryInMB: types.NullUint64{Value: 64, IsSet: true},
  1396  												},
  1397  												InstanceDetails: []v3action.ProcessInstance{
  1398  													v3action.ProcessInstance{
  1399  														Index:       0,
  1400  														State:       constant.ProcessInstanceRunning,
  1401  														MemoryUsage: 4000000,
  1402  														DiskUsage:   4000000,
  1403  														MemoryQuota: 67108864,
  1404  														DiskQuota:   8000000,
  1405  														Uptime:      time.Now().Sub(time.Unix(1371859200, 0)),
  1406  													},
  1407  												},
  1408  											},
  1409  										},
  1410  									}
  1411  
  1412  									fakeV3PushActor.GetApplicationSummaryByNameAndSpaceReturns(summary, v3action.Warnings{"display-warning-1", "display-warning-2"}, nil)
  1413  								})
  1414  
  1415  								Context("when getting the application routes fails", func() {
  1416  									BeforeEach(func() {
  1417  										fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{},
  1418  											v2action.Warnings{"route-warning-1", "route-warning-2"}, errors.New("some-error"))
  1419  									})
  1420  
  1421  									It("displays all warnings and returns the error", func() {
  1422  										Expect(executeErr).To(MatchError("some-error"))
  1423  
  1424  										Expect(testUI.Out).To(Say(`Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.`))
  1425  
  1426  										Expect(testUI.Err).To(Say("display-warning-1"))
  1427  										Expect(testUI.Err).To(Say("display-warning-2"))
  1428  										Expect(testUI.Err).To(Say("route-warning-1"))
  1429  										Expect(testUI.Err).To(Say("route-warning-2"))
  1430  
  1431  										Expect(testUI.Out).ToNot(Say(`name:\s+some-app`))
  1432  									})
  1433  								})
  1434  
  1435  								Context("when getting the application routes is successful", func() {
  1436  									BeforeEach(func() {
  1437  										fakeV2AppActor.GetApplicationRoutesReturns([]v2action.Route{
  1438  											{Domain: v2action.Domain{Name: "some-other-domain"}}, {
  1439  												Domain: v2action.Domain{Name: "some-domain"}}},
  1440  											v2action.Warnings{"route-warning-1", "route-warning-2"}, nil)
  1441  									})
  1442  
  1443  									It("prints the application summary and outputs warnings", func() {
  1444  										Expect(executeErr).ToNot(HaveOccurred())
  1445  
  1446  										Expect(testUI.Out).To(Say(`(?m)Showing health and status for app some-app in org some-org / space some-space as banana\.\.\.\n\n`))
  1447  										Expect(testUI.Out).To(Say(`name:\s+some-app`))
  1448  										Expect(testUI.Out).To(Say(`requested state:\s+started`))
  1449  										Expect(testUI.Out).To(Say(`routes:\s+some-other-domain, some-domain`))
  1450  										Expect(testUI.Out).To(Say(`stack:\s+cflinuxfs2`))
  1451  										Expect(testUI.Out).To(Say(`(?m)buildpacks:\s+some-detect-output\n\n`))
  1452  
  1453  										Expect(testUI.Out).To(Say(`type:\s+worker`))
  1454  										Expect(testUI.Out).To(Say(`instances:\s+1/1`))
  1455  										Expect(testUI.Out).To(Say(`memory usage:\s+64M`))
  1456  										Expect(testUI.Out).To(Say(`\s+state\s+since\s+cpu\s+memory\s+disk`))
  1457  										Expect(testUI.Out).To(Say(`#0\s+running\s+2013-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [AP]M\s+0.0%\s+3.8M of 64M\s+3.8M of 7.6M`))
  1458  
  1459  										Expect(testUI.Err).To(Say("display-warning-1"))
  1460  										Expect(testUI.Err).To(Say("display-warning-2"))
  1461  										Expect(testUI.Err).To(Say("route-warning-1"))
  1462  										Expect(testUI.Err).To(Say("route-warning-2"))
  1463  
  1464  										Expect(fakeV3PushActor.GetApplicationSummaryByNameAndSpaceCallCount()).To(Equal(1))
  1465  										appName, spaceGUID, withObfuscatedValues := fakeV3PushActor.GetApplicationSummaryByNameAndSpaceArgsForCall(0)
  1466  										Expect(appName).To(Equal("some-app"))
  1467  										Expect(spaceGUID).To(Equal("some-space-guid"))
  1468  
  1469  										Expect(fakeV2AppActor.GetApplicationRoutesCallCount()).To(Equal(1))
  1470  										Expect(fakeV2AppActor.GetApplicationRoutesArgsForCall(0)).To(Equal("some-app-guid"))
  1471  										Expect(withObfuscatedValues).To(BeFalse())
  1472  									})
  1473  								})
  1474  							})
  1475  						})
  1476  					})
  1477  
  1478  					Context("when no-start is provided", func() {
  1479  						BeforeEach(func() {
  1480  							cmd.NoStart = true
  1481  						})
  1482  
  1483  						It("does nothing", func() {
  1484  							Expect(executeErr).ToNot(HaveOccurred())
  1485  
  1486  							Expect(fakeZdtActor.RestartApplicationCallCount()).To(Equal(0))
  1487  							Expect(fakeZdtActor.CreateDeploymentCallCount()).To(Equal(0))
  1488  						})
  1489  					})
  1490  				})
  1491  			})
  1492  		})
  1493  	})
  1494  })