github.com/willmadison/cli@v6.40.1-0.20181018160101-29d5937903ff+incompatible/actor/sharedaction/resource_test.go (about) 1 package sharedaction_test 2 3 import ( 4 "archive/zip" 5 "io" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 10 "code.cloudfoundry.org/cli/actor/actionerror" 11 . "code.cloudfoundry.org/cli/actor/sharedaction" 12 "code.cloudfoundry.org/cli/actor/sharedaction/sharedactionfakes" 13 "code.cloudfoundry.org/ykk" 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("Resource Actions", func() { 19 var ( 20 fakeConfig *sharedactionfakes.FakeConfig 21 actor *Actor 22 srcDir string 23 ) 24 25 BeforeEach(func() { 26 fakeConfig = new(sharedactionfakes.FakeConfig) 27 actor = NewActor(fakeConfig) 28 29 // Creates the following directory structure: 30 // level1/level2/tmpFile1 31 // tmpfile2 32 // tmpfile3 33 34 var err error 35 srcDir, err = ioutil.TempDir("", "resource-actions-test") 36 Expect(err).ToNot(HaveOccurred()) 37 38 subDir := filepath.Join(srcDir, "level1", "level2") 39 err = os.MkdirAll(subDir, 0777) 40 Expect(err).ToNot(HaveOccurred()) 41 42 err = ioutil.WriteFile(filepath.Join(subDir, "tmpFile1"), []byte("why hello"), 0600) 43 Expect(err).ToNot(HaveOccurred()) 44 45 err = ioutil.WriteFile(filepath.Join(srcDir, "tmpFile2"), []byte("Hello, Binky"), 0600) 46 Expect(err).ToNot(HaveOccurred()) 47 48 err = ioutil.WriteFile(filepath.Join(srcDir, "tmpFile3"), []byte("Bananarama"), 0600) 49 Expect(err).ToNot(HaveOccurred()) 50 51 relativePath, err := filepath.Rel(srcDir, subDir) 52 Expect(err).ToNot(HaveOccurred()) 53 54 // ./symlink -> ./level1/level2/tmpfile1 55 err = os.Symlink(filepath.Join(relativePath, "tmpFile1"), filepath.Join(srcDir, "symlink1")) 56 Expect(err).ToNot(HaveOccurred()) 57 58 // ./level1/level2/symlink2 -> ../../tmpfile2 59 err = os.Symlink("../../tmpfile2", filepath.Join(subDir, "symlink2")) 60 Expect(err).ToNot(HaveOccurred()) 61 }) 62 63 AfterEach(func() { 64 Expect(os.RemoveAll(srcDir)).ToNot(HaveOccurred()) 65 }) 66 67 Describe("GatherArchiveResources", func() { 68 // tests are under resource_unix_test.go and resource_windows_test.go 69 }) 70 71 Describe("GatherDirectoryResources", func() { 72 // tests are under resource_unix_test.go and resource_windows_test.go 73 }) 74 75 Describe("ReadArchive", func() { 76 var ( 77 archivePath string 78 executeErr error 79 80 readCloser io.ReadCloser 81 fileSize int64 82 ) 83 84 JustBeforeEach(func() { 85 readCloser, fileSize, executeErr = actor.ReadArchive(archivePath) 86 }) 87 88 AfterEach(func() { 89 Expect(os.RemoveAll(archivePath)).ToNot(HaveOccurred()) 90 }) 91 92 When("the archive can be accessed properly", func() { 93 BeforeEach(func() { 94 tmpfile, err := ioutil.TempFile("", "fake-archive") 95 Expect(err).ToNot(HaveOccurred()) 96 _, err = tmpfile.Write([]byte("123456")) 97 Expect(err).ToNot(HaveOccurred()) 98 Expect(tmpfile.Close()).ToNot(HaveOccurred()) 99 100 archivePath = tmpfile.Name() 101 }) 102 103 It("returns zero errors", func() { 104 defer readCloser.Close() 105 106 Expect(executeErr).ToNot(HaveOccurred()) 107 Expect(fileSize).To(BeNumerically("==", 6)) 108 109 b := make([]byte, 100) 110 size, err := readCloser.Read(b) 111 Expect(err).ToNot(HaveOccurred()) 112 Expect(b[:size]).To(Equal([]byte("123456"))) 113 }) 114 }) 115 116 When("the archive returns any access errors", func() { 117 It("returns the error", func() { 118 _, ok := executeErr.(*os.PathError) 119 Expect(ok).To(BeTrue()) 120 }) 121 }) 122 }) 123 124 Describe("ZipArchiveResources", func() { 125 var ( 126 archive string 127 resultZip string 128 resources []Resource 129 executeErr error 130 ) 131 132 BeforeEach(func() { 133 tmpfile, err := ioutil.TempFile("", "zip-archive-resources") 134 Expect(err).ToNot(HaveOccurred()) 135 defer tmpfile.Close() 136 archive = tmpfile.Name() 137 138 err = zipit(srcDir, archive, "") 139 Expect(err).ToNot(HaveOccurred()) 140 }) 141 142 JustBeforeEach(func() { 143 resultZip, executeErr = actor.ZipArchiveResources(archive, resources) 144 }) 145 146 AfterEach(func() { 147 Expect(os.RemoveAll(archive)).ToNot(HaveOccurred()) 148 Expect(os.RemoveAll(resultZip)).ToNot(HaveOccurred()) 149 }) 150 151 When("the files have not been changed since scanning them", func() { 152 When("there are no symlinks", func() { 153 BeforeEach(func() { 154 resources = []Resource{ 155 {Filename: "/"}, 156 {Filename: "/level1/"}, 157 {Filename: "/level1/level2/"}, 158 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 159 {Filename: "/tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95"}, 160 // Explicitly skipping /tmpFile3 161 } 162 }) 163 164 It("zips the file and returns a populated resources list", func() { 165 Expect(executeErr).ToNot(HaveOccurred()) 166 167 Expect(resultZip).ToNot(BeEmpty()) 168 zipFile, err := os.Open(resultZip) 169 Expect(err).ToNot(HaveOccurred()) 170 defer zipFile.Close() 171 172 zipInfo, err := zipFile.Stat() 173 Expect(err).ToNot(HaveOccurred()) 174 175 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 176 Expect(err).ToNot(HaveOccurred()) 177 178 Expect(reader.File).To(HaveLen(5)) 179 Expect(reader.File[0].Name).To(Equal("/")) 180 Expect(reader.File[1].Name).To(Equal("/level1/")) 181 Expect(reader.File[2].Name).To(Equal("/level1/level2/")) 182 Expect(reader.File[3].Name).To(Equal("/level1/level2/tmpFile1")) 183 Expect(reader.File[4].Name).To(Equal("/tmpFile2")) 184 185 expectFileContentsToEqual(reader.File[3], "why hello") 186 expectFileContentsToEqual(reader.File[4], "Hello, Binky") 187 188 for _, file := range reader.File { 189 Expect(file.Method).To(Equal(zip.Deflate)) 190 } 191 }) 192 }) 193 194 When("there are relative symlink files", func() { 195 BeforeEach(func() { 196 resources = []Resource{ 197 {Filename: "/"}, 198 {Filename: "/level1/"}, 199 {Filename: "/level1/level2/"}, 200 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 201 {Filename: "/symlink1", Mode: os.ModeSymlink | 0777}, 202 {Filename: "/level1/level2/symlink2", Mode: os.ModeSymlink | 0777}, 203 } 204 }) 205 206 It("zips the file and returns a populated resources list", func() { 207 Expect(executeErr).ToNot(HaveOccurred()) 208 209 Expect(resultZip).ToNot(BeEmpty()) 210 zipFile, err := os.Open(resultZip) 211 Expect(err).ToNot(HaveOccurred()) 212 defer zipFile.Close() 213 214 zipInfo, err := zipFile.Stat() 215 Expect(err).ToNot(HaveOccurred()) 216 217 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 218 Expect(err).ToNot(HaveOccurred()) 219 220 Expect(reader.File).To(HaveLen(6)) 221 Expect(reader.File[0].Name).To(Equal("/")) 222 Expect(reader.File[1].Name).To(Equal("/level1/")) 223 Expect(reader.File[2].Name).To(Equal("/level1/level2/")) 224 Expect(reader.File[3].Name).To(Equal("/level1/level2/symlink2")) 225 Expect(reader.File[4].Name).To(Equal("/level1/level2/tmpFile1")) 226 Expect(reader.File[5].Name).To(Equal("/symlink1")) 227 228 expectFileContentsToEqual(reader.File[4], "why hello") 229 Expect(reader.File[5].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 230 expectFileContentsToEqual(reader.File[5], filepath.FromSlash("level1/level2/tmpFile1")) 231 232 Expect(reader.File[3].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 233 expectFileContentsToEqual(reader.File[3], filepath.FromSlash("../../tmpfile2")) 234 }) 235 }) 236 }) 237 238 When("the files have changed since the scanning", func() { 239 BeforeEach(func() { 240 resources = []Resource{ 241 {Filename: "/"}, 242 {Filename: "/level1/"}, 243 {Filename: "/level1/level2/"}, 244 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 245 {Filename: "/tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95"}, 246 {Filename: "/tmpFile3", SHA1: "i dunno, 7?"}, 247 } 248 }) 249 250 It("returns an FileChangedError", func() { 251 Expect(executeErr).To(Equal(actionerror.FileChangedError{Filename: "/tmpFile3"})) 252 }) 253 }) 254 }) 255 256 Describe("ZipDirectoryResources", func() { 257 var ( 258 resultZip string 259 resources []Resource 260 executeErr error 261 ) 262 263 JustBeforeEach(func() { 264 resultZip, executeErr = actor.ZipDirectoryResources(srcDir, resources) 265 }) 266 267 AfterEach(func() { 268 Expect(os.RemoveAll(resultZip)).ToNot(HaveOccurred()) 269 }) 270 271 When("the files have not been changed since scanning them", func() { 272 When("there are no symlinks", func() { 273 BeforeEach(func() { 274 resources = []Resource{ 275 {Filename: "level1"}, 276 {Filename: "level1/level2"}, 277 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 278 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95"}, 279 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879"}, 280 } 281 }) 282 283 It("zips the file and returns a populated resources list", func() { 284 Expect(executeErr).ToNot(HaveOccurred()) 285 286 Expect(resultZip).ToNot(BeEmpty()) 287 zipFile, err := os.Open(resultZip) 288 Expect(err).ToNot(HaveOccurred()) 289 defer zipFile.Close() 290 291 zipInfo, err := zipFile.Stat() 292 Expect(err).ToNot(HaveOccurred()) 293 294 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 295 Expect(err).ToNot(HaveOccurred()) 296 297 Expect(reader.File).To(HaveLen(5)) 298 Expect(reader.File[0].Name).To(Equal("level1/")) 299 Expect(reader.File[1].Name).To(Equal("level1/level2/")) 300 Expect(reader.File[2].Name).To(Equal("level1/level2/tmpFile1")) 301 Expect(reader.File[3].Name).To(Equal("tmpFile2")) 302 Expect(reader.File[4].Name).To(Equal("tmpFile3")) 303 304 expectFileContentsToEqual(reader.File[2], "why hello") 305 expectFileContentsToEqual(reader.File[3], "Hello, Binky") 306 expectFileContentsToEqual(reader.File[4], "Bananarama") 307 308 for _, file := range reader.File { 309 Expect(file.Method).To(Equal(zip.Deflate)) 310 } 311 }) 312 }) 313 314 When("there are relative symlink files", func() { 315 BeforeEach(func() { 316 resources = []Resource{ 317 {Filename: "level1"}, 318 {Filename: "level1/level2"}, 319 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 320 {Filename: "symlink1", Mode: os.ModeSymlink}, 321 {Filename: "level1/level2/symlink2", Mode: os.ModeSymlink}, 322 } 323 }) 324 325 It("zips the file and returns a populated resources list", func() { 326 Expect(executeErr).ToNot(HaveOccurred()) 327 328 Expect(resultZip).ToNot(BeEmpty()) 329 zipFile, err := os.Open(resultZip) 330 Expect(err).ToNot(HaveOccurred()) 331 defer zipFile.Close() 332 333 zipInfo, err := zipFile.Stat() 334 Expect(err).ToNot(HaveOccurred()) 335 336 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 337 Expect(err).ToNot(HaveOccurred()) 338 339 Expect(reader.File).To(HaveLen(5)) 340 Expect(reader.File[0].Name).To(Equal("level1/")) 341 Expect(reader.File[1].Name).To(Equal("level1/level2/")) 342 Expect(reader.File[2].Name).To(Equal("level1/level2/tmpFile1")) 343 Expect(reader.File[3].Name).To(Equal("symlink1")) 344 Expect(reader.File[4].Name).To(Equal("level1/level2/symlink2")) 345 346 expectFileContentsToEqual(reader.File[2], "why hello") 347 Expect(reader.File[3].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 348 expectFileContentsToEqual(reader.File[3], filepath.FromSlash("level1/level2/tmpFile1")) 349 350 Expect(reader.File[4].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 351 expectFileContentsToEqual(reader.File[4], filepath.FromSlash("../../tmpfile2")) 352 }) 353 }) 354 }) 355 356 When("the files have changed since the scanning", func() { 357 BeforeEach(func() { 358 resources = []Resource{ 359 {Filename: "level1"}, 360 {Filename: "level1/level2"}, 361 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 362 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95"}, 363 {Filename: "tmpFile3", SHA1: "i dunno, 7?"}, 364 } 365 }) 366 367 It("returns an FileChangedError", func() { 368 Expect(executeErr).To(Equal(actionerror.FileChangedError{Filename: filepath.Join(srcDir, "tmpFile3")})) 369 }) 370 }) 371 }) 372 }) 373 374 func expectFileContentsToEqual(file *zip.File, expectedContents string) { 375 reader, err := file.Open() 376 Expect(err).ToNot(HaveOccurred()) 377 defer reader.Close() 378 379 body, err := ioutil.ReadAll(reader) 380 Expect(err).ToNot(HaveOccurred()) 381 382 Expect(string(body)).To(Equal(expectedContents)) 383 }