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

     1  package v7_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"time"
     7  
     8  	"code.cloudfoundry.org/cli/actor/actionerror"
     9  	"code.cloudfoundry.org/cli/actor/sharedaction"
    10  	"code.cloudfoundry.org/cli/actor/sharedaction/sharedactionfakes"
    11  	"code.cloudfoundry.org/cli/actor/v7action"
    12  	"code.cloudfoundry.org/cli/actor/v7pushaction"
    13  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    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/v6fakes"
    18  	. "code.cloudfoundry.org/cli/command/v7"
    19  	"code.cloudfoundry.org/cli/command/v7/v7fakes"
    20  	"code.cloudfoundry.org/cli/types"
    21  	"code.cloudfoundry.org/cli/util/configv3"
    22  	"code.cloudfoundry.org/cli/util/manifestparser"
    23  	"code.cloudfoundry.org/cli/util/ui"
    24  	"github.com/cloudfoundry/bosh-cli/director/template"
    25  	. "github.com/onsi/ginkgo"
    26  	. "github.com/onsi/ginkgo/extensions/table"
    27  	. "github.com/onsi/gomega"
    28  	. "github.com/onsi/gomega/gbytes"
    29  )
    30  
    31  type Step struct {
    32  	Plan     v7pushaction.PushPlan
    33  	Error    error
    34  	Event    v7pushaction.Event
    35  	Warnings v7pushaction.Warnings
    36  }
    37  
    38  func FillInEvents(steps []Step) <-chan *v7pushaction.PushEvent {
    39  	eventStream := make(chan *v7pushaction.PushEvent)
    40  
    41  	go func() {
    42  		defer close(eventStream)
    43  
    44  		for _, step := range steps {
    45  			eventStream <- &v7pushaction.PushEvent{Plan: step.Plan, Warnings: step.Warnings, Err: step.Error, Event: step.Event}
    46  		}
    47  	}()
    48  
    49  	return eventStream
    50  }
    51  
    52  type LogEvent struct {
    53  	Log   *sharedaction.LogMessage
    54  	Error error
    55  }
    56  
    57  func ReturnLogs(logevents []LogEvent, passedWarnings v7action.Warnings, passedError error) func(appName string, spaceGUID string, client sharedaction.LogCacheClient) (<-chan sharedaction.LogMessage, <-chan error, context.CancelFunc, v7action.Warnings, error) {
    58  	return func(appName string, spaceGUID string, client sharedaction.LogCacheClient) (<-chan sharedaction.LogMessage, <-chan error, context.CancelFunc, v7action.Warnings, error) {
    59  		logStream := make(chan sharedaction.LogMessage)
    60  		errStream := make(chan error)
    61  		go func() {
    62  			defer close(logStream)
    63  			defer close(errStream)
    64  
    65  			for _, log := range logevents {
    66  				if log.Log != nil {
    67  					logStream <- *log.Log
    68  				}
    69  				if log.Error != nil {
    70  					errStream <- log.Error
    71  				}
    72  			}
    73  		}()
    74  
    75  		return logStream, errStream, func() {}, passedWarnings, passedError
    76  	}
    77  }
    78  
    79  var _ = Describe("push Command", func() {
    80  	var (
    81  		cmd                 PushCommand
    82  		input               *Buffer
    83  		testUI              *ui.UI
    84  		fakeConfig          *commandfakes.FakeConfig
    85  		fakeSharedActor     *commandfakes.FakeSharedActor
    86  		fakeActor           *v7fakes.FakePushActor
    87  		fakeVersionActor    *v7fakes.FakeV7ActorForPush
    88  		fakeProgressBar     *v6fakes.FakeProgressBar
    89  		fakeLogCacheClient  *sharedactionfakes.FakeLogCacheClient
    90  		fakeManifestLocator *v7fakes.FakeManifestLocator
    91  		fakeManifestParser  *v7fakes.FakeManifestParser
    92  		binaryName          string
    93  		executeErr          error
    94  
    95  		appName1  string
    96  		appName2  string
    97  		userName  string
    98  		spaceName string
    99  		orgName   string
   100  		pwd       string
   101  	)
   102  
   103  	BeforeEach(func() {
   104  		input = NewBuffer()
   105  		testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer())
   106  		fakeConfig = new(commandfakes.FakeConfig)
   107  		fakeSharedActor = new(commandfakes.FakeSharedActor)
   108  		fakeActor = new(v7fakes.FakePushActor)
   109  		fakeVersionActor = new(v7fakes.FakeV7ActorForPush)
   110  		fakeProgressBar = new(v6fakes.FakeProgressBar)
   111  		fakeLogCacheClient = new(sharedactionfakes.FakeLogCacheClient)
   112  
   113  		appName1 = "first-app"
   114  		appName2 = "second-app"
   115  		userName = "some-user"
   116  		spaceName = "some-space"
   117  		orgName = "some-org"
   118  		pwd = "/push/cmd/test"
   119  		fakeManifestLocator = new(v7fakes.FakeManifestLocator)
   120  		fakeManifestParser = new(v7fakes.FakeManifestParser)
   121  
   122  		binaryName = "faceman"
   123  		fakeConfig.BinaryNameReturns(binaryName)
   124  
   125  		cmd = PushCommand{
   126  			UI:              testUI,
   127  			Config:          fakeConfig,
   128  			Actor:           fakeActor,
   129  			VersionActor:    fakeVersionActor,
   130  			SharedActor:     fakeSharedActor,
   131  			ProgressBar:     fakeProgressBar,
   132  			LogCacheClient:  fakeLogCacheClient,
   133  			CWD:             pwd,
   134  			ManifestLocator: fakeManifestLocator,
   135  			ManifestParser:  fakeManifestParser,
   136  		}
   137  	})
   138  
   139  	Describe("Execute", func() {
   140  		JustBeforeEach(func() {
   141  			executeErr = cmd.Execute(nil)
   142  		})
   143  
   144  		BeforeEach(func() {
   145  			fakeActor.ActualizeStub = func(v7pushaction.PushPlan, v7pushaction.ProgressBar) <-chan *v7pushaction.PushEvent {
   146  				return FillInEvents([]Step{})
   147  			}
   148  		})
   149  
   150  		When("checking target fails", func() {
   151  			BeforeEach(func() {
   152  				fakeSharedActor.CheckTargetReturns(actionerror.NoOrganizationTargetedError{BinaryName: binaryName})
   153  			})
   154  
   155  			It("returns an error", func() {
   156  				Expect(executeErr).To(MatchError(actionerror.NoOrganizationTargetedError{BinaryName: binaryName}))
   157  
   158  				Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   159  				checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   160  				Expect(checkTargetedOrg).To(BeTrue())
   161  				Expect(checkTargetedSpace).To(BeTrue())
   162  			})
   163  		})
   164  
   165  		When("checking target fails because the user is not logged in", func() {
   166  			BeforeEach(func() {
   167  				fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
   168  			})
   169  
   170  			It("returns an error", func() {
   171  				Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName}))
   172  
   173  				Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   174  				checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   175  				Expect(checkTargetedOrg).To(BeTrue())
   176  				Expect(checkTargetedSpace).To(BeTrue())
   177  			})
   178  		})
   179  
   180  		When("the user is logged in, and org and space are targeted", func() {
   181  			BeforeEach(func() {
   182  				fakeConfig.CurrentUserReturns(configv3.User{Name: userName}, nil)
   183  
   184  				fakeConfig.TargetedOrganizationReturns(configv3.Organization{
   185  					Name: orgName,
   186  					GUID: "some-org-guid",
   187  				})
   188  				fakeConfig.TargetedSpaceReturns(configv3.Space{
   189  					Name: spaceName,
   190  					GUID: "some-space-guid",
   191  				})
   192  			})
   193  
   194  			When("invalid flags are passed", func() {
   195  				BeforeEach(func() {
   196  					cmd.DockerUsername = "some-docker-username"
   197  				})
   198  
   199  				It("returns a validation error", func() {
   200  					Expect(executeErr).To(MatchError(translatableerror.RequiredFlagsError{Arg1: "--docker-image, -o", Arg2: "--docker-username"}))
   201  				})
   202  			})
   203  
   204  			When("the flags are all valid", func() {
   205  				It("delegating to the GetBaseManifest", func() {
   206  					// This tells us GetBaseManifest is being called because we dont have a fake
   207  					Expect(fakeManifestLocator.PathCallCount()).To(Equal(1))
   208  				})
   209  
   210  				When("getting the base manifest fails", func() {
   211  					BeforeEach(func() {
   212  						fakeManifestLocator.PathReturns("", false, errors.New("locate-error"))
   213  					})
   214  
   215  					It("returns the error", func() {
   216  						Expect(executeErr).To(MatchError(errors.New("locate-error")))
   217  					})
   218  				})
   219  
   220  				When("getting the base manifest succeeds", func() {
   221  					BeforeEach(func() {
   222  						// essentially fakes GetBaseManifest
   223  						fakeManifestLocator.PathReturns("", true, nil)
   224  						fakeManifestParser.InterpolateAndParseReturns(
   225  							manifestparser.Manifest{
   226  								Applications: []manifestparser.Application{
   227  									{
   228  										Name: "some-app-name",
   229  									},
   230  								},
   231  							},
   232  							nil,
   233  						)
   234  					})
   235  
   236  					It("delegates to the flag override handler", func() {
   237  						Expect(fakeActor.HandleFlagOverridesCallCount()).To(Equal(1))
   238  						actualManifest, actualFlagOverrides := fakeActor.HandleFlagOverridesArgsForCall(0)
   239  						Expect(actualManifest).To(Equal(
   240  							manifestparser.Manifest{
   241  								Applications: []manifestparser.Application{
   242  									{Name: "some-app-name"},
   243  								},
   244  							},
   245  						))
   246  						Expect(actualFlagOverrides).To(Equal(v7pushaction.FlagOverrides{}))
   247  					})
   248  
   249  					When("handling the flag overrides fails", func() {
   250  						BeforeEach(func() {
   251  							fakeActor.HandleFlagOverridesReturns(manifestparser.Manifest{}, errors.New("override-handler-error"))
   252  						})
   253  
   254  						It("returns the error", func() {
   255  							Expect(executeErr).To(MatchError("override-handler-error"))
   256  						})
   257  					})
   258  
   259  					When("handling the flag overrides succeeds", func() {
   260  						BeforeEach(func() {
   261  							fakeActor.HandleFlagOverridesReturns(
   262  								manifestparser.Manifest{
   263  									Applications: []manifestparser.Application{
   264  										{Name: "some-app-name"},
   265  									},
   266  								},
   267  								nil,
   268  							)
   269  						})
   270  
   271  						When("the docker password is needed", func() {
   272  							// TODO remove this in favor of a fake manifest
   273  							BeforeEach(func() {
   274  								fakeActor.HandleFlagOverridesReturns(
   275  									manifestparser.Manifest{
   276  										Applications: []manifestparser.Application{
   277  											{
   278  												Name:   "some-app-name",
   279  												Docker: &manifestparser.Docker{Username: "username", Image: "image"},
   280  											},
   281  										},
   282  									},
   283  									nil,
   284  								)
   285  							})
   286  
   287  							It("delegates to the GetDockerPassword", func() {
   288  								Expect(fakeConfig.DockerPasswordCallCount()).To(Equal(1))
   289  							})
   290  						})
   291  
   292  						It("delegates to the manifest parser", func() {
   293  							Expect(fakeManifestParser.MarshalManifestCallCount()).To(Equal(1))
   294  							Expect(fakeManifestParser.MarshalManifestArgsForCall(0)).To(Equal(
   295  								manifestparser.Manifest{
   296  									Applications: []manifestparser.Application{
   297  										{Name: "some-app-name"},
   298  									},
   299  								},
   300  							))
   301  						})
   302  
   303  						When("marshalling the manifest fails", func() {
   304  							BeforeEach(func() {
   305  								fakeManifestParser.MarshalManifestReturns([]byte{}, errors.New("marshal error"))
   306  							})
   307  
   308  							It("returns the error", func() {
   309  								Expect(executeErr).To(MatchError("marshal error"))
   310  							})
   311  						})
   312  
   313  						When("marsahlling the manifest succeeds", func() {
   314  							BeforeEach(func() {
   315  								fakeManifestParser.MarshalManifestReturns([]byte("our-manifest"), nil)
   316  							})
   317  
   318  							It("delegates to the version actor", func() {
   319  								Expect(fakeVersionActor.SetSpaceManifestCallCount()).To(Equal(1))
   320  								actualSpaceGUID, actualManifestBytes := fakeVersionActor.SetSpaceManifestArgsForCall(0)
   321  								Expect(actualSpaceGUID).To(Equal("some-space-guid"))
   322  								Expect(actualManifestBytes).To(Equal([]byte("our-manifest")))
   323  							})
   324  
   325  							When("applying the manifest fails", func() {
   326  								BeforeEach(func() {
   327  									fakeVersionActor.SetSpaceManifestReturns(v7action.Warnings{"apply-manifest-warnings"}, errors.New("apply-manifest-error"))
   328  								})
   329  
   330  								It("returns an error and prints warnings", func() {
   331  									Expect(executeErr).To(MatchError("apply-manifest-error"))
   332  									Expect(testUI.Err).To(Say("apply-manifest-warnings"))
   333  								})
   334  
   335  							})
   336  
   337  							When("applying the manifest succeeds", func() {
   338  								BeforeEach(func() {
   339  									fakeVersionActor.SetSpaceManifestReturns(v7action.Warnings{"apply-manifest-warnings"}, nil)
   340  								})
   341  
   342  								It("delegates to the push actor", func() {
   343  									Expect(fakeActor.CreatePushPlansCallCount()).To(Equal(1))
   344  									spaceGUID, orgGUID, manifest, overrides := fakeActor.CreatePushPlansArgsForCall(0)
   345  									Expect(spaceGUID).To(Equal("some-space-guid"))
   346  									Expect(orgGUID).To(Equal("some-org-guid"))
   347  									Expect(manifest).To(Equal(
   348  										manifestparser.Manifest{
   349  											Applications: []manifestparser.Application{
   350  												{Name: "some-app-name"},
   351  											},
   352  										},
   353  									))
   354  									Expect(overrides).To(Equal(v7pushaction.FlagOverrides{}))
   355  								})
   356  
   357  								When("creating the push plans fails", func() {
   358  									BeforeEach(func() {
   359  										fakeActor.CreatePushPlansReturns(
   360  											nil,
   361  											v7action.Warnings{"create-push-plans-warnings"},
   362  											errors.New("create-push-plans-error"),
   363  										)
   364  									})
   365  
   366  									It("returns errors and warnings", func() {
   367  										Expect(executeErr).To(MatchError("create-push-plans-error"))
   368  										Expect(testUI.Err).To(Say("create-push-plans-warnings"))
   369  									})
   370  
   371  								})
   372  
   373  								When("creating the push plans succeeds", func() {
   374  									BeforeEach(func() {
   375  										fakeActor.CreatePushPlansReturns(
   376  											[]v7pushaction.PushPlan{
   377  												v7pushaction.PushPlan{Application: v7action.Application{Name: "first-app", GUID: "potato"}},
   378  												v7pushaction.PushPlan{Application: v7action.Application{Name: "second-app", GUID: "potato"}},
   379  											},
   380  											v7action.Warnings{"create-push-plans-warnings"},
   381  											nil,
   382  										)
   383  									})
   384  
   385  									It("it displays the warnings from create push plans", func() {
   386  										Expect(testUI.Err).To(Say("create-push-plans-warnings"))
   387  									})
   388  
   389  									Describe("delegating to Actor.Actualize", func() {
   390  										When("Actualize returns success", func() {
   391  											BeforeEach(func() {
   392  												fakeActor.ActualizeStub = func(v7pushaction.PushPlan, v7pushaction.ProgressBar) <-chan *v7pushaction.PushEvent {
   393  													return FillInEvents([]Step{
   394  														{Plan: v7pushaction.PushPlan{Application: v7action.Application{GUID: "potato"}}},
   395  													})
   396  												}
   397  											})
   398  
   399  											Describe("actualize events", func() {
   400  												BeforeEach(func() {
   401  													fakeActor.ActualizeStub = func(pushPlan v7pushaction.PushPlan, _ v7pushaction.ProgressBar) <-chan *v7pushaction.PushEvent {
   402  														return FillInEvents([]Step{
   403  															{
   404  																Plan:  v7pushaction.PushPlan{Application: v7action.Application{GUID: pushPlan.Application.GUID, Name: pushPlan.Application.Name}},
   405  																Event: v7pushaction.CreatingArchive,
   406  															},
   407  															{
   408  																Plan:     v7pushaction.PushPlan{Application: v7action.Application{GUID: pushPlan.Application.GUID, Name: pushPlan.Application.Name}},
   409  																Event:    v7pushaction.UploadingApplicationWithArchive,
   410  																Warnings: v7pushaction.Warnings{"upload app archive warning"},
   411  															},
   412  															{
   413  																Plan:     v7pushaction.PushPlan{Application: v7action.Application{GUID: pushPlan.Application.GUID, Name: pushPlan.Application.Name}},
   414  																Event:    v7pushaction.RetryUpload,
   415  																Warnings: v7pushaction.Warnings{"retry upload warning"},
   416  															},
   417  															{
   418  																Plan:  v7pushaction.PushPlan{Application: v7action.Application{GUID: pushPlan.Application.GUID, Name: pushPlan.Application.Name}},
   419  																Event: v7pushaction.UploadWithArchiveComplete,
   420  															},
   421  															{
   422  																Plan:  v7pushaction.PushPlan{Application: v7action.Application{GUID: pushPlan.Application.GUID, Name: pushPlan.Application.Name}},
   423  																Event: v7pushaction.RestartingApplication,
   424  															},
   425  															{
   426  																Plan:  v7pushaction.PushPlan{Application: v7action.Application{GUID: pushPlan.Application.GUID, Name: pushPlan.Application.Name}},
   427  																Event: v7pushaction.StartingDeployment,
   428  															},
   429  															{
   430  																Plan:  v7pushaction.PushPlan{Application: v7action.Application{GUID: pushPlan.Application.GUID, Name: pushPlan.Application.Name}},
   431  																Event: v7pushaction.WaitingForDeployment,
   432  															},
   433  														})
   434  													}
   435  												})
   436  
   437  												It("actualizes the application and displays events/warnings", func() {
   438  													Expect(executeErr).ToNot(HaveOccurred())
   439  
   440  													Expect(fakeProgressBar.ReadyCallCount()).Should(Equal(2))
   441  													Expect(fakeProgressBar.CompleteCallCount()).Should(Equal(2))
   442  
   443  													Expect(testUI.Out).To(Say("Packaging files to upload..."))
   444  
   445  													Expect(testUI.Out).To(Say("Uploading files..."))
   446  													Expect(testUI.Err).To(Say("upload app archive warning"))
   447  
   448  													Expect(testUI.Out).To(Say("Retrying upload due to an error..."))
   449  													Expect(testUI.Err).To(Say("retry upload warning"))
   450  
   451  													Expect(testUI.Out).To(Say("Waiting for API to complete processing files..."))
   452  
   453  													Expect(testUI.Out).To(Say("Waiting for app first-app to start..."))
   454  
   455  													Expect(testUI.Out).To(Say("Packaging files to upload..."))
   456  
   457  													Expect(testUI.Out).To(Say("Uploading files..."))
   458  													Expect(testUI.Err).To(Say("upload app archive warning"))
   459  
   460  													Expect(testUI.Out).To(Say("Retrying upload due to an error..."))
   461  													Expect(testUI.Err).To(Say("retry upload warning"))
   462  
   463  													Expect(testUI.Out).To(Say("Waiting for API to complete processing files..."))
   464  
   465  													Expect(testUI.Out).To(Say("Waiting for app second-app to start..."))
   466  
   467  													Expect(testUI.Out).To(Say("Starting deployment for app second-app..."))
   468  
   469  													Expect(testUI.Out).To(Say("Waiting for app to deploy..."))
   470  												})
   471  											})
   472  
   473  											Describe("staging logs", func() {
   474  												BeforeEach(func() {
   475  													fakeActor.ActualizeStub = func(pushPlan v7pushaction.PushPlan, _ v7pushaction.ProgressBar) <-chan *v7pushaction.PushEvent {
   476  														return FillInEvents([]Step{
   477  															{Plan: pushPlan, Event: v7pushaction.StartingStaging},
   478  														})
   479  													}
   480  												})
   481  
   482  												When("there are no logging errors", func() {
   483  													BeforeEach(func() {
   484  														fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceStub = ReturnLogs(
   485  															[]LogEvent{
   486  																{Log: sharedaction.NewLogMessage("log-message-1", "OUT", time.Now(), sharedaction.StagingLog, "source-instance")},
   487  																{Log: sharedaction.NewLogMessage("log-message-2", "OUT", time.Now(), sharedaction.StagingLog, "source-instance")},
   488  																{Log: sharedaction.NewLogMessage("log-message-3", "OUT", time.Now(), "potato", "source-instance")},
   489  															},
   490  															v7action.Warnings{"log-warning-1", "log-warning-2"},
   491  															nil,
   492  														)
   493  													})
   494  
   495  													It("displays the staging logs and warnings", func() {
   496  														Expect(testUI.Out).To(Say("Staging app and tracing logs..."))
   497  
   498  														Expect(testUI.Err).To(Say("log-warning-1"))
   499  														Expect(testUI.Err).To(Say("log-warning-2"))
   500  
   501  														Eventually(testUI.Out).Should(Say("log-message-1"))
   502  														Eventually(testUI.Out).Should(Say("log-message-2"))
   503  														Eventually(testUI.Out).ShouldNot(Say("log-message-3"))
   504  
   505  														Expect(fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceCallCount()).To(Equal(2))
   506  														passedAppName, spaceGUID, _ := fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceArgsForCall(0)
   507  														Expect(passedAppName).To(Equal(appName1))
   508  														Expect(spaceGUID).To(Equal("some-space-guid"))
   509  														passedAppName, spaceGUID, _ = fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceArgsForCall(1)
   510  														Expect(passedAppName).To(Equal(appName2))
   511  														Expect(spaceGUID).To(Equal("some-space-guid"))
   512  
   513  													})
   514  												})
   515  
   516  												When("there are logging errors", func() {
   517  													BeforeEach(func() {
   518  														fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceStub = ReturnLogs(
   519  															[]LogEvent{
   520  																{Error: errors.New("some-random-err")},
   521  																{Error: actionerror.LogCacheTimeoutError{}},
   522  																{Log: sharedaction.NewLogMessage("log-message-1", "OUT", time.Now(), sharedaction.StagingLog, "source-instance")},
   523  															},
   524  															v7action.Warnings{"log-warning-1", "log-warning-2"},
   525  															nil,
   526  														)
   527  													})
   528  
   529  													It("displays the errors as warnings", func() {
   530  														Expect(testUI.Out).To(Say("Staging app and tracing logs..."))
   531  
   532  														Expect(testUI.Err).To(Say("log-warning-1"))
   533  														Expect(testUI.Err).To(Say("log-warning-2"))
   534  														Eventually(testUI.Err).Should(Say("some-random-err"))
   535  														Eventually(testUI.Err).Should(Say("timeout connecting to log server, no log will be shown"))
   536  
   537  														Eventually(testUI.Out).Should(Say("log-message-1"))
   538  													})
   539  												})
   540  											})
   541  
   542  											When("when getting the application summary succeeds", func() {
   543  												BeforeEach(func() {
   544  													summary := v7action.DetailedApplicationSummary{
   545  														ApplicationSummary: v7action.ApplicationSummary{
   546  															Application:      v7action.Application{},
   547  															ProcessSummaries: v7action.ProcessSummaries{},
   548  														},
   549  														CurrentDroplet: v7action.Droplet{},
   550  													}
   551  													fakeVersionActor.GetDetailedAppSummaryReturnsOnCall(0, summary, v7action.Warnings{"app-1-summary-warning-1", "app-1-summary-warning-2"}, nil)
   552  													fakeVersionActor.GetDetailedAppSummaryReturnsOnCall(1, summary, v7action.Warnings{"app-2-summary-warning-1", "app-2-summary-warning-2"}, nil)
   553  												})
   554  
   555  												// TODO: Don't test the shared.AppSummaryDisplayer.AppDisplay method.
   556  												// Use DI to pass in a new AppSummaryDisplayer to the Command instead.
   557  												It("displays the app summary", func() {
   558  													Expect(executeErr).ToNot(HaveOccurred())
   559  													Expect(fakeVersionActor.GetDetailedAppSummaryCallCount()).To(Equal(2))
   560  												})
   561  											})
   562  
   563  											When("getting the application summary fails", func() {
   564  												BeforeEach(func() {
   565  													fakeVersionActor.GetDetailedAppSummaryReturns(
   566  														v7action.DetailedApplicationSummary{},
   567  														v7action.Warnings{"get-application-summary-warnings"},
   568  														errors.New("get-application-summary-error"),
   569  													)
   570  												})
   571  
   572  												It("does not display the app summary", func() {
   573  													Expect(testUI.Out).ToNot(Say(`requested state:`))
   574  												})
   575  
   576  												It("returns the error from GetDetailedAppSummary", func() {
   577  													Expect(executeErr).To(MatchError("get-application-summary-error"))
   578  												})
   579  
   580  												It("prints the warnings", func() {
   581  													Expect(testUI.Err).To(Say("get-application-summary-warnings"))
   582  												})
   583  											})
   584  
   585  										})
   586  
   587  										When("actualize returns an error", func() {
   588  											When("the error is generic", func() {
   589  												BeforeEach(func() {
   590  													fakeActor.ActualizeStub = func(v7pushaction.PushPlan, v7pushaction.ProgressBar) <-chan *v7pushaction.PushEvent {
   591  														return FillInEvents([]Step{
   592  															{Error: errors.New("anti avant garde naming")},
   593  														})
   594  													}
   595  												})
   596  
   597  												It("returns the error", func() {
   598  													Expect(executeErr).To(MatchError("anti avant garde naming"))
   599  												})
   600  											})
   601  
   602  											When("the error is a startup timeout error", func() {
   603  												BeforeEach(func() {
   604  													fakeActor.ActualizeStub = func(v7pushaction.PushPlan, v7pushaction.ProgressBar) <-chan *v7pushaction.PushEvent {
   605  														return FillInEvents([]Step{
   606  															{Error: actionerror.StartupTimeoutError{}},
   607  														})
   608  													}
   609  												})
   610  
   611  												It("returns the StartupTimeoutError and prints warnings", func() {
   612  													Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{
   613  														AppName:    "first-app",
   614  														BinaryName: binaryName,
   615  													}))
   616  												})
   617  											})
   618  
   619  											When("the error is a process crashed error", func() {
   620  												BeforeEach(func() {
   621  													fakeActor.ActualizeStub = func(v7pushaction.PushPlan, v7pushaction.ProgressBar) <-chan *v7pushaction.PushEvent {
   622  														return FillInEvents([]Step{
   623  															{Error: actionerror.AllInstancesCrashedError{}},
   624  														})
   625  													}
   626  												})
   627  
   628  												It("returns the ApplicationUnableToStartError", func() {
   629  													Expect(executeErr).To(MatchError(translatableerror.ApplicationUnableToStartError{
   630  														AppName:    "first-app",
   631  														BinaryName: binaryName,
   632  													}))
   633  												})
   634  
   635  												It("displays the app summary", func() {
   636  													Expect(executeErr).To(HaveOccurred())
   637  													Expect(fakeVersionActor.GetDetailedAppSummaryCallCount()).To(Equal(1))
   638  												})
   639  											})
   640  										})
   641  									})
   642  								})
   643  							})
   644  						})
   645  					})
   646  				})
   647  			})
   648  		})
   649  	})
   650  
   651  	Describe("GetDockerPassword", func() {
   652  		var (
   653  			cmd        PushCommand
   654  			fakeConfig *commandfakes.FakeConfig
   655  			testUI     *ui.UI
   656  
   657  			dockerUsername        string
   658  			containsPrivateDocker bool
   659  
   660  			executeErr     error
   661  			dockerPassword string
   662  
   663  			input *Buffer
   664  		)
   665  
   666  		BeforeEach(func() {
   667  			input = NewBuffer()
   668  			testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer())
   669  			fakeConfig = new(commandfakes.FakeConfig)
   670  
   671  			cmd = PushCommand{
   672  				Config: fakeConfig,
   673  				UI:     testUI,
   674  			}
   675  		})
   676  
   677  		Describe("Get", func() {
   678  			JustBeforeEach(func() {
   679  				dockerPassword, executeErr = cmd.GetDockerPassword(dockerUsername, containsPrivateDocker)
   680  			})
   681  
   682  			When("docker image is private", func() {
   683  				When("there is a manifest", func() {
   684  					BeforeEach(func() {
   685  						dockerUsername = ""
   686  						containsPrivateDocker = true
   687  					})
   688  
   689  					When("a password is provided via environment variable", func() {
   690  						BeforeEach(func() {
   691  							fakeConfig.DockerPasswordReturns("some-docker-password")
   692  						})
   693  
   694  						It("takes the password from the environment", func() {
   695  							Expect(executeErr).ToNot(HaveOccurred())
   696  
   697  							Expect(testUI.Out).ToNot(Say("Environment variable CF_DOCKER_PASSWORD not set."))
   698  							Expect(testUI.Out).ToNot(Say("Docker password"))
   699  
   700  							Expect(testUI.Out).To(Say("Using docker repository password from environment variable CF_DOCKER_PASSWORD."))
   701  
   702  							Expect(dockerPassword).To(Equal("some-docker-password"))
   703  						})
   704  					})
   705  
   706  					When("no password is provided", func() {
   707  						BeforeEach(func() {
   708  							_, err := input.Write([]byte("some-docker-password\n"))
   709  							Expect(err).ToNot(HaveOccurred())
   710  						})
   711  
   712  						It("prompts for a password", func() {
   713  							Expect(executeErr).ToNot(HaveOccurred())
   714  
   715  							Expect(testUI.Out).To(Say("Environment variable CF_DOCKER_PASSWORD not set."))
   716  							Expect(testUI.Out).To(Say("Docker password"))
   717  
   718  							Expect(dockerPassword).To(Equal("some-docker-password"))
   719  						})
   720  					})
   721  				})
   722  
   723  				When("there is no manifest", func() {
   724  					BeforeEach(func() {
   725  						dockerUsername = "some-docker-username"
   726  						containsPrivateDocker = false
   727  					})
   728  
   729  					When("a password is provided via environment variable", func() {
   730  						BeforeEach(func() {
   731  							fakeConfig.DockerPasswordReturns("some-docker-password")
   732  						})
   733  
   734  						It("takes the password from the environment", func() {
   735  							Expect(executeErr).ToNot(HaveOccurred())
   736  
   737  							Expect(testUI.Out).ToNot(Say("Environment variable CF_DOCKER_PASSWORD not set."))
   738  							Expect(testUI.Out).ToNot(Say("Docker password"))
   739  
   740  							Expect(testUI.Out).To(Say("Using docker repository password from environment variable CF_DOCKER_PASSWORD."))
   741  
   742  							Expect(dockerPassword).To(Equal("some-docker-password"))
   743  						})
   744  					})
   745  
   746  					When("no password is provided", func() {
   747  						BeforeEach(func() {
   748  							_, err := input.Write([]byte("some-docker-password\n"))
   749  							Expect(err).ToNot(HaveOccurred())
   750  						})
   751  
   752  						It("prompts for a password", func() {
   753  							Expect(executeErr).ToNot(HaveOccurred())
   754  
   755  							Expect(testUI.Out).To(Say("Environment variable CF_DOCKER_PASSWORD not set."))
   756  							Expect(testUI.Out).To(Say("Docker password"))
   757  
   758  							Expect(dockerPassword).To(Equal("some-docker-password"))
   759  						})
   760  					})
   761  				})
   762  			})
   763  			When("docker image is public", func() {
   764  				BeforeEach(func() {
   765  					dockerUsername = ""
   766  					containsPrivateDocker = false
   767  				})
   768  
   769  				It("does not prompt for a password", func() {
   770  					Expect(testUI.Out).ToNot(Say("Environment variable CF_DOCKER_PASSWORD not set."))
   771  					Expect(testUI.Out).ToNot(Say("Docker password"))
   772  					Expect(testUI.Out).ToNot(Say("Using docker repository password from environment variable CF_DOCKER_PASSWORD."))
   773  				})
   774  
   775  				It("returns an empty password", func() {
   776  					Expect(executeErr).ToNot(HaveOccurred())
   777  					Expect(dockerPassword).To(Equal(""))
   778  				})
   779  			})
   780  		})
   781  	})
   782  
   783  	Describe("GetBaseManifest", func() {
   784  		var (
   785  			somePath      string
   786  			flagOverrides v7pushaction.FlagOverrides
   787  			manifest      manifestparser.Manifest
   788  			executeErr    error
   789  		)
   790  
   791  		JustBeforeEach(func() {
   792  			manifest, executeErr = cmd.GetBaseManifest(flagOverrides)
   793  		})
   794  
   795  		When("no flags are specified", func() {
   796  			BeforeEach(func() {
   797  				cmd.CWD = somePath
   798  			})
   799  
   800  			When("a manifest exists in the current dir", func() {
   801  				BeforeEach(func() {
   802  					fakeManifestLocator.PathReturns("/manifest/path", true, nil)
   803  					fakeManifestParser.InterpolateAndParseReturns(
   804  						manifestparser.Manifest{
   805  							Applications: []manifestparser.Application{
   806  								{Name: "new-app"},
   807  							},
   808  						},
   809  						nil,
   810  					)
   811  				})
   812  
   813  				It("uses the manifest in the current directory", func() {
   814  					Expect(executeErr).ToNot(HaveOccurred())
   815  					Expect(manifest).To(Equal(
   816  						manifestparser.Manifest{
   817  							Applications: []manifestparser.Application{
   818  								{Name: "new-app"},
   819  							},
   820  						}),
   821  					)
   822  
   823  					Expect(fakeManifestLocator.PathCallCount()).To(Equal(1))
   824  					Expect(fakeManifestLocator.PathArgsForCall(0)).To(Equal(cmd.CWD))
   825  
   826  					Expect(fakeManifestParser.InterpolateAndParseCallCount()).To(Equal(1))
   827  					actualManifestPath, _, _ := fakeManifestParser.InterpolateAndParseArgsForCall(0)
   828  					Expect(actualManifestPath).To(Equal("/manifest/path"))
   829  				})
   830  			})
   831  
   832  			When("there is not a manifest in the current dir", func() {
   833  				BeforeEach(func() {
   834  					flagOverrides.AppName = "new-app"
   835  					fakeManifestLocator.PathReturns("", false, nil)
   836  				})
   837  
   838  				It("ignores the file not found error", func() {
   839  					Expect(executeErr).ToNot(HaveOccurred())
   840  					Expect(fakeManifestParser.InterpolateAndParseCallCount()).To(Equal(0))
   841  				})
   842  
   843  				It("returns a default empty manifest", func() {
   844  					Expect(manifest).To(Equal(
   845  						manifestparser.Manifest{
   846  							Applications: []manifestparser.Application{
   847  								{Name: "new-app"},
   848  							},
   849  						}),
   850  					)
   851  				})
   852  			})
   853  
   854  			When("when there is an error locating the manifest in the current directory", func() {
   855  				BeforeEach(func() {
   856  					fakeManifestLocator.PathReturns("", false, errors.New("err-location"))
   857  				})
   858  
   859  				It("returns the error", func() {
   860  					Expect(executeErr).To(MatchError("err-location"))
   861  					Expect(fakeManifestParser.InterpolateAndParseCallCount()).To(Equal(0))
   862  				})
   863  			})
   864  
   865  			When("parsing the manifest fails", func() {
   866  				BeforeEach(func() {
   867  					fakeManifestLocator.PathReturns("/manifest/path", true, nil)
   868  					fakeManifestParser.InterpolateAndParseReturns(
   869  						manifestparser.Manifest{},
   870  						errors.New("bad yaml"),
   871  					)
   872  				})
   873  
   874  				It("returns the error", func() {
   875  					Expect(executeErr).To(MatchError("bad yaml"))
   876  					Expect(fakeManifestParser.InterpolateAndParseCallCount()).To(Equal(1))
   877  				})
   878  			})
   879  		})
   880  
   881  		When("The -f flag is specified", func() {
   882  			BeforeEach(func() {
   883  				somePath = "some-path"
   884  				flagOverrides.ManifestPath = somePath
   885  				fakeManifestLocator.PathReturns("/manifest/path", true, nil)
   886  				fakeManifestParser.InterpolateAndParseReturns(
   887  					manifestparser.Manifest{
   888  						Applications: []manifestparser.Application{
   889  							{Name: "new-app"},
   890  						},
   891  					},
   892  					nil,
   893  				)
   894  			})
   895  
   896  			It("parses the specified manifest", func() {
   897  				Expect(executeErr).ToNot(HaveOccurred())
   898  
   899  				Expect(fakeManifestLocator.PathCallCount()).To(Equal(1))
   900  				Expect(fakeManifestLocator.PathArgsForCall(0)).To(Equal(somePath))
   901  
   902  				Expect(fakeManifestParser.InterpolateAndParseCallCount()).To(Equal(1))
   903  				actualManifestPath, _, _ := fakeManifestParser.InterpolateAndParseArgsForCall(0)
   904  				Expect(actualManifestPath).To(Equal("/manifest/path"))
   905  				Expect(manifest).To(Equal(
   906  					manifestparser.Manifest{
   907  						Applications: []manifestparser.Application{
   908  							{Name: "new-app"},
   909  						},
   910  					}),
   911  				)
   912  			})
   913  		})
   914  
   915  		When("--vars-files are specified", func() {
   916  			var varsFiles []string
   917  
   918  			BeforeEach(func() {
   919  				fakeManifestLocator.PathReturns("/manifest/path", true, nil)
   920  				varsFiles = []string{"path1", "path2"}
   921  				flagOverrides.PathsToVarsFiles = append(flagOverrides.PathsToVarsFiles, varsFiles...)
   922  			})
   923  
   924  			It("passes vars files to the manifest parser", func() {
   925  				Expect(executeErr).ToNot(HaveOccurred())
   926  
   927  				Expect(fakeManifestParser.InterpolateAndParseCallCount()).To(Equal(1))
   928  				_, actualVarsFiles, _ := fakeManifestParser.InterpolateAndParseArgsForCall(0)
   929  				Expect(actualVarsFiles).To(Equal(varsFiles))
   930  			})
   931  		})
   932  
   933  		When("The --var flag is provided", func() {
   934  			var vars []template.VarKV
   935  
   936  			BeforeEach(func() {
   937  				fakeManifestLocator.PathReturns("/manifest/path", true, nil)
   938  				vars = []template.VarKV{
   939  					{Name: "put-var-here", Value: "turtle"},
   940  				}
   941  				flagOverrides.Vars = vars
   942  			})
   943  
   944  			It("passes vars files to the manifest parser", func() {
   945  				Expect(executeErr).ToNot(HaveOccurred())
   946  
   947  				Expect(fakeManifestParser.InterpolateAndParseCallCount()).To(Equal(1))
   948  				_, _, actualVars := fakeManifestParser.InterpolateAndParseArgsForCall(0)
   949  				Expect(actualVars).To(Equal(vars))
   950  			})
   951  		})
   952  	})
   953  
   954  	Describe("GetFlagOverrides", func() {
   955  		var (
   956  			overrides    v7pushaction.FlagOverrides
   957  			overridesErr error
   958  		)
   959  
   960  		BeforeEach(func() {
   961  			cmd.Buildpacks = []string{"buildpack-1", "buildpack-2"}
   962  			cmd.Stack = "validStack"
   963  			cmd.HealthCheckType = flag.HealthCheckType{Type: constant.Port}
   964  			cmd.HealthCheckHTTPEndpoint = "/health-check-http-endpoint"
   965  			cmd.HealthCheckTimeout = flag.PositiveInteger{Value: 7}
   966  			cmd.Memory = "64M"
   967  			cmd.Disk = "256M"
   968  			cmd.DropletPath = flag.PathWithExistenceCheck("some-droplet.tgz")
   969  			cmd.StartCommand = flag.Command{FilteredString: types.FilteredString{IsSet: true, Value: "some-start-command"}}
   970  			cmd.NoRoute = true
   971  			cmd.RandomRoute = false
   972  			cmd.NoStart = true
   973  			cmd.NoWait = true
   974  			cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyRolling}
   975  			cmd.Instances = flag.Instances{NullInt: types.NullInt{Value: 10, IsSet: true}}
   976  			cmd.PathToManifest = "/manifest/path"
   977  			cmd.PathsToVarsFiles = []flag.PathWithExistenceCheck{"/vars1", "/vars2"}
   978  			cmd.Vars = []template.VarKV{{Name: "key", Value: "val"}}
   979  			cmd.Task = true
   980  		})
   981  
   982  		JustBeforeEach(func() {
   983  			overrides, overridesErr = cmd.GetFlagOverrides()
   984  			Expect(overridesErr).ToNot(HaveOccurred())
   985  		})
   986  
   987  		It("sets them on the flag overrides", func() {
   988  			Expect(overridesErr).ToNot(HaveOccurred())
   989  			Expect(overrides.Buildpacks).To(ConsistOf("buildpack-1", "buildpack-2"))
   990  			Expect(overrides.DropletPath).To(Equal("some-droplet.tgz"))
   991  			Expect(overrides.Stack).To(Equal("validStack"))
   992  			Expect(overrides.HealthCheckType).To(Equal(constant.Port))
   993  			Expect(overrides.HealthCheckEndpoint).To(Equal("/health-check-http-endpoint"))
   994  			Expect(overrides.HealthCheckTimeout).To(BeEquivalentTo(7))
   995  			Expect(overrides.Memory).To(Equal("64M"))
   996  			Expect(overrides.Disk).To(Equal("256M"))
   997  			Expect(overrides.StartCommand).To(Equal(types.FilteredString{IsSet: true, Value: "some-start-command"}))
   998  			Expect(overrides.NoRoute).To(BeTrue())
   999  			Expect(overrides.NoStart).To(BeTrue())
  1000  			Expect(overrides.NoWait).To(BeTrue())
  1001  			Expect(overrides.RandomRoute).To(BeFalse())
  1002  			Expect(overrides.Strategy).To(Equal(constant.DeploymentStrategyRolling))
  1003  			Expect(overrides.Instances).To(Equal(types.NullInt{Value: 10, IsSet: true}))
  1004  			Expect(overrides.ManifestPath).To(Equal("/manifest/path"))
  1005  			Expect(overrides.PathsToVarsFiles).To(Equal([]string{"/vars1", "/vars2"}))
  1006  			Expect(overrides.Vars).To(Equal([]template.VarKV{{Name: "key", Value: "val"}}))
  1007  			Expect(overrides.Task).To(BeTrue())
  1008  		})
  1009  
  1010  		When("a docker image is provided", func() {
  1011  			BeforeEach(func() {
  1012  				cmd.DockerImage = flag.DockerImage{Path: "some-docker-image"}
  1013  			})
  1014  
  1015  			It("sets docker image on the flag overrides", func() {
  1016  				Expect(overridesErr).ToNot(HaveOccurred())
  1017  				Expect(overrides.DockerImage).To(Equal("some-docker-image"))
  1018  			})
  1019  		})
  1020  	})
  1021  
  1022  	DescribeTable("ValidateFlags returns an error",
  1023  		func(setup func(), expectedErr error) {
  1024  			setup()
  1025  			err := cmd.ValidateFlags()
  1026  			if expectedErr == nil {
  1027  				Expect(err).To(BeNil())
  1028  			} else {
  1029  				Expect(err).To(MatchError(expectedErr))
  1030  			}
  1031  		},
  1032  
  1033  		Entry("when docker username flag is passed *without* docker flag",
  1034  			func() {
  1035  				cmd.DockerUsername = "some-docker-username"
  1036  			},
  1037  			translatableerror.RequiredFlagsError{Arg1: "--docker-image, -o", Arg2: "--docker-username"}),
  1038  
  1039  		Entry("when docker and buildpacks flags are passed",
  1040  			func() {
  1041  				cmd.DockerImage.Path = "some-docker-image"
  1042  				cmd.Buildpacks = []string{"some-buildpack"}
  1043  			},
  1044  			translatableerror.ArgumentCombinationError{Args: []string{"--buildpack, -b", "--docker-image, -o"}}),
  1045  
  1046  		Entry("when docker and stack flags are passed",
  1047  			func() {
  1048  				cmd.DockerImage.Path = "some-docker-image"
  1049  				cmd.Stack = "validStack"
  1050  			},
  1051  			translatableerror.ArgumentCombinationError{Args: []string{"--stack, -s", "--docker-image, -o"}}),
  1052  
  1053  		Entry("when docker and path flags are passed",
  1054  			func() {
  1055  				cmd.DockerImage.Path = "some-docker-image"
  1056  				cmd.AppPath = "some-directory-path"
  1057  			},
  1058  			translatableerror.ArgumentCombinationError{Args: []string{"--docker-image, -o", "--path, -p"}}),
  1059  
  1060  		Entry("when -u http does not have a matching --endpoint",
  1061  			func() {
  1062  				cmd.HealthCheckType.Type = constant.HTTP
  1063  			},
  1064  			translatableerror.RequiredFlagsError{Arg1: "--endpoint", Arg2: "--health-check-type=http, -u=http"}),
  1065  
  1066  		Entry("when -u http does have a matching --endpoint",
  1067  			func() {
  1068  				cmd.HealthCheckType.Type = constant.HTTP
  1069  				cmd.HealthCheckHTTPEndpoint = "/health"
  1070  			},
  1071  			nil),
  1072  
  1073  		Entry("when droplet and path flags are passed",
  1074  			func() {
  1075  				cmd.DropletPath = "some-droplet.tgz"
  1076  				cmd.AppPath = "/my/app"
  1077  			},
  1078  			translatableerror.ArgumentCombinationError{
  1079  				Args: []string{
  1080  					"--droplet", "--docker-image, -o", "--docker-username", "-p",
  1081  				},
  1082  			}),
  1083  
  1084  		Entry("when droplet and docker image flags are passed",
  1085  			func() {
  1086  				cmd.DropletPath = "some-droplet.tgz"
  1087  				cmd.DockerImage.Path = "docker-image"
  1088  			},
  1089  			translatableerror.ArgumentCombinationError{
  1090  				Args: []string{
  1091  					"--droplet", "--docker-image, -o", "--docker-username", "-p",
  1092  				},
  1093  			}),
  1094  
  1095  		Entry("when droplet, docker image, and docker username flags are passed",
  1096  			func() {
  1097  				cmd.DropletPath = "some-droplet.tgz"
  1098  				cmd.DockerImage.Path = "docker-image"
  1099  				cmd.DockerUsername = "docker-username"
  1100  			},
  1101  			translatableerror.ArgumentCombinationError{
  1102  				Args: []string{
  1103  					"--droplet", "--docker-image, -o", "--docker-username", "-p",
  1104  				},
  1105  			}),
  1106  
  1107  		Entry("when strategy 'rolling' and no-start flags are passed",
  1108  			func() {
  1109  				cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyRolling}
  1110  				cmd.NoStart = true
  1111  			},
  1112  			translatableerror.ArgumentCombinationError{
  1113  				Args: []string{
  1114  					"--no-start", "--strategy=rolling",
  1115  				},
  1116  			}),
  1117  
  1118  		Entry("when strategy is not set and no-start flags are passed",
  1119  			func() {
  1120  				cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyDefault}
  1121  				cmd.NoStart = true
  1122  			},
  1123  			nil),
  1124  
  1125  		Entry("when no-start and no-wait flags are passed",
  1126  			func() {
  1127  				cmd.NoStart = true
  1128  				cmd.NoWait = true
  1129  			},
  1130  			translatableerror.ArgumentCombinationError{
  1131  				Args: []string{
  1132  					"--no-start", "--no-wait",
  1133  				},
  1134  			}),
  1135  		Entry("when no-route and random-route flags are passed",
  1136  			func() {
  1137  				cmd.NoRoute = true
  1138  				cmd.RandomRoute = true
  1139  			},
  1140  			translatableerror.ArgumentCombinationError{
  1141  				Args: []string{
  1142  					"--no-route", "--random-route",
  1143  				},
  1144  			}),
  1145  
  1146  		Entry("default is combined with non default buildpacks",
  1147  			func() {
  1148  				cmd.Buildpacks = []string{"some-docker-username", "default"}
  1149  			},
  1150  			translatableerror.InvalidBuildpacksError{}),
  1151  
  1152  		Entry("default is combined with non default buildpacks",
  1153  			func() {
  1154  				cmd.Buildpacks = []string{"some-docker-username", "null"}
  1155  			},
  1156  			translatableerror.InvalidBuildpacksError{}),
  1157  
  1158  		Entry("task and strategy flags are passed",
  1159  			func() {
  1160  				cmd.Task = true
  1161  				cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyRolling}
  1162  			},
  1163  			translatableerror.ArgumentCombinationError{
  1164  				Args: []string{
  1165  					"--task", "--strategy=rolling",
  1166  				},
  1167  			}),
  1168  	)
  1169  })