github.com/hawser/git-hawser@v2.5.2+incompatible/tools/filetools_test.go (about) 1 package tools 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "runtime" 9 "sort" 10 "testing" 11 12 "github.com/git-lfs/git-lfs/subprocess" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func TestCleanPathsCleansPaths(t *testing.T) { 17 cleaned := CleanPaths("/foo/bar/,/foo/bar/baz", ",") 18 assert.Equal(t, []string{"/foo/bar", "/foo/bar/baz"}, cleaned) 19 } 20 21 func TestCleanPathsReturnsNoResultsWhenGivenNoPaths(t *testing.T) { 22 cleaned := CleanPaths("", ",") 23 assert.Empty(t, cleaned) 24 } 25 26 func TestFastWalkBasic(t *testing.T) { 27 rootDir, err := ioutil.TempDir(os.TempDir(), "GitLfsTestFastWalkBasic") 28 if err != nil { 29 assert.FailNow(t, "Unable to get temp dir: %v", err) 30 } 31 defer os.RemoveAll(rootDir) 32 os.Chdir(rootDir) 33 34 expectedEntries := createFastWalkInputData(10, 160) 35 36 walker := fastWalkWithExcludeFiles(expectedEntries[0], "") 37 gotEntries, gotErrors := collectFastWalkResults(walker.ch) 38 39 assert.Empty(t, gotErrors) 40 41 sort.Strings(expectedEntries) 42 sort.Strings(gotEntries) 43 assert.Equal(t, expectedEntries, gotEntries) 44 } 45 46 func BenchmarkFastWalkGitRepoChannels(b *testing.B) { 47 rootDir, err := ioutil.TempDir(os.TempDir(), "GitLfsBenchFastWalkGitRepoChannels") 48 if err != nil { 49 assert.FailNow(b, "Unable to get temp dir: %v", err) 50 } 51 defer os.RemoveAll(rootDir) 52 os.Chdir(rootDir) 53 entries := createFastWalkInputData(1000, 5000) 54 55 for i := 0; i < b.N; i++ { 56 var files, errors int 57 FastWalkGitRepo(entries[0], func(parent string, info os.FileInfo, err error) { 58 if err != nil { 59 errors++ 60 } else { 61 files++ 62 } 63 }) 64 b.Logf("files: %d, errors: %d", files, errors) 65 } 66 } 67 68 func BenchmarkFastWalkGitRepoCallback(b *testing.B) { 69 rootDir, err := ioutil.TempDir(os.TempDir(), "GitLfsBenchFastWalkGitRepoCallback") 70 if err != nil { 71 assert.FailNow(b, "Unable to get temp dir: %v", err) 72 } 73 defer os.RemoveAll(rootDir) 74 os.Chdir(rootDir) 75 entries := createFastWalkInputData(1000, 5000) 76 77 for i := 0; i < b.N; i++ { 78 var files, errors int 79 FastWalkGitRepo(entries[0], func(parentDir string, info os.FileInfo, err error) { 80 if err != nil { 81 errors++ 82 } else { 83 files++ 84 } 85 }) 86 87 b.Logf("files: %d, errors: %d", files, errors) 88 } 89 } 90 91 func TestFastWalkGitRepo(t *testing.T) { 92 rootDir, err := ioutil.TempDir(os.TempDir(), "GitLfsTestFastWalkGitRepo") 93 if err != nil { 94 assert.FailNow(t, "Unable to get temp dir: %v", err) 95 } 96 defer os.RemoveAll(rootDir) 97 os.Chdir(rootDir) 98 99 expectedEntries := createFastWalkInputData(3, 3) 100 101 mainDir := expectedEntries[0] 102 103 // Set up a git repo and add some ignored files / dirs 104 subprocess.SimpleExec("git", "init", mainDir) 105 ignored := []string{ 106 "filethatweignore.ign", 107 "foldercontainingignored", 108 "foldercontainingignored/notthisone.ign", 109 "foldercontainingignored/ignoredfolder", 110 "foldercontainingignored/ignoredfolder/file1.txt", 111 "foldercontainingignored/ignoredfolder/file2.txt", 112 "ignoredfolder", 113 "ignoredfolder/file1.txt", 114 "ignoredfolder/file2.txt", 115 "ignoredfrominside", 116 "ignoredfrominside/thisisok.txt", 117 "ignoredfrominside/thisisnot.txt", 118 "ignoredfrominside/thisone", 119 "ignoredfrominside/thisone/file1.txt", 120 } 121 for _, f := range ignored { 122 fullPath := join(mainDir, f) 123 if len(filepath.Ext(f)) > 0 { 124 ioutil.WriteFile(fullPath, []byte("TEST"), 0644) 125 } else { 126 os.MkdirAll(fullPath, 0755) 127 } 128 } 129 // write root .gitignore 130 rootGitIgnore := ` 131 # ignore *.ign everywhere 132 *.ign 133 # ignore folder 134 ignoredfolder 135 ` 136 ioutil.WriteFile(join(mainDir, ".gitignore"), []byte(rootGitIgnore), 0644) 137 // Subfolder ignore; folder will show up but but subfolder 'thisone' won't 138 subFolderIgnore := ` 139 thisone 140 thisisnot.txt 141 ` 142 ioutil.WriteFile(join(mainDir, "ignoredfrominside", ".gitignore"), []byte(subFolderIgnore), 0644) 143 144 // This dir will be walked but content won't be 145 expectedEntries = append(expectedEntries, join(mainDir, "foldercontainingignored")) 146 // This dir will be walked and some of its content but has its own gitignore 147 expectedEntries = append(expectedEntries, join(mainDir, "ignoredfrominside")) 148 expectedEntries = append(expectedEntries, join(mainDir, "ignoredfrominside", "thisisok.txt")) 149 // Also gitignores 150 expectedEntries = append(expectedEntries, join(mainDir, ".gitignore")) 151 expectedEntries = append(expectedEntries, join(mainDir, "ignoredfrominside", ".gitignore")) 152 // nothing else should be there 153 154 gotEntries := make([]string, 0, 1000) 155 gotErrors := make([]error, 0, 5) 156 FastWalkGitRepo(mainDir, func(parent string, info os.FileInfo, err error) { 157 if err != nil { 158 gotErrors = append(gotErrors, err) 159 } else { 160 if len(parent) == 0 { 161 gotEntries = append(gotEntries, info.Name()) 162 } else { 163 gotEntries = append(gotEntries, join(parent, info.Name())) 164 } 165 } 166 }) 167 168 assert.Empty(t, gotErrors) 169 170 sort.Strings(expectedEntries) 171 sort.Strings(gotEntries) 172 assert.Equal(t, expectedEntries, gotEntries) 173 174 } 175 176 // Make test data - ensure you've Chdir'ed into a temp dir first 177 // Returns list of files/dirs that are created 178 // First entry is the parent dir of all others 179 func createFastWalkInputData(smallFolder, largeFolder int) []string { 180 dirs := []string{ 181 "testroot", 182 "testroot/folder1", 183 "testroot/folder2", 184 "testroot/folder2/subfolder1", 185 "testroot/folder2/subfolder2", 186 "testroot/folder2/subfolder3", 187 "testroot/folder2/subfolder4", 188 "testroot/folder2/subfolder4/subsub", 189 } 190 expectedEntries := make([]string, 0, 250) 191 192 for i, dir := range dirs { 193 os.MkdirAll(dir, 0755) 194 numFiles := smallFolder 195 expectedEntries = append(expectedEntries, dir) 196 if i >= 3 && i <= 5 { 197 // Bulk test to ensure works with > 1 batch 198 numFiles = largeFolder 199 } 200 for f := 0; f < numFiles; f++ { 201 filename := join(dir, fmt.Sprintf("file%d.txt", f)) 202 ioutil.WriteFile(filename, []byte("TEST"), 0644) 203 expectedEntries = append(expectedEntries, filename) 204 } 205 } 206 207 return expectedEntries 208 } 209 210 func collectFastWalkResults(fchan <-chan fastWalkInfo) ([]string, []error) { 211 gotEntries := make([]string, 0, 1000) 212 gotErrors := make([]error, 0, 5) 213 for o := range fchan { 214 if o.Err != nil { 215 gotErrors = append(gotErrors, o.Err) 216 } else { 217 if len(o.ParentDir) == 0 { 218 gotEntries = append(gotEntries, o.Info.Name()) 219 } else { 220 gotEntries = append(gotEntries, join(o.ParentDir, o.Info.Name())) 221 } 222 } 223 } 224 225 return gotEntries, gotErrors 226 } 227 228 func getFileMode(filename string) os.FileMode { 229 s, err := os.Stat(filename) 230 if err != nil { 231 return 0000 232 } 233 return s.Mode() 234 } 235 236 func TestSetWriteFlag(t *testing.T) { 237 f, err := ioutil.TempFile("", "lfstestwriteflag") 238 assert.Nil(t, err) 239 filename := f.Name() 240 defer os.Remove(filename) 241 f.Close() 242 // Set up with read/write bit for all but no execute 243 assert.Nil(t, os.Chmod(filename, 0666)) 244 245 assert.Nil(t, SetFileWriteFlag(filename, false)) 246 // should turn off all write 247 assert.EqualValues(t, 0444, getFileMode(filename)) 248 assert.Nil(t, SetFileWriteFlag(filename, true)) 249 // should only add back user write (on Mac/Linux) 250 if runtime.GOOS == "windows" { 251 assert.EqualValues(t, 0666, getFileMode(filename)) 252 } else { 253 assert.EqualValues(t, 0644, getFileMode(filename)) 254 } 255 256 // Can't run selective UGO tests on Windows as doesn't support separate roles 257 // Also Golang only supports read/write but not execute on Windows 258 if runtime.GOOS != "windows" { 259 // Set up with read/write/execute bit for all but no execute 260 assert.Nil(t, os.Chmod(filename, 0777)) 261 assert.Nil(t, SetFileWriteFlag(filename, false)) 262 // should turn off all write but not execute 263 assert.EqualValues(t, 0555, getFileMode(filename)) 264 assert.Nil(t, SetFileWriteFlag(filename, true)) 265 // should only add back user write (on Mac/Linux) 266 if runtime.GOOS == "windows" { 267 assert.EqualValues(t, 0777, getFileMode(filename)) 268 } else { 269 assert.EqualValues(t, 0755, getFileMode(filename)) 270 } 271 272 assert.Nil(t, os.Chmod(filename, 0440)) 273 assert.Nil(t, SetFileWriteFlag(filename, false)) 274 assert.EqualValues(t, 0440, getFileMode(filename)) 275 assert.Nil(t, SetFileWriteFlag(filename, true)) 276 // should only add back user write 277 assert.EqualValues(t, 0640, getFileMode(filename)) 278 } 279 }