github.com/randomtask1155/cli@v6.41.1-0.20181227003417-a98eed78cbde+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 180 Expect(reader.File[0].Name).To(Equal("/")) 181 182 Expect(reader.File[1].Name).To(Equal("/level1/")) 183 184 Expect(reader.File[2].Name).To(Equal("/level1/level2/")) 185 186 Expect(reader.File[3].Name).To(Equal("/level1/level2/tmpFile1")) 187 Expect(reader.File[3].Method).To(Equal(zip.Deflate)) 188 expectFileContentsToEqual(reader.File[3], "why hello") 189 190 Expect(reader.File[4].Name).To(Equal("/tmpFile2")) 191 Expect(reader.File[4].Method).To(Equal(zip.Deflate)) 192 expectFileContentsToEqual(reader.File[4], "Hello, Binky") 193 }) 194 }) 195 196 When("there are relative symlink files", func() { 197 BeforeEach(func() { 198 resources = []Resource{ 199 {Filename: "/"}, 200 {Filename: "/level1/"}, 201 {Filename: "/level1/level2/"}, 202 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 203 {Filename: "/symlink1", Mode: os.ModeSymlink | 0777}, 204 {Filename: "/level1/level2/symlink2", Mode: os.ModeSymlink | 0777}, 205 } 206 }) 207 208 It("zips the file and returns a populated resources list", func() { 209 Expect(executeErr).ToNot(HaveOccurred()) 210 211 Expect(resultZip).ToNot(BeEmpty()) 212 zipFile, err := os.Open(resultZip) 213 Expect(err).ToNot(HaveOccurred()) 214 defer zipFile.Close() 215 216 zipInfo, err := zipFile.Stat() 217 Expect(err).ToNot(HaveOccurred()) 218 219 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 220 Expect(err).ToNot(HaveOccurred()) 221 222 Expect(reader.File).To(HaveLen(6)) 223 Expect(reader.File[0].Name).To(Equal("/")) 224 Expect(reader.File[1].Name).To(Equal("/level1/")) 225 Expect(reader.File[2].Name).To(Equal("/level1/level2/")) 226 Expect(reader.File[3].Name).To(Equal("/level1/level2/symlink2")) 227 Expect(reader.File[4].Name).To(Equal("/level1/level2/tmpFile1")) 228 Expect(reader.File[5].Name).To(Equal("/symlink1")) 229 230 expectFileContentsToEqual(reader.File[4], "why hello") 231 Expect(reader.File[5].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 232 expectFileContentsToEqual(reader.File[5], filepath.FromSlash("level1/level2/tmpFile1")) 233 234 Expect(reader.File[3].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 235 expectFileContentsToEqual(reader.File[3], filepath.FromSlash("../../tmpfile2")) 236 }) 237 }) 238 }) 239 240 When("the files have changed since the scanning", func() { 241 BeforeEach(func() { 242 resources = []Resource{ 243 {Filename: "/"}, 244 {Filename: "/level1/"}, 245 {Filename: "/level1/level2/"}, 246 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 247 {Filename: "/tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95"}, 248 {Filename: "/tmpFile3", SHA1: "i dunno, 7?"}, 249 } 250 }) 251 252 It("returns an FileChangedError", func() { 253 Expect(executeErr).To(Equal(actionerror.FileChangedError{Filename: "/tmpFile3"})) 254 }) 255 }) 256 }) 257 258 Describe("ZipDirectoryResources", func() { 259 var ( 260 resultZip string 261 resources []Resource 262 executeErr error 263 ) 264 265 JustBeforeEach(func() { 266 resultZip, executeErr = actor.ZipDirectoryResources(srcDir, resources) 267 }) 268 269 AfterEach(func() { 270 Expect(os.RemoveAll(resultZip)).ToNot(HaveOccurred()) 271 }) 272 273 When("the files have not been changed since scanning them", func() { 274 When("there are no symlinks", func() { 275 BeforeEach(func() { 276 resources = []Resource{ 277 {Filename: "level1"}, 278 {Filename: "level1/level2"}, 279 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 280 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95"}, 281 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879"}, 282 } 283 }) 284 285 It("zips the file and returns a populated resources list", func() { 286 Expect(executeErr).ToNot(HaveOccurred()) 287 288 Expect(resultZip).ToNot(BeEmpty()) 289 zipFile, err := os.Open(resultZip) 290 Expect(err).ToNot(HaveOccurred()) 291 defer zipFile.Close() 292 293 zipInfo, err := zipFile.Stat() 294 Expect(err).ToNot(HaveOccurred()) 295 296 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 297 Expect(err).ToNot(HaveOccurred()) 298 299 Expect(reader.File).To(HaveLen(5)) 300 Expect(reader.File[0].Name).To(Equal("level1/")) 301 302 Expect(reader.File[1].Name).To(Equal("level1/level2/")) 303 304 Expect(reader.File[2].Name).To(Equal("level1/level2/tmpFile1")) 305 Expect(reader.File[2].Method).To(Equal(zip.Deflate)) 306 expectFileContentsToEqual(reader.File[2], "why hello") 307 308 Expect(reader.File[3].Name).To(Equal("tmpFile2")) 309 Expect(reader.File[3].Method).To(Equal(zip.Deflate)) 310 expectFileContentsToEqual(reader.File[3], "Hello, Binky") 311 312 Expect(reader.File[4].Name).To(Equal("tmpFile3")) 313 Expect(reader.File[4].Method).To(Equal(zip.Deflate)) 314 expectFileContentsToEqual(reader.File[4], "Bananarama") 315 }) 316 }) 317 318 When("there are relative symlink files", func() { 319 BeforeEach(func() { 320 resources = []Resource{ 321 {Filename: "level1"}, 322 {Filename: "level1/level2"}, 323 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 324 {Filename: "symlink1", Mode: os.ModeSymlink}, 325 {Filename: "level1/level2/symlink2", Mode: os.ModeSymlink}, 326 } 327 }) 328 329 It("zips the file and returns a populated resources list", func() { 330 Expect(executeErr).ToNot(HaveOccurred()) 331 332 Expect(resultZip).ToNot(BeEmpty()) 333 zipFile, err := os.Open(resultZip) 334 Expect(err).ToNot(HaveOccurred()) 335 defer zipFile.Close() 336 337 zipInfo, err := zipFile.Stat() 338 Expect(err).ToNot(HaveOccurred()) 339 340 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 341 Expect(err).ToNot(HaveOccurred()) 342 343 Expect(reader.File).To(HaveLen(5)) 344 345 Expect(reader.File[0].Name).To(Equal("level1/")) 346 347 Expect(reader.File[1].Name).To(Equal("level1/level2/")) 348 349 Expect(reader.File[2].Name).To(Equal("level1/level2/tmpFile1")) 350 expectFileContentsToEqual(reader.File[2], "why hello") 351 352 Expect(reader.File[3].Name).To(Equal("symlink1")) 353 Expect(reader.File[3].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 354 expectFileContentsToEqual(reader.File[3], filepath.FromSlash("level1/level2/tmpFile1")) 355 356 Expect(reader.File[4].Name).To(Equal("level1/level2/symlink2")) 357 Expect(reader.File[4].Mode() & os.ModeSymlink).To(Equal(os.ModeSymlink)) 358 expectFileContentsToEqual(reader.File[4], filepath.FromSlash("../../tmpfile2")) 359 }) 360 }) 361 }) 362 363 When("the files have changed since the scanning", func() { 364 BeforeEach(func() { 365 resources = []Resource{ 366 {Filename: "level1"}, 367 {Filename: "level1/level2"}, 368 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4"}, 369 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95"}, 370 {Filename: "tmpFile3", SHA1: "i dunno, 7?"}, 371 } 372 }) 373 374 It("returns an FileChangedError", func() { 375 Expect(executeErr).To(Equal(actionerror.FileChangedError{Filename: filepath.Join(srcDir, "tmpFile3")})) 376 }) 377 }) 378 }) 379 }) 380 381 func expectFileContentsToEqual(file *zip.File, expectedContents string) { 382 reader, err := file.Open() 383 Expect(err).ToNot(HaveOccurred()) 384 defer reader.Close() 385 386 body, err := ioutil.ReadAll(reader) 387 Expect(err).ToNot(HaveOccurred()) 388 389 Expect(string(body)).To(Equal(expectedContents)) 390 }