Joost Jager
3 years ago
10 changed files with 307 additions and 313 deletions
@ -1,42 +0,0 @@
|
||||
// +build kvdb_etcd
|
||||
|
||||
package etcd |
||||
|
||||
// bkey is a helper functon used in tests to create a bucket key from passed
|
||||
// bucket list.
|
||||
func bkey(buckets ...string) string { |
||||
var bucketKey []byte |
||||
|
||||
rootID := makeBucketID([]byte(etcdDefaultRootBucketId)) |
||||
parent := rootID[:] |
||||
|
||||
for _, bucketName := range buckets { |
||||
bucketKey = makeBucketKey(parent, []byte(bucketName)) |
||||
id := makeBucketID(bucketKey) |
||||
parent = id[:] |
||||
} |
||||
|
||||
return string(bucketKey) |
||||
} |
||||
|
||||
// bval is a helper function used in tests to create a bucket value (the value
|
||||
// for a bucket key) from the passed bucket list.
|
||||
func bval(buckets ...string) string { |
||||
id := makeBucketID([]byte(bkey(buckets...))) |
||||
return string(id[:]) |
||||
} |
||||
|
||||
// vkey is a helper function used in tests to create a value key from the
|
||||
// passed key and bucket list.
|
||||
func vkey(key string, buckets ...string) string { |
||||
rootID := makeBucketID([]byte(etcdDefaultRootBucketId)) |
||||
bucket := rootID[:] |
||||
|
||||
for _, bucketName := range buckets { |
||||
bucketKey := makeBucketKey(bucket, []byte(bucketName)) |
||||
id := makeBucketID(bucketKey) |
||||
bucket = id[:] |
||||
} |
||||
|
||||
return string(makeValueKey(bucket, []byte(key))) |
||||
} |
@ -0,0 +1,154 @@
|
||||
// +build kvdb_etcd
|
||||
|
||||
package kvdb |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/btcsuite/btcwallet/walletdb" |
||||
"github.com/lightningnetwork/lnd/kvdb/etcd" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
var ( |
||||
bkey = etcd.BucketKey |
||||
bval = etcd.BucketVal |
||||
vkey = etcd.ValueKey |
||||
) |
||||
|
||||
func TestEtcd(t *testing.T) { |
||||
tests := []struct { |
||||
name string |
||||
test func(*testing.T, walletdb.DB) |
||||
expectedDb map[string]string |
||||
}{ |
||||
{ |
||||
name: "read cursor empty interval", |
||||
test: testReadCursorEmptyInterval, |
||||
}, |
||||
{ |
||||
name: "read cursor non empty interval", |
||||
test: testReadCursorNonEmptyInterval, |
||||
}, |
||||
{ |
||||
name: "read write cursor", |
||||
test: testReadWriteCursor, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
vkey("a", "apple"): "0", |
||||
vkey("c", "apple"): "3", |
||||
vkey("cx", "apple"): "x", |
||||
vkey("cy", "apple"): "y", |
||||
vkey("da", "apple"): "3", |
||||
vkey("f", "apple"): "5", |
||||
}, |
||||
}, |
||||
{ |
||||
name: "read write cursor with bucket and value", |
||||
test: testReadWriteCursorWithBucketAndValue, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
bkey("apple", "banana"): bval("apple", "banana"), |
||||
bkey("apple", "pear"): bval("apple", "pear"), |
||||
vkey("key", "apple"): "val", |
||||
}, |
||||
}, |
||||
{ |
||||
name: "bucket creation", |
||||
test: testBucketCreation, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
bkey("apple", "banana"): bval("apple", "banana"), |
||||
bkey("apple", "mango"): bval("apple", "mango"), |
||||
bkey("apple", "banana", "pear"): bval("apple", "banana", "pear"), |
||||
}, |
||||
}, |
||||
{ |
||||
name: "bucket deletion", |
||||
test: testBucketDeletion, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
bkey("apple", "banana"): bval("apple", "banana"), |
||||
vkey("key1", "apple", "banana"): "val1", |
||||
vkey("key3", "apple", "banana"): "val3", |
||||
}, |
||||
}, |
||||
{ |
||||
name: "bucket for each", |
||||
test: testBucketForEach, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
bkey("apple", "banana"): bval("apple", "banana"), |
||||
vkey("key1", "apple"): "val1", |
||||
vkey("key2", "apple"): "val2", |
||||
vkey("key3", "apple"): "val3", |
||||
vkey("key1", "apple", "banana"): "val1", |
||||
vkey("key2", "apple", "banana"): "val2", |
||||
vkey("key3", "apple", "banana"): "val3", |
||||
}, |
||||
}, |
||||
{ |
||||
name: "bucket for each with error", |
||||
test: testBucketForEachWithError, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
bkey("apple", "banana"): bval("apple", "banana"), |
||||
bkey("apple", "pear"): bval("apple", "pear"), |
||||
vkey("key1", "apple"): "val1", |
||||
vkey("key2", "apple"): "val2", |
||||
}, |
||||
}, |
||||
{ |
||||
name: "bucket sequence", |
||||
test: testBucketSequence, |
||||
}, |
||||
{ |
||||
name: "key clash", |
||||
test: testKeyClash, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
bkey("apple", "banana"): bval("apple", "banana"), |
||||
vkey("key", "apple"): "val", |
||||
}, |
||||
}, |
||||
{ |
||||
name: "bucket create delete", |
||||
test: testBucketCreateDelete, |
||||
expectedDb: map[string]string{ |
||||
vkey("banana", "apple"): "value", |
||||
bkey("apple"): bval("apple"), |
||||
}, |
||||
}, |
||||
{ |
||||
name: "tx manual commit", |
||||
test: testTxManualCommit, |
||||
expectedDb: map[string]string{ |
||||
bkey("apple"): bval("apple"), |
||||
vkey("testKey", "apple"): "testVal", |
||||
}, |
||||
}, |
||||
{ |
||||
name: "tx rollback", |
||||
test: testTxRollback, |
||||
expectedDb: map[string]string{}, |
||||
}, |
||||
} |
||||
|
||||
for _, test := range tests { |
||||
test := test |
||||
|
||||
t.Run(test.name, func(t *testing.T) { |
||||
t.Parallel() |
||||
|
||||
f := etcd.NewEtcdTestFixture(t) |
||||
defer f.Cleanup() |
||||
|
||||
test.test(t, f.NewBackend()) |
||||
|
||||
if test.expectedDb != nil { |
||||
dump := f.Dump() |
||||
require.Equal(t, test.expectedDb, dump) |
||||
} |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,49 @@
|
||||
package kvdb |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/btcsuite/btcwallet/walletdb" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
func testTxManualCommit(t *testing.T, db walletdb.DB) { |
||||
tx, err := db.BeginReadWriteTx() |
||||
require.NoError(t, err) |
||||
require.NotNil(t, tx) |
||||
|
||||
committed := false |
||||
|
||||
tx.OnCommit(func() { |
||||
committed = true |
||||
}) |
||||
|
||||
apple, err := tx.CreateTopLevelBucket([]byte("apple")) |
||||
require.NoError(t, err) |
||||
require.NotNil(t, apple) |
||||
require.NoError(t, apple.Put([]byte("testKey"), []byte("testVal"))) |
||||
|
||||
banana, err := tx.CreateTopLevelBucket([]byte("banana")) |
||||
require.NoError(t, err) |
||||
require.NotNil(t, banana) |
||||
require.NoError(t, banana.Put([]byte("testKey"), []byte("testVal"))) |
||||
require.NoError(t, tx.DeleteTopLevelBucket([]byte("banana"))) |
||||
|
||||
require.NoError(t, tx.Commit()) |
||||
require.True(t, committed) |
||||
} |
||||
|
||||
func testTxRollback(t *testing.T, db walletdb.DB) { |
||||
tx, err := db.BeginReadWriteTx() |
||||
require.Nil(t, err) |
||||
require.NotNil(t, tx) |
||||
|
||||
apple, err := tx.CreateTopLevelBucket([]byte("apple")) |
||||
require.Nil(t, err) |
||||
require.NotNil(t, apple) |
||||
|
||||
require.NoError(t, apple.Put([]byte("testKey"), []byte("testVal"))) |
||||
|
||||
require.NoError(t, tx.Rollback()) |
||||
require.Error(t, walletdb.ErrTxClosed, tx.Commit()) |
||||
} |
Loading…
Reference in new issue