github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/push_command_test.go (about) 1 package v7_test 2 3 import ( 4 "context" 5 "errors" 6 "time" 7 8 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/actionerror" 9 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/sharedaction" 10 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/sharedaction/sharedactionfakes" 11 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action" 12 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7pushaction" 13 "github.com/LukasHeimann/cloudfoundrycli/v8/api/cloudcontroller/ccerror" 14 "github.com/LukasHeimann/cloudfoundrycli/v8/api/cloudcontroller/ccv3/constant" 15 "github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes" 16 "github.com/LukasHeimann/cloudfoundrycli/v8/command/flag" 17 "github.com/LukasHeimann/cloudfoundrycli/v8/command/translatableerror" 18 . "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7" 19 "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes" 20 "github.com/LukasHeimann/cloudfoundrycli/v8/resources" 21 "github.com/LukasHeimann/cloudfoundrycli/v8/types" 22 "github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3" 23 "github.com/LukasHeimann/cloudfoundrycli/v8/util/manifestparser" 24 "github.com/LukasHeimann/cloudfoundrycli/v8/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("marsahlling 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 }) 1082 1083 JustBeforeEach(func() { 1084 overrides, overridesErr = cmd.GetFlagOverrides() 1085 Expect(overridesErr).ToNot(HaveOccurred()) 1086 }) 1087 1088 It("sets them on the flag overrides", func() { 1089 Expect(overridesErr).ToNot(HaveOccurred()) 1090 Expect(overrides.Buildpacks).To(ConsistOf("buildpack-1", "buildpack-2")) 1091 Expect(overrides.DropletPath).To(Equal("some-droplet.tgz")) 1092 Expect(overrides.Stack).To(Equal("validStack")) 1093 Expect(overrides.HealthCheckType).To(Equal(constant.Port)) 1094 Expect(overrides.HealthCheckEndpoint).To(Equal("/health-check-http-endpoint")) 1095 Expect(overrides.HealthCheckTimeout).To(BeEquivalentTo(7)) 1096 Expect(overrides.Memory).To(Equal("64M")) 1097 Expect(overrides.Disk).To(Equal("256M")) 1098 Expect(overrides.StartCommand).To(Equal(types.FilteredString{IsSet: true, Value: "some-start-command"})) 1099 Expect(overrides.NoRoute).To(BeTrue()) 1100 Expect(overrides.NoStart).To(BeTrue()) 1101 Expect(overrides.NoWait).To(BeTrue()) 1102 Expect(overrides.RandomRoute).To(BeFalse()) 1103 Expect(overrides.Strategy).To(Equal(constant.DeploymentStrategyRolling)) 1104 Expect(overrides.Instances).To(Equal(types.NullInt{Value: 10, IsSet: true})) 1105 Expect(overrides.ManifestPath).To(Equal("/manifest/path")) 1106 Expect(overrides.PathsToVarsFiles).To(Equal([]string{"/vars1", "/vars2"})) 1107 Expect(overrides.Vars).To(Equal([]template.VarKV{{Name: "key", Value: "val"}})) 1108 Expect(overrides.Task).To(BeTrue()) 1109 }) 1110 1111 When("a docker image is provided", func() { 1112 BeforeEach(func() { 1113 cmd.DockerImage = flag.DockerImage{Path: "some-docker-image"} 1114 }) 1115 1116 It("sets docker image on the flag overrides", func() { 1117 Expect(overridesErr).ToNot(HaveOccurred()) 1118 Expect(overrides.DockerImage).To(Equal("some-docker-image")) 1119 }) 1120 }) 1121 }) 1122 1123 DescribeTable("ValidateFlags returns an error", 1124 func(setup func(), expectedErr error) { 1125 setup() 1126 err := cmd.ValidateFlags() 1127 if expectedErr == nil { 1128 Expect(err).To(BeNil()) 1129 } else { 1130 Expect(err).To(MatchError(expectedErr)) 1131 } 1132 }, 1133 1134 Entry("when docker username flag is passed *without* docker flag", 1135 func() { 1136 cmd.DockerUsername = "some-docker-username" 1137 }, 1138 translatableerror.RequiredFlagsError{Arg1: "--docker-image, -o", Arg2: "--docker-username"}), 1139 1140 Entry("when docker and buildpacks flags are passed", 1141 func() { 1142 cmd.DockerImage.Path = "some-docker-image" 1143 cmd.Buildpacks = []string{"some-buildpack"} 1144 }, 1145 translatableerror.ArgumentCombinationError{Args: []string{"--buildpack, -b", "--docker-image, -o"}}), 1146 1147 Entry("when docker and stack flags are passed", 1148 func() { 1149 cmd.DockerImage.Path = "some-docker-image" 1150 cmd.Stack = "validStack" 1151 }, 1152 translatableerror.ArgumentCombinationError{Args: []string{"--stack, -s", "--docker-image, -o"}}), 1153 1154 Entry("when docker and path flags are passed", 1155 func() { 1156 cmd.DockerImage.Path = "some-docker-image" 1157 cmd.AppPath = "some-directory-path" 1158 }, 1159 translatableerror.ArgumentCombinationError{Args: []string{"--docker-image, -o", "--path, -p"}}), 1160 1161 Entry("when -u http does not have a matching --endpoint", 1162 func() { 1163 cmd.HealthCheckType.Type = constant.HTTP 1164 }, 1165 translatableerror.RequiredFlagsError{Arg1: "--endpoint", Arg2: "--health-check-type=http, -u=http"}), 1166 1167 Entry("when -u http does have a matching --endpoint", 1168 func() { 1169 cmd.HealthCheckType.Type = constant.HTTP 1170 cmd.HealthCheckHTTPEndpoint = "/health" 1171 }, 1172 nil), 1173 1174 Entry("when droplet and path flags are passed", 1175 func() { 1176 cmd.DropletPath = "some-droplet.tgz" 1177 cmd.AppPath = "/my/app" 1178 }, 1179 translatableerror.ArgumentCombinationError{ 1180 Args: []string{ 1181 "--droplet", "--docker-image, -o", "--docker-username", "-p", 1182 }, 1183 }), 1184 1185 Entry("when droplet and docker image flags are passed", 1186 func() { 1187 cmd.DropletPath = "some-droplet.tgz" 1188 cmd.DockerImage.Path = "docker-image" 1189 }, 1190 translatableerror.ArgumentCombinationError{ 1191 Args: []string{ 1192 "--droplet", "--docker-image, -o", "--docker-username", "-p", 1193 }, 1194 }), 1195 1196 Entry("when droplet, docker image, and docker username flags are passed", 1197 func() { 1198 cmd.DropletPath = "some-droplet.tgz" 1199 cmd.DockerImage.Path = "docker-image" 1200 cmd.DockerUsername = "docker-username" 1201 }, 1202 translatableerror.ArgumentCombinationError{ 1203 Args: []string{ 1204 "--droplet", "--docker-image, -o", "--docker-username", "-p", 1205 }, 1206 }), 1207 1208 Entry("when strategy 'rolling' and no-start flags are passed", 1209 func() { 1210 cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyRolling} 1211 cmd.NoStart = true 1212 }, 1213 translatableerror.ArgumentCombinationError{ 1214 Args: []string{ 1215 "--no-start", "--strategy=rolling", 1216 }, 1217 }), 1218 1219 Entry("when strategy is not set and no-start flags are passed", 1220 func() { 1221 cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyDefault} 1222 cmd.NoStart = true 1223 }, 1224 nil), 1225 1226 Entry("when no-start and no-wait flags are passed", 1227 func() { 1228 cmd.NoStart = true 1229 cmd.NoWait = true 1230 }, 1231 translatableerror.ArgumentCombinationError{ 1232 Args: []string{ 1233 "--no-start", "--no-wait", 1234 }, 1235 }), 1236 Entry("when no-route and random-route flags are passed", 1237 func() { 1238 cmd.NoRoute = true 1239 cmd.RandomRoute = true 1240 }, 1241 translatableerror.ArgumentCombinationError{ 1242 Args: []string{ 1243 "--no-route", "--random-route", 1244 }, 1245 }), 1246 1247 Entry("default is combined with non default buildpacks", 1248 func() { 1249 cmd.Buildpacks = []string{"some-docker-username", "default"} 1250 }, 1251 translatableerror.InvalidBuildpacksError{}), 1252 1253 Entry("default is combined with non default buildpacks", 1254 func() { 1255 cmd.Buildpacks = []string{"some-docker-username", "null"} 1256 }, 1257 translatableerror.InvalidBuildpacksError{}), 1258 1259 Entry("task and strategy flags are passed", 1260 func() { 1261 cmd.Task = true 1262 cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyRolling} 1263 }, 1264 translatableerror.ArgumentCombinationError{ 1265 Args: []string{ 1266 "--task", "--strategy=rolling", 1267 }, 1268 }), 1269 ) 1270 })