github.com/sleungcy/cli@v7.1.0+incompatible/actor/v7pushaction/create_droplet_for_application_test.go (about) 1 package v7pushaction_test 2 3 import ( 4 "errors" 5 "strings" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 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 "code.cloudfoundry.org/cli/resources" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("CreateDropletForApplication", func() { 18 var ( 19 actor *Actor 20 fakeV7Actor *v7pushactionfakes.FakeV7Actor 21 fakeSharedActor *v7pushactionfakes.FakeSharedActor 22 23 returnedPushPlan PushPlan 24 paramPlan PushPlan 25 fakeProgressBar *v7pushactionfakes.FakeProgressBar 26 27 warnings Warnings 28 executeErr error 29 30 events []Event 31 ) 32 33 BeforeEach(func() { 34 actor, fakeV7Actor, fakeSharedActor = getTestPushActor() 35 36 fakeProgressBar = new(v7pushactionfakes.FakeProgressBar) 37 38 fakeSharedActor.ReadArchiveReturns(new(v7pushactionfakes.FakeReadCloser), 0, nil) 39 40 paramPlan = PushPlan{ 41 Application: resources.Application{ 42 GUID: "some-app-guid", 43 }, 44 } 45 }) 46 47 JustBeforeEach(func() { 48 events = EventFollower(func(eventStream chan<- *PushEvent) { 49 returnedPushPlan, warnings, executeErr = actor.CreateDropletForApplication(paramPlan, eventStream, fakeProgressBar) 50 }) 51 }) 52 53 When("the plan has a droplet path specified", func() { 54 BeforeEach(func() { 55 paramPlan.DropletPath = "path/to/some-droplet.tgz" 56 }) 57 58 When("creating the droplet for app fails", func() { 59 var createError = errors.New("create droplet failed") 60 61 BeforeEach(func() { 62 fakeV7Actor.CreateApplicationDropletReturns( 63 resources.Droplet{}, 64 v7action.Warnings{"create-droplet-warning"}, 65 createError, 66 ) 67 }) 68 69 It("only records an event for creating droplet", func() { 70 Expect(events).To(Equal([]Event{ 71 CreatingDroplet, 72 })) 73 }) 74 75 It("returns the unmodified plan, warnings, and error", func() { 76 Expect(returnedPushPlan).To(Equal(paramPlan)) 77 Expect(warnings).To(ConsistOf("create-droplet-warning")) 78 Expect(executeErr).To(Equal(createError)) 79 }) 80 }) 81 82 When("reading droplet file fails", func() { 83 var readError = errors.New("reading file failed") 84 85 BeforeEach(func() { 86 fakeV7Actor.CreateApplicationDropletReturns( 87 resources.Droplet{}, 88 v7action.Warnings{"create-droplet-warning"}, 89 nil, 90 ) 91 92 fakeSharedActor.ReadArchiveReturns( 93 nil, 94 0, 95 readError, 96 ) 97 }) 98 99 It("records events for creating droplet, reading archive", func() { 100 Expect(events).To(Equal([]Event{ 101 CreatingDroplet, 102 ReadingArchive, 103 })) 104 }) 105 106 It("returns the unmodified plan, warnings, and error", func() { 107 Expect(returnedPushPlan).To(Equal(paramPlan)) 108 Expect(warnings).To(ConsistOf("create-droplet-warning")) 109 Expect(executeErr).To(Equal(readError)) 110 }) 111 }) 112 113 When("uploading droplet fails", func() { 114 var createdDroplet = resources.Droplet{GUID: "created-droplet-guid"} 115 var progressReader = strings.NewReader("123456") 116 var uploadError = errors.New("uploading droplet failed") 117 118 BeforeEach(func() { 119 fakeV7Actor.CreateApplicationDropletReturns( 120 createdDroplet, 121 v7action.Warnings{"create-droplet-warning"}, 122 nil, 123 ) 124 125 fakeSharedActor.ReadArchiveReturns( 126 new(v7pushactionfakes.FakeReadCloser), 127 int64(128), 128 nil, 129 ) 130 131 fakeProgressBar.NewProgressBarWrapperReturns(progressReader) 132 133 fakeV7Actor.UploadDropletReturns( 134 v7action.Warnings{"upload-droplet-warning"}, 135 uploadError, 136 ) 137 }) 138 139 It("tries to upload the droplet with given path", func() { 140 Expect(fakeV7Actor.UploadDropletCallCount()).To(Equal(1)) 141 givenDropletGUID, givenDropletPath, givenProgressReader, givenSize := fakeV7Actor.UploadDropletArgsForCall(0) 142 Expect(givenDropletGUID).To(Equal(createdDroplet.GUID)) 143 Expect(givenDropletPath).To(Equal(paramPlan.DropletPath)) 144 Expect(givenProgressReader).To(Equal(progressReader)) 145 Expect(givenSize).To(Equal(int64(128))) 146 }) 147 148 It("records events for creating droplet, reading archive, uploading droplet", func() { 149 Expect(events).To(Equal([]Event{ 150 CreatingDroplet, 151 ReadingArchive, 152 UploadingDroplet, 153 UploadDropletComplete, 154 })) 155 }) 156 157 It("returns the unmodified plan, warnings, and error", func() { 158 Expect(returnedPushPlan).To(Equal(paramPlan)) 159 Expect(warnings).To(ConsistOf("create-droplet-warning", "upload-droplet-warning")) 160 Expect(executeErr).To(Equal(uploadError)) 161 }) 162 }) 163 164 When("a retryable failure occurs", func() { 165 var createdDroplet = resources.Droplet{GUID: "created-droplet-guid"} 166 var progressReader = strings.NewReader("123456") 167 var retryableError = ccerror.PipeSeekError{ 168 Err: errors.New("network error"), 169 } 170 171 BeforeEach(func() { 172 fakeV7Actor.CreateApplicationDropletReturns( 173 createdDroplet, 174 v7action.Warnings{"create-droplet-warning"}, 175 nil, 176 ) 177 178 fakeSharedActor.ReadArchiveReturns( 179 new(v7pushactionfakes.FakeReadCloser), 180 int64(128), 181 nil, 182 ) 183 184 fakeProgressBar.NewProgressBarWrapperReturns(progressReader) 185 }) 186 187 When("all upload attempts fail", func() { 188 BeforeEach(func() { 189 fakeV7Actor.UploadDropletReturns( 190 v7action.Warnings{"upload-droplet-warning"}, 191 retryableError, 192 ) 193 }) 194 195 It("records events for creating droplet, reading archive, uploading droplet, retrying", func() { 196 Expect(events).To(Equal([]Event{ 197 CreatingDroplet, 198 ReadingArchive, 199 UploadingDroplet, 200 RetryUpload, 201 ReadingArchive, 202 UploadingDroplet, 203 RetryUpload, 204 ReadingArchive, 205 UploadingDroplet, 206 RetryUpload, 207 })) 208 }) 209 210 It("returns the unmodified plan, all warnings, and wrapped error", func() { 211 Expect(returnedPushPlan).To(Equal(paramPlan)) 212 Expect(warnings).To(ConsistOf( 213 "create-droplet-warning", 214 "upload-droplet-warning", 215 "upload-droplet-warning", 216 "upload-droplet-warning", 217 )) 218 Expect(executeErr).To(Equal(actionerror.UploadFailedError{ 219 Err: retryableError.Err, 220 })) 221 }) 222 }) 223 224 When("the upload eventually succeeds", func() { 225 BeforeEach(func() { 226 fakeV7Actor.UploadDropletReturnsOnCall(0, 227 v7action.Warnings{"upload-droplet-warning"}, 228 retryableError, 229 ) 230 231 fakeV7Actor.UploadDropletReturnsOnCall(1, 232 v7action.Warnings{"upload-droplet-warning"}, 233 retryableError, 234 ) 235 236 fakeV7Actor.UploadDropletReturnsOnCall(2, 237 v7action.Warnings{"upload-droplet-warning"}, 238 nil, 239 ) 240 }) 241 242 It("records events for creating droplet, reading archive, uploading droplet, retrying, completing", func() { 243 Expect(events).To(Equal([]Event{ 244 CreatingDroplet, 245 ReadingArchive, 246 UploadingDroplet, 247 RetryUpload, 248 ReadingArchive, 249 UploadingDroplet, 250 RetryUpload, 251 ReadingArchive, 252 UploadingDroplet, 253 UploadDropletComplete, 254 })) 255 }) 256 257 It("returns the modified plan, all warnings, and no error", func() { 258 Expect(returnedPushPlan.DropletGUID).To(Equal(createdDroplet.GUID)) 259 Expect(warnings).To(ConsistOf( 260 "create-droplet-warning", 261 "upload-droplet-warning", 262 "upload-droplet-warning", 263 "upload-droplet-warning", 264 )) 265 Expect(executeErr).NotTo(HaveOccurred()) 266 }) 267 }) 268 }) 269 270 When("upload completes successfully", func() { 271 var createdDroplet = resources.Droplet{GUID: "created-droplet-guid"} 272 var progressReader = strings.NewReader("123456") 273 274 BeforeEach(func() { 275 fakeV7Actor.CreateApplicationDropletReturns( 276 createdDroplet, 277 v7action.Warnings{"create-droplet-warning"}, 278 nil, 279 ) 280 281 fakeSharedActor.ReadArchiveReturns( 282 new(v7pushactionfakes.FakeReadCloser), 283 int64(128), 284 nil, 285 ) 286 287 fakeProgressBar.NewProgressBarWrapperReturns(progressReader) 288 289 fakeV7Actor.UploadDropletReturns( 290 v7action.Warnings{"upload-droplet-warning"}, 291 nil, 292 ) 293 }) 294 295 It("records events for creating droplet, reading archive, uploading droplet, retrying, completing", func() { 296 Expect(events).To(Equal([]Event{ 297 CreatingDroplet, 298 ReadingArchive, 299 UploadingDroplet, 300 UploadDropletComplete, 301 })) 302 }) 303 304 It("returns the modified plan, all warnings, and no error", func() { 305 Expect(returnedPushPlan.DropletGUID).To(Equal(createdDroplet.GUID)) 306 Expect(warnings).To(ConsistOf( 307 "create-droplet-warning", 308 "upload-droplet-warning", 309 )) 310 Expect(executeErr).NotTo(HaveOccurred()) 311 }) 312 }) 313 }) 314 })