mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-24 14:50:40 +01:00
Similarly as with kvdb.View this commits adds a reset closure to the kvdb.Update call in order to be able to reset external state if the underlying db backend needs to retry the transaction.
156 lines
3.4 KiB
Go
156 lines
3.4 KiB
Go
// +build kvdb_etcd
|
|
|
|
package etcd
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/btcsuite/btcwallet/walletdb"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestTxManualCommit(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
defer f.Cleanup()
|
|
|
|
db, err := newEtcdBackend(f.BackendConfig())
|
|
require.NoError(t, err)
|
|
|
|
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)
|
|
|
|
expected := map[string]string{
|
|
bkey("apple"): bval("apple"),
|
|
vkey("testKey", "apple"): "testVal",
|
|
}
|
|
require.Equal(t, expected, f.Dump())
|
|
}
|
|
|
|
func TestTxRollback(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
defer f.Cleanup()
|
|
|
|
db, err := newEtcdBackend(f.BackendConfig())
|
|
require.NoError(t, err)
|
|
|
|
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())
|
|
require.Equal(t, map[string]string{}, f.Dump())
|
|
}
|
|
|
|
func TestChangeDuringManualTx(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
defer f.Cleanup()
|
|
|
|
db, err := newEtcdBackend(f.BackendConfig())
|
|
require.NoError(t, err)
|
|
|
|
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")))
|
|
|
|
// Try overwriting the bucket key.
|
|
f.Put(bkey("apple"), "banana")
|
|
|
|
// TODO: translate error
|
|
require.NotNil(t, tx.Commit())
|
|
require.Equal(t, map[string]string{
|
|
bkey("apple"): "banana",
|
|
}, f.Dump())
|
|
}
|
|
|
|
func TestChangeDuringUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
defer f.Cleanup()
|
|
|
|
db, err := newEtcdBackend(f.BackendConfig())
|
|
require.NoError(t, err)
|
|
|
|
count := 0
|
|
|
|
err = db.Update(func(tx walletdb.ReadWriteTx) error {
|
|
apple, err := tx.CreateTopLevelBucket([]byte("apple"))
|
|
require.NoError(t, err)
|
|
require.NotNil(t, apple)
|
|
|
|
require.NoError(t, apple.Put([]byte("key"), []byte("value")))
|
|
|
|
if count == 0 {
|
|
f.Put(vkey("key", "apple"), "new_value")
|
|
f.Put(vkey("key2", "apple"), "value2")
|
|
}
|
|
|
|
cursor := apple.ReadCursor()
|
|
k, v := cursor.First()
|
|
require.Equal(t, []byte("key"), k)
|
|
require.Equal(t, []byte("value"), v)
|
|
require.Equal(t, v, apple.Get([]byte("key")))
|
|
|
|
k, v = cursor.Next()
|
|
if count == 0 {
|
|
require.Nil(t, k)
|
|
require.Nil(t, v)
|
|
} else {
|
|
require.Equal(t, []byte("key2"), k)
|
|
require.Equal(t, []byte("value2"), v)
|
|
}
|
|
|
|
count++
|
|
return nil
|
|
}, func() {})
|
|
|
|
require.Nil(t, err)
|
|
require.Equal(t, count, 2)
|
|
|
|
expected := map[string]string{
|
|
bkey("apple"): bval("apple"),
|
|
vkey("key", "apple"): "value",
|
|
vkey("key2", "apple"): "value2",
|
|
}
|
|
require.Equal(t, expected, f.Dump())
|
|
}
|