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