github.com/jghiloni/cli@v6.28.1-0.20170628223758-0ce05fe032a2+incompatible/actor/v3action/package_test.go (about) 1 package v3action_test 2 3 import ( 4 "archive/zip" 5 "errors" 6 "io/ioutil" 7 "net/url" 8 "os" 9 "path/filepath" 10 11 . "code.cloudfoundry.org/cli/actor/v3action" 12 "code.cloudfoundry.org/cli/actor/v3action/v3actionfakes" 13 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 14 15 . "github.com/onsi/ginkgo" 16 . "github.com/onsi/ginkgo/extensions/table" 17 . "github.com/onsi/gomega" 18 ) 19 20 func createFile(root, path, contents string) int64 { 21 filepath := filepath.Join(root, path) 22 err := ioutil.WriteFile(filepath, []byte(contents), 0666) 23 Expect(err).NotTo(HaveOccurred()) 24 25 fileInfo, err := os.Stat(filepath) 26 Expect(err).NotTo(HaveOccurred()) 27 return fileInfo.Size() 28 } 29 30 var _ = Describe("Package Actions", func() { 31 var ( 32 actor *Actor 33 fakeCloudControllerClient *v3actionfakes.FakeCloudControllerClient 34 fakeConfig *v3actionfakes.FakeConfig 35 ) 36 37 BeforeEach(func() { 38 fakeCloudControllerClient = new(v3actionfakes.FakeCloudControllerClient) 39 fakeConfig = new(v3actionfakes.FakeConfig) 40 actor = NewActor(fakeCloudControllerClient, fakeConfig) 41 }) 42 43 Describe("CreateAndUploadPackageByApplicationNameAndSpace", func() { 44 Context("when the application can be retrieved", func() { 45 BeforeEach(func() { 46 fakeCloudControllerClient.GetApplicationsReturns( 47 []ccv3.Application{ 48 { 49 Name: "some-app-name", 50 GUID: "some-app-guid", 51 }, 52 }, 53 ccv3.Warnings{"some-app-warning"}, 54 nil, 55 ) 56 }) 57 58 Context("when the zip can be created", func() { 59 var ( 60 bitsPath string 61 expectedFilesInZip map[string]int64 62 ) 63 64 BeforeEach(func() { 65 var err error 66 bitsPath, err = ioutil.TempDir("", "example") 67 Expect(err).ToNot(HaveOccurred()) 68 69 expectedFilesInZip = map[string]int64{ 70 "tmpfile": 0, 71 "folder1/tmpfile": 0, 72 } 73 74 err = os.Mkdir(filepath.Join(bitsPath, "folder1"), 0777) 75 Expect(err).ToNot(HaveOccurred()) 76 77 for path, _ := range expectedFilesInZip { 78 expectedFilesInZip[path] = createFile(bitsPath, path, "some-contents") 79 } 80 expectedFilesInZip["folder1/"] = 0 81 82 }) 83 84 AfterEach(func() { 85 if bitsPath != "" { 86 err := os.RemoveAll(bitsPath) 87 Expect(err).ToNot(HaveOccurred()) 88 } 89 }) 90 91 Context("when the package is created successfully", func() { 92 var createdPackage ccv3.Package 93 94 BeforeEach(func() { 95 createdPackage = ccv3.Package{ 96 GUID: "some-pkg-guid", 97 State: ccv3.PackageStateAwaitingUpload, 98 Relationships: ccv3.Relationships{ 99 ccv3.ApplicationRelationship: ccv3.Relationship{ 100 GUID: "some-app-guid", 101 }, 102 }, 103 } 104 105 fakeCloudControllerClient.CreatePackageReturns( 106 createdPackage, 107 ccv3.Warnings{"some-pkg-warning"}, 108 nil, 109 ) 110 }) 111 112 Context("when the file uploading is successful", func() { 113 BeforeEach(func() { 114 fakeCloudControllerClient.UploadPackageReturns(ccv3.Package{}, ccv3.Warnings{"some-upload-pkg-warning"}, nil) 115 }) 116 117 Context("when the polling is successful", func() { 118 BeforeEach(func() { 119 fakeCloudControllerClient.GetPackageReturns( 120 ccv3.Package{GUID: "some-pkg-guid", State: ccv3.PackageStateReady}, 121 ccv3.Warnings{"some-get-pkg-warning"}, 122 nil, 123 ) 124 }) 125 126 It("correctly constructs the zip", func() { 127 fakeCloudControllerClient.UploadPackageStub = func(pkg ccv3.Package, zipFilePart string) (ccv3.Package, ccv3.Warnings, error) { 128 filestats := map[string]int64{} 129 reader, err := zip.OpenReader(zipFilePart) 130 Expect(err).ToNot(HaveOccurred()) 131 132 for _, file := range reader.File { 133 filestats[file.Name] = file.FileInfo().Size() 134 } 135 136 Expect(filestats).To(Equal(expectedFilesInZip)) 137 138 return ccv3.Package{}, nil, nil 139 } 140 _, _, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 141 Expect(err).NotTo(HaveOccurred()) 142 Expect(fakeCloudControllerClient.UploadPackageCallCount()).To(Equal(1)) 143 }) 144 145 It("collects all warnings", func() { 146 _, warnings, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 147 Expect(err).NotTo(HaveOccurred()) 148 Expect(warnings).To(ConsistOf("some-app-warning", "some-pkg-warning", "some-upload-pkg-warning", "some-get-pkg-warning")) 149 }) 150 151 It("successfully resolves the app name", func() { 152 _, _, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 153 Expect(err).ToNot(HaveOccurred()) 154 155 Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1)) 156 expectedQuery := url.Values{ 157 "names": []string{"some-app-name"}, 158 "space_guids": []string{"some-space-guid"}, 159 } 160 query := fakeCloudControllerClient.GetApplicationsArgsForCall(0) 161 Expect(query).To(Equal(expectedQuery)) 162 }) 163 164 It("successfully creates the Package", func() { 165 _, _, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 166 Expect(err).ToNot(HaveOccurred()) 167 168 Expect(fakeCloudControllerClient.CreatePackageCallCount()).To(Equal(1)) 169 inputPackage := fakeCloudControllerClient.CreatePackageArgsForCall(0) 170 Expect(inputPackage).To(Equal(ccv3.Package{ 171 Type: ccv3.PackageTypeBits, 172 Relationships: ccv3.Relationships{ 173 ccv3.ApplicationRelationship: ccv3.Relationship{GUID: "some-app-guid"}, 174 }, 175 })) 176 }) 177 178 It("returns the package", func() { 179 pkg, _, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 180 Expect(err).ToNot(HaveOccurred()) 181 182 expectedPackage := ccv3.Package{ 183 GUID: "some-pkg-guid", 184 State: ccv3.PackageStateReady, 185 } 186 Expect(pkg).To(Equal(Package(expectedPackage))) 187 188 Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(1)) 189 Expect(fakeCloudControllerClient.GetPackageArgsForCall(0)).To(Equal("some-pkg-guid")) 190 }) 191 192 DescribeTable("polls until terminal state is reached", 193 func(finalState ccv3.PackageState, expectedErr error) { 194 fakeCloudControllerClient.GetPackageReturns( 195 ccv3.Package{GUID: "some-pkg-guid", State: ccv3.PackageStateAwaitingUpload}, 196 ccv3.Warnings{"some-get-pkg-warning"}, 197 nil, 198 ) 199 fakeCloudControllerClient.GetPackageReturnsOnCall( 200 2, 201 ccv3.Package{State: finalState}, 202 ccv3.Warnings{"some-get-pkg-warning"}, 203 nil, 204 ) 205 206 _, warnings, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 207 208 if expectedErr == nil { 209 Expect(err).ToNot(HaveOccurred()) 210 } else { 211 Expect(err).To(MatchError(expectedErr)) 212 } 213 214 Expect(warnings).To(ConsistOf("some-app-warning", "some-pkg-warning", "some-upload-pkg-warning", "some-get-pkg-warning", "some-get-pkg-warning", "some-get-pkg-warning")) 215 216 Expect(fakeCloudControllerClient.GetPackageCallCount()).To(Equal(3)) 217 Expect(fakeConfig.PollingIntervalCallCount()).To(Equal(3)) 218 }, 219 220 Entry("READY", ccv3.PackageStateReady, nil), 221 Entry("FAILED", ccv3.PackageStateFailed, PackageProcessingFailedError{}), 222 Entry("EXPIRED", ccv3.PackageStateExpired, PackageProcessingExpiredError{}), 223 ) 224 }) 225 226 Context("when the polling errors", func() { 227 var expectedErr error 228 BeforeEach(func() { 229 expectedErr = errors.New("Fake error during polling") 230 fakeCloudControllerClient.GetPackageReturns( 231 ccv3.Package{}, 232 ccv3.Warnings{"some-get-pkg-warning"}, 233 expectedErr, 234 ) 235 }) 236 237 It("returns the error and warnings", func() { 238 _, warnings, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 239 Expect(err).To(MatchError(expectedErr)) 240 Expect(warnings).To(ConsistOf("some-app-warning", "some-pkg-warning", "some-upload-pkg-warning", "some-get-pkg-warning")) 241 }) 242 }) 243 }) 244 245 Context("when the file uploading errors", func() { 246 var expectedErr error 247 248 BeforeEach(func() { 249 expectedErr = errors.New("ZOMG Package Uploading") 250 fakeCloudControllerClient.UploadPackageReturns(ccv3.Package{}, ccv3.Warnings{"some-upload-pkg-warning"}, expectedErr) 251 }) 252 253 It("returns the warnings and the error", func() { 254 _, warnings, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 255 Expect(err).To(MatchError(expectedErr)) 256 Expect(warnings).To(ConsistOf("some-app-warning", "some-pkg-warning", "some-upload-pkg-warning")) 257 }) 258 }) 259 }) 260 261 Context("when the package creation errors", func() { 262 var expectedErr error 263 264 BeforeEach(func() { 265 expectedErr = errors.New("ZOMG Package Creation") 266 fakeCloudControllerClient.CreatePackageReturns( 267 ccv3.Package{}, 268 ccv3.Warnings{"some-pkg-warning"}, 269 expectedErr, 270 ) 271 }) 272 273 It("returns the warnings and the error", func() { 274 _, warnings, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", bitsPath) 275 Expect(err).To(MatchError(expectedErr)) 276 Expect(warnings).To(ConsistOf("some-app-warning", "some-pkg-warning")) 277 }) 278 }) 279 }) 280 281 Context("when creating the zip errors", func() { 282 It("returns the warnings and the error", func() { 283 _, warnings, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", "/banana") 284 // Windows returns back a different error message 285 Expect(err.Error()).To(MatchRegexp("open /banana: no such file or directory|The system cannot find the file specified")) 286 Expect(warnings).To(ConsistOf("some-app-warning")) 287 }) 288 }) 289 }) 290 291 Context("when retrieving the application errors", func() { 292 var expectedErr error 293 294 BeforeEach(func() { 295 expectedErr = errors.New("I am a CloudControllerClient Error") 296 fakeCloudControllerClient.GetApplicationsReturns( 297 []ccv3.Application{}, 298 ccv3.Warnings{"some-warning"}, 299 expectedErr) 300 }) 301 302 It("returns the warnings and the error", func() { 303 _, warnings, err := actor.CreateAndUploadPackageByApplicationNameAndSpace("some-app-name", "some-space-guid", "some-path") 304 Expect(err).To(MatchError(expectedErr)) 305 Expect(warnings).To(ConsistOf("some-warning")) 306 }) 307 }) 308 }) 309 })