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