github.com/aquanetwork/aquachain@v1.7.8/aquadb/database_test.go (about) 1 // Copyright 2014 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 aquadb_test 18 19 import ( 20 "bytes" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "strconv" 25 "sync" 26 "testing" 27 28 "gitlab.com/aquachain/aquachain/aquadb" 29 ) 30 31 func newTestLDB() (*aquadb.LDBDatabase, func()) { 32 dirname, err := ioutil.TempDir(os.TempDir(), "aquadb_test_") 33 if err != nil { 34 panic("failed to create test file: " + err.Error()) 35 } 36 db, err := aquadb.NewLDBDatabase(dirname, 0, 0) 37 if err != nil { 38 panic("failed to create test database: " + err.Error()) 39 } 40 41 return db, func() { 42 db.Close() 43 os.RemoveAll(dirname) 44 } 45 } 46 47 var test_values = []string{"", "a", "1251", "\x00123\x00"} 48 49 func TestLDB_PutGet(t *testing.T) { 50 db, remove := newTestLDB() 51 defer remove() 52 testPutGet(db, t) 53 } 54 55 func TestMemoryDB_PutGet(t *testing.T) { 56 testPutGet(aquadb.NewMemDatabase(), t) 57 } 58 59 func testPutGet(db aquadb.Database, t *testing.T) { 60 t.Parallel() 61 62 for _, k := range test_values { 63 err := db.Put([]byte(k), nil) 64 if err != nil { 65 t.Fatalf("put failed: %v", err) 66 } 67 } 68 69 for _, k := range test_values { 70 data, err := db.Get([]byte(k)) 71 if err != nil { 72 t.Fatalf("get failed: %v", err) 73 } 74 if len(data) != 0 { 75 t.Fatalf("get returned wrong result, got %q expected nil", string(data)) 76 } 77 } 78 79 _, err := db.Get([]byte("non-exist-key")) 80 if err == nil { 81 t.Fatalf("expect to return a not found error") 82 } 83 84 for _, v := range test_values { 85 err := db.Put([]byte(v), []byte(v)) 86 if err != nil { 87 t.Fatalf("put failed: %v", err) 88 } 89 } 90 91 for _, v := range test_values { 92 data, err := db.Get([]byte(v)) 93 if err != nil { 94 t.Fatalf("get failed: %v", err) 95 } 96 if !bytes.Equal(data, []byte(v)) { 97 t.Fatalf("get returned wrong result, got %q expected %q", string(data), v) 98 } 99 } 100 101 for _, v := range test_values { 102 err := db.Put([]byte(v), []byte("?")) 103 if err != nil { 104 t.Fatalf("put override failed: %v", err) 105 } 106 } 107 108 for _, v := range test_values { 109 data, err := db.Get([]byte(v)) 110 if err != nil { 111 t.Fatalf("get failed: %v", err) 112 } 113 if !bytes.Equal(data, []byte("?")) { 114 t.Fatalf("get returned wrong result, got %q expected ?", string(data)) 115 } 116 } 117 118 for _, v := range test_values { 119 orig, err := db.Get([]byte(v)) 120 if err != nil { 121 t.Fatalf("get failed: %v", err) 122 } 123 orig[0] = byte(0xff) 124 data, err := db.Get([]byte(v)) 125 if err != nil { 126 t.Fatalf("get failed: %v", err) 127 } 128 if !bytes.Equal(data, []byte("?")) { 129 t.Fatalf("get returned wrong result, got %q expected ?", string(data)) 130 } 131 } 132 133 for _, v := range test_values { 134 err := db.Delete([]byte(v)) 135 if err != nil { 136 t.Fatalf("delete %q failed: %v", v, err) 137 } 138 } 139 140 for _, v := range test_values { 141 _, err := db.Get([]byte(v)) 142 if err == nil { 143 t.Fatalf("got deleted value %q", v) 144 } 145 } 146 } 147 148 func TestLDB_ParallelPutGet(t *testing.T) { 149 db, remove := newTestLDB() 150 defer remove() 151 testParallelPutGet(db, t) 152 } 153 154 func TestMemoryDB_ParallelPutGet(t *testing.T) { 155 testParallelPutGet(aquadb.NewMemDatabase(), t) 156 } 157 158 func testParallelPutGet(db aquadb.Database, t *testing.T) { 159 const n = 8 160 var pending sync.WaitGroup 161 162 pending.Add(n) 163 for i := 0; i < n; i++ { 164 go func(key string) { 165 defer pending.Done() 166 err := db.Put([]byte(key), []byte("v"+key)) 167 if err != nil { 168 panic("put failed: " + err.Error()) 169 } 170 }(strconv.Itoa(i)) 171 } 172 pending.Wait() 173 174 pending.Add(n) 175 for i := 0; i < n; i++ { 176 go func(key string) { 177 defer pending.Done() 178 data, err := db.Get([]byte(key)) 179 if err != nil { 180 panic("get failed: " + err.Error()) 181 } 182 if !bytes.Equal(data, []byte("v"+key)) { 183 panic(fmt.Sprintf("get failed, got %q expected %q", []byte(data), []byte("v"+key))) 184 } 185 }(strconv.Itoa(i)) 186 } 187 pending.Wait() 188 189 pending.Add(n) 190 for i := 0; i < n; i++ { 191 go func(key string) { 192 defer pending.Done() 193 err := db.Delete([]byte(key)) 194 if err != nil { 195 panic("delete failed: " + err.Error()) 196 } 197 }(strconv.Itoa(i)) 198 } 199 pending.Wait() 200 201 pending.Add(n) 202 for i := 0; i < n; i++ { 203 go func(key string) { 204 defer pending.Done() 205 _, err := db.Get([]byte(key)) 206 if err == nil { 207 panic("get succeeded") 208 } 209 }(strconv.Itoa(i)) 210 } 211 pending.Wait() 212 }