github.com/atlassian/git-lob@v0.0.0-20150806085256-2386a5ed291a/integration_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "regexp" 10 "strings" 11 12 . "github.com/atlassian/git-lob/Godeps/_workspace/src/github.com/onsi/ginkgo" 13 . "github.com/atlassian/git-lob/Godeps/_workspace/src/github.com/onsi/gomega" 14 . "github.com/atlassian/git-lob/core" 15 ) 16 17 // This test file is about running git commands with git filters configured 18 // In order to do this, we have to actually run 'go build' to produce a git-lob 19 // binary, and configure filters & .gitattributes in a repo to do it 20 var _ = Describe("Integration", func() { 21 22 BeforeEach(func() { 23 // This singular BeforeEach will just perform the build 24 outp, err := exec.Command("go", "build").CombinedOutput() 25 if err != nil { 26 Fail(fmt.Sprintf("Failed to call 'go build': %v\n%v", err.Error(), string(outp))) 27 } 28 }) 29 30 var gitlobbinarypath string 31 // Function to create a git repo configured with git-lob filters for integration testing 32 createConfiguredRepoFunc := func(root string) { 33 CreateGitRepoForTest(root) 34 ioutil.WriteFile(filepath.Join(root, ".gitattributes"), 35 []byte(`*.png filter=testlob -crlf 36 *.jpg filter=testlob -crlf 37 *.zip filter=testlob -crlf 38 *.tiff filter=testlob -crlf 39 *.tga filter=testlob -crlf 40 *.dds filter=testlob -crlf 41 *.bmp filter=testlob -crlf 42 *.mov filter=testlob -crlf`), 0644) 43 f, err := os.OpenFile(filepath.Join(root, ".git", "config"), os.O_APPEND|os.O_RDWR|os.O_CREATE, 0644) 44 if err != nil { 45 Fail(fmt.Sprintf("Can't write gitconfig: %v", err.Error())) 46 } 47 // Here we have to assume that go test is running in the root source folder 48 cwd, _ := os.Getwd() 49 gitlobbinarypath = filepath.Join(cwd, "git-lob") 50 // For windows we need to convert \ to / since Git doesn't allow backslashes 51 gitlobbinarypath = strings.Replace(gitlobbinarypath, "\\", "/", -1) 52 f.WriteString(fmt.Sprintf(` 53 [filter "testlob"] 54 clean = "%v filter-clean %%f" 55 smudge = "%v filter-smudge %%f" 56 `, gitlobbinarypath, gitlobbinarypath)) 57 f.Close() 58 } 59 60 Context("Integration tests", func() { 61 // All actual tests nested here 62 root := filepath.Join(os.TempDir(), "IntegrationTest") 63 var oldwd string 64 filespercommit := [][]string{ 65 []string{ 66 "img1.png", "img2.jpg", 67 filepath.Join("movies", "movie1.mov"), 68 filepath.Join("movies", "movie2.mov"), 69 filepath.Join("other", "files", "windows.bmp"), 70 }, 71 []string{ 72 "img3.tga", "img4.tiff", "img5.png", 73 filepath.Join("movies", "movie3.mov"), 74 filepath.Join("movies", "movie4.mov"), 75 filepath.Join("other", "files", "windows7.bmp"), 76 }, 77 []string{ 78 "img6.jpg", 79 filepath.Join("other", "files", "windows10.bmp"), 80 }, 81 } 82 sizeForFile := func(filename string, i int) int64 { 83 // not actually that big, we're not doing size tests here 84 if strings.HasSuffix(filename, ".mov") { 85 return int64(i%3*1000 + 2000) 86 } else { 87 return int64(i%3*100 + 300) 88 } 89 } 90 checkExistsAndRightSize := func(fileset int) { 91 files := filespercommit[fileset] 92 for i, file := range files { 93 sz := sizeForFile(file, i) 94 stat, err := os.Stat(file) 95 Expect(err).To(BeNil(), fmt.Sprintf("%v should exist", file)) 96 Expect(stat.Size()).To(BeEquivalentTo(sz), fmt.Sprintf("%v should be correct size", file)) 97 } 98 } 99 checkExistsAndIsPlaceholder := func(fileset int) { 100 files := filespercommit[fileset] 101 for _, file := range files { 102 stat, err := os.Stat(file) 103 Expect(err).To(BeNil(), fmt.Sprintf("%v should exist", file)) 104 Expect(stat.Size()).To(BeEquivalentTo(SHALineLen), fmt.Sprintf("%v should be correct size", file)) 105 } 106 } 107 checkNotExists := func(fileset int) { 108 files := filespercommit[fileset] 109 for _, file := range files { 110 _, err := os.Stat(file) 111 Expect(err).ToNot(BeNil(), fmt.Sprintf("%v should not exist", file)) 112 } 113 } 114 checkGitStatusNotModified := func() { 115 outp, err := exec.Command("git", "status", "--porcelain", "-uno").CombinedOutput() 116 Expect(outp).To(HaveLen(0), "Should be no modified files") 117 Expect(err).To(BeNil(), "git status should succeed") 118 } 119 moveAsideLOBs := func(shas []string) { 120 for _, sha := range shas { 121 meta := GetLocalLOBMetaPath(sha) 122 err := os.Rename(meta, meta+"_bak") 123 Expect(err).To(BeNil(), fmt.Sprintf("Rename should succeed for %v", meta)) 124 // Assuming only one chunk for this test 125 chunk := GetLocalLOBChunkPath(sha, 0) 126 err = os.Rename(chunk, chunk+"_bak") 127 Expect(err).To(BeNil(), fmt.Sprintf("Rename should succeed for %v", chunk)) 128 } 129 130 } 131 restoreLOBs := func(shas []string) { 132 for _, sha := range shas { 133 meta := GetLocalLOBMetaPath(sha) 134 err := os.Rename(meta+"_bak", meta) 135 Expect(err).To(BeNil(), fmt.Sprintf("Rename should succeed for %v", meta)) 136 // Assuming only one chunk for this test 137 chunk := GetLocalLOBChunkPath(sha, 0) 138 err = os.Rename(chunk+"_bak", chunk) 139 Expect(err).To(BeNil(), fmt.Sprintf("Rename should succeed for %v", chunk)) 140 } 141 142 } 143 144 BeforeEach(func() { 145 createConfiguredRepoFunc(root) 146 oldwd, _ = os.Getwd() 147 os.Chdir(root) 148 }) 149 AfterEach(func() { 150 os.Chdir(oldwd) 151 err := ForceRemoveAll(root) 152 if err != nil { 153 Fail(err.Error()) 154 } 155 }) 156 157 It("Git filters work", func() { 158 159 diffregex := regexp.MustCompile("(?m)git-lob: ([A-Fa-f0-9]{40})") 160 // Create commits 161 for ci, commitfiles := range filespercommit { 162 for i, file := range commitfiles { 163 err := os.MkdirAll(filepath.Dir(file), 0755) 164 Expect(err).To(BeNil(), "Shouldn't fail creating dir") 165 sz := sizeForFile(file, i) 166 // Create real content 167 CreateRandomFileForTest(sz, file) 168 // git add, will write placeholder & store via filter (or should) 169 err = exec.Command("git", "add", file).Run() 170 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail in git add for %v", file)) 171 172 // Check content of index & that binaries created 173 174 diffout, err := exec.Command("git", "diff", "--cached", file).CombinedOutput() 175 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail in git diff for %v", file)) 176 match := diffregex.FindStringSubmatch(string(diffout)) 177 Expect(match).ToNot(BeNil(), fmt.Sprintf("Should find git-lob ref in diff for %v", file)) 178 Expect(match).To(HaveLen(2), "Should be 2 matches") 179 sha := match[1] 180 181 // confirm that the file is stored correctly 182 err = CheckLOBFilesForSHA(sha, GetLocalLOBRoot(), false) 183 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail checking storage for %v", file)) 184 } 185 // Commit & tag 186 err := exec.Command("git", "commit", "-m", fmt.Sprintf("Commit %d", ci)).Run() 187 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail commit %d", ci)) 188 err = exec.Command("git", "tag", "-a", "-m", "Nothing", fmt.Sprintf("Tag%d", ci)).Run() 189 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail tagging %d", ci)) 190 191 checkGitStatusNotModified() 192 } 193 194 // Now check out a few times to make sure working copy changes appropriately 195 err := exec.Command("git", "checkout", "Tag0").Run() 196 Expect(err).To(BeNil(), "Shouldn't fail to checkout") 197 checkExistsAndRightSize(0) 198 checkNotExists(1) 199 checkNotExists(2) 200 checkGitStatusNotModified() 201 202 err = exec.Command("git", "checkout", "Tag1").Run() 203 Expect(err).To(BeNil(), "Shouldn't fail to checkout") 204 checkExistsAndRightSize(0) 205 checkExistsAndRightSize(1) 206 checkNotExists(2) 207 checkGitStatusNotModified() 208 209 err = exec.Command("git", "checkout", "Tag2").Run() 210 Expect(err).To(BeNil(), "Shouldn't fail to checkout") 211 checkExistsAndRightSize(0) 212 checkExistsAndRightSize(1) 213 checkExistsAndRightSize(2) 214 checkGitStatusNotModified() 215 216 }) 217 218 It("leaves files unmodified when placeholders present and after checkout", func() { 219 diffregex := regexp.MustCompile("(?m)git-lob: ([A-Fa-f0-9]{40})") 220 var shaspercommit [][]string 221 // Create commits 222 for ci, commitfiles := range filespercommit { 223 var shas []string 224 for i, file := range commitfiles { 225 err := os.MkdirAll(filepath.Dir(file), 0755) 226 Expect(err).To(BeNil(), "Shouldn't fail creating dir") 227 sz := sizeForFile(file, i) 228 // Create real content 229 CreateRandomFileForTest(sz, file) 230 // git add, will write placeholder & store via filter (or should) 231 err = exec.Command("git", "add", file).Run() 232 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail in git add for %v", file)) 233 234 // Get SHA 235 diffout, err := exec.Command("git", "diff", "--cached", file).CombinedOutput() 236 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail in git diff for %v", file)) 237 match := diffregex.FindStringSubmatch(string(diffout)) 238 Expect(match).ToNot(BeNil(), fmt.Sprintf("Should find git-lob ref in diff for %v", file)) 239 Expect(match).To(HaveLen(2), "Should be 2 matches") 240 sha := match[1] 241 242 shas = append(shas, sha) 243 } 244 // Commit & tag 245 err := exec.Command("git", "commit", "-m", fmt.Sprintf("Commit %d", ci)).Run() 246 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail commit %d", ci)) 247 err = exec.Command("git", "tag", "-a", "-m", "Nothing", fmt.Sprintf("Tag%d", ci)).Run() 248 Expect(err).To(BeNil(), fmt.Sprintf("Shouldn't fail tagging %d", ci)) 249 250 shaspercommit = append(shaspercommit, shas) 251 } 252 253 // check out Tag0, thus deleting everything in Tag1/2 254 err := exec.Command("git", "checkout", "Tag0").Run() 255 Expect(err).To(BeNil(), "Shouldn't fail to checkout") 256 checkNotExists(1) 257 checkNotExists(2) 258 checkGitStatusNotModified() 259 260 // Now move aside storage for files in Tag1/2 so that they will be missing 261 // when we try to check them out 262 moveAsideLOBs(shaspercommit[1]) 263 moveAsideLOBs(shaspercommit[2]) 264 err = exec.Command("git", "checkout", "Tag2").Run() 265 Expect(err).To(BeNil(), "Shouldn't fail to checkout") 266 checkExistsAndIsPlaceholder(1) 267 checkExistsAndIsPlaceholder(2) 268 269 // now restore data for 1 270 restoreLOBs(shaspercommit[1]) 271 // Now git-lob checkout - note we call direct not via "git lob" so we don't assume this test version is 272 // on the path (it probably isn't). We ignore errors because Tag2 files are still missing so will return non-zero 273 exec.Command(gitlobbinarypath, "checkout").Run() 274 checkExistsAndRightSize(1) 275 checkExistsAndIsPlaceholder(2) 276 checkGitStatusNotModified() 277 278 // now restore data for 2 279 restoreLOBs(shaspercommit[2]) 280 // Now git-lob checkout - note we call direct not via "git lob" so we don't assume this test version is 281 // on the path (it probably isn't). Should be no errors this time since complete data 282 err = exec.Command(gitlobbinarypath, "checkout").Run() 283 Expect(err).To(BeNil(), "Shouldn't fail to git-lob checkout") 284 checkExistsAndRightSize(1) 285 checkExistsAndRightSize(2) 286 checkGitStatusNotModified() 287 288 }) 289 290 }) 291 })