kaspad/database/ffldb/dbcache_test.go

137 lines
4.1 KiB
Go

package ffldb
import (
"bytes"
"testing"
"github.com/kaspanet/kaspad/database"
ldbutil "github.com/syndtr/goleveldb/leveldb/util"
)
func TestExhaustedDbCacheIterator(t *testing.T) {
db := newTestDb("TestExhaustedDbCacheIterator", t)
defer db.Close()
snapshot, err := db.cache.Snapshot()
if err != nil {
t.Fatalf("TestExhaustedDbCacheIterator: Error creating cache snapshot: %s", err)
}
iterator := snapshot.NewIterator(&ldbutil.Range{})
if next := iterator.Next(); next != false {
t.Errorf("TestExhaustedDbCacheIterator: Expected .Next() = false, but got %v", next)
}
if prev := iterator.Prev(); prev != false {
t.Errorf("TestExhaustedDbCacheIterator: Expected .Prev() = false, but got %v", prev)
}
if key := iterator.Key(); key != nil {
t.Errorf("TestExhaustedDbCacheIterator: Expected .Key() = nil, but got %v", key)
}
if value := iterator.Value(); value != nil {
t.Errorf("TestExhaustedDbCacheIterator: Expected .Value() = nil, but got %v", value)
}
}
// TestLDBIteratorImplPlaceholders hits functions that are there to implement leveldb iterator.Iterator interface,
// but surve no other purpose.
func TestLDBIteratorImplPlaceholders(t *testing.T) {
db := newTestDb("TestIteratorImplPlaceholders", t)
defer db.Close()
snapshot, err := db.cache.Snapshot()
if err != nil {
t.Fatalf("TestLDBIteratorImplPlaceholders: Error creating cache snapshot: %s", err)
}
iterator := newLdbCacheIter(snapshot, &ldbutil.Range{})
if err = iterator.Error(); err != nil {
t.Errorf("TestLDBIteratorImplPlaceholders: Expected .Error() = nil, but got %v", err)
}
// Call SetReleaser to achieve coverage of it. Actually does nothing
iterator.SetReleaser(nil)
}
func TestSkipPendingUpdatesCache(t *testing.T) {
pdb := newTestDb("TestSkipPendingUpdatesCache", t)
defer pdb.Close()
value := []byte("value")
// Add numbered prefixes to keys so that they are in expected order, and before any other keys
firstKey := []byte("1 - first")
toDeleteKey := []byte("2 - toDelete")
toUpdateKey := []byte("3 - toUpdate")
secondKey := []byte("4 - second")
// create initial metadata for test
err := pdb.Update(func(dbTx database.Tx) error {
metadata := dbTx.Metadata()
if err := metadata.Put(firstKey, value); err != nil {
return err
}
if err := metadata.Put(toDeleteKey, value); err != nil {
return err
}
if err := metadata.Put(toUpdateKey, value); err != nil {
return err
}
if err := metadata.Put(secondKey, value); err != nil {
return err
}
return nil
})
if err != nil {
t.Fatalf("Error adding to metadata: %s", err)
}
err = pdb.cache.flush()
if err != nil {
t.Fatalf("Error flushing cache: %s", err)
}
// test skips
err = pdb.Update(func(dbTx database.Tx) error {
snapshot, err := pdb.cache.Snapshot()
if err != nil {
t.Fatalf("TestSkipPendingUpdatesCache: Error getting snapshot: %s", err)
}
iterator := snapshot.NewIterator(&ldbutil.Range{})
snapshot.pendingRemove = snapshot.pendingRemove.Put(bucketizedKey(metadataBucketID, toDeleteKey), value)
snapshot.pendingKeys = snapshot.pendingKeys.Put(bucketizedKey(metadataBucketID, toUpdateKey), value)
// Check that first is ok
iterator.First()
expectedKey := bucketizedKey(metadataBucketID, firstKey)
actualKey := iterator.Key()
if !bytes.Equal(actualKey, expectedKey) {
t.Errorf("TestSkipPendingUpdatesCache: 1: key expected to be %v but is %v", expectedKey, actualKey)
}
// Go to the next key, which is second, toDelete and toUpdate will be skipped
iterator.Next()
expectedKey = bucketizedKey(metadataBucketID, secondKey)
actualKey = iterator.Key()
if !bytes.Equal(actualKey, expectedKey) {
t.Errorf("TestSkipPendingUpdatesCache: 2: key expected to be %s but is %s", expectedKey, actualKey)
}
// now traverse backwards - should get first, toUpdate and toDelete will be skipped
iterator.Prev()
expectedKey = bucketizedKey(metadataBucketID, firstKey)
actualKey = iterator.Key()
if !bytes.Equal(actualKey, expectedKey) {
t.Errorf("TestSkipPendingUpdatesCache: 4: key expected to be %s but is %s", expectedKey, actualKey)
}
return nil
})
if err != nil {
t.Fatalf("TestSkipPendingUpdatesCache: Error running main part of test: %s", err)
}
}