github.com/paketo-buildpacks/packit@v1.3.2-0.20211206231111-86b75c657449/fs/checksum_calculator_test.go (about) 1 package fs_test 2 3 import ( 4 "fmt" 5 "math/rand" 6 "os" 7 "path/filepath" 8 "testing" 9 10 "github.com/paketo-buildpacks/packit/fs" 11 "github.com/sclevine/spec" 12 13 . "github.com/onsi/gomega" 14 ) 15 16 func testChecksumCalculator(t *testing.T, context spec.G, it spec.S) { 17 var ( 18 Expect = NewWithT(t).Expect 19 20 calculator fs.ChecksumCalculator 21 workingDir string 22 ) 23 24 context("Sum", func() { 25 it.Before(func() { 26 var err error 27 workingDir, err = os.MkdirTemp("", "working-dir") 28 Expect(err).NotTo(HaveOccurred()) 29 30 calculator = fs.NewChecksumCalculator() 31 }) 32 33 it.After(func() { 34 Expect(os.RemoveAll(workingDir)).To(Succeed()) 35 }) 36 37 context("when given a single file", func() { 38 var path string 39 40 it.Before(func() { 41 path = filepath.Join(workingDir, "some-file") 42 Expect(os.WriteFile(path, []byte{}, os.ModePerm)).To(Succeed()) 43 }) 44 45 it("generates the SHA256 checksum for that file", func() { 46 sum, err := calculator.Sum(path) 47 Expect(err).ToNot(HaveOccurred()) 48 Expect(sum).To(Equal("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")) 49 }) 50 }) 51 52 context("when given an empty directory", func() { 53 var path string 54 it.Before(func() { 55 path = filepath.Join(workingDir, "some-dir") 56 Expect(os.MkdirAll(path, os.ModePerm)).To(Succeed()) 57 }) 58 59 it("generates the SHA256 checksum for that directory", func() { 60 sum, err := calculator.Sum(path) 61 Expect(err).ToNot(HaveOccurred()) 62 Expect(sum).To(Equal("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")) 63 }) 64 65 }) 66 67 context("when given multiple files", func() { 68 var path1 string 69 var path2 string 70 var paths []string 71 72 it.Before(func() { 73 path1 = filepath.Join(workingDir, "some-file1") 74 Expect(os.WriteFile(path1, []byte{}, os.ModePerm)).To(Succeed()) 75 path2 = filepath.Join(workingDir, "some-file2") 76 Expect(os.WriteFile(path2, []byte{}, os.ModePerm)).To(Succeed()) 77 }) 78 79 it("generates the SHA256 checksum for multiple files", func() { 80 sum, err := calculator.Sum(path1, path2) 81 Expect(err).ToNot(HaveOccurred()) 82 Expect(sum).To(Equal("2dba5dbc339e7316aea2683faf839c1b7b1ee2313db792112588118df066aa35")) 83 }) 84 85 context("when the files are different", func() { 86 it.Before(func() { 87 // Generate a bunch of files and shuffle input order to ensure test fails consistently without sorting implemented 88 for i := 0; i < 10; i++ { 89 path := filepath.Join(workingDir, fmt.Sprintf("some-file-%d", i)) 90 Expect(os.WriteFile(path, []byte(fmt.Sprintf("some-file-contents-%d", i)), os.ModePerm)).To(Succeed()) 91 paths = append(paths, path) 92 } 93 }) 94 95 it("generates the same checksum no matter the order of the inputs", func() { 96 var shuffledPaths []string 97 sum1, err := calculator.Sum(paths...) 98 Expect(err).NotTo(HaveOccurred()) 99 100 for _, value := range rand.Perm(len(paths)) { 101 shuffledPaths = append(shuffledPaths, paths[value]) 102 } 103 104 sum2, err := calculator.Sum(shuffledPaths...) 105 Expect(err).NotTo(HaveOccurred()) 106 Expect(sum1).To(Equal(sum2)) 107 }) 108 }) 109 110 context("failure cases", func() { 111 context("either of the files cannot be read", func() { 112 it.Before(func() { 113 Expect(os.Chmod(path2, 0222)).To(Succeed()) 114 }) 115 116 it("returns an error", func() { 117 _, err := calculator.Sum(path1, path2) 118 Expect(err).To(MatchError(ContainSubstring("failed to calculate checksum"))) 119 Expect(err).To(MatchError(ContainSubstring("permission denied"))) 120 }) 121 }) 122 }) 123 }) 124 125 context("when given multiple directories", func() { 126 var dir1 string 127 var dir2 string 128 129 it.Before(func() { 130 dir1 = filepath.Join(workingDir, "some-dir") 131 Expect(os.MkdirAll(dir1, os.ModePerm)).To(Succeed()) 132 133 dir2 = filepath.Join(workingDir, "some-other-dir") 134 Expect(os.MkdirAll(dir2, os.ModePerm)).To(Succeed()) 135 136 Expect(os.WriteFile(filepath.Join(dir1, "some-file"), []byte{}, os.ModePerm)).To(Succeed()) 137 Expect(os.WriteFile(filepath.Join(dir1, "some-other-file"), []byte{}, os.ModePerm)).To(Succeed()) 138 139 Expect(os.WriteFile(filepath.Join(dir2, "some-file"), []byte{}, os.ModePerm)).To(Succeed()) 140 Expect(os.WriteFile(filepath.Join(dir2, "some-other-file"), []byte{}, os.ModePerm)).To(Succeed()) 141 }) 142 143 it("returns the 256 sha sum of a directory containing the directories", func() { 144 sum, err := calculator.Sum(dir1, dir2) 145 Expect(err).ToNot(HaveOccurred()) 146 Expect(sum).To(Equal("9fb03d22515ca48e57b578de80bbc1e75d5126dbb2de6db177947c3da3b2276f")) 147 }) 148 149 context("failure cases", func() { 150 context("when one of the directories cannot be read", func() { 151 it.Before(func() { 152 Expect(os.Chmod(dir2, 0222)).To(Succeed()) 153 }) 154 155 it.After(func() { 156 Expect(os.Chmod(dir2, os.ModePerm)).To(Succeed()) 157 }) 158 159 it("returns an error", func() { 160 _, err := calculator.Sum(dir1, dir2) 161 Expect(err).To(MatchError(ContainSubstring("failed to calculate checksum"))) 162 Expect(err).To(MatchError(ContainSubstring("permission denied"))) 163 }) 164 }) 165 166 context("when a file in the directory cannot be read", func() { 167 it.Before(func() { 168 Expect(os.Chmod(filepath.Join(dir2, "some-file"), 0222)).To(Succeed()) 169 }) 170 171 it("returns an error", func() { 172 _, err := calculator.Sum(dir1, dir2) 173 Expect(err).To(MatchError(ContainSubstring("failed to calculate checksum"))) 174 Expect(err).To(MatchError(ContainSubstring("permission denied"))) 175 }) 176 }) 177 }) 178 }) 179 180 context("when given a combination of files and directories", func() { 181 var dir string 182 var path string 183 184 it.Before(func() { 185 dir = filepath.Join(workingDir, "some-dir") 186 path = filepath.Join(workingDir, "some-filepath") 187 Expect(os.MkdirAll(dir, os.ModePerm)).To(Succeed()) 188 189 Expect(os.WriteFile(filepath.Join(dir, "some-file"), []byte{}, os.ModePerm)).To(Succeed()) 190 Expect(os.WriteFile(filepath.Join(dir, "some-other-file"), []byte{}, os.ModePerm)).To(Succeed()) 191 Expect(os.WriteFile(path, []byte{}, os.ModePerm)).To(Succeed()) 192 }) 193 194 it("returns the 256 sha sum of a directory containing the file and directory", func() { 195 sum, err := calculator.Sum(dir, path) 196 Expect(err).ToNot(HaveOccurred()) 197 Expect(sum).To(Equal("1a03c02fb531d7e1ce353b2f20711c79af2b66730d6de865fb130734973ccd2c")) 198 }) 199 }) 200 201 context("when given multiple items with same base name", func() { 202 var dir string 203 var path string 204 205 it.Before(func() { 206 dir = filepath.Join(workingDir, "some-dir", "the-item") 207 path = filepath.Join(workingDir, "the-item") 208 Expect(os.MkdirAll(dir, os.ModePerm)).To(Succeed()) 209 210 Expect(os.WriteFile(filepath.Join(dir, "some-file"), []byte{}, os.ModePerm)).To(Succeed()) 211 Expect(os.WriteFile(filepath.Join(dir, "some-other-file"), []byte{}, os.ModePerm)).To(Succeed()) 212 Expect(os.WriteFile(path, []byte{}, os.ModePerm)).To(Succeed()) 213 214 }) 215 216 it("returns the 256 sha sum of the items", func() { 217 sum, err := calculator.Sum(dir, path) 218 Expect(err).ToNot(HaveOccurred()) 219 Expect(sum).To(Equal("1a03c02fb531d7e1ce353b2f20711c79af2b66730d6de865fb130734973ccd2c")) 220 }) 221 }) 222 223 context("failure cases", func() { 224 context("when any of the given paths do not exist", func() { 225 it("returns an error", func() { 226 _, err := calculator.Sum("not a real path") 227 Expect(err).To(MatchError(ContainSubstring("failed to calculate checksum"))) 228 Expect(err).To(MatchError(ContainSubstring("no such file or directory"))) 229 }) 230 }) 231 }) 232 }) 233 }