2020-05-15 17:59:37 +03:00
|
|
|
// +build kvdb_etcd
|
|
|
|
|
2020-02-18 21:35:53 +03:00
|
|
|
package etcd
|
|
|
|
|
|
|
|
import (
|
2021-02-09 22:19:31 +03:00
|
|
|
"context"
|
2020-02-18 21:35:53 +03:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/btcsuite/btcwallet/walletdb"
|
2020-06-29 15:53:38 +03:00
|
|
|
"github.com/stretchr/testify/require"
|
2020-02-18 21:35:53 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestTxManualCommit(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
|
|
defer f.Cleanup()
|
|
|
|
|
2021-02-09 22:19:31 +03:00
|
|
|
db, err := newEtcdBackend(context.TODO(), f.BackendConfig())
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
tx, err := db.BeginReadWriteTx()
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, tx)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
committed := false
|
|
|
|
|
|
|
|
tx.OnCommit(func() {
|
|
|
|
committed = true
|
|
|
|
})
|
|
|
|
|
|
|
|
apple, err := tx.CreateTopLevelBucket([]byte("apple"))
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, apple)
|
|
|
|
require.NoError(t, apple.Put([]byte("testKey"), []byte("testVal")))
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
banana, err := tx.CreateTopLevelBucket([]byte("banana"))
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, banana)
|
|
|
|
require.NoError(t, banana.Put([]byte("testKey"), []byte("testVal")))
|
|
|
|
require.NoError(t, tx.DeleteTopLevelBucket([]byte("banana")))
|
2020-02-18 21:35:53 +03:00
|
|
|
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, tx.Commit())
|
|
|
|
require.True(t, committed)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
expected := map[string]string{
|
|
|
|
bkey("apple"): bval("apple"),
|
|
|
|
vkey("testKey", "apple"): "testVal",
|
|
|
|
}
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Equal(t, expected, f.Dump())
|
2020-02-18 21:35:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestTxRollback(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
|
|
defer f.Cleanup()
|
|
|
|
|
2021-02-09 22:19:31 +03:00
|
|
|
db, err := newEtcdBackend(context.TODO(), f.BackendConfig())
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
tx, err := db.BeginReadWriteTx()
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, tx)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
apple, err := tx.CreateTopLevelBucket([]byte("apple"))
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, apple)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, apple.Put([]byte("testKey"), []byte("testVal")))
|
2020-02-18 21:35:53 +03:00
|
|
|
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, tx.Rollback())
|
|
|
|
require.Error(t, walletdb.ErrTxClosed, tx.Commit())
|
|
|
|
require.Equal(t, map[string]string{}, f.Dump())
|
2020-02-18 21:35:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestChangeDuringManualTx(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
|
|
defer f.Cleanup()
|
|
|
|
|
2021-02-09 22:19:31 +03:00
|
|
|
db, err := newEtcdBackend(context.TODO(), f.BackendConfig())
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
tx, err := db.BeginReadWriteTx()
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, tx)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
apple, err := tx.CreateTopLevelBucket([]byte("apple"))
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, apple)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, apple.Put([]byte("testKey"), []byte("testVal")))
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
// Try overwriting the bucket key.
|
|
|
|
f.Put(bkey("apple"), "banana")
|
|
|
|
|
|
|
|
// TODO: translate error
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NotNil(t, tx.Commit())
|
|
|
|
require.Equal(t, map[string]string{
|
2020-02-18 21:35:53 +03:00
|
|
|
bkey("apple"): "banana",
|
|
|
|
}, f.Dump())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestChangeDuringUpdate(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
f := NewEtcdTestFixture(t)
|
|
|
|
defer f.Cleanup()
|
|
|
|
|
2021-02-09 22:19:31 +03:00
|
|
|
db, err := newEtcdBackend(context.TODO(), f.BackendConfig())
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
count := 0
|
|
|
|
|
|
|
|
err = db.Update(func(tx walletdb.ReadWriteTx) error {
|
|
|
|
apple, err := tx.CreateTopLevelBucket([]byte("apple"))
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, apple)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
2020-06-29 15:53:38 +03:00
|
|
|
require.NoError(t, apple.Put([]byte("key"), []byte("value")))
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
if count == 0 {
|
|
|
|
f.Put(vkey("key", "apple"), "new_value")
|
|
|
|
f.Put(vkey("key2", "apple"), "value2")
|
|
|
|
}
|
|
|
|
|
|
|
|
cursor := apple.ReadCursor()
|
|
|
|
k, v := cursor.First()
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Equal(t, []byte("key"), k)
|
|
|
|
require.Equal(t, []byte("value"), v)
|
|
|
|
require.Equal(t, v, apple.Get([]byte("key")))
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
k, v = cursor.Next()
|
|
|
|
if count == 0 {
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Nil(t, k)
|
|
|
|
require.Nil(t, v)
|
2020-02-18 21:35:53 +03:00
|
|
|
} else {
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Equal(t, []byte("key2"), k)
|
|
|
|
require.Equal(t, []byte("value2"), v)
|
2020-02-18 21:35:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
count++
|
|
|
|
return nil
|
2020-10-26 16:06:32 +03:00
|
|
|
}, func() {})
|
2020-02-18 21:35:53 +03:00
|
|
|
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Nil(t, err)
|
|
|
|
require.Equal(t, count, 2)
|
2020-02-18 21:35:53 +03:00
|
|
|
|
|
|
|
expected := map[string]string{
|
|
|
|
bkey("apple"): bval("apple"),
|
|
|
|
vkey("key", "apple"): "value",
|
|
|
|
vkey("key2", "apple"): "value2",
|
|
|
|
}
|
2020-06-29 15:53:38 +03:00
|
|
|
require.Equal(t, expected, f.Dump())
|
2020-02-18 21:35:53 +03:00
|
|
|
}
|