kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/storage/inmemory/inmemory_test.go (about) 1 /* 2 * Copyright 2018 The Kythe Authors. All rights reserved. 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 inmemory 18 19 import ( 20 "context" 21 "io" 22 "sort" 23 "testing" 24 25 "kythe.io/kythe/go/storage/keyvalue" 26 27 "github.com/google/go-cmp/cmp" 28 ) 29 30 var ctx = context.Background() 31 32 func TestKeyValueDB_get(t *testing.T) { 33 db := NewKeyValueDB() 34 35 if val, err := db.Get(ctx, []byte("nonExistent"), nil); err == nil { 36 t.Errorf("Found nonExistent value: %q", val) 37 } else if err != io.EOF { 38 t.Errorf("Unexpected error: %v", err) 39 } 40 41 write(t, db, "nonExistent", "val") 42 43 if val, err := db.Get(ctx, []byte("nonExistent"), nil); err != nil { 44 t.Errorf("Unexpected error: %v", err) 45 } else if found := string(val); found != "val" { 46 t.Errorf("Expected %q; found %q", "val", found) 47 } 48 49 if err := db.Close(ctx); err != nil { 50 t.Fatalf("DB close error: %v", err) 51 } 52 } 53 54 func TestKeyValueDB_overwrite(t *testing.T) { 55 db := NewKeyValueDB() 56 57 write(t, db, "key", "val") 58 59 if val, err := db.Get(ctx, []byte("key"), nil); err != nil { 60 t.Errorf("Unexpected error: %v", err) 61 } else if found := string(val); found != "val" { 62 t.Errorf("Expected %q; found %q", "val", found) 63 } 64 65 write(t, db, "key", "val2") 66 67 if val, err := db.Get(ctx, []byte("key"), nil); err != nil { 68 t.Errorf("Unexpected error: %v", err) 69 } else if found := string(val); found != "val2" { 70 t.Errorf("Expected %q; found %q", "val2", found) 71 } 72 73 if err := db.Close(ctx); err != nil { 74 t.Fatalf("DB close error: %v", err) 75 } 76 } 77 78 type entry struct{ Key, Value string } 79 80 func TestKeyValueDB_scanPrefix(t *testing.T) { 81 db := NewKeyValueDB() 82 83 entries := []entry{ 84 {"k1", "val1"}, 85 {"k4", "val4"}, 86 {"k3", "val3"}, 87 {"k0", "val0"}, 88 {"k2", "val2"}, 89 {"k", "val"}, 90 } 91 writeEntries(t, db, entries) 92 writeEntries(t, db, []entry{ 93 {"j1", "val1"}, 94 {"j0", "val0"}, 95 }) 96 97 it, err := db.ScanPrefix(ctx, []byte("k"), nil) 98 if err != nil { 99 t.Fatalf("ScanPrefix error: %v", err) 100 } 101 102 var found []entry 103 for { 104 k, v, err := it.Next() 105 if err == io.EOF { 106 break 107 } 108 found = append(found, entry{string(k), string(v)}) 109 } 110 111 if err := it.Close(); err != nil { 112 t.Fatalf("Iterator close error: %v", err) 113 } 114 115 sort.Slice(entries, func(i, j int) bool { return entries[i].Key < entries[j].Key }) 116 if diff := cmp.Diff(entries, found); diff != "" { 117 t.Fatalf("Found entry differences: (- expected; + found)\n%s", diff) 118 } 119 120 if err := db.Close(ctx); err != nil { 121 t.Fatalf("DB close error: %v", err) 122 } 123 } 124 125 func TestKeyValueDB_scanRange(t *testing.T) { 126 db := NewKeyValueDB() 127 128 entries := []entry{ 129 {"k1", "val1"}, 130 {"k0", "val0"}, 131 {"k2", "val2"}, 132 } 133 writeEntries(t, db, entries) 134 writeEntries(t, db, []entry{ 135 {"k3", "val3"}, 136 {"k", "val"}, 137 {"j1", "val1"}, 138 {"k4", "val4"}, 139 {"j0", "val0"}, 140 }) 141 142 it, err := db.ScanRange(ctx, &keyvalue.Range{ 143 Start: []byte("k0"), 144 End: []byte("k3"), 145 }, nil) 146 if err != nil { 147 t.Fatalf("ScanRange error: %v", err) 148 } 149 150 var found []entry 151 for { 152 k, v, err := it.Next() 153 if err == io.EOF { 154 break 155 } 156 found = append(found, entry{string(k), string(v)}) 157 } 158 159 if err := it.Close(); err != nil { 160 t.Fatalf("Iterator close error: %v", err) 161 } 162 163 sort.Slice(entries, func(i, j int) bool { return entries[i].Key < entries[j].Key }) 164 if diff := cmp.Diff(entries, found); diff != "" { 165 t.Fatalf("Found entry differences: (- expected; + found)\n%s", diff) 166 } 167 168 if err := db.Close(ctx); err != nil { 169 t.Fatalf("DB close error: %v", err) 170 } 171 } 172 173 func TestKeyValueDB_scanPrefixSeek(t *testing.T) { 174 db := NewKeyValueDB() 175 176 entries := []entry{ 177 {"k4", "val4"}, 178 {"k3", "val3"}, 179 {"k2", "val2"}, 180 } 181 writeEntries(t, db, entries) 182 writeEntries(t, db, []entry{ 183 {"k", "val"}, 184 {"k0", "val0"}, 185 {"k1", "val1"}, 186 {"j1", "val1"}, 187 {"j0", "val0"}, 188 }) 189 190 it, err := db.ScanPrefix(ctx, []byte("k"), nil) 191 if err != nil { 192 t.Fatalf("ScanPrefix error: %v", err) 193 } 194 195 // Seek past k1 key 196 if err := it.Seek([]byte("k10")); err != nil { 197 t.Fatalf("Seek error: %v", err) 198 } 199 200 var found []entry 201 for { 202 k, v, err := it.Next() 203 if err == io.EOF { 204 break 205 } 206 found = append(found, entry{string(k), string(v)}) 207 } 208 209 if err := it.Close(); err != nil { 210 t.Fatalf("Iterator close error: %v", err) 211 } 212 213 sort.Slice(entries, func(i, j int) bool { return entries[i].Key < entries[j].Key }) 214 if diff := cmp.Diff(entries, found); diff != "" { 215 t.Fatalf("Found entry differences: (- expected; + found)\n%s", diff) 216 } 217 218 if err := db.Close(ctx); err != nil { 219 t.Fatalf("DB close error: %v", err) 220 } 221 } 222 223 func TestKeyValueDB_scanRangeSeek(t *testing.T) { 224 db := NewKeyValueDB() 225 226 entries := []entry{ 227 {"k1", "val1"}, 228 {"k2", "val2"}, 229 } 230 writeEntries(t, db, entries) 231 writeEntries(t, db, []entry{ 232 {"k0", "val0"}, 233 {"k3", "val3"}, 234 {"k", "val"}, 235 {"j1", "val1"}, 236 {"k4", "val4"}, 237 {"j0", "val0"}, 238 }) 239 240 it, err := db.ScanRange(ctx, &keyvalue.Range{ 241 Start: []byte("k0"), 242 End: []byte("k3"), 243 }, nil) 244 if err != nil { 245 t.Fatalf("ScanRange error: %v", err) 246 } 247 248 // Seek past k0 key 249 if err := it.Seek([]byte("k1")); err != nil { 250 t.Fatalf("Seek error: %v", err) 251 } 252 253 var found []entry 254 for { 255 k, v, err := it.Next() 256 if err == io.EOF { 257 break 258 } 259 found = append(found, entry{string(k), string(v)}) 260 } 261 262 if err := it.Close(); err != nil { 263 t.Fatalf("Iterator close error: %v", err) 264 } 265 266 sort.Slice(entries, func(i, j int) bool { return entries[i].Key < entries[j].Key }) 267 if diff := cmp.Diff(entries, found); diff != "" { 268 t.Fatalf("Found entry differences: (- expected; + found)\n%s", diff) 269 } 270 271 if err := db.Close(ctx); err != nil { 272 t.Fatalf("DB close error: %v", err) 273 } 274 } 275 276 func writeEntries(t *testing.T, db *KeyValueDB, entries []entry) { 277 for _, e := range entries { 278 write(t, db, e.Key, e.Value) 279 } 280 } 281 282 func write(t *testing.T, db *KeyValueDB, key, val string) { 283 w, err := db.Writer(ctx) 284 if err != nil { 285 t.Fatalf("Writer error: %v", err) 286 } 287 288 if err := w.Write([]byte(key), []byte(val)); err != nil { 289 t.Fatalf("Write error: %v", err) 290 } else if err := w.Close(); err != nil { 291 t.Fatalf("Write close error: %v", err) 292 } 293 }