github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/registry/storage/walk_test.go (about) 1 package storage 2 3 import ( 4 "fmt" 5 "sort" 6 "testing" 7 8 "github.com/docker/distribution/context" 9 "github.com/docker/distribution/registry/storage/driver" 10 "github.com/docker/distribution/registry/storage/driver/inmemory" 11 ) 12 13 func testFS(t *testing.T) (driver.StorageDriver, map[string]string, context.Context) { 14 d := inmemory.New() 15 ctx := context.Background() 16 17 expected := map[string]string{ 18 "/a": "dir", 19 "/a/b": "dir", 20 "/a/b/c": "dir", 21 "/a/b/c/d": "file", 22 "/a/b/c/e": "file", 23 "/a/b/f": "dir", 24 "/a/b/f/g": "file", 25 "/a/b/f/h": "file", 26 "/a/b/f/i": "file", 27 "/z": "dir", 28 "/z/y": "file", 29 } 30 31 for p, typ := range expected { 32 if typ != "file" { 33 continue 34 } 35 36 if err := d.PutContent(ctx, p, []byte(p)); err != nil { 37 t.Fatalf("unable to put content into fixture: %v", err) 38 } 39 } 40 41 return d, expected, ctx 42 } 43 44 func TestWalkErrors(t *testing.T) { 45 d, expected, ctx := testFS(t) 46 fileCount := len(expected) 47 err := Walk(ctx, d, "", func(fileInfo driver.FileInfo) error { 48 return nil 49 }) 50 if err == nil { 51 t.Error("Expected invalid root err") 52 } 53 54 errEarlyExpected := fmt.Errorf("Early termination") 55 56 err = Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error { 57 // error on the 2nd file 58 if fileInfo.Path() == "/a/b" { 59 return errEarlyExpected 60 } 61 62 delete(expected, fileInfo.Path()) 63 return nil 64 }) 65 if len(expected) != fileCount-1 { 66 t.Error("Walk failed to terminate with error") 67 } 68 if err != errEarlyExpected { 69 if err == nil { 70 t.Fatalf("expected an error due to early termination") 71 } else { 72 t.Error(err.Error()) 73 } 74 } 75 76 err = Walk(ctx, d, "/nonexistant", func(fileInfo driver.FileInfo) error { 77 return nil 78 }) 79 if err == nil { 80 t.Errorf("Expected missing file err") 81 } 82 83 } 84 85 func TestWalk(t *testing.T) { 86 d, expected, ctx := testFS(t) 87 var traversed []string 88 err := Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error { 89 filePath := fileInfo.Path() 90 filetype, ok := expected[filePath] 91 if !ok { 92 t.Fatalf("Unexpected file in walk: %q", filePath) 93 } 94 95 if fileInfo.IsDir() { 96 if filetype != "dir" { 97 t.Errorf("Unexpected file type: %q", filePath) 98 } 99 } else { 100 if filetype != "file" { 101 t.Errorf("Unexpected file type: %q", filePath) 102 } 103 104 // each file has its own path as the contents. If the length 105 // doesn't match the path length, fail. 106 if fileInfo.Size() != int64(len(fileInfo.Path())) { 107 t.Fatalf("unexpected size for %q: %v != %v", 108 fileInfo.Path(), fileInfo.Size(), len(fileInfo.Path())) 109 } 110 } 111 delete(expected, filePath) 112 traversed = append(traversed, filePath) 113 return nil 114 }) 115 if len(expected) > 0 { 116 t.Errorf("Missed files in walk: %q", expected) 117 } 118 119 if !sort.StringsAreSorted(traversed) { 120 t.Errorf("result should be sorted: %v", traversed) 121 } 122 123 if err != nil { 124 t.Fatalf(err.Error()) 125 } 126 } 127 128 func TestWalkSkipDir(t *testing.T) { 129 d, expected, ctx := testFS(t) 130 err := Walk(ctx, d, "/", func(fileInfo driver.FileInfo) error { 131 filePath := fileInfo.Path() 132 if filePath == "/a/b" { 133 // skip processing /a/b/c and /a/b/c/d 134 return ErrSkipDir 135 } 136 delete(expected, filePath) 137 return nil 138 }) 139 if err != nil { 140 t.Fatalf(err.Error()) 141 } 142 if _, ok := expected["/a/b/c"]; !ok { 143 t.Errorf("/a/b/c not skipped") 144 } 145 if _, ok := expected["/a/b/c/d"]; !ok { 146 t.Errorf("/a/b/c/d not skipped") 147 } 148 if _, ok := expected["/a/b/c/e"]; !ok { 149 t.Errorf("/a/b/c/e not skipped") 150 } 151 152 }