github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/actor/pushaction/resource_test.go (about) 1 package pushaction_test 2 3 import ( 4 "errors" 5 "io" 6 "io/ioutil" 7 "os" 8 "strings" 9 10 . "code.cloudfoundry.org/cli/actor/pushaction" 11 "code.cloudfoundry.org/cli/actor/pushaction/pushactionfakes" 12 "code.cloudfoundry.org/cli/actor/v2action" 13 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("Resources", func() { 19 var ( 20 actor *Actor 21 fakeV2Actor *pushactionfakes.FakeV2Actor 22 fakeSharedActor *pushactionfakes.FakeSharedActor 23 ) 24 25 BeforeEach(func() { 26 fakeV2Actor = new(pushactionfakes.FakeV2Actor) 27 fakeSharedActor = new(pushactionfakes.FakeSharedActor) 28 actor = NewActor(fakeV2Actor, nil, fakeSharedActor) 29 }) 30 31 Describe("CreateArchive", func() { 32 var ( 33 config ApplicationConfig 34 35 archivePath string 36 executeErr error 37 38 resourcesToArchive []v2action.Resource 39 ) 40 41 BeforeEach(func() { 42 config = ApplicationConfig{ 43 Path: "some-path", 44 DesiredApplication: Application{ 45 Application: v2action.Application{ 46 GUID: "some-app-guid", 47 }}, 48 } 49 50 resourcesToArchive = []v2action.Resource{{Filename: "file1"}, {Filename: "file2"}} 51 config.UnmatchedResources = resourcesToArchive 52 }) 53 54 JustBeforeEach(func() { 55 archivePath, executeErr = actor.CreateArchive(config) 56 }) 57 58 Context("when the source is an archive", func() { 59 BeforeEach(func() { 60 config.Archive = true 61 }) 62 63 Context("when the zipping is successful", func() { 64 var fakeArchivePath string 65 66 BeforeEach(func() { 67 fakeArchivePath = "some-archive-path" 68 fakeSharedActor.ZipArchiveResourcesReturns(fakeArchivePath, nil) 69 }) 70 71 It("returns the path to the zip", func() { 72 Expect(executeErr).ToNot(HaveOccurred()) 73 Expect(archivePath).To(Equal(fakeArchivePath)) 74 75 Expect(fakeSharedActor.ZipArchiveResourcesCallCount()).To(Equal(1)) 76 sourceDir, passedResources := fakeSharedActor.ZipArchiveResourcesArgsForCall(0) 77 Expect(sourceDir).To(Equal("some-path")) 78 sharedResourcesToArchive := actor.ConvertV2ResourcesToSharedResources(resourcesToArchive) 79 Expect(passedResources).To(Equal(sharedResourcesToArchive)) 80 81 }) 82 }) 83 84 Context("when creating the archive errors", func() { 85 var expectedErr error 86 87 BeforeEach(func() { 88 expectedErr = errors.New("oh no") 89 fakeSharedActor.ZipArchiveResourcesReturns("", expectedErr) 90 }) 91 92 It("sends errors and returns true", func() { 93 Expect(executeErr).To(MatchError(expectedErr)) 94 }) 95 }) 96 }) 97 98 Context("when the source is a directory", func() { 99 Context("when the zipping is successful", func() { 100 var fakeArchivePath string 101 BeforeEach(func() { 102 fakeArchivePath = "some-archive-path" 103 fakeSharedActor.ZipDirectoryResourcesReturns(fakeArchivePath, nil) 104 }) 105 106 It("returns the path to the zip", func() { 107 Expect(executeErr).ToNot(HaveOccurred()) 108 Expect(archivePath).To(Equal(fakeArchivePath)) 109 110 Expect(fakeSharedActor.ZipDirectoryResourcesCallCount()).To(Equal(1)) 111 sourceDir, passedResources := fakeSharedActor.ZipDirectoryResourcesArgsForCall(0) 112 Expect(sourceDir).To(Equal("some-path")) 113 sharedResourcesToArchive := actor.ConvertV2ResourcesToSharedResources(resourcesToArchive) 114 Expect(passedResources).To(Equal(sharedResourcesToArchive)) 115 }) 116 }) 117 118 Context("when creating the archive errors", func() { 119 var expectedErr error 120 121 BeforeEach(func() { 122 expectedErr = errors.New("oh no") 123 fakeSharedActor.ZipDirectoryResourcesReturns("", expectedErr) 124 }) 125 126 It("sends errors and returns true", func() { 127 Expect(executeErr).To(MatchError(expectedErr)) 128 }) 129 }) 130 }) 131 }) 132 133 Describe("SetMatchedResources", func() { 134 var ( 135 inputConfig ApplicationConfig 136 outputConfig ApplicationConfig 137 warnings Warnings 138 ) 139 JustBeforeEach(func() { 140 outputConfig, warnings = actor.SetMatchedResources(inputConfig) 141 }) 142 143 BeforeEach(func() { 144 inputConfig.AllResources = []v2action.Resource{ 145 {Filename: "file-1"}, 146 {Filename: "file-2"}, 147 } 148 }) 149 150 Context("when the resource matching is successful", func() { 151 BeforeEach(func() { 152 fakeV2Actor.ResourceMatchReturns( 153 []v2action.Resource{{Filename: "file-1"}}, 154 []v2action.Resource{{Filename: "file-2"}}, 155 v2action.Warnings{"warning-1"}, 156 nil, 157 ) 158 }) 159 160 It("sets the matched and unmatched resources", func() { 161 Expect(outputConfig.MatchedResources).To(ConsistOf(v2action.Resource{Filename: "file-1"})) 162 Expect(outputConfig.UnmatchedResources).To(ConsistOf(v2action.Resource{Filename: "file-2"})) 163 164 Expect(warnings).To(ConsistOf("warning-1")) 165 }) 166 }) 167 168 Context("when resource matching returns an error", func() { 169 BeforeEach(func() { 170 fakeV2Actor.ResourceMatchReturns(nil, nil, v2action.Warnings{"warning-1"}, errors.New("some-error")) 171 }) 172 173 It("sets the unmatched resources to AllResources", func() { 174 Expect(outputConfig.UnmatchedResources).To(Equal(inputConfig.AllResources)) 175 176 Expect(warnings).To(ConsistOf("warning-1")) 177 }) 178 }) 179 }) 180 181 Describe("UploadPackage", func() { 182 var ( 183 config ApplicationConfig 184 185 warnings Warnings 186 executeErr error 187 188 resources []v2action.Resource 189 ) 190 191 BeforeEach(func() { 192 resources = []v2action.Resource{ 193 {Filename: "file-1"}, 194 {Filename: "file-2"}, 195 } 196 197 config = ApplicationConfig{ 198 DesiredApplication: Application{ 199 Application: v2action.Application{ 200 GUID: "some-app-guid", 201 }}, 202 MatchedResources: resources, 203 } 204 }) 205 206 JustBeforeEach(func() { 207 warnings, executeErr = actor.UploadPackage(config) 208 }) 209 210 Context("when the upload is successful", func() { 211 var uploadJob v2action.Job 212 213 BeforeEach(func() { 214 uploadJob.GUID = "some-job-guid" 215 fakeV2Actor.UploadApplicationPackageReturns(uploadJob, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, nil) 216 }) 217 218 Context("when polling is successful", func() { 219 BeforeEach(func() { 220 fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, nil) 221 }) 222 223 It("uploads the existing resources", func() { 224 Expect(executeErr).ToNot(HaveOccurred()) 225 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2")) 226 227 Expect(fakeV2Actor.UploadApplicationPackageCallCount()).To(Equal(1)) 228 appGUID, existingResources, reader, newResourcesLength := fakeV2Actor.UploadApplicationPackageArgsForCall(0) 229 Expect(appGUID).To(Equal("some-app-guid")) 230 Expect(existingResources).To(Equal(resources)) 231 Expect(reader).To(BeNil()) 232 Expect(newResourcesLength).To(BeNumerically("==", 0)) 233 234 Expect(fakeV2Actor.PollJobCallCount()).To(Equal(1)) 235 Expect(fakeV2Actor.PollJobArgsForCall(0)).To(Equal(uploadJob)) 236 }) 237 }) 238 239 Context("when the polling fails", func() { 240 var expectedErr error 241 242 BeforeEach(func() { 243 expectedErr = errors.New("I can't let you do that starfox") 244 fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, expectedErr) 245 }) 246 247 It("returns the warnings", func() { 248 Expect(executeErr).To(MatchError(expectedErr)) 249 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2")) 250 }) 251 }) 252 }) 253 254 Context("when the upload errors", func() { 255 var expectedErr error 256 257 BeforeEach(func() { 258 expectedErr = errors.New("I can't let you do that starfox") 259 fakeV2Actor.UploadApplicationPackageReturns(v2action.Job{}, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, expectedErr) 260 }) 261 262 It("returns the error and warnings", func() { 263 Expect(executeErr).To(MatchError(expectedErr)) 264 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2")) 265 }) 266 }) 267 }) 268 269 Describe("UploadPackageWithArchive", func() { 270 var ( 271 config ApplicationConfig 272 archivePath string 273 fakeProgressBar *pushactionfakes.FakeProgressBar 274 eventStream chan Event 275 276 warnings Warnings 277 executeErr error 278 279 resources []v2action.Resource 280 ) 281 282 BeforeEach(func() { 283 resources = []v2action.Resource{ 284 {Filename: "file-1"}, 285 {Filename: "file-2"}, 286 } 287 288 config = ApplicationConfig{ 289 DesiredApplication: Application{ 290 Application: v2action.Application{ 291 GUID: "some-app-guid", 292 }}, 293 MatchedResources: resources, 294 } 295 fakeProgressBar = new(pushactionfakes.FakeProgressBar) 296 eventStream = make(chan Event) 297 }) 298 299 AfterEach(func() { 300 close(eventStream) 301 }) 302 303 JustBeforeEach(func() { 304 warnings, executeErr = actor.UploadPackageWithArchive(config, archivePath, fakeProgressBar, eventStream) 305 }) 306 307 Context("when the archive can be accessed properly", func() { 308 BeforeEach(func() { 309 tmpfile, err := ioutil.TempFile("", "fake-archive") 310 Expect(err).ToNot(HaveOccurred()) 311 _, err = tmpfile.Write([]byte("123456")) 312 Expect(err).ToNot(HaveOccurred()) 313 Expect(tmpfile.Close()).ToNot(HaveOccurred()) 314 315 archivePath = tmpfile.Name() 316 }) 317 318 AfterEach(func() { 319 Expect(os.Remove(archivePath)).ToNot(HaveOccurred()) 320 }) 321 322 Context("when the upload is successful", func() { 323 var ( 324 progressBarReader io.Reader 325 uploadJob v2action.Job 326 ) 327 328 BeforeEach(func() { 329 uploadJob.GUID = "some-job-guid" 330 fakeV2Actor.UploadApplicationPackageReturns(uploadJob, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, nil) 331 332 progressBarReader = strings.NewReader("123456") 333 fakeProgressBar.NewProgressBarWrapperReturns(progressBarReader) 334 335 go func() { 336 defer GinkgoRecover() 337 338 Eventually(eventStream).Should(Receive(Equal(UploadingApplicationWithArchive))) 339 Eventually(eventStream).Should(Receive(Equal(UploadWithArchiveComplete))) 340 }() 341 }) 342 343 Context("when the polling is successful", func() { 344 BeforeEach(func() { 345 fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, nil) 346 }) 347 348 It("returns the warnings", func() { 349 Expect(executeErr).ToNot(HaveOccurred()) 350 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2")) 351 352 Expect(fakeV2Actor.UploadApplicationPackageCallCount()).To(Equal(1)) 353 appGUID, existingResources, _, newResourcesLength := fakeV2Actor.UploadApplicationPackageArgsForCall(0) 354 Expect(appGUID).To(Equal("some-app-guid")) 355 Expect(existingResources).To(Equal(resources)) 356 Expect(newResourcesLength).To(BeNumerically("==", 6)) 357 358 Expect(fakeV2Actor.PollJobCallCount()).To(Equal(1)) 359 Expect(fakeV2Actor.PollJobArgsForCall(0)).To(Equal(uploadJob)) 360 }) 361 362 It("passes the file reader to the progress bar", func() { 363 Expect(executeErr).ToNot(HaveOccurred()) 364 365 Expect(fakeProgressBar.NewProgressBarWrapperCallCount()).To(Equal(1)) 366 _, size := fakeProgressBar.NewProgressBarWrapperArgsForCall(0) 367 Expect(size).To(BeNumerically("==", 6)) 368 }) 369 }) 370 371 Context("when the polling fails", func() { 372 var expectedErr error 373 374 BeforeEach(func() { 375 expectedErr = errors.New("I can't let you do that starfox") 376 fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, expectedErr) 377 }) 378 379 It("returns the warnings", func() { 380 Expect(executeErr).To(MatchError(expectedErr)) 381 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2")) 382 }) 383 }) 384 }) 385 386 Context("when the upload errors", func() { 387 var ( 388 expectedErr error 389 done chan bool 390 ) 391 392 BeforeEach(func() { 393 expectedErr = errors.New("I can't let you do that starfox") 394 fakeV2Actor.UploadApplicationPackageReturns(v2action.Job{}, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, expectedErr) 395 396 done = make(chan bool) 397 398 go func() { 399 defer GinkgoRecover() 400 401 Eventually(eventStream).Should(Receive(Equal(UploadingApplicationWithArchive))) 402 Consistently(eventStream).ShouldNot(Receive()) 403 done <- true 404 }() 405 }) 406 407 AfterEach(func() { 408 close(done) 409 }) 410 411 It("returns the error and warnings", func() { 412 Eventually(done).Should(Receive()) 413 Expect(executeErr).To(MatchError(expectedErr)) 414 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2")) 415 }) 416 }) 417 }) 418 419 Context("when the archive returns any access errors", func() { 420 It("returns the error", func() { 421 _, ok := executeErr.(*os.PathError) 422 Expect(ok).To(BeTrue()) 423 }) 424 }) 425 }) 426 427 Describe("UploadDroplet", func() { 428 var ( 429 config ApplicationConfig 430 dropletPath string 431 fakeProgressBar *pushactionfakes.FakeProgressBar 432 eventStream chan Event 433 434 warnings Warnings 435 executeErr error 436 ) 437 438 BeforeEach(func() { 439 config = ApplicationConfig{ 440 DesiredApplication: Application{ 441 Application: v2action.Application{ 442 GUID: "some-app-guid", 443 }}, 444 } 445 fakeProgressBar = new(pushactionfakes.FakeProgressBar) 446 eventStream = make(chan Event) 447 }) 448 449 AfterEach(func() { 450 close(eventStream) 451 }) 452 453 JustBeforeEach(func() { 454 warnings, executeErr = actor.UploadDroplet(config, dropletPath, fakeProgressBar, eventStream) 455 }) 456 457 Context("when the droplet can be accessed properly", func() { 458 BeforeEach(func() { 459 tmpfile, err := ioutil.TempFile("", "fake-droplet") 460 Expect(err).ToNot(HaveOccurred()) 461 _, err = tmpfile.Write([]byte("123456")) 462 Expect(err).ToNot(HaveOccurred()) 463 Expect(tmpfile.Close()).ToNot(HaveOccurred()) 464 465 dropletPath = tmpfile.Name() 466 }) 467 468 AfterEach(func() { 469 Expect(os.RemoveAll(dropletPath)).ToNot(HaveOccurred()) 470 }) 471 472 Context("when the upload is successful", func() { 473 var ( 474 progressBarReader io.Reader 475 uploadJob v2action.Job 476 ) 477 478 BeforeEach(func() { 479 uploadJob.GUID = "some-job-guid" 480 fakeV2Actor.UploadDropletReturns(uploadJob, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, nil) 481 482 progressBarReader = strings.NewReader("123456") 483 fakeProgressBar.NewProgressBarWrapperReturns(progressBarReader) 484 485 go func() { 486 defer GinkgoRecover() 487 488 Eventually(eventStream).Should(Receive(Equal(UploadDropletComplete))) 489 }() 490 }) 491 492 Context("when the polling is successful", func() { 493 BeforeEach(func() { 494 fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, nil) 495 }) 496 497 It("returns the warnings", func() { 498 Expect(executeErr).ToNot(HaveOccurred()) 499 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2")) 500 501 Expect(fakeV2Actor.UploadDropletCallCount()).To(Equal(1)) 502 appGUID, _, dropletLength := fakeV2Actor.UploadDropletArgsForCall(0) 503 Expect(appGUID).To(Equal("some-app-guid")) 504 Expect(dropletLength).To(BeNumerically("==", 6)) 505 506 Expect(fakeV2Actor.PollJobCallCount()).To(Equal(1)) 507 Expect(fakeV2Actor.PollJobArgsForCall(0)).To(Equal(uploadJob)) 508 }) 509 510 It("passes the file reader to the progress bar", func() { 511 Expect(executeErr).ToNot(HaveOccurred()) 512 513 Expect(fakeProgressBar.NewProgressBarWrapperCallCount()).To(Equal(1)) 514 _, size := fakeProgressBar.NewProgressBarWrapperArgsForCall(0) 515 Expect(size).To(BeNumerically("==", 6)) 516 }) 517 }) 518 519 Context("when the polling fails", func() { 520 var expectedErr error 521 522 BeforeEach(func() { 523 expectedErr = errors.New("I can't let you do that starfox") 524 fakeV2Actor.PollJobReturns(v2action.Warnings{"poll-warning-1", "poll-warning-2"}, expectedErr) 525 }) 526 527 It("returns the warnings", func() { 528 Expect(executeErr).To(MatchError(expectedErr)) 529 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2", "poll-warning-1", "poll-warning-2")) 530 }) 531 }) 532 }) 533 534 Context("when the upload errors", func() { 535 var ( 536 expectedErr error 537 done chan bool 538 ) 539 540 BeforeEach(func() { 541 expectedErr = errors.New("I can't let you do that starfox") 542 fakeV2Actor.UploadDropletReturns(v2action.Job{}, v2action.Warnings{"upload-warning-1", "upload-warning-2"}, expectedErr) 543 544 done = make(chan bool) 545 546 go func() { 547 defer GinkgoRecover() 548 549 Consistently(eventStream).ShouldNot(Receive(Equal(UploadDropletComplete))) 550 done <- true 551 }() 552 }) 553 554 AfterEach(func() { 555 close(done) 556 }) 557 558 It("returns the error and warnings", func() { 559 Eventually(done).Should(Receive()) 560 Expect(executeErr).To(MatchError(expectedErr)) 561 Expect(warnings).To(ConsistOf("upload-warning-1", "upload-warning-2")) 562 }) 563 }) 564 }) 565 }) 566 })