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

     1  package v6_test
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"time"
     7  
     8  	"code.cloudfoundry.org/cli/actor/actionerror"
     9  	"code.cloudfoundry.org/cli/actor/pushaction"
    10  	"code.cloudfoundry.org/cli/actor/v3action"
    11  	"code.cloudfoundry.org/cli/actor/v3action/v3actionfakes"
    12  	"code.cloudfoundry.org/cli/command/commandfakes"
    13  	"code.cloudfoundry.org/cli/command/flag"
    14  	"code.cloudfoundry.org/cli/command/translatableerror"
    15  	. "code.cloudfoundry.org/cli/command/v6"
    16  	"code.cloudfoundry.org/cli/command/v6/v6fakes"
    17  	"code.cloudfoundry.org/cli/util/configv3"
    18  	"code.cloudfoundry.org/cli/util/ui"
    19  	. "github.com/onsi/ginkgo"
    20  	. "github.com/onsi/gomega"
    21  	. "github.com/onsi/gomega/gbytes"
    22  	. "github.com/onsi/gomega/gstruct"
    23  )
    24  
    25  type Step struct {
    26  	Error    error
    27  	Event    pushaction.Event
    28  	Warnings pushaction.Warnings
    29  }
    30  
    31  func FillInValues(tuples []Step, state pushaction.PushState) func(pushaction.PushState, pushaction.ProgressBar) (<-chan pushaction.PushState, <-chan pushaction.Event, <-chan pushaction.Warnings, <-chan error) {
    32  	return func(pushaction.PushState, pushaction.ProgressBar) (<-chan pushaction.PushState, <-chan pushaction.Event, <-chan pushaction.Warnings, <-chan error) {
    33  		stateStream := make(chan pushaction.PushState)
    34  
    35  		eventStream := make(chan pushaction.Event)
    36  		warningsStream := make(chan pushaction.Warnings)
    37  		errorStream := make(chan error)
    38  
    39  		go func() {
    40  			defer close(stateStream)
    41  			defer close(eventStream)
    42  			defer close(warningsStream)
    43  			defer close(errorStream)
    44  
    45  			for _, tuple := range tuples {
    46  				warningsStream <- tuple.Warnings
    47  				if tuple.Error != nil {
    48  					errorStream <- tuple.Error
    49  					return
    50  				} else {
    51  					eventStream <- tuple.Event
    52  				}
    53  			}
    54  
    55  			stateStream <- state
    56  			eventStream <- pushaction.Complete
    57  		}()
    58  
    59  		return stateStream, eventStream, warningsStream, errorStream
    60  	}
    61  }
    62  
    63  type LogEvent struct {
    64  	Log   *v3action.LogMessage
    65  	Error error
    66  }
    67  
    68  func ReturnLogs(logevents []LogEvent, passedWarnings v3action.Warnings, passedError error) func(appName string, spaceGUID string, client v3action.NOAAClient) (<-chan *v3action.LogMessage, <-chan error, v3action.Warnings, error) {
    69  	return func(appName string, spaceGUID string, client v3action.NOAAClient) (<-chan *v3action.LogMessage, <-chan error, v3action.Warnings, error) {
    70  		logStream := make(chan *v3action.LogMessage)
    71  		errStream := make(chan error)
    72  		go func() {
    73  			defer close(logStream)
    74  			defer close(errStream)
    75  
    76  			for _, log := range logevents {
    77  				if log.Log != nil {
    78  					logStream <- log.Log
    79  				}
    80  				if log.Error != nil {
    81  					errStream <- log.Error
    82  				}
    83  			}
    84  		}()
    85  
    86  		return logStream, errStream, passedWarnings, passedError
    87  	}
    88  }
    89  
    90  var _ = Describe("v3-push Command", func() {
    91  	var (
    92  		cmd              V3PushCommand
    93  		testUI           *ui.UI
    94  		fakeConfig       *commandfakes.FakeConfig
    95  		fakeSharedActor  *commandfakes.FakeSharedActor
    96  		fakeActor        *v6fakes.FakeV3PushActor
    97  		fakeVersionActor *v6fakes.FakeV3PushVersionActor
    98  		fakeProgressBar  *v6fakes.FakeProgressBar
    99  		fakeNOAAClient   *v3actionfakes.FakeNOAAClient
   100  		binaryName       string
   101  		executeErr       error
   102  
   103  		appName   string
   104  		userName  string
   105  		spaceName string
   106  		orgName   string
   107  	)
   108  
   109  	BeforeEach(func() {
   110  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
   111  		fakeConfig = new(commandfakes.FakeConfig)
   112  		fakeSharedActor = new(commandfakes.FakeSharedActor)
   113  		fakeActor = new(v6fakes.FakeV3PushActor)
   114  		fakeVersionActor = new(v6fakes.FakeV3PushVersionActor)
   115  		fakeProgressBar = new(v6fakes.FakeProgressBar)
   116  		fakeNOAAClient = new(v3actionfakes.FakeNOAAClient)
   117  
   118  		binaryName = "faceman"
   119  		fakeConfig.BinaryNameReturns(binaryName)
   120  		fakeConfig.ExperimentalReturns(true) // TODO: Delete once we remove the experimental flag
   121  
   122  		cmd = V3PushCommand{
   123  			RequiredArgs: flag.AppName{AppName: "some-app"},
   124  			UI:           testUI,
   125  			Config:       fakeConfig,
   126  			Actor:        fakeActor,
   127  			VersionActor: fakeVersionActor,
   128  			SharedActor:  fakeSharedActor,
   129  			ProgressBar:  fakeProgressBar,
   130  			NOAAClient:   fakeNOAAClient,
   131  		}
   132  
   133  		appName = "some-app"
   134  		userName = "some-user"
   135  		spaceName = "some-space"
   136  		orgName = "some-org"
   137  	})
   138  
   139  	Describe("Execute", func() {
   140  		JustBeforeEach(func() {
   141  			executeErr = cmd.Execute(nil)
   142  		})
   143  
   144  		When("checking target fails", func() {
   145  			BeforeEach(func() {
   146  				fakeSharedActor.CheckTargetReturns(actionerror.NoOrganizationTargetedError{BinaryName: binaryName})
   147  			})
   148  
   149  			It("returns an error", func() {
   150  				Expect(executeErr).To(MatchError(actionerror.NoOrganizationTargetedError{BinaryName: binaryName}))
   151  
   152  				Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   153  				checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   154  				Expect(checkTargetedOrg).To(BeTrue())
   155  				Expect(checkTargetedSpace).To(BeTrue())
   156  			})
   157  		})
   158  
   159  		When("checking target fails because the user is not logged in", func() {
   160  			BeforeEach(func() {
   161  				fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
   162  			})
   163  
   164  			It("returns an error", func() {
   165  				Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName}))
   166  
   167  				Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   168  				checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   169  				Expect(checkTargetedOrg).To(BeTrue())
   170  				Expect(checkTargetedSpace).To(BeTrue())
   171  			})
   172  		})
   173  
   174  		When("the user is logged in, and org and space are targeted", func() {
   175  			BeforeEach(func() {
   176  				fakeConfig.CurrentUserReturns(configv3.User{Name: userName}, nil)
   177  
   178  				fakeConfig.TargetedOrganizationReturns(configv3.Organization{
   179  					Name: orgName,
   180  					GUID: "some-org-guid",
   181  				})
   182  				fakeConfig.TargetedSpaceReturns(configv3.Space{
   183  					Name: spaceName,
   184  					GUID: "some-space-guid",
   185  				})
   186  			})
   187  
   188  			It("displays the experimental warning", func() {
   189  				Expect(testUI.Err).To(Say("This command is in EXPERIMENTAL stage and may change without notice"))
   190  			})
   191  
   192  			When("getting app settings is successful", func() {
   193  				BeforeEach(func() {
   194  					fakeActor.ConceptualizeReturns(
   195  						[]pushaction.PushState{
   196  							{
   197  								Application: v3action.Application{Name: appName},
   198  							},
   199  						},
   200  						pushaction.Warnings{"some-warning-1"}, nil)
   201  				})
   202  
   203  				Describe("actualizing non-logging events", func() {
   204  					BeforeEach(func() {
   205  						fakeActor.ActualizeStub = FillInValues([]Step{
   206  							{
   207  								Event:    pushaction.SkippingApplicationCreation,
   208  								Warnings: pushaction.Warnings{"skipping app creation warnings"},
   209  							},
   210  							{
   211  								Event:    pushaction.CreatedApplication,
   212  								Warnings: pushaction.Warnings{"app creation warnings"},
   213  							},
   214  							{
   215  								Event: pushaction.CreatingArchive,
   216  							},
   217  							{
   218  								Event:    pushaction.UploadingApplicationWithArchive,
   219  								Warnings: pushaction.Warnings{"upload app archive warning"},
   220  							},
   221  							{
   222  								Event:    pushaction.RetryUpload,
   223  								Warnings: pushaction.Warnings{"retry upload warning"},
   224  							},
   225  							{
   226  								Event: pushaction.UploadWithArchiveComplete,
   227  							},
   228  							{
   229  								Event: pushaction.StagingComplete,
   230  							},
   231  						}, pushaction.PushState{})
   232  					})
   233  
   234  					It("generates a push state with the specified app path", func() {
   235  						Expect(executeErr).ToNot(HaveOccurred())
   236  						Expect(testUI.Out).To(Say("Pushing app %s to org some-org / space some-space as some-user", appName))
   237  						Expect(testUI.Out).To(Say(`Getting app info\.\.\.`))
   238  						Expect(testUI.Err).To(Say("some-warning-1"))
   239  
   240  						Expect(fakeActor.ConceptualizeCallCount()).To(Equal(1))
   241  						settings, spaceGUID := fakeActor.ConceptualizeArgsForCall(0)
   242  						Expect(settings).To(MatchFields(IgnoreExtras, Fields{
   243  							"Name": Equal("some-app"),
   244  						}))
   245  						Expect(spaceGUID).To(Equal("some-space-guid"))
   246  					})
   247  
   248  					It("actualizes the application and displays events/warnings", func() {
   249  						Expect(executeErr).ToNot(HaveOccurred())
   250  
   251  						Expect(testUI.Out).To(Say("Updating app some-app..."))
   252  						Expect(testUI.Err).To(Say("skipping app creation warnings"))
   253  
   254  						Expect(testUI.Out).To(Say("Creating app some-app..."))
   255  						Expect(testUI.Err).To(Say("app creation warnings"))
   256  
   257  						Expect(testUI.Out).To(Say("Packaging files to upload..."))
   258  
   259  						Expect(testUI.Out).To(Say("Uploading files..."))
   260  						Expect(testUI.Err).To(Say("upload app archive warning"))
   261  						Expect(fakeProgressBar.ReadyCallCount()).Should(Equal(1))
   262  
   263  						Expect(testUI.Out).To(Say("Retrying upload due to an error..."))
   264  						Expect(testUI.Err).To(Say("retry upload warning"))
   265  
   266  						Expect(testUI.Out).To(Say("Waiting for API to complete processing files..."))
   267  
   268  						Expect(testUI.Out).To(Say("Waiting for app to start..."))
   269  						Expect(fakeProgressBar.CompleteCallCount()).Should(Equal(1))
   270  					})
   271  				})
   272  
   273  				Describe("actualizing logging events", func() {
   274  					BeforeEach(func() {
   275  						fakeActor.ActualizeStub = FillInValues([]Step{
   276  							{
   277  								Event: pushaction.StartingStaging,
   278  							},
   279  						}, pushaction.PushState{})
   280  					})
   281  
   282  					When("there are no logging errors", func() {
   283  						BeforeEach(func() {
   284  							fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceStub = ReturnLogs(
   285  								[]LogEvent{
   286  									{Log: v3action.NewLogMessage("log-message-1", 1, time.Now(), v3action.StagingLog, "source-instance")},
   287  									{Log: v3action.NewLogMessage("log-message-2", 1, time.Now(), v3action.StagingLog, "source-instance")},
   288  									{Log: v3action.NewLogMessage("log-message-3", 1, time.Now(), "potato", "source-instance")},
   289  								},
   290  								v3action.Warnings{"log-warning-1", "log-warning-2"},
   291  								nil,
   292  							)
   293  						})
   294  
   295  						It("displays the staging logs and warnings", func() {
   296  							Expect(testUI.Out).To(Say("Staging app and tracing logs..."))
   297  
   298  							Expect(testUI.Err).To(Say("log-warning-1"))
   299  							Expect(testUI.Err).To(Say("log-warning-2"))
   300  
   301  							Eventually(testUI.Out).Should(Say("log-message-1"))
   302  							Eventually(testUI.Out).Should(Say("log-message-2"))
   303  							Eventually(testUI.Out).ShouldNot(Say("log-message-3"))
   304  
   305  							Expect(fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceCallCount()).To(Equal(1))
   306  							passedAppName, spaceGUID, _ := fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceArgsForCall(0)
   307  							Expect(passedAppName).To(Equal(appName))
   308  							Expect(spaceGUID).To(Equal("some-space-guid"))
   309  						})
   310  					})
   311  
   312  					When("there are logging errors", func() {
   313  						BeforeEach(func() {
   314  							fakeVersionActor.GetStreamingLogsForApplicationByNameAndSpaceStub = ReturnLogs(
   315  								[]LogEvent{
   316  									{Error: errors.New("some-random-err")},
   317  									{Error: actionerror.NOAATimeoutError{}},
   318  									{Log: v3action.NewLogMessage("log-message-1", 1, time.Now(), v3action.StagingLog, "source-instance")},
   319  								},
   320  								v3action.Warnings{"log-warning-1", "log-warning-2"},
   321  								nil,
   322  							)
   323  						})
   324  
   325  						It("displays the errors as warnings", func() {
   326  							Expect(testUI.Out).To(Say("Staging app and tracing logs..."))
   327  
   328  							Expect(testUI.Err).To(Say("log-warning-1"))
   329  							Expect(testUI.Err).To(Say("log-warning-2"))
   330  							Eventually(testUI.Err).Should(Say("some-random-err"))
   331  							Eventually(testUI.Err).Should(Say("timeout connecting to log server, no log will be shown"))
   332  
   333  							Eventually(testUI.Out).Should(Say("log-message-1"))
   334  						})
   335  					})
   336  				})
   337  
   338  				When("the app is successfully actualized", func() {
   339  					BeforeEach(func() {
   340  						fakeActor.ActualizeStub = FillInValues([]Step{
   341  							{},
   342  						}, pushaction.PushState{Application: v3action.Application{GUID: "potato"}})
   343  					})
   344  
   345  					// It("outputs flavor text prior to generating app configuration", func() {
   346  					// })
   347  
   348  					When("restarting the app succeeds", func() {
   349  						BeforeEach(func() {
   350  							fakeVersionActor.RestartApplicationReturns(v3action.Warnings{"some-restart-warning"}, nil)
   351  						})
   352  
   353  						It("restarts the app and displays warnings", func() {
   354  							Expect(executeErr).ToNot(HaveOccurred())
   355  							Expect(fakeVersionActor.RestartApplicationCallCount()).To(Equal(1))
   356  							Expect(fakeVersionActor.RestartApplicationArgsForCall(0)).To(Equal("potato"))
   357  							Expect(testUI.Err).To(Say("some-restart-warning"))
   358  						})
   359  
   360  						When("polling the restart succeeds", func() {
   361  							BeforeEach(func() {
   362  								fakeVersionActor.PollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
   363  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
   364  									return nil
   365  								}
   366  							})
   367  
   368  							It("displays all warnings", func() {
   369  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
   370  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
   371  
   372  								Expect(executeErr).ToNot(HaveOccurred())
   373  							})
   374  						})
   375  
   376  						When("polling the start fails", func() {
   377  							BeforeEach(func() {
   378  								fakeVersionActor.PollStartStub = func(appGUID string, warnings chan<- v3action.Warnings) error {
   379  									warnings <- v3action.Warnings{"some-poll-warning-1", "some-poll-warning-2"}
   380  									return errors.New("some-error")
   381  								}
   382  							})
   383  
   384  							It("displays all warnings and fails", func() {
   385  								Expect(testUI.Err).To(Say("some-poll-warning-1"))
   386  								Expect(testUI.Err).To(Say("some-poll-warning-2"))
   387  
   388  								Expect(executeErr).To(MatchError("some-error"))
   389  							})
   390  						})
   391  
   392  						When("polling times out", func() {
   393  							BeforeEach(func() {
   394  								fakeVersionActor.PollStartReturns(actionerror.StartupTimeoutError{})
   395  							})
   396  
   397  							It("returns the StartupTimeoutError", func() {
   398  								Expect(executeErr).To(MatchError(translatableerror.StartupTimeoutError{
   399  									AppName:    "some-app",
   400  									BinaryName: binaryName,
   401  								}))
   402  							})
   403  						})
   404  					})
   405  
   406  					When("restarting the app fails", func() {
   407  						BeforeEach(func() {
   408  							fakeVersionActor.RestartApplicationReturns(v3action.Warnings{"some-restart-warning"}, errors.New("restart failure"))
   409  						})
   410  
   411  						It("returns an error and any warnings", func() {
   412  							Expect(executeErr).To(MatchError("restart failure"))
   413  							Expect(testUI.Err).To(Say("some-restart-warning"))
   414  						})
   415  					})
   416  				})
   417  
   418  				When("actualizing fails", func() {
   419  					BeforeEach(func() {
   420  						fakeActor.ActualizeStub = FillInValues([]Step{
   421  							{
   422  								Error: errors.New("anti avant garde naming"),
   423  							},
   424  						}, pushaction.PushState{})
   425  					})
   426  
   427  					It("returns the error", func() {
   428  						Expect(executeErr).To(MatchError("anti avant garde naming"))
   429  					})
   430  				})
   431  			})
   432  
   433  			When("getting app settings returns an error", func() {
   434  				var expectedErr error
   435  
   436  				BeforeEach(func() {
   437  					expectedErr = errors.New("some-error")
   438  					fakeActor.ConceptualizeReturns(nil, pushaction.Warnings{"some-warning-1"}, expectedErr)
   439  				})
   440  
   441  				It("generates a push state with the specified app path", func() {
   442  					Expect(executeErr).To(MatchError(expectedErr))
   443  					Expect(testUI.Err).To(Say("some-warning-1"))
   444  				})
   445  			})
   446  
   447  			When("app path is specified", func() {
   448  				BeforeEach(func() {
   449  					cmd.AppPath = "some/app/path"
   450  				})
   451  
   452  				It("generates a push state with the specified app path", func() {
   453  					Expect(fakeActor.ConceptualizeCallCount()).To(Equal(1))
   454  					settings, spaceGUID := fakeActor.ConceptualizeArgsForCall(0)
   455  					Expect(settings).To(MatchFields(IgnoreExtras, Fields{
   456  						"Name":            Equal("some-app"),
   457  						"ProvidedAppPath": Equal("some/app/path"),
   458  					}))
   459  					Expect(spaceGUID).To(Equal("some-space-guid"))
   460  				})
   461  			})
   462  
   463  			When("buildpack is specified", func() {
   464  				BeforeEach(func() {
   465  					cmd.Buildpacks = []string{"some-buildpack-1", "some-buildpack-2"}
   466  				})
   467  
   468  				It("generates a push state with the specified buildpacks", func() {
   469  					Expect(fakeActor.ConceptualizeCallCount()).To(Equal(1))
   470  					settings, spaceGUID := fakeActor.ConceptualizeArgsForCall(0)
   471  					Expect(settings).To(MatchFields(IgnoreExtras, Fields{
   472  						"Name":       Equal("some-app"),
   473  						"Buildpacks": Equal([]string{"some-buildpack-1", "some-buildpack-2"}),
   474  					}))
   475  					Expect(spaceGUID).To(Equal("some-space-guid"))
   476  				})
   477  			})
   478  		})
   479  	})
   480  
   481  	Describe("GetCommandLineSettings", func() {
   482  		Context("valid flag combinations", func() {
   483  			var (
   484  				settings               pushaction.CommandLineSettings
   485  				commandLineSettingsErr error
   486  			)
   487  
   488  			JustBeforeEach(func() {
   489  				settings, commandLineSettingsErr = cmd.GetCommandLineSettings()
   490  				Expect(commandLineSettingsErr).ToNot(HaveOccurred())
   491  			})
   492  
   493  			// When("general app settings are given", func() {
   494  			// 	BeforeEach(func() {
   495  			// 		cmd.Buildpacks = []string{"some-buildpack"}
   496  			// 		cmd.Command = flag.Command{FilteredString: types.FilteredString{IsSet: true, Value: "echo foo bar baz"}}
   497  			// 		cmd.DiskQuota = flag.Megabytes{NullUint64: types.NullUint64{Value: 1024, IsSet: true}}
   498  			// 		cmd.HealthCheckTimeout = 14
   499  			// 		cmd.HealthCheckType = flag.HealthCheckTypeWithDeprecatedValue{Type: constant.HTTP}
   500  			// 		cmd.Instances = flag.Instances{NullInt: types.NullInt{Value: 12, IsSet: true}}
   501  			// 		cmd.Memory = flag.Megabytes{NullUint64: types.NullUint64{Value: 100, IsSet: true}}
   502  			// 		cmd.StackName = "some-stack"
   503  			// 	})
   504  
   505  			// 	It("sets them on the command line settings", func() {
   506  			// 		Expect(commandLineSettingsErr).ToNot(HaveOccurred())
   507  			// 		Expect(settings.Buildpacks).To(ConsistOf("some-buildpack"))
   508  			// 		Expect(settings.Command).To(Equal(types.FilteredString{IsSet: true, Value: "echo foo bar baz"}))
   509  			// 		Expect(settings.DiskQuota).To(Equal(uint64(1024)))
   510  			// 		Expect(settings.HealthCheckTimeout).To(Equal(14))
   511  			// 		Expect(settings.HealthCheckType).To(Equal(constant.HTTP))
   512  			// 		Expect(settings.Instances).To(Equal(types.NullInt{Value: 12, IsSet: true}))
   513  			// 		Expect(settings.Memory).To(Equal(uint64(100)))
   514  			// 		Expect(settings.StackName).To(Equal("some-stack"))
   515  			// 	})
   516  			// })
   517  
   518  			// Context("route related flags", func() {
   519  			// 	When("given customed route settings", func() {
   520  			// 		BeforeEach(func() {
   521  			// 			cmd.Domain = "some-domain"
   522  			// 		})
   523  
   524  			// 		It("sets NoHostname on the command line settings", func() {
   525  			// 			Expect(settings.DefaultRouteDomain).To(Equal("some-domain"))
   526  			// 		})
   527  			// 	})
   528  
   529  			// 	When("--hostname is given", func() {
   530  			// 		BeforeEach(func() {
   531  			// 			cmd.Hostname = "some-hostname"
   532  			// 		})
   533  
   534  			// 		It("sets DefaultRouteHostname on the command line settings", func() {
   535  			// 			Expect(settings.DefaultRouteHostname).To(Equal("some-hostname"))
   536  			// 		})
   537  			// 	})
   538  
   539  			// 	When("--no-hostname is given", func() {
   540  			// 		BeforeEach(func() {
   541  			// 			cmd.NoHostname = true
   542  			// 		})
   543  
   544  			// 		It("sets NoHostname on the command line settings", func() {
   545  			// 			Expect(settings.NoHostname).To(BeTrue())
   546  			// 		})
   547  			// 	})
   548  
   549  			// 	When("--random-route is given", func() {
   550  			// 		BeforeEach(func() {
   551  			// 			cmd.RandomRoute = true
   552  			// 		})
   553  
   554  			// 		It("sets --random-route on the command line settings", func() {
   555  			// 			Expect(commandLineSettingsErr).ToNot(HaveOccurred())
   556  			// 			Expect(settings.RandomRoute).To(BeTrue())
   557  			// 		})
   558  			// 	})
   559  
   560  			// 	When("--route-path is given", func() {
   561  			// 		BeforeEach(func() {
   562  			// 			cmd.RoutePath = flag.RoutePath{Path: "/some-path"}
   563  			// 		})
   564  
   565  			// 		It("sets --route-path on the command line settings", func() {
   566  			// 			Expect(commandLineSettingsErr).ToNot(HaveOccurred())
   567  			// 			Expect(settings.RoutePath).To(Equal("/some-path"))
   568  			// 		})
   569  			// 	})
   570  
   571  			// 	When("--no-route is given", func() {
   572  			// 		BeforeEach(func() {
   573  			// 			cmd.NoRoute = true
   574  			// 		})
   575  
   576  			// 		It("sets NoRoute on the command line settings", func() {
   577  			// 			Expect(settings.NoRoute).To(BeTrue())
   578  			// 		})
   579  			// 	})
   580  			// })
   581  
   582  			Context("app bits", func() {
   583  				When("-p flag is given", func() {
   584  					BeforeEach(func() {
   585  						cmd.AppPath = "some-directory-path"
   586  					})
   587  
   588  					It("sets ProvidedAppPath", func() {
   589  						Expect(settings.ProvidedAppPath).To(Equal("some-directory-path"))
   590  					})
   591  				})
   592  
   593  				It("sets the current directory in the command config", func() {
   594  					pwd, err := os.Getwd()
   595  					Expect(err).ToNot(HaveOccurred())
   596  					Expect(settings.CurrentDirectory).To(Equal(pwd))
   597  				})
   598  
   599  				// When("the -o flag is given", func() {
   600  				// 	BeforeEach(func() {
   601  				// 		cmd.DockerImage.Path = "some-docker-image-path"
   602  				// 	})
   603  
   604  				// 	It("creates command line setting from command line arguments", func() {
   605  				// 		Expect(settings.DockerImage).To(Equal("some-docker-image-path"))
   606  				// 	})
   607  
   608  				// 	Context("--docker-username flags is given", func() {
   609  				// 		BeforeEach(func() {
   610  				// 			cmd.DockerUsername = "some-docker-username"
   611  				// 		})
   612  
   613  				// 		Context("the docker password environment variable is set", func() {
   614  				// 			BeforeEach(func() {
   615  				// 				fakeConfig.DockerPasswordReturns("some-docker-password")
   616  				// 			})
   617  
   618  				// 			It("creates command line setting from command line arguments and config", func() {
   619  				// 				Expect(testUI.Out).To(Say("Using docker repository password from environment variable CF_DOCKER_PASSWORD."))
   620  
   621  				// 				Expect(settings.Name).To(Equal(appName))
   622  				// 				Expect(settings.DockerImage).To(Equal("some-docker-image-path"))
   623  				// 				Expect(settings.DockerUsername).To(Equal("some-docker-username"))
   624  				// 				Expect(settings.DockerPassword).To(Equal("some-docker-password"))
   625  				// 			})
   626  				// 		})
   627  
   628  				// 		Context("the docker password environment variable is *not* set", func() {
   629  				// 			BeforeEach(func() {
   630  				// 				input.Write([]byte("some-docker-password\n"))
   631  				// 			})
   632  
   633  				// 			It("prompts the user for a password", func() {
   634  				// 				Expect(testUI.Out).To(Say("Environment variable CF_DOCKER_PASSWORD not set."))
   635  				// 				Expect(testUI.Out).To(Say("Docker password"))
   636  
   637  				// 				Expect(settings.Name).To(Equal(appName))
   638  				// 				Expect(settings.DockerImage).To(Equal("some-docker-image-path"))
   639  				// 				Expect(settings.DockerUsername).To(Equal("some-docker-username"))
   640  				// 				Expect(settings.DockerPassword).To(Equal("some-docker-password"))
   641  				// 			})
   642  				// 		})
   643  				// 	})
   644  				// })
   645  			})
   646  		})
   647  
   648  		// DescribeTable("validation errors when flags are passed",
   649  		// 	func(setup func(), expectedErr error) {
   650  		// 		setup()
   651  		// 		_, commandLineSettingsErr := cmd.GetCommandLineSettings()
   652  		// 		Expect(commandLineSettingsErr).To(MatchError(expectedErr))
   653  		// 	},
   654  
   655  		// 	Entry("--droplet and --docker-username",
   656  		// 		func() {
   657  		// 			cmd.DropletPath = "some-droplet-path"
   658  		// 			cmd.DockerUsername = "some-docker-username"
   659  		// 		},
   660  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--droplet", "--docker-username", "-p"}}),
   661  
   662  		// 	Entry("--droplet and --docker-image",
   663  		// 		func() {
   664  		// 			cmd.DropletPath = "some-droplet-path"
   665  		// 			cmd.DockerImage.Path = "some-docker-image"
   666  		// 		},
   667  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--droplet", "--docker-image", "-o"}}),
   668  
   669  		// 	Entry("--droplet and -p",
   670  		// 		func() {
   671  		// 			cmd.DropletPath = "some-droplet-path"
   672  		// 			cmd.AppPath = "some-directory-path"
   673  		// 		},
   674  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--droplet", "-p"}}),
   675  
   676  		// 	Entry("-o and -p",
   677  		// 		func() {
   678  		// 			cmd.DockerImage.Path = "some-docker-image"
   679  		// 			cmd.AppPath = "some-directory-path"
   680  		// 		},
   681  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--docker-image, -o", "-p"}}),
   682  
   683  		// 	Entry("-b and --docker-image",
   684  		// 		func() {
   685  		// 			cmd.DockerImage.Path = "some-docker-image"
   686  		// 			cmd.Buildpacks = []string{"some-buildpack"}
   687  		// 		},
   688  		// 		translatableerror.ArgumentCombinationError{Args: []string{"-b", "--docker-image, -o"}}),
   689  
   690  		// 	Entry("--docker-username (without DOCKER_PASSWORD env set)",
   691  		// 		func() {
   692  		// 			cmd.DockerUsername = "some-docker-username"
   693  		// 		},
   694  		// 		translatableerror.RequiredFlagsError{Arg1: "--docker-image, -o", Arg2: "--docker-username"}),
   695  
   696  		// 	Entry("-d and --no-route",
   697  		// 		func() {
   698  		// 			cmd.Domain = "some-domain"
   699  		// 			cmd.NoRoute = true
   700  		// 		},
   701  		// 		translatableerror.ArgumentCombinationError{Args: []string{"-d", "--no-route"}}),
   702  
   703  		// 	Entry("--hostname and --no-hostname",
   704  		// 		func() {
   705  		// 			cmd.Hostname = "po-tate-toe"
   706  		// 			cmd.NoHostname = true
   707  		// 		},
   708  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--hostname", "-n", "--no-hostname"}}),
   709  
   710  		// 	Entry("--hostname and --no-route",
   711  		// 		func() {
   712  		// 			cmd.Hostname = "po-tate-toe"
   713  		// 			cmd.NoRoute = true
   714  		// 		},
   715  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--hostname", "-n", "--no-route"}}),
   716  
   717  		// 	Entry("--no-hostname and --no-route",
   718  		// 		func() {
   719  		// 			cmd.NoHostname = true
   720  		// 			cmd.NoRoute = true
   721  		// 		},
   722  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--no-hostname", "--no-route"}}),
   723  
   724  		// 	Entry("-f and --no-manifest",
   725  		// 		func() {
   726  		// 			cmd.PathToManifest = "/some/path.yml"
   727  		// 			cmd.NoManifest = true
   728  		// 		},
   729  		// 		translatableerror.ArgumentCombinationError{Args: []string{"-f", "--no-manifest"}}),
   730  
   731  		// 	Entry("--random-route and --hostname",
   732  		// 		func() {
   733  		// 			cmd.Hostname = "po-tate-toe"
   734  		// 			cmd.RandomRoute = true
   735  		// 		},
   736  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--hostname", "-n", "--random-route"}}),
   737  
   738  		// 	Entry("--random-route and --no-hostname",
   739  		// 		func() {
   740  		// 			cmd.RandomRoute = true
   741  		// 			cmd.NoHostname = true
   742  		// 		},
   743  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--no-hostname", "--random-route"}}),
   744  
   745  		// 	Entry("--random-route and --no-route",
   746  		// 		func() {
   747  		// 			cmd.RandomRoute = true
   748  		// 			cmd.NoRoute = true
   749  		// 		},
   750  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--no-route", "--random-route"}}),
   751  
   752  		// 	Entry("--random-route and --route-path",
   753  		// 		func() {
   754  		// 			cmd.RoutePath = flag.RoutePath{Path: "/bananas"}
   755  		// 			cmd.RandomRoute = true
   756  		// 		},
   757  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--random-route", "--route-path"}}),
   758  
   759  		// 	Entry("--route-path and --no-route",
   760  		// 		func() {
   761  		// 			cmd.RoutePath = flag.RoutePath{Path: "/bananas"}
   762  		// 			cmd.NoRoute = true
   763  		// 		},
   764  		// 		translatableerror.ArgumentCombinationError{Args: []string{"--route-path", "--no-route"}}),
   765  		// )
   766  	})
   767  })