github.com/paketo-buildpacks/packit@v1.3.2-0.20211206231111-86b75c657449/fs/move_test.go (about)

     1  package fs_test
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/paketo-buildpacks/packit/fs"
     9  	"github.com/sclevine/spec"
    10  
    11  	. "github.com/onsi/gomega"
    12  )
    13  
    14  func testMove(t *testing.T, context spec.G, it spec.S) {
    15  	var Expect = NewWithT(t).Expect
    16  
    17  	context("Move", func() {
    18  		var (
    19  			sourceDir      string
    20  			destinationDir string
    21  		)
    22  
    23  		it.Before(func() {
    24  			var err error
    25  			sourceDir, err = os.MkdirTemp("", "source")
    26  			Expect(err).NotTo(HaveOccurred())
    27  
    28  			destinationDir, err = os.MkdirTemp("", "destination")
    29  			Expect(err).NotTo(HaveOccurred())
    30  		})
    31  
    32  		it.After(func() {
    33  			Expect(os.RemoveAll(sourceDir)).To(Succeed())
    34  			Expect(os.RemoveAll(destinationDir)).To(Succeed())
    35  		})
    36  
    37  		context("when the source is a file", func() {
    38  			var source, destination string
    39  
    40  			it.Before(func() {
    41  				source = filepath.Join(sourceDir, "source")
    42  				destination = filepath.Join(destinationDir, "destination")
    43  
    44  				err := os.WriteFile(source, []byte("some-content"), 0644)
    45  				Expect(err).NotTo(HaveOccurred())
    46  			})
    47  
    48  			it("moves the source file to the destination", func() {
    49  				err := fs.Move(source, destination)
    50  				Expect(err).NotTo(HaveOccurred())
    51  
    52  				content, err := os.ReadFile(destination)
    53  				Expect(err).NotTo(HaveOccurred())
    54  				Expect(string(content)).To(Equal("some-content"))
    55  
    56  				info, err := os.Stat(destination)
    57  				Expect(err).NotTo(HaveOccurred())
    58  				Expect(info.Mode()).To(Equal(os.FileMode(0644)))
    59  
    60  				Expect(source).NotTo(BeAnExistingFile())
    61  			})
    62  
    63  			context("failure cases", func() {
    64  				context("when the source cannot be read", func() {
    65  					it.Before(func() {
    66  						Expect(os.Chmod(source, 0000)).To(Succeed())
    67  					})
    68  
    69  					it("returns an error", func() {
    70  						err := fs.Move(source, destination)
    71  						Expect(err).To(MatchError(ContainSubstring("permission denied")))
    72  					})
    73  				})
    74  
    75  				context("when the destination cannot be removed", func() {
    76  					it.Before(func() {
    77  						Expect(os.Chmod(destinationDir, 0000)).To(Succeed())
    78  					})
    79  
    80  					it("returns an error", func() {
    81  						err := fs.Move(source, destination)
    82  						Expect(err).To(MatchError(ContainSubstring("failed to move: failed to copy: destination exists:")))
    83  						Expect(err).To(MatchError(ContainSubstring("permission denied")))
    84  					})
    85  				})
    86  			})
    87  		})
    88  
    89  		context("when the source is a directory", func() {
    90  			var source, destination, external string
    91  
    92  			it.Before(func() {
    93  				var err error
    94  				external, err = os.MkdirTemp("", "external")
    95  				Expect(err).NotTo(HaveOccurred())
    96  
    97  				err = os.WriteFile(filepath.Join(external, "some-file"), []byte("some-content"), 0644)
    98  				Expect(err).NotTo(HaveOccurred())
    99  
   100  				source = filepath.Join(sourceDir, "source")
   101  				destination = filepath.Join(destinationDir, "destination")
   102  
   103  				Expect(os.MkdirAll(filepath.Join(source, "some-dir"), os.ModePerm)).To(Succeed())
   104  
   105  				err = os.WriteFile(filepath.Join(source, "some-dir", "some-file"), []byte("some-content"), 0644)
   106  				Expect(err).NotTo(HaveOccurred())
   107  
   108  				err = os.WriteFile(filepath.Join(source, "some-dir", "readonly-file"), []byte("some-content"), 0444)
   109  				Expect(err).NotTo(HaveOccurred())
   110  
   111  				err = os.Symlink("some-file", filepath.Join(source, "some-dir", "some-symlink"))
   112  				Expect(err).NotTo(HaveOccurred())
   113  
   114  				err = os.Symlink(filepath.Join(external, "some-file"), filepath.Join(source, "some-dir", "external-symlink"))
   115  				Expect(err).NotTo(HaveOccurred())
   116  			})
   117  
   118  			context("when the destination does not exist", func() {
   119  				it("moves the source directory to the destination", func() {
   120  					err := fs.Move(source, destination)
   121  					Expect(err).NotTo(HaveOccurred())
   122  
   123  					Expect(destination).To(BeADirectory())
   124  
   125  					content, err := os.ReadFile(filepath.Join(destination, "some-dir", "some-file"))
   126  					Expect(err).NotTo(HaveOccurred())
   127  					Expect(string(content)).To(Equal("some-content"))
   128  
   129  					info, err := os.Stat(filepath.Join(destination, "some-dir", "some-file"))
   130  					Expect(err).NotTo(HaveOccurred())
   131  					Expect(info.Mode()).To(Equal(os.FileMode(0644)))
   132  
   133  					info, err = os.Stat(filepath.Join(destination, "some-dir", "readonly-file"))
   134  					Expect(err).NotTo(HaveOccurred())
   135  					Expect(info.Mode()).To(Equal(os.FileMode(0444)))
   136  
   137  					path, err := os.Readlink(filepath.Join(destination, "some-dir", "some-symlink"))
   138  					Expect(err).NotTo(HaveOccurred())
   139  					Expect(path).To(Equal("some-file"))
   140  
   141  					path, err = os.Readlink(filepath.Join(destination, "some-dir", "external-symlink"))
   142  					Expect(err).NotTo(HaveOccurred())
   143  					Expect(path).To(Equal(filepath.Join(external, "some-file")))
   144  
   145  					Expect(source).NotTo(BeAnExistingFile())
   146  				})
   147  			})
   148  
   149  			context("when the destination is a file", func() {
   150  				it.Before(func() {
   151  					Expect(os.RemoveAll(destination))
   152  					Expect(os.WriteFile(destination, []byte{}, os.ModePerm)).To(Succeed())
   153  				})
   154  
   155  				it("moves the source directory to the destination", func() {
   156  					err := fs.Move(source, destination)
   157  					Expect(err).NotTo(HaveOccurred())
   158  
   159  					Expect(destination).To(BeADirectory())
   160  
   161  					content, err := os.ReadFile(filepath.Join(destination, "some-dir", "some-file"))
   162  					Expect(err).NotTo(HaveOccurred())
   163  					Expect(string(content)).To(Equal("some-content"))
   164  
   165  					info, err := os.Stat(filepath.Join(destination, "some-dir", "some-file"))
   166  					Expect(err).NotTo(HaveOccurred())
   167  					Expect(info.Mode()).To(Equal(os.FileMode(0644)))
   168  
   169  					info, err = os.Stat(filepath.Join(destination, "some-dir", "readonly-file"))
   170  					Expect(err).NotTo(HaveOccurred())
   171  					Expect(info.Mode()).To(Equal(os.FileMode(0444)))
   172  
   173  					path, err := os.Readlink(filepath.Join(destination, "some-dir", "some-symlink"))
   174  					Expect(err).NotTo(HaveOccurred())
   175  					Expect(path).To(Equal("some-file"))
   176  
   177  					path, err = os.Readlink(filepath.Join(destination, "some-dir", "external-symlink"))
   178  					Expect(err).NotTo(HaveOccurred())
   179  					Expect(path).To(Equal(filepath.Join(external, "some-file")))
   180  
   181  					Expect(source).NotTo(BeAnExistingFile())
   182  				})
   183  			})
   184  
   185  			context("failure cases", func() {
   186  				context("when the source does not exist", func() {
   187  					it("returns an error", func() {
   188  						err := fs.Move("no-such-source", destination)
   189  						Expect(err).To(MatchError(ContainSubstring("no such file or directory")))
   190  					})
   191  				})
   192  
   193  				context("when the source cannot be walked", func() {
   194  					it.Before(func() {
   195  						Expect(os.Chmod(source, 0000)).To(Succeed())
   196  					})
   197  
   198  					it.After(func() {
   199  						Expect(os.Chmod(source, 0777)).To(Succeed())
   200  					})
   201  
   202  					it("returns an error", func() {
   203  						err := fs.Move(source, destination)
   204  						Expect(err).To(MatchError(ContainSubstring("permission denied")))
   205  					})
   206  				})
   207  			})
   208  		})
   209  	})
   210  }