github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/local/diff_test.go (about) 1 package local_test 2 3 import ( 4 "io/fs" 5 "os" 6 "path/filepath" 7 "sort" 8 "testing" 9 "time" 10 11 "github.com/go-openapi/swag" 12 "github.com/stretchr/testify/require" 13 "github.com/treeverse/lakefs/pkg/api/apigen" 14 "github.com/treeverse/lakefs/pkg/local" 15 ) 16 17 const ( 18 diffTestCorrectTime = 1691570412 19 ) 20 21 func TestDiffLocal(t *testing.T) { 22 cases := []struct { 23 Name string 24 LocalPath string 25 RemoteList []apigen.ObjectStats 26 Expected []*local.Change 27 }{ 28 { 29 Name: "t1_no_diff", 30 LocalPath: "testdata/localdiff/t1", 31 RemoteList: []apigen.ObjectStats{ 32 { 33 Path: ".hidden-file", 34 SizeBytes: swag.Int64(64), 35 Mtime: diffTestCorrectTime, 36 }, { 37 Path: "sub/f.txt", 38 SizeBytes: swag.Int64(3), 39 Mtime: diffTestCorrectTime, 40 }, { 41 Path: "sub/folder/f.txt", 42 SizeBytes: swag.Int64(6), 43 Mtime: diffTestCorrectTime, 44 }, 45 }, 46 Expected: []*local.Change{}, 47 }, 48 { 49 Name: "t1_modified", 50 LocalPath: "testdata/localdiff/t1", 51 RemoteList: []apigen.ObjectStats{ 52 { 53 Path: ".hidden-file", 54 SizeBytes: swag.Int64(64), 55 Mtime: diffTestCorrectTime, 56 }, { 57 Path: "sub/f.txt", 58 SizeBytes: swag.Int64(3), 59 Mtime: 169095766, 60 }, { 61 Path: "sub/folder/f.txt", 62 SizeBytes: swag.Int64(12), 63 Mtime: 1690957665, 64 }, 65 }, 66 Expected: []*local.Change{ 67 { 68 Path: "sub/f.txt", 69 Type: local.ChangeTypeModified, 70 }, { 71 Path: "sub/folder/f.txt", 72 Type: local.ChangeTypeModified, 73 }, 74 }, 75 }, 76 { 77 Name: "t1_local_before", 78 LocalPath: "testdata/localdiff/t1", 79 RemoteList: []apigen.ObjectStats{ 80 { 81 Path: ".hidden-file", 82 SizeBytes: swag.Int64(64), 83 Mtime: diffTestCorrectTime, 84 }, { 85 Path: "sub/folder/f.txt", 86 SizeBytes: swag.Int64(6), 87 Mtime: diffTestCorrectTime, 88 }, 89 }, 90 Expected: []*local.Change{ 91 { 92 Path: "sub/f.txt", 93 Type: local.ChangeTypeAdded, 94 }, 95 }, 96 }, 97 { 98 Name: "t1_local_after", 99 LocalPath: "testdata/localdiff/t1", 100 RemoteList: []apigen.ObjectStats{{ 101 Path: ".hidden-file", 102 SizeBytes: swag.Int64(64), 103 Mtime: diffTestCorrectTime, 104 }, { 105 Path: "tub/r.txt", 106 SizeBytes: swag.Int64(6), 107 Mtime: 1690957665, 108 }, 109 }, 110 Expected: []*local.Change{ 111 { 112 Path: "sub/f.txt", 113 Type: local.ChangeTypeAdded, 114 }, 115 { 116 Path: "sub/folder/f.txt", 117 Type: local.ChangeTypeAdded, 118 }, 119 { 120 Path: "tub/r.txt", 121 Type: local.ChangeTypeRemoved, 122 }, 123 }, 124 }, 125 { 126 Name: "t1_hidden_changed", 127 LocalPath: "testdata/localdiff/t1", 128 RemoteList: []apigen.ObjectStats{ 129 { 130 Path: ".hidden-file", 131 SizeBytes: swag.Int64(17), 132 Mtime: diffTestCorrectTime, 133 }, { 134 Path: "sub/f.txt", 135 SizeBytes: swag.Int64(3), 136 Mtime: diffTestCorrectTime, 137 }, { 138 Path: "sub/folder/f.txt", 139 SizeBytes: swag.Int64(6), 140 Mtime: diffTestCorrectTime, 141 }, 142 }, 143 Expected: []*local.Change{ 144 { 145 Path: ".hidden-file", 146 Type: local.ChangeTypeModified, 147 }, 148 }, 149 }, 150 } 151 152 for _, tt := range cases { 153 t.Run(tt.Name, func(t *testing.T) { 154 fixTime(t, tt.LocalPath) 155 left := tt.RemoteList 156 sort.SliceStable(left, func(i, j int) bool { 157 return left[i].Path < left[j].Path 158 }) 159 lc := make(chan apigen.ObjectStats, len(left)) 160 makeChan(lc, left) 161 changes, err := local.DiffLocalWithHead(lc, tt.LocalPath) 162 if err != nil { 163 t.Fatal(err) 164 } 165 if len(changes) != len(tt.Expected) { 166 t.Fatalf("expected %d changes, got %d\n\n%v", len(tt.Expected), len(changes), changes) 167 } 168 for i, c := range changes { 169 require.Equal(t, c.Path, tt.Expected[i].Path, "wrong path") 170 require.Equal(t, c.Type, tt.Expected[i].Type, "wrong type") 171 } 172 }) 173 } 174 } 175 176 func makeChan[T any](c chan<- T, l []T) { 177 for _, o := range l { 178 c <- o 179 } 180 close(c) 181 } 182 183 func fixTime(t *testing.T, localPath string) { 184 err := filepath.WalkDir(localPath, func(path string, d fs.DirEntry, err error) error { 185 if !d.IsDir() { 186 return os.Chtimes(path, time.Now(), time.Unix(diffTestCorrectTime, 0)) 187 } 188 return nil 189 }) 190 require.NoError(t, err) 191 }