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  })