github.com/cloudfoundry/cli@v7.1.0+incompatible/actor/sharedaction/resource_windows_test.go (about) 1 package sharedaction_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 8 "code.cloudfoundry.org/cli/actor/actionerror" 9 . "code.cloudfoundry.org/cli/actor/sharedaction" 10 "code.cloudfoundry.org/cli/actor/sharedaction/sharedactionfakes" 11 "code.cloudfoundry.org/ykk" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 ) 15 16 var _ = Describe("Resource Actions", func() { 17 var ( 18 actor *Actor 19 fakeConfig *sharedactionfakes.FakeConfig 20 srcDir string 21 ) 22 23 BeforeEach(func() { 24 fakeConfig = &sharedactionfakes.FakeConfig{} 25 actor = NewActor(fakeConfig) 26 27 // Creates the following directory structure: 28 // level1/level2/tmpFile1 29 // tmpfile2 30 // tmpfile3 31 32 var err error 33 srcDir, err = ioutil.TempDir("", "v2-resource-actions") 34 Expect(err).ToNot(HaveOccurred()) 35 36 subDir := filepath.Join(srcDir, "level1", "level2") 37 err = os.MkdirAll(subDir, 0777) 38 Expect(err).ToNot(HaveOccurred()) 39 40 err = ioutil.WriteFile(filepath.Join(subDir, "tmpFile1"), []byte("why hello"), 0666) 41 Expect(err).ToNot(HaveOccurred()) 42 43 err = ioutil.WriteFile(filepath.Join(srcDir, "tmpFile2"), []byte("Hello, Binky"), 0666) 44 Expect(err).ToNot(HaveOccurred()) 45 46 err = ioutil.WriteFile(filepath.Join(srcDir, "tmpFile3"), []byte("Bananarama"), 0666) 47 Expect(err).ToNot(HaveOccurred()) 48 }) 49 50 AfterEach(func() { 51 Expect(os.RemoveAll(srcDir)).ToNot(HaveOccurred()) 52 }) 53 54 Describe("GatherArchiveResources", func() { 55 When("the archive exists", func() { 56 var ( 57 archive string 58 59 resources []Resource 60 executeErr error 61 ) 62 63 BeforeEach(func() { 64 tmpfile, err := ioutil.TempFile("", "gather-archive-resource-test") 65 Expect(err).ToNot(HaveOccurred()) 66 defer tmpfile.Close() 67 archive = tmpfile.Name() 68 }) 69 70 JustBeforeEach(func() { 71 err := zipit(srcDir, archive, "") 72 Expect(err).ToNot(HaveOccurred()) 73 74 resources, executeErr = actor.GatherArchiveResources(archive) 75 }) 76 77 AfterEach(func() { 78 Expect(os.RemoveAll(archive)).ToNot(HaveOccurred()) 79 }) 80 81 It("gathers a list of all files in a source archive", func() { 82 Expect(executeErr).ToNot(HaveOccurred()) 83 84 Expect(resources).To(Equal( 85 []Resource{ 86 {Filename: "/", Mode: DefaultFolderPermissions}, 87 {Filename: "/level1/", Mode: DefaultFolderPermissions}, 88 {Filename: "/level1/level2/", Mode: DefaultFolderPermissions}, 89 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: DefaultArchiveFilePermissions}, 90 {Filename: "/tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: DefaultArchiveFilePermissions}, 91 {Filename: "/tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: DefaultArchiveFilePermissions}, 92 })) 93 }) 94 95 When("the file is a symlink to an archive", func() { 96 var symlinkToArchive string 97 98 BeforeEach(func() { 99 tempFile, err := ioutil.TempFile("", "symlink-to-archive") 100 Expect(err).ToNot(HaveOccurred()) 101 Expect(tempFile.Close()).To(Succeed()) 102 symlinkToArchive = tempFile.Name() 103 Expect(os.Remove(symlinkToArchive)).To(Succeed()) 104 105 Expect(os.Symlink(archive, symlinkToArchive)).To(Succeed()) 106 }) 107 108 JustBeforeEach(func() { 109 resources, executeErr = actor.GatherArchiveResources(symlinkToArchive) 110 }) 111 112 AfterEach(func() { 113 Expect(os.Remove(symlinkToArchive)).To(Succeed()) 114 }) 115 116 It("gathers a list of all files in a source archive", func() { 117 Expect(executeErr).ToNot(HaveOccurred()) 118 119 Expect(resources).To(Equal( 120 []Resource{ 121 {Filename: "/", Mode: DefaultFolderPermissions}, 122 {Filename: "/level1/", Mode: DefaultFolderPermissions}, 123 {Filename: "/level1/level2/", Mode: DefaultFolderPermissions}, 124 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: DefaultArchiveFilePermissions}, 125 {Filename: "/tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: DefaultArchiveFilePermissions}, 126 {Filename: "/tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: DefaultArchiveFilePermissions}, 127 })) 128 }) 129 }) 130 131 When("a .cfignore file exists in the archive", func() { 132 BeforeEach(func() { 133 err := ioutil.WriteFile(filepath.Join(srcDir, ".cfignore"), []byte("level2"), 0655) 134 Expect(err).ToNot(HaveOccurred()) 135 }) 136 137 It("excludes all patterns of files mentioned in .cfignore", func() { 138 Expect(executeErr).ToNot(HaveOccurred()) 139 140 Expect(resources).To(Equal( 141 []Resource{ 142 {Filename: "/", Mode: DefaultFolderPermissions}, 143 {Filename: "/level1/", Mode: DefaultFolderPermissions}, 144 {Filename: "/tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: DefaultArchiveFilePermissions}, 145 {Filename: "/tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: DefaultArchiveFilePermissions}, 146 })) 147 }) 148 }) 149 150 When("default ignored files exist in the archive", func() { 151 BeforeEach(func() { 152 for _, filename := range DefaultIgnoreLines { 153 if filename != ".cfignore" { 154 err := ioutil.WriteFile(filepath.Join(srcDir, filename), nil, 0655) 155 Expect(err).ToNot(HaveOccurred()) 156 err = ioutil.WriteFile(filepath.Join(srcDir, "level1", filename), nil, 0655) 157 Expect(err).ToNot(HaveOccurred()) 158 } 159 } 160 }) 161 162 It("excludes all default files", func() { 163 Expect(executeErr).ToNot(HaveOccurred()) 164 165 Expect(resources).To(Equal( 166 []Resource{ 167 {Filename: "/", Mode: DefaultFolderPermissions}, 168 {Filename: "/level1/", Mode: DefaultFolderPermissions}, 169 {Filename: "/level1/level2/", Mode: DefaultFolderPermissions}, 170 {Filename: "/level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: DefaultArchiveFilePermissions}, 171 {Filename: "/tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: DefaultArchiveFilePermissions}, 172 {Filename: "/tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: DefaultArchiveFilePermissions}, 173 })) 174 }) 175 }) 176 }) 177 178 When("the archive does not exist", func() { 179 It("returns an error if the file is problematic", func() { 180 _, err := actor.GatherArchiveResources("/does/not/exist") 181 Expect(os.IsNotExist(err)).To(BeTrue()) 182 }) 183 }) 184 }) 185 186 Describe("GatherDirectoryResources", func() { 187 When("files exist in the directory", func() { 188 var ( 189 gatheredResources []Resource 190 executeErr error 191 ) 192 193 JustBeforeEach(func() { 194 gatheredResources, executeErr = actor.GatherDirectoryResources(srcDir) 195 }) 196 197 It("gathers a list of all directories files in a source directory", func() { 198 Expect(executeErr).ToNot(HaveOccurred()) 199 200 Expect(gatheredResources).To(Equal( 201 []Resource{ 202 {Filename: "level1", Mode: DefaultFolderPermissions}, 203 {Filename: "level1/level2", Mode: DefaultFolderPermissions}, 204 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: 0766}, 205 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: 0766}, 206 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: 0766}, 207 })) 208 }) 209 210 When("the provided path is a symlink to the directory", func() { 211 var tmpDir string 212 213 BeforeEach(func() { 214 tmpDir = srcDir 215 216 tmpFile, err := ioutil.TempFile("", "symlink-file-") 217 Expect(err).ToNot(HaveOccurred()) 218 Expect(tmpFile.Close()).To(Succeed()) 219 220 srcDir = tmpFile.Name() 221 Expect(os.Remove(srcDir)).To(Succeed()) 222 Expect(os.Symlink(tmpDir, srcDir)).To(Succeed()) 223 }) 224 225 AfterEach(func() { 226 Expect(os.RemoveAll(tmpDir)).To(Succeed()) 227 }) 228 229 It("gathers a list of all directories files in a source directory", func() { 230 Expect(executeErr).ToNot(HaveOccurred()) 231 232 Expect(gatheredResources).To(Equal( 233 []Resource{ 234 {Filename: "level1", Mode: DefaultFolderPermissions}, 235 {Filename: "level1/level2", Mode: DefaultFolderPermissions}, 236 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: 0766}, 237 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: 0766}, 238 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: 0766}, 239 })) 240 }) 241 }) 242 243 When("a .cfignore file exists in the sourceDir", func() { 244 Context("with relative paths", func() { 245 BeforeEach(func() { 246 err := ioutil.WriteFile(filepath.Join(srcDir, ".cfignore"), []byte("level2"), 0666) 247 Expect(err).ToNot(HaveOccurred()) 248 }) 249 250 It("excludes all patterns of files mentioned in .cfignore", func() { 251 Expect(executeErr).ToNot(HaveOccurred()) 252 253 Expect(gatheredResources).To(Equal( 254 []Resource{ 255 {Filename: "level1", Mode: DefaultFolderPermissions}, 256 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: 0766}, 257 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: 0766}, 258 })) 259 }) 260 }) 261 262 Context("with absolute paths - where '/' == sourceDir", func() { 263 BeforeEach(func() { 264 err := ioutil.WriteFile(filepath.Join(srcDir, ".cfignore"), []byte("/level1/level2"), 0666) 265 Expect(err).ToNot(HaveOccurred()) 266 }) 267 268 It("excludes all patterns of files mentioned in .cfignore", func() { 269 Expect(executeErr).ToNot(HaveOccurred()) 270 271 Expect(gatheredResources).To(Equal( 272 []Resource{ 273 {Filename: "level1", Mode: DefaultFolderPermissions}, 274 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: 0766}, 275 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: 0766}, 276 })) 277 }) 278 }) 279 }) 280 281 When("default ignored files exist in the app dir", func() { 282 BeforeEach(func() { 283 for _, filename := range DefaultIgnoreLines { 284 if filename != ".cfignore" { 285 err := ioutil.WriteFile(filepath.Join(srcDir, filename), nil, 0655) 286 Expect(err).ToNot(HaveOccurred()) 287 err = ioutil.WriteFile(filepath.Join(srcDir, "level1", filename), nil, 0655) 288 Expect(err).ToNot(HaveOccurred()) 289 } 290 } 291 }) 292 293 It("excludes all default files", func() { 294 Expect(executeErr).ToNot(HaveOccurred()) 295 296 Expect(gatheredResources).To(Equal( 297 []Resource{ 298 {Filename: "level1", Mode: DefaultFolderPermissions}, 299 {Filename: "level1/level2", Mode: DefaultFolderPermissions}, 300 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: 0766}, 301 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: 0766}, 302 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: 0766}, 303 })) 304 }) 305 }) 306 307 When("trace files are in the source directory", func() { 308 BeforeEach(func() { 309 traceFilePath := filepath.Join(srcDir, "i-am-trace.txt") 310 err := ioutil.WriteFile(traceFilePath, nil, 0666) 311 Expect(err).ToNot(HaveOccurred()) 312 313 fakeConfig.VerboseReturns(false, []string{traceFilePath, "C:\\some-other-path"}) 314 }) 315 316 It("excludes all of the trace files", func() { 317 Expect(executeErr).ToNot(HaveOccurred()) 318 319 Expect(gatheredResources).To(Equal( 320 []Resource{ 321 {Filename: "level1", Mode: DefaultFolderPermissions}, 322 {Filename: "level1/level2", Mode: DefaultFolderPermissions}, 323 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: 0766}, 324 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: 0766}, 325 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: 0766}, 326 })) 327 }) 328 }) 329 }) 330 331 When("the directory is empty", func() { 332 var emptyDir string 333 334 BeforeEach(func() { 335 var err error 336 emptyDir, err = ioutil.TempDir("", "v2-resource-actions-empty") 337 Expect(err).ToNot(HaveOccurred()) 338 }) 339 340 AfterEach(func() { 341 Expect(os.RemoveAll(emptyDir)).ToNot(HaveOccurred()) 342 }) 343 344 It("returns an EmptyDirectoryError", func() { 345 _, err := actor.GatherDirectoryResources(emptyDir) 346 Expect(err).To(MatchError(actionerror.EmptyDirectoryError{Path: emptyDir})) 347 }) 348 }) 349 }) 350 351 Describe("ZipDirectoryResources", func() { 352 var ( 353 resultZip string 354 resources []Resource 355 executeErr error 356 ) 357 358 BeforeEach(func() { 359 resources = []Resource{ 360 {Filename: "level1", Mode: DefaultFolderPermissions}, 361 {Filename: "level1/level2", Mode: DefaultFolderPermissions}, 362 {Filename: "level1/level2/tmpFile1", SHA1: "9e36efec86d571de3a38389ea799a796fe4782f4", Size: 9, Mode: 0766}, 363 {Filename: "tmpFile2", SHA1: "e594bdc795bb293a0e55724137e53a36dc0d9e95", Size: 12, Mode: 0766}, 364 {Filename: "tmpFile3", SHA1: "f4c9ca85f3e084ffad3abbdabbd2a890c034c879", Size: 10, Mode: 0766}, 365 } 366 }) 367 368 JustBeforeEach(func() { 369 resultZip, executeErr = actor.ZipDirectoryResources(srcDir, resources) 370 }) 371 372 AfterEach(func() { 373 err := os.RemoveAll(srcDir) 374 Expect(err).ToNot(HaveOccurred()) 375 376 err = os.RemoveAll(resultZip) 377 Expect(err).ToNot(HaveOccurred()) 378 }) 379 380 When("zipping on windows", func() { 381 It("zips the directory and sets all the file modes to 07XX", func() { 382 Expect(executeErr).ToNot(HaveOccurred()) 383 384 Expect(resultZip).ToNot(BeEmpty()) 385 zipFile, err := os.Open(resultZip) 386 Expect(err).ToNot(HaveOccurred()) 387 defer zipFile.Close() 388 389 zipInfo, err := zipFile.Stat() 390 Expect(err).ToNot(HaveOccurred()) 391 392 reader, err := ykk.NewReader(zipFile, zipInfo.Size()) 393 Expect(err).ToNot(HaveOccurred()) 394 395 Expect(reader.File).To(HaveLen(5)) 396 Expect(reader.File[2].Mode()).To(Equal(os.FileMode(0766)), reader.File[2].Name) 397 Expect(reader.File[3].Mode()).To(Equal(os.FileMode(0766)), reader.File[3].Name) 398 Expect(reader.File[4].Mode()).To(Equal(os.FileMode(0766)), reader.File[4].Name) 399 }) 400 }) 401 }) 402 })