vitess.io/vitess@v0.16.2/go/vt/topo/test/directory.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package test 18 19 import ( 20 "reflect" 21 "testing" 22 23 "context" 24 25 "vitess.io/vitess/go/vt/topo" 26 ) 27 28 // checkDirectory tests the directory part of the topo.Conn API. 29 func checkDirectory(t *testing.T, ts *topo.Server) { 30 ctx := context.Background() 31 32 // global cell 33 t.Logf("=== checkDirectoryInCell global") 34 conn, err := ts.ConnForCell(ctx, topo.GlobalCell) 35 if err != nil { 36 t.Fatalf("ConnForCell(global) failed: %v", err) 37 } 38 checkDirectoryInCell(t, conn, true /*hasCells*/) 39 40 // local cell 41 t.Logf("=== checkDirectoryInCell test") 42 conn, err = ts.ConnForCell(ctx, LocalCellName) 43 if err != nil { 44 t.Fatalf("ConnForCell(test) failed: %v", err) 45 } 46 checkDirectoryInCell(t, conn, false /*hasCells*/) 47 } 48 49 func checkListDir(ctx context.Context, t *testing.T, conn topo.Conn, dirPath string, expected []topo.DirEntry) { 50 t.Helper() 51 52 // Build the shallow expected list, when full=false. 53 se := make([]topo.DirEntry, len(expected)) 54 for i, e := range expected { 55 se[i].Name = e.Name 56 } 57 58 // Test with full=false. 59 entries, err := conn.ListDir(ctx, dirPath, false /*full*/) 60 switch { 61 case topo.IsErrType(err, topo.NoNode): 62 if len(se) != 0 { 63 t.Errorf("ListDir(%v, false) returned ErrNoNode but was expecting %v", dirPath, se) 64 } 65 case err == nil: 66 if len(se) != 0 || len(entries) != 0 { 67 if !reflect.DeepEqual(entries, se) { 68 t.Errorf("ListDir(%v, false) returned %v but was expecting %v", dirPath, entries, se) 69 } 70 } 71 default: 72 t.Errorf("ListDir(%v, false) returned unexpected error: %v", dirPath, err) 73 } 74 75 // Test with full=true. 76 entries, err = conn.ListDir(ctx, dirPath, true /*full*/) 77 switch { 78 case topo.IsErrType(err, topo.NoNode): 79 if len(expected) != 0 { 80 t.Errorf("ListDir(%v, true) returned ErrNoNode but was expecting %v", dirPath, expected) 81 } 82 case err == nil: 83 if len(expected) != 0 || len(entries) != 0 { 84 if !reflect.DeepEqual(entries, expected) { 85 t.Errorf("ListDir(%v, true) returned %v but was expecting %v", dirPath, entries, expected) 86 } 87 } 88 default: 89 t.Errorf("ListDir(%v, true) returned unexpected error: %v", dirPath, err) 90 } 91 } 92 93 func checkDirectoryInCell(t *testing.T, conn topo.Conn, hasCells bool) { 94 ctx := context.Background() 95 96 // ListDir root: nothing 97 var expected []topo.DirEntry 98 if hasCells { 99 expected = append(expected, topo.DirEntry{ 100 Name: "cells", 101 Type: topo.TypeDirectory, 102 }) 103 } 104 checkListDir(ctx, t, conn, "/", expected) 105 106 // Create a topolevel entry 107 version, err := conn.Create(ctx, "/MyFile", []byte{'a'}) 108 if err != nil { 109 t.Fatalf("cannot create toplevel file: %v", err) 110 } 111 112 // ListDir should return it. 113 expected = append([]topo.DirEntry{ 114 { 115 Name: "MyFile", 116 Type: topo.TypeFile, 117 }, 118 }, expected...) 119 checkListDir(ctx, t, conn, "/", expected) 120 121 // Delete it, it should be gone. 122 if err := conn.Delete(ctx, "/MyFile", version); err != nil { 123 t.Fatalf("cannot delete toplevel file: %v", err) 124 } 125 expected = expected[1:] 126 checkListDir(ctx, t, conn, "/", expected) 127 128 // Create a file 3 layers down. 129 version, err = conn.Create(ctx, "/types/name/MyFile", []byte{'a'}) 130 if err != nil { 131 t.Fatalf("cannot create deep file: %v", err) 132 } 133 expected = append(expected, topo.DirEntry{ 134 Name: "types", 135 Type: topo.TypeDirectory, 136 }) 137 138 // Check listing at all levels. 139 checkListDir(ctx, t, conn, "/", expected) 140 checkListDir(ctx, t, conn, "/types/", []topo.DirEntry{ 141 { 142 Name: "name", 143 Type: topo.TypeDirectory, 144 }, 145 }) 146 checkListDir(ctx, t, conn, "/types/name/", []topo.DirEntry{ 147 { 148 Name: "MyFile", 149 Type: topo.TypeFile, 150 }, 151 }) 152 153 // Add a second file 154 version2, err := conn.Create(ctx, "/types/othername/MyFile", []byte{'a'}) 155 if err != nil { 156 t.Fatalf("cannot create deep file2: %v", err) 157 } 158 159 // Check entries at all levels 160 checkListDir(ctx, t, conn, "/", expected) 161 checkListDir(ctx, t, conn, "/types/", []topo.DirEntry{ 162 { 163 Name: "name", 164 Type: topo.TypeDirectory, 165 }, 166 { 167 Name: "othername", 168 Type: topo.TypeDirectory, 169 }, 170 }) 171 checkListDir(ctx, t, conn, "/types/name/", []topo.DirEntry{ 172 { 173 Name: "MyFile", 174 Type: topo.TypeFile, 175 }, 176 }) 177 checkListDir(ctx, t, conn, "/types/othername/", []topo.DirEntry{ 178 { 179 Name: "MyFile", 180 Type: topo.TypeFile, 181 }, 182 }) 183 184 // Delete the first file, expect all lists to return the second one. 185 if err := conn.Delete(ctx, "/types/name/MyFile", version); err != nil { 186 t.Fatalf("cannot delete deep file: %v", err) 187 } 188 checkListDir(ctx, t, conn, "/", expected) 189 checkListDir(ctx, t, conn, "/types/", []topo.DirEntry{ 190 { 191 Name: "othername", 192 Type: topo.TypeDirectory, 193 }, 194 }) 195 checkListDir(ctx, t, conn, "/types/name/", nil) 196 checkListDir(ctx, t, conn, "/types/othername/", []topo.DirEntry{ 197 { 198 Name: "MyFile", 199 Type: topo.TypeFile, 200 }, 201 }) 202 203 // Delete the second file, expect all lists to return nothing. 204 if err := conn.Delete(ctx, "/types/othername/MyFile", version2); err != nil { 205 t.Fatalf("cannot delete second deep file: %v", err) 206 } 207 for _, dir := range []string{"/types/", "/types/name/", "/types/othername/"} { 208 checkListDir(ctx, t, conn, dir, nil) 209 } 210 expected = expected[:len(expected)-1] 211 checkListDir(ctx, t, conn, "/", expected) 212 }