github.com/arunkumar7540/cli@v6.45.0+incompatible/actor/v7pushaction/create_bits_package_for_application_test.go (about) 1 package v7pushaction_test 2 3 import ( 4 "errors" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 "code.cloudfoundry.org/cli/actor/sharedaction" 8 "code.cloudfoundry.org/cli/actor/v7action" 9 . "code.cloudfoundry.org/cli/actor/v7pushaction" 10 "code.cloudfoundry.org/cli/actor/v7pushaction/v7pushactionfakes" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 ) 15 16 var _ = Describe("CreateBitsPackageForApplication", func() { 17 var ( 18 actor *Actor 19 fakeV7Actor *v7pushactionfakes.FakeV7Actor 20 fakeSharedActor *v7pushactionfakes.FakeSharedActor 21 22 returnedPushPlan PushPlan 23 paramPlan PushPlan 24 fakeProgressBar *v7pushactionfakes.FakeProgressBar 25 26 warnings Warnings 27 executeErr error 28 29 events []Event 30 ) 31 32 BeforeEach(func() { 33 actor, _, fakeV7Actor, fakeSharedActor = getTestPushActor() 34 35 fakeProgressBar = new(v7pushactionfakes.FakeProgressBar) 36 37 fakeSharedActor.ReadArchiveReturns(new(v7pushactionfakes.FakeReadCloser), 0, nil) 38 39 paramPlan = PushPlan{ 40 Application: v7action.Application{ 41 GUID: "some-app-guid", 42 }, 43 DockerImageCredentialsNeedsUpdate: false, 44 } 45 }) 46 47 JustBeforeEach(func() { 48 events = EventFollower(func(eventStream chan<- Event) { 49 returnedPushPlan, warnings, executeErr = actor.CreateBitsPackageForApplication(paramPlan, eventStream, fakeProgressBar) 50 }) 51 }) 52 53 Describe("package upload", func() { 54 When("resource match errors ", func() { 55 BeforeEach(func() { 56 fakeV7Actor.ResourceMatchReturns( 57 nil, 58 v7action.Warnings{"some-resource-match-warning"}, 59 errors.New("resource-match-error")) 60 }) 61 62 It("raises the error", func() { 63 Expect(executeErr).To(MatchError("resource-match-error")) 64 Expect(events).To(ConsistOf(ResourceMatching)) 65 Expect(warnings).To(ConsistOf("some-resource-match-warning")) 66 }) 67 }) 68 69 When("resource match is successful", func() { 70 var ( 71 matches []sharedaction.V3Resource 72 unmatches []sharedaction.V3Resource 73 ) 74 75 When("there are unmatched resources", func() { 76 BeforeEach(func() { 77 matches = []sharedaction.V3Resource{ 78 buildV3Resource("some-matching-filename"), 79 } 80 81 unmatches = []sharedaction.V3Resource{ 82 buildV3Resource("some-unmatching-filename"), 83 } 84 85 paramPlan = PushPlan{ 86 Application: v7action.Application{ 87 Name: "some-app", 88 GUID: "some-app-guid", 89 }, 90 BitsPath: "/some-bits-path", 91 AllResources: append( 92 matches, 93 unmatches..., 94 ), 95 } 96 97 fakeV7Actor.ResourceMatchReturns( 98 matches, 99 v7action.Warnings{"some-good-good-resource-match-warnings"}, 100 nil, 101 ) 102 }) 103 104 When("the bits path is an archive", func() { 105 BeforeEach(func() { 106 paramPlan.Archive = true 107 }) 108 109 It("creates the archive with the unmatched resources", func() { 110 Expect(fakeSharedActor.ZipArchiveResourcesCallCount()).To(Equal(1)) 111 bitsPath, resources := fakeSharedActor.ZipArchiveResourcesArgsForCall(0) 112 Expect(bitsPath).To(Equal("/some-bits-path")) 113 Expect(resources).To(HaveLen(1)) 114 Expect(resources[0].ToV3Resource()).To(Equal(unmatches[0])) 115 }) 116 }) 117 118 When("The bits path is a directory", func() { 119 It("creates the archive", func() { 120 Expect(fakeSharedActor.ZipDirectoryResourcesCallCount()).To(Equal(1)) 121 bitsPath, resources := fakeSharedActor.ZipDirectoryResourcesArgsForCall(0) 122 Expect(bitsPath).To(Equal("/some-bits-path")) 123 Expect(resources).To(HaveLen(1)) 124 Expect(resources[0].ToV3Resource()).To(Equal(unmatches[0])) 125 }) 126 }) 127 128 When("the archive creation is successful", func() { 129 BeforeEach(func() { 130 fakeSharedActor.ZipDirectoryResourcesReturns("/some/archive/path", nil) 131 fakeV7Actor.UpdateApplicationReturns( 132 v7action.Application{ 133 Name: "some-app", 134 GUID: paramPlan.Application.GUID, 135 }, 136 v7action.Warnings{"some-app-update-warnings"}, 137 nil) 138 }) 139 140 It("creates the package", func() { 141 Expect(fakeV7Actor.CreateBitsPackageByApplicationCallCount()).To(Equal(1)) 142 Expect(fakeV7Actor.CreateBitsPackageByApplicationArgsForCall(0)).To(Equal("some-app-guid")) 143 }) 144 145 When("the package creation is successful", func() { 146 BeforeEach(func() { 147 fakeV7Actor.CreateBitsPackageByApplicationReturns(v7action.Package{GUID: "some-guid"}, v7action.Warnings{"some-create-package-warning"}, nil) 148 }) 149 150 It("reads the archive", func() { 151 Expect(fakeSharedActor.ReadArchiveCallCount()).To(Equal(1)) 152 Expect(fakeSharedActor.ReadArchiveArgsForCall(0)).To(Equal("/some/archive/path")) 153 }) 154 155 When("reading the archive is successful", func() { 156 BeforeEach(func() { 157 fakeReadCloser := new(v7pushactionfakes.FakeReadCloser) 158 fakeSharedActor.ReadArchiveReturns(fakeReadCloser, 6, nil) 159 }) 160 161 It("uploads the bits package", func() { 162 Expect(fakeV7Actor.UploadBitsPackageCallCount()).To(Equal(1)) 163 pkg, resource, _, size := fakeV7Actor.UploadBitsPackageArgsForCall(0) 164 165 Expect(pkg).To(Equal(v7action.Package{GUID: "some-guid"})) 166 Expect(resource).To(Equal(matches)) 167 Expect(size).To(BeNumerically("==", 6)) 168 }) 169 170 When("the upload is successful", func() { 171 BeforeEach(func() { 172 fakeV7Actor.UploadBitsPackageReturns(v7action.Package{GUID: "some-guid"}, v7action.Warnings{"some-upload-package-warning"}, nil) 173 }) 174 175 It("returns an upload complete event and warnings", func() { 176 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, CreatingArchive, ReadingArchive, UploadingApplicationWithArchive, UploadWithArchiveComplete)) 177 Expect(warnings).To(ConsistOf("some-good-good-resource-match-warnings", "some-create-package-warning", "some-upload-package-warning")) 178 }) 179 180 When("the upload errors", func() { 181 When("the upload error is a retryable error", func() { 182 var someErr error 183 184 BeforeEach(func() { 185 someErr = errors.New("I AM A BANANA") 186 fakeV7Actor.UploadBitsPackageReturns(v7action.Package{}, v7action.Warnings{"upload-warnings-1", "upload-warnings-2"}, ccerror.PipeSeekError{Err: someErr}) 187 }) 188 189 It("should send a RetryUpload event and retry uploading", func() { 190 Expect(events).To(ConsistOf( 191 ResourceMatching, CreatingPackage, CreatingArchive, 192 ReadingArchive, UploadingApplicationWithArchive, RetryUpload, 193 ReadingArchive, UploadingApplicationWithArchive, RetryUpload, 194 ReadingArchive, UploadingApplicationWithArchive, RetryUpload, 195 )) 196 197 Expect(warnings).To(ConsistOf("some-good-good-resource-match-warnings", "some-create-package-warning", "upload-warnings-1", "upload-warnings-2", "upload-warnings-1", "upload-warnings-2", "upload-warnings-1", "upload-warnings-2")) 198 199 Expect(fakeV7Actor.UploadBitsPackageCallCount()).To(Equal(3)) 200 Expect(executeErr).To(MatchError(actionerror.UploadFailedError{Err: someErr})) 201 }) 202 203 }) 204 205 When("the upload error is not a retryable error", func() { 206 BeforeEach(func() { 207 fakeV7Actor.UploadBitsPackageReturns(v7action.Package{}, v7action.Warnings{"upload-warnings-1", "upload-warnings-2"}, errors.New("dios mio")) 208 }) 209 210 It("sends warnings and errors, then stops", func() { 211 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, CreatingArchive, ReadingArchive, UploadingApplicationWithArchive)) 212 Expect(warnings).To(ConsistOf("some-good-good-resource-match-warnings", "some-create-package-warning", "upload-warnings-1", "upload-warnings-2")) 213 Expect(executeErr).To(MatchError("dios mio")) 214 }) 215 }) 216 }) 217 }) 218 219 When("reading the archive fails", func() { 220 BeforeEach(func() { 221 fakeSharedActor.ReadArchiveReturns(nil, 0, errors.New("the bits")) 222 }) 223 224 It("returns an error", func() { 225 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, CreatingArchive, ReadingArchive)) 226 Expect(executeErr).To(MatchError("the bits")) 227 }) 228 }) 229 }) 230 231 When("the package creation errors", func() { 232 BeforeEach(func() { 233 fakeV7Actor.CreateBitsPackageByApplicationReturns(v7action.Package{}, v7action.Warnings{"package-creation-warning"}, errors.New("the package")) 234 }) 235 236 It("it returns errors and warnings", func() { 237 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage)) 238 239 Expect(warnings).To(ConsistOf("some-good-good-resource-match-warnings", "package-creation-warning")) 240 Expect(executeErr).To(MatchError("the package")) 241 }) 242 }) 243 }) 244 245 When("the archive creation errors", func() { 246 BeforeEach(func() { 247 fakeSharedActor.ZipDirectoryResourcesReturns("", errors.New("oh no")) 248 }) 249 250 It("returns an error and exits", func() { 251 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, CreatingArchive)) 252 Expect(executeErr).To(MatchError("oh no")) 253 }) 254 }) 255 }) 256 }) 257 258 When("All resources are matched", func() { 259 BeforeEach(func() { 260 matches = []sharedaction.V3Resource{ 261 buildV3Resource("some-matching-filename"), 262 } 263 264 paramPlan = PushPlan{ 265 Application: v7action.Application{ 266 Name: "some-app", 267 GUID: "some-app-guid", 268 }, 269 BitsPath: "/some-bits-path", 270 AllResources: matches, 271 } 272 273 fakeV7Actor.ResourceMatchReturns( 274 matches, 275 v7action.Warnings{"some-good-good-resource-match-warnings"}, 276 nil, 277 ) 278 }) 279 280 When("package upload succeeds", func() { 281 BeforeEach(func() { 282 fakeV7Actor.UploadBitsPackageReturns(v7action.Package{GUID: "some-guid"}, v7action.Warnings{"upload-warning"}, nil) 283 }) 284 285 It("Uploads the package without a zip", func() { 286 Expect(fakeSharedActor.ZipArchiveResourcesCallCount()).To(BeZero()) 287 Expect(fakeSharedActor.ZipDirectoryResourcesCallCount()).To(BeZero()) 288 Expect(fakeSharedActor.ReadArchiveCallCount()).To(BeZero()) 289 290 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, UploadingApplication)) 291 Expect(fakeV7Actor.UploadBitsPackageCallCount()).To(Equal(1)) 292 _, actualMatchedResources, actualProgressReader, actualSize := fakeV7Actor.UploadBitsPackageArgsForCall(0) 293 294 Expect(actualMatchedResources).To(Equal(matches)) 295 Expect(actualProgressReader).To(BeNil()) 296 Expect(actualSize).To(BeZero()) 297 }) 298 }) 299 300 When("package upload fails", func() { 301 BeforeEach(func() { 302 fakeV7Actor.UploadBitsPackageReturns( 303 v7action.Package{}, 304 v7action.Warnings{"upload-warning"}, 305 errors.New("upload-error"), 306 ) 307 }) 308 309 It("returns an error", func() { 310 Expect(fakeSharedActor.ZipArchiveResourcesCallCount()).To(BeZero()) 311 Expect(fakeSharedActor.ZipDirectoryResourcesCallCount()).To(BeZero()) 312 Expect(fakeSharedActor.ReadArchiveCallCount()).To(BeZero()) 313 314 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, UploadingApplication)) 315 Expect(fakeV7Actor.UploadBitsPackageCallCount()).To(Equal(1)) 316 _, actualMatchedResources, actualProgressReader, actualSize := fakeV7Actor.UploadBitsPackageArgsForCall(0) 317 318 Expect(actualMatchedResources).To(Equal(matches)) 319 Expect(actualProgressReader).To(BeNil()) 320 Expect(actualSize).To(BeZero()) 321 322 Expect(warnings).To(ConsistOf("some-good-good-resource-match-warnings", "upload-warning")) 323 Expect(executeErr).To(MatchError("upload-error")) 324 }) 325 }) 326 }) 327 }) 328 }) 329 330 Describe("polling package", func() { 331 var ( 332 matches []sharedaction.V3Resource 333 unmatches []sharedaction.V3Resource 334 ) 335 336 BeforeEach(func() { 337 matches = []sharedaction.V3Resource{ 338 buildV3Resource("some-matching-filename"), 339 } 340 341 unmatches = []sharedaction.V3Resource{ 342 buildV3Resource("some-unmatching-filename"), 343 } 344 345 paramPlan = PushPlan{ 346 Application: v7action.Application{ 347 Name: "some-app", 348 GUID: "some-app-guid", 349 }, 350 BitsPath: "/some-bits-path", 351 AllResources: append( 352 matches, 353 unmatches..., 354 ), 355 } 356 357 fakeV7Actor.ResourceMatchReturns( 358 matches, 359 v7action.Warnings{"some-good-good-resource-match-warnings"}, 360 nil, 361 ) 362 }) 363 364 When("the the polling is successful", func() { 365 BeforeEach(func() { 366 fakeV7Actor.PollPackageReturns(v7action.Package{GUID: "some-package-guid"}, v7action.Warnings{"some-poll-package-warning"}, nil) 367 }) 368 369 It("returns warnings", func() { 370 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, CreatingArchive, ReadingArchive, UploadingApplicationWithArchive, UploadWithArchiveComplete)) 371 Expect(warnings).To(ConsistOf("some-good-good-resource-match-warnings", "some-poll-package-warning")) 372 }) 373 374 It("sets the package guid on push plan", func() { 375 Expect(returnedPushPlan.PackageGUID).To(Equal("some-package-guid")) 376 }) 377 }) 378 379 When("the the polling returns an error", func() { 380 var someErr error 381 382 BeforeEach(func() { 383 someErr = errors.New("I AM A BANANA") 384 fakeV7Actor.PollPackageReturns(v7action.Package{}, v7action.Warnings{"some-poll-package-warning"}, someErr) 385 }) 386 387 It("returns errors and warnings", func() { 388 Expect(events).To(ConsistOf(ResourceMatching, CreatingPackage, CreatingArchive, ReadingArchive, UploadingApplicationWithArchive, UploadWithArchiveComplete)) 389 Expect(executeErr).To(MatchError(someErr)) 390 }) 391 }) 392 }) 393 })