github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/common/ledger/util/leveldbhelper/leveldb_provider_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package leveldbhelper 8 9 import ( 10 "fmt" 11 "os" 12 "testing" 13 14 "github.com/osdi23p228/fabric/common/ledger/dataformat" 15 16 "github.com/osdi23p228/fabric/common/flogging" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func TestMain(m *testing.M) { 22 flogging.ActivateSpec("leveldbhelper=debug") 23 os.Exit(m.Run()) 24 } 25 26 func TestDBBasicWriteAndReads(t *testing.T) { 27 testDBBasicWriteAndReads(t, "db1", "db2", "") 28 } 29 30 func TestIterator(t *testing.T) { 31 env := newTestProviderEnv(t, testDBPath) 32 defer env.cleanup() 33 p := env.provider 34 35 db1 := p.GetDBHandle("db1") 36 db2 := p.GetDBHandle("db2") 37 db3 := p.GetDBHandle("db3") 38 for i := 0; i < 20; i++ { 39 db1.Put([]byte(createTestKey(i)), []byte(createTestValue("db1", i)), false) 40 db2.Put([]byte(createTestKey(i)), []byte(createTestValue("db2", i)), false) 41 db3.Put([]byte(createTestKey(i)), []byte(createTestValue("db3", i)), false) 42 } 43 44 rangeTestCases := []struct { 45 startKey []byte 46 endKey []byte 47 expectedKeys []string 48 expectedValues []string 49 }{ 50 { 51 startKey: []byte(createTestKey(2)), 52 endKey: []byte(createTestKey(4)), 53 expectedKeys: createTestKeys(2, 3), 54 expectedValues: createTestValues("db2", 2, 3), 55 }, 56 { 57 startKey: []byte(createTestKey(2)), 58 endKey: nil, 59 expectedKeys: createTestKeys(2, 19), 60 expectedValues: createTestValues("db2", 2, 19), 61 }, 62 { 63 startKey: nil, 64 endKey: nil, 65 expectedKeys: createTestKeys(0, 19), 66 expectedValues: createTestValues("db2", 0, 19), 67 }, 68 } 69 70 for i, testCase := range rangeTestCases { 71 t.Run( 72 fmt.Sprintf("range testCase %d", i), 73 func(t *testing.T) { 74 itr, err := db2.GetIterator(testCase.startKey, testCase.endKey) 75 require.NoError(t, err) 76 defer itr.Release() 77 checkItrResults(t, itr, testCase.expectedKeys, testCase.expectedValues) 78 }, 79 ) 80 } 81 82 rangeWithSeekTestCases := []struct { 83 startKey []byte 84 endKey []byte 85 seekToKey []byte 86 itrAtKeyAfterSeek []byte 87 expectedKeys []string 88 expectedValues []string 89 }{ 90 { 91 startKey: nil, 92 endKey: nil, 93 seekToKey: []byte(createTestKey(10)), 94 itrAtKeyAfterSeek: []byte(createTestKey(10)), 95 expectedKeys: createTestKeys(11, 19), 96 expectedValues: createTestValues("db1", 11, 19), 97 }, 98 { 99 startKey: []byte(createTestKey(11)), 100 endKey: nil, 101 seekToKey: []byte(createTestKey(5)), 102 itrAtKeyAfterSeek: []byte(createTestKey(11)), 103 expectedKeys: createTestKeys(12, 19), 104 expectedValues: createTestValues("db1", 12, 19), 105 }, 106 { 107 startKey: nil, 108 endKey: nil, 109 seekToKey: []byte(createTestKey(19)), 110 itrAtKeyAfterSeek: []byte(createTestKey(19)), 111 expectedKeys: nil, 112 expectedValues: nil, 113 }, 114 } 115 116 for i, testCase := range rangeWithSeekTestCases { 117 t.Run( 118 fmt.Sprintf("range with seek testCase %d", i), 119 func(t *testing.T) { 120 itr, err := db1.GetIterator(testCase.startKey, testCase.endKey) 121 require.NoError(t, err) 122 defer itr.Release() 123 require.True(t, itr.Seek(testCase.seekToKey)) 124 require.Equal(t, testCase.itrAtKeyAfterSeek, itr.Key()) 125 checkItrResults(t, itr, testCase.expectedKeys, testCase.expectedValues) 126 }, 127 ) 128 } 129 130 t.Run("test-first-prev", func(t *testing.T) { 131 itr, err := db1.GetIterator(nil, nil) 132 require.NoError(t, err) 133 defer itr.Release() 134 require.True(t, itr.Seek([]byte(createTestKey(10)))) 135 require.Equal(t, []byte(createTestKey(10)), itr.Key()) 136 checkItrResults(t, itr, createTestKeys(11, 19), createTestValues("db1", 11, 19)) 137 138 require.True(t, itr.First()) 139 require.True(t, itr.Seek([]byte(createTestKey(10)))) 140 require.Equal(t, []byte(createTestKey(10)), itr.Key()) 141 require.True(t, itr.Prev()) 142 checkItrResults(t, itr, createTestKeys(10, 19), createTestValues("db1", 10, 19)) 143 144 require.True(t, itr.First()) 145 require.False(t, itr.Seek([]byte(createTestKey(20)))) 146 require.True(t, itr.First()) 147 checkItrResults(t, itr, createTestKeys(1, 19), createTestValues("db1", 1, 19)) 148 149 require.True(t, itr.First()) 150 require.False(t, itr.Prev()) 151 checkItrResults(t, itr, createTestKeys(0, 19), createTestValues("db1", 0, 19)) 152 153 require.True(t, itr.First()) 154 require.True(t, itr.Last()) 155 checkItrResults(t, itr, nil, nil) 156 }) 157 158 t.Run("test-error-path", func(t *testing.T) { 159 env.provider.Close() 160 itr, err := db1.GetIterator(nil, nil) 161 require.EqualError(t, err, "internal leveldb error while obtaining db iterator: leveldb: closed") 162 require.Nil(t, itr) 163 }) 164 } 165 166 func TestBatchedUpdates(t *testing.T) { 167 env := newTestProviderEnv(t, testDBPath) 168 defer env.cleanup() 169 p := env.provider 170 171 db1 := p.GetDBHandle("db1") 172 db2 := p.GetDBHandle("db2") 173 174 dbs := []*DBHandle{db1, db2} 175 for _, db := range dbs { 176 batch := db.NewUpdateBatch() 177 batch.Put([]byte("key1"), []byte("value1")) 178 batch.Put([]byte("key2"), []byte("value2")) 179 batch.Put([]byte("key3"), []byte("value3")) 180 db.WriteBatch(batch, true) 181 } 182 183 for _, db := range dbs { 184 batch := db.NewUpdateBatch() 185 batch.Delete([]byte("key2")) 186 db.WriteBatch(batch, true) 187 } 188 189 for _, db := range dbs { 190 val1, _ := db.Get([]byte("key1")) 191 assert.Equal(t, "value1", string(val1)) 192 193 val2, err2 := db.Get([]byte("key2")) 194 assert.NoError(t, err2, "") 195 assert.Nil(t, val2) 196 197 val3, _ := db.Get([]byte("key3")) 198 assert.Equal(t, "value3", string(val3)) 199 } 200 } 201 202 func TestDeleteAll(t *testing.T) { 203 env := newTestProviderEnv(t, testDBPath) 204 defer env.cleanup() 205 p := env.provider 206 207 db1 := p.GetDBHandle("db1") 208 db2 := p.GetDBHandle("db2") 209 db3 := p.GetDBHandle("db3") 210 db4 := p.GetDBHandle("db4") 211 for i := 0; i < 20; i++ { 212 db1.Put([]byte(createTestKey(i)), []byte(createTestValue("db1", i)), false) 213 db2.Put([]byte(createTestKey(i)), []byte(createTestValue("db2", i)), false) 214 db3.Put([]byte(createTestKey(i)), []byte(createTestValue("db3", i)), false) 215 } 216 // db4 is used to test remove when multiple batches are needed (each long key has 125 bytes) 217 for i := 0; i < 10000; i++ { 218 db4.Put([]byte(createTestLongKey(i)), []byte(createTestValue("db4", i)), false) 219 } 220 221 expectedSetup := []struct { 222 db *DBHandle 223 expectedKeys []string 224 expectedValues []string 225 }{ 226 { 227 db: db1, 228 expectedKeys: createTestKeys(0, 19), 229 expectedValues: createTestValues("db1", 0, 19), 230 }, 231 { 232 db: db2, 233 expectedKeys: createTestKeys(0, 19), 234 expectedValues: createTestValues("db2", 0, 19), 235 }, 236 { 237 db: db3, 238 expectedKeys: createTestKeys(0, 19), 239 expectedValues: createTestValues("db3", 0, 19), 240 }, 241 { 242 db: db4, 243 expectedKeys: createTestLongKeys(0, 9999), 244 expectedValues: createTestValues("db4", 0, 9999), 245 }, 246 } 247 248 for _, dbSetup := range expectedSetup { 249 itr, err := dbSetup.db.GetIterator(nil, nil) 250 require.NoError(t, err) 251 checkItrResults(t, itr, dbSetup.expectedKeys, dbSetup.expectedValues) 252 itr.Release() 253 } 254 255 require.NoError(t, db1.DeleteAll()) 256 require.NoError(t, db4.DeleteAll()) 257 258 expectedResults := []struct { 259 db *DBHandle 260 expectedKeys []string 261 expectedValues []string 262 }{ 263 { 264 db: db1, 265 expectedKeys: nil, 266 expectedValues: nil, 267 }, 268 { 269 db: db2, 270 expectedKeys: createTestKeys(0, 19), 271 expectedValues: createTestValues("db2", 0, 19), 272 }, 273 { 274 db: db3, 275 expectedKeys: createTestKeys(0, 19), 276 expectedValues: createTestValues("db3", 0, 19), 277 }, 278 { 279 db: db4, 280 expectedKeys: nil, 281 expectedValues: nil, 282 }, 283 } 284 285 for _, result := range expectedResults { 286 itr, err := result.db.GetIterator(nil, nil) 287 require.NoError(t, err) 288 checkItrResults(t, itr, result.expectedKeys, result.expectedValues) 289 itr.Release() 290 } 291 292 // negative test 293 p.Close() 294 require.EqualError(t, db2.DeleteAll(), "internal leveldb error while obtaining db iterator: leveldb: closed") 295 } 296 297 func TestFormatCheck(t *testing.T) { 298 testCases := []struct { 299 dataFormat string 300 dataExists bool 301 expectedFormat string 302 expectedErr *dataformat.ErrFormatMismatch 303 }{ 304 { 305 dataFormat: "", 306 dataExists: true, 307 expectedFormat: "", 308 expectedErr: nil, 309 }, 310 { 311 dataFormat: "", 312 dataExists: false, 313 expectedFormat: "", 314 expectedErr: nil, 315 }, 316 { 317 dataFormat: "", 318 dataExists: false, 319 expectedFormat: "2.0", 320 expectedErr: nil, 321 }, 322 { 323 dataFormat: "", 324 dataExists: true, 325 expectedFormat: "2.0", 326 expectedErr: &dataformat.ErrFormatMismatch{Format: "", ExpectedFormat: "2.0"}, 327 }, 328 { 329 dataFormat: "2.0", 330 dataExists: true, 331 expectedFormat: "2.0", 332 expectedErr: nil, 333 }, 334 { 335 dataFormat: "2.0", 336 dataExists: true, 337 expectedFormat: "3.0", 338 expectedErr: &dataformat.ErrFormatMismatch{Format: "2.0", ExpectedFormat: "3.0"}, 339 }, 340 } 341 342 for i, testCase := range testCases { 343 t.Run( 344 fmt.Sprintf("testCase %d", i), 345 func(t *testing.T) { 346 testFormatCheck(t, testCase.dataFormat, testCase.expectedFormat, testCase.dataExists, testCase.expectedErr) 347 }) 348 } 349 } 350 351 func TestClose(t *testing.T) { 352 env := newTestProviderEnv(t, testDBPath) 353 defer env.cleanup() 354 p := env.provider 355 356 db1 := p.GetDBHandle("db1") 357 db2 := p.GetDBHandle("db2") 358 359 expectedDBHandles := map[string]*DBHandle{ 360 "db1": db1, 361 "db2": db2, 362 } 363 require.Equal(t, expectedDBHandles, p.dbHandles) 364 365 db1.Close() 366 expectedDBHandles = map[string]*DBHandle{ 367 "db2": db2, 368 } 369 require.Equal(t, expectedDBHandles, p.dbHandles) 370 371 db2.Close() 372 require.Equal(t, map[string]*DBHandle{}, p.dbHandles) 373 } 374 375 func testFormatCheck(t *testing.T, dataFormat, expectedFormat string, dataExists bool, expectedErr *dataformat.ErrFormatMismatch) { 376 assert.NoError(t, os.RemoveAll(testDBPath)) 377 defer func() { 378 assert.NoError(t, os.RemoveAll(testDBPath)) 379 }() 380 381 // setup test pre-conditions (create a db with dbformat) 382 p, err := NewProvider(&Conf{DBPath: testDBPath, ExpectedFormat: dataFormat}) 383 assert.NoError(t, err) 384 f, err := p.GetDataFormat() 385 assert.NoError(t, err) 386 assert.Equal(t, dataFormat, f) 387 if dataExists { 388 assert.NoError(t, p.GetDBHandle("testdb").Put([]byte("key"), []byte("value"), true)) 389 } 390 391 // close and reopen with new conf 392 p.Close() 393 p, err = NewProvider(&Conf{DBPath: testDBPath, ExpectedFormat: expectedFormat}) 394 if expectedErr != nil { 395 expectedErr.DBInfo = fmt.Sprintf("leveldb at [%s]", testDBPath) 396 assert.Equal(t, err, expectedErr) 397 return 398 } 399 assert.NoError(t, err) 400 f, err = p.GetDataFormat() 401 assert.NoError(t, err) 402 assert.Equal(t, expectedFormat, f) 403 } 404 405 func testDBBasicWriteAndReads(t *testing.T, dbNames ...string) { 406 env := newTestProviderEnv(t, testDBPath) 407 defer env.cleanup() 408 p := env.provider 409 410 for _, dbName := range dbNames { 411 db := p.GetDBHandle(dbName) 412 db.Put([]byte("key1"), []byte("value1_"+dbName), false) 413 db.Put([]byte("key2"), []byte("value2_"+dbName), false) 414 db.Put([]byte("key3"), []byte("value3_"+dbName), false) 415 } 416 417 for _, dbName := range dbNames { 418 db := p.GetDBHandle(dbName) 419 val, err := db.Get([]byte("key1")) 420 assert.NoError(t, err, "") 421 assert.Equal(t, []byte("value1_"+dbName), val) 422 423 val, err = db.Get([]byte("key2")) 424 assert.NoError(t, err, "") 425 assert.Equal(t, []byte("value2_"+dbName), val) 426 427 val, err = db.Get([]byte("key3")) 428 assert.NoError(t, err, "") 429 assert.Equal(t, []byte("value3_"+dbName), val) 430 } 431 432 for _, dbName := range dbNames { 433 db := p.GetDBHandle(dbName) 434 assert.NoError(t, db.Delete([]byte("key1"), false), "") 435 val, err := db.Get([]byte("key1")) 436 assert.NoError(t, err, "") 437 assert.Nil(t, val) 438 439 assert.NoError(t, db.Delete([]byte("key2"), false), "") 440 val, err = db.Get([]byte("key2")) 441 assert.NoError(t, err, "") 442 assert.Nil(t, val) 443 444 assert.NoError(t, db.Delete([]byte("key3"), false), "") 445 val, err = db.Get([]byte("key3")) 446 assert.NoError(t, err, "") 447 assert.Nil(t, val) 448 } 449 } 450 451 func checkItrResults(t *testing.T, itr *Iterator, expectedKeys []string, expectedValues []string) { 452 var actualKeys []string 453 var actualValues []string 454 for itr.Next(); itr.Valid(); itr.Next() { 455 actualKeys = append(actualKeys, string(itr.Key())) 456 actualValues = append(actualValues, string(itr.Value())) 457 } 458 assert.Equal(t, expectedKeys, actualKeys) 459 assert.Equal(t, expectedValues, actualValues) 460 assert.Equal(t, false, itr.Next()) 461 } 462 463 func createTestKey(i int) string { 464 return fmt.Sprintf("key_%06d", i) 465 } 466 467 const padding100 = "_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_0123456789_" 468 469 func createTestLongKey(i int) string { 470 return fmt.Sprintf("key_%s_%10d", padding100, i) 471 } 472 473 func createTestValue(dbname string, i int) string { 474 return fmt.Sprintf("value_%s_%06d", dbname, i) 475 } 476 477 func createTestKeys(start int, end int) []string { 478 var keys []string 479 for i := start; i <= end; i++ { 480 keys = append(keys, createTestKey(i)) 481 } 482 return keys 483 } 484 485 func createTestLongKeys(start int, end int) []string { 486 var keys []string 487 for i := start; i <= end; i++ { 488 keys = append(keys, createTestLongKey(i)) 489 } 490 return keys 491 } 492 493 func createTestValues(dbname string, start int, end int) []string { 494 var values []string 495 for i := start; i <= end; i++ { 496 values = append(values, createTestValue(dbname, i)) 497 } 498 return values 499 }