github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/daemon/graphdriver/graphtest/testutil.go (about) 1 package graphtest // import "github.com/demonoid81/moby/daemon/graphdriver/graphtest" 2 3 import ( 4 "bytes" 5 "fmt" 6 "math/rand" 7 "os" 8 "sort" 9 10 "github.com/containerd/continuity/driver" 11 "github.com/demonoid81/moby/daemon/graphdriver" 12 "github.com/demonoid81/moby/pkg/archive" 13 "github.com/demonoid81/moby/pkg/stringid" 14 ) 15 16 func randomContent(size int, seed int64) []byte { 17 s := rand.NewSource(seed) 18 content := make([]byte, size) 19 20 for i := 0; i < len(content); i += 7 { 21 val := s.Int63() 22 for j := 0; i+j < len(content) && j < 7; j++ { 23 content[i+j] = byte(val) 24 val >>= 8 25 } 26 } 27 28 return content 29 } 30 31 func addFiles(drv graphdriver.Driver, layer string, seed int64) error { 32 root, err := drv.Get(layer, "") 33 if err != nil { 34 return err 35 } 36 defer drv.Put(layer) 37 38 if err := driver.WriteFile(root, root.Join(root.Path(), "file-a"), randomContent(64, seed), 0755); err != nil { 39 return err 40 } 41 if err := root.MkdirAll(root.Join(root.Path(), "dir-b"), 0755); err != nil { 42 return err 43 } 44 if err := driver.WriteFile(root, root.Join(root.Path(), "dir-b", "file-b"), randomContent(128, seed+1), 0755); err != nil { 45 return err 46 } 47 48 return driver.WriteFile(root, root.Join(root.Path(), "file-c"), randomContent(128*128, seed+2), 0755) 49 } 50 51 func checkFile(drv graphdriver.Driver, layer, filename string, content []byte) error { 52 root, err := drv.Get(layer, "") 53 if err != nil { 54 return err 55 } 56 defer drv.Put(layer) 57 58 fileContent, err := driver.ReadFile(root, root.Join(root.Path(), filename)) 59 if err != nil { 60 return err 61 } 62 63 if !bytes.Equal(fileContent, content) { 64 return fmt.Errorf("mismatched file content %v, expecting %v", fileContent, content) 65 } 66 67 return nil 68 } 69 70 func addFile(drv graphdriver.Driver, layer, filename string, content []byte) error { 71 root, err := drv.Get(layer, "") 72 if err != nil { 73 return err 74 } 75 defer drv.Put(layer) 76 77 return driver.WriteFile(root, root.Join(root.Path(), filename), content, 0755) 78 } 79 80 func addDirectory(drv graphdriver.Driver, layer, dir string) error { 81 root, err := drv.Get(layer, "") 82 if err != nil { 83 return err 84 } 85 defer drv.Put(layer) 86 87 return root.MkdirAll(root.Join(root.Path(), dir), 0755) 88 } 89 90 func removeAll(drv graphdriver.Driver, layer string, names ...string) error { 91 root, err := drv.Get(layer, "") 92 if err != nil { 93 return err 94 } 95 defer drv.Put(layer) 96 97 for _, filename := range names { 98 if err := root.RemoveAll(root.Join(root.Path(), filename)); err != nil { 99 return err 100 } 101 } 102 return nil 103 } 104 105 func checkFileRemoved(drv graphdriver.Driver, layer, filename string) error { 106 root, err := drv.Get(layer, "") 107 if err != nil { 108 return err 109 } 110 defer drv.Put(layer) 111 112 if _, err := root.Stat(root.Join(root.Path(), filename)); err == nil { 113 return fmt.Errorf("file still exists: %s", root.Join(root.Path(), filename)) 114 } else if !os.IsNotExist(err) { 115 return err 116 } 117 118 return nil 119 } 120 121 func addManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) error { 122 root, err := drv.Get(layer, "") 123 if err != nil { 124 return err 125 } 126 defer drv.Put(layer) 127 128 for i := 0; i < count; i += 100 { 129 dir := root.Join(root.Path(), fmt.Sprintf("directory-%d", i)) 130 if err := root.MkdirAll(dir, 0755); err != nil { 131 return err 132 } 133 for j := 0; i+j < count && j < 100; j++ { 134 file := root.Join(dir, fmt.Sprintf("file-%d", i+j)) 135 if err := driver.WriteFile(root, file, randomContent(64, seed+int64(i+j)), 0755); err != nil { 136 return err 137 } 138 } 139 } 140 141 return nil 142 } 143 144 func changeManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) ([]archive.Change, error) { 145 root, err := drv.Get(layer, "") 146 if err != nil { 147 return nil, err 148 } 149 defer drv.Put(layer) 150 151 var changes []archive.Change 152 for i := 0; i < count; i += 100 { 153 archiveRoot := fmt.Sprintf("/directory-%d", i) 154 if err := root.MkdirAll(root.Join(root.Path(), archiveRoot), 0755); err != nil { 155 return nil, err 156 } 157 for j := 0; i+j < count && j < 100; j++ { 158 if j == 0 { 159 changes = append(changes, archive.Change{ 160 Path: archiveRoot, 161 Kind: archive.ChangeModify, 162 }) 163 } 164 var change archive.Change 165 switch j % 3 { 166 // Update file 167 case 0: 168 change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d", i+j)) 169 change.Kind = archive.ChangeModify 170 if err := driver.WriteFile(root, root.Join(root.Path(), change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil { 171 return nil, err 172 } 173 // Add file 174 case 1: 175 change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d-%d", seed, i+j)) 176 change.Kind = archive.ChangeAdd 177 if err := driver.WriteFile(root, root.Join(root.Path(), change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil { 178 return nil, err 179 } 180 // Remove file 181 case 2: 182 change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d", i+j)) 183 change.Kind = archive.ChangeDelete 184 if err := root.Remove(root.Join(root.Path(), change.Path)); err != nil { 185 return nil, err 186 } 187 } 188 changes = append(changes, change) 189 } 190 } 191 192 return changes, nil 193 } 194 195 func checkManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) error { 196 root, err := drv.Get(layer, "") 197 if err != nil { 198 return err 199 } 200 defer drv.Put(layer) 201 202 for i := 0; i < count; i += 100 { 203 dir := root.Join(root.Path(), fmt.Sprintf("directory-%d", i)) 204 for j := 0; i+j < count && j < 100; j++ { 205 file := root.Join(dir, fmt.Sprintf("file-%d", i+j)) 206 fileContent, err := driver.ReadFile(root, file) 207 if err != nil { 208 return err 209 } 210 211 content := randomContent(64, seed+int64(i+j)) 212 213 if !bytes.Equal(fileContent, content) { 214 return fmt.Errorf("mismatched file content %v, expecting %v", fileContent, content) 215 } 216 } 217 } 218 219 return nil 220 } 221 222 type changeList []archive.Change 223 224 func (c changeList) Less(i, j int) bool { 225 if c[i].Path == c[j].Path { 226 return c[i].Kind < c[j].Kind 227 } 228 return c[i].Path < c[j].Path 229 } 230 func (c changeList) Len() int { return len(c) } 231 func (c changeList) Swap(i, j int) { c[j], c[i] = c[i], c[j] } 232 233 func checkChanges(expected, actual []archive.Change) error { 234 if len(expected) != len(actual) { 235 return fmt.Errorf("unexpected number of changes, expected %d, got %d", len(expected), len(actual)) 236 } 237 sort.Sort(changeList(expected)) 238 sort.Sort(changeList(actual)) 239 240 for i := range expected { 241 if expected[i] != actual[i] { 242 return fmt.Errorf("unexpected change, expecting %v, got %v", expected[i], actual[i]) 243 } 244 } 245 246 return nil 247 } 248 249 func addLayerFiles(drv graphdriver.Driver, layer, parent string, i int) error { 250 root, err := drv.Get(layer, "") 251 if err != nil { 252 return err 253 } 254 defer drv.Put(layer) 255 256 if err := driver.WriteFile(root, root.Join(root.Path(), "top-id"), []byte(layer), 0755); err != nil { 257 return err 258 } 259 layerDir := root.Join(root.Path(), fmt.Sprintf("layer-%d", i)) 260 if err := root.MkdirAll(layerDir, 0755); err != nil { 261 return err 262 } 263 if err := driver.WriteFile(root, root.Join(layerDir, "layer-id"), []byte(layer), 0755); err != nil { 264 return err 265 } 266 return driver.WriteFile(root, root.Join(layerDir, "parent-id"), []byte(parent), 0755) 267 } 268 269 func addManyLayers(drv graphdriver.Driver, baseLayer string, count int) (string, error) { 270 lastLayer := baseLayer 271 for i := 1; i <= count; i++ { 272 nextLayer := stringid.GenerateRandomID() 273 if err := drv.Create(nextLayer, lastLayer, nil); err != nil { 274 return "", err 275 } 276 if err := addLayerFiles(drv, nextLayer, lastLayer, i); err != nil { 277 return "", err 278 } 279 280 lastLayer = nextLayer 281 282 } 283 return lastLayer, nil 284 } 285 286 func checkManyLayers(drv graphdriver.Driver, layer string, count int) error { 287 root, err := drv.Get(layer, "") 288 if err != nil { 289 return err 290 } 291 defer drv.Put(layer) 292 293 layerIDBytes, err := driver.ReadFile(root, root.Join(root.Path(), "top-id")) 294 if err != nil { 295 return err 296 } 297 298 if !bytes.Equal(layerIDBytes, []byte(layer)) { 299 return fmt.Errorf("mismatched file content %v, expecting %v", layerIDBytes, []byte(layer)) 300 } 301 302 for i := count; i > 0; i-- { 303 layerDir := root.Join(root.Path(), fmt.Sprintf("layer-%d", i)) 304 305 thisLayerIDBytes, err := driver.ReadFile(root, root.Join(layerDir, "layer-id")) 306 if err != nil { 307 return err 308 } 309 if !bytes.Equal(thisLayerIDBytes, layerIDBytes) { 310 return fmt.Errorf("mismatched file content %v, expecting %v", thisLayerIDBytes, layerIDBytes) 311 } 312 layerIDBytes, err = driver.ReadFile(root, root.Join(layerDir, "parent-id")) 313 if err != nil { 314 return err 315 } 316 } 317 return nil 318 } 319 320 // readDir reads a directory just like driver.ReadDir() 321 // then hides specific files (currently "lost+found") 322 // so the tests don't "see" it 323 func readDir(r driver.Driver, dir string) ([]os.FileInfo, error) { 324 a, err := driver.ReadDir(r, dir) 325 if err != nil { 326 return nil, err 327 } 328 329 b := a[:0] 330 for _, x := range a { 331 if x.Name() != "lost+found" { // ext4 always have this dir 332 b = append(b, x) 333 } 334 } 335 336 return b, nil 337 }