github.com/bloxroute-labs/bor@v0.1.4/ethdb/memorydb/memorydb_test.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package memorydb 18 19 import ( 20 "bytes" 21 "testing" 22 ) 23 24 // Tests that key-value iteration on top of a memory database works. 25 func TestMemoryDBIterator(t *testing.T) { 26 tests := []struct { 27 content map[string]string 28 prefix string 29 order []string 30 }{ 31 // Empty databases should be iterable 32 {map[string]string{}, "", nil}, 33 {map[string]string{}, "non-existent-prefix", nil}, 34 35 // Single-item databases should be iterable 36 {map[string]string{"key": "val"}, "", []string{"key"}}, 37 {map[string]string{"key": "val"}, "k", []string{"key"}}, 38 {map[string]string{"key": "val"}, "l", nil}, 39 40 // Multi-item databases should be fully iterable 41 { 42 map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"}, 43 "", 44 []string{"k1", "k2", "k3", "k4", "k5"}, 45 }, 46 { 47 map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"}, 48 "k", 49 []string{"k1", "k2", "k3", "k4", "k5"}, 50 }, 51 { 52 map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"}, 53 "l", 54 nil, 55 }, 56 // Multi-item databases should be prefix-iterable 57 { 58 map[string]string{ 59 "ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3", 60 "kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3", 61 }, 62 "ka", 63 []string{"ka1", "ka2", "ka3", "ka4", "ka5"}, 64 }, 65 { 66 map[string]string{ 67 "ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3", 68 "kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3", 69 }, 70 "kc", 71 nil, 72 }, 73 } 74 for i, tt := range tests { 75 // Create the key-value data store 76 db := New() 77 for key, val := range tt.content { 78 if err := db.Put([]byte(key), []byte(val)); err != nil { 79 t.Fatalf("test %d: failed to insert item %s:%s into database: %v", i, key, val, err) 80 } 81 } 82 // Iterate over the database with the given configs and verify the results 83 it, idx := db.NewIteratorWithPrefix([]byte(tt.prefix)), 0 84 for it.Next() { 85 if !bytes.Equal(it.Key(), []byte(tt.order[idx])) { 86 t.Errorf("test %d: item %d: key mismatch: have %s, want %s", i, idx, string(it.Key()), tt.order[idx]) 87 } 88 if !bytes.Equal(it.Value(), []byte(tt.content[tt.order[idx]])) { 89 t.Errorf("test %d: item %d: value mismatch: have %s, want %s", i, idx, string(it.Value()), tt.content[tt.order[idx]]) 90 } 91 idx++ 92 } 93 if err := it.Error(); err != nil { 94 t.Errorf("test %d: iteration failed: %v", i, err) 95 } 96 if idx != len(tt.order) { 97 t.Errorf("test %d: iteration terminated prematurely: have %d, want %d", i, idx, len(tt.order)) 98 } 99 } 100 }