pool/clientdb/batch_test.go
2020-04-03 21:53:04 +02:00

199 lines
5 KiB
Go

package clientdb
import (
"fmt"
"testing"
"github.com/btcsuite/btcutil"
"github.com/lightninglabs/agora/client/account"
"github.com/lightninglabs/agora/client/clmscript"
"github.com/lightninglabs/agora/client/order"
)
// TestPersistBatchResult tests that a batch result can be persisted correctly.
func TestPersistBatchResult(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
expectedErr string
runTest func(db *DB, a *order.Ask, b *order.Bid,
acct *account.Account) error
}{
{
name: "len mismatch order",
expectedErr: "order modifier length mismatch",
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
_ *account.Account) error {
return db.PersistBatchResult(
[]order.Nonce{a.Nonce()}, nil, nil, nil,
)
},
},
{
name: "len mismatch account",
expectedErr: "account modifier length mismatch",
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
acct *account.Account) error {
return db.PersistBatchResult(
nil, nil, []*account.Account{acct}, nil,
)
},
},
{
name: "non-existent order",
expectedErr: ErrNoOrder.Error(),
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
acct *account.Account) error {
modifiers := [][]order.Modifier{{
order.StateModifier(order.StateExecuted),
}}
return db.PersistBatchResult(
[]order.Nonce{{0, 1, 2}}, modifiers,
nil, nil,
)
},
},
{
name: "non-existent account",
expectedErr: ErrAccountNotFound.Error(),
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
acct *account.Account) error {
acct.TraderKey.PubKey = clmscript.IncrementKey(
acct.TraderKey.PubKey,
)
modifiers := [][]account.Modifier{{
account.StateModifier(account.StateClosed),
}}
return db.PersistBatchResult(
nil, nil, []*account.Account{acct},
modifiers,
)
},
},
{
name: "happy path",
expectedErr: "",
runTest: func(db *DB, a *order.Ask, b *order.Bid,
acct *account.Account) error {
// Store some changes to the orders and account.
orders := []order.Nonce{a.Nonce(), b.Nonce()}
orderModifiers := [][]order.Modifier{
{order.UnitsFulfilledModifier(42)},
{order.UnitsFulfilledModifier(21)},
}
accounts := []*account.Account{acct}
acctModifiers := [][]account.Modifier{{
account.StateModifier(
account.StatePendingOpen,
),
}}
err := db.PersistBatchResult(
orders, orderModifiers,
accounts, acctModifiers,
)
if err != nil {
return err
}
// Verify get the right result.
o1, err := db.GetOrder(a.Nonce())
if err != nil {
return err
}
if o1.Details().UnitsUnfulfilled != 42 {
return fmt.Errorf("unexpected number "+
"of unfulfilled units, got %d "+
"wanted %d",
o1.Details().UnitsUnfulfilled,
42)
}
o2, err := db.GetOrder(b.Nonce())
if err != nil {
return err
}
if o2.Details().UnitsUnfulfilled != 21 {
return fmt.Errorf("unexpected number "+
"of unfulfilled units, got %d "+
"wanted %d",
o2.Details().UnitsUnfulfilled,
21)
}
a2, err := db.Account(acct.TraderKey.PubKey)
if err != nil {
return err
}
if a2.State != account.StatePendingOpen {
return fmt.Errorf("unexpected state "+
"of account, got %d wanted %d",
a2.State,
account.StatePendingOpen)
}
return nil
},
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
// Create a new store every time to make sure we start
// with a clean slate.
store, cleanup := newTestDB(t)
defer cleanup()
// Create a test account and two matching orders that
// spend from that account. This never happens in real
// life but is good enough to just test the database.
acct := &account.Account{
Value: btcutil.SatoshiPerBitcoin,
Expiry: 1337,
TraderKey: testTraderKeyDesc,
AuctioneerKey: testAuctioneerKey,
BatchKey: testBatchKey,
Secret: sharedSecret,
State: account.StateOpen,
HeightHint: 1,
}
ask := &order.Ask{
Kit: *dummyOrder(t, 900000),
MaxDuration: 1337,
}
ask.State = order.StateSubmitted
bid := &order.Bid{
Kit: *dummyOrder(t, 900000),
MinDuration: 1337,
}
bid.State = order.StateSubmitted
// Prepare the DB state by storing our test account and
// orders.
err := store.AddAccount(acct)
if err != nil {
t.Fatalf("error storing test account: %v", err)
}
err = store.SubmitOrder(ask)
if err != nil {
t.Fatalf("error storing test ask: %v", err)
}
err = store.SubmitOrder(bid)
if err != nil {
t.Fatalf("error storing test bid: %v", err)
}
// Run the test case and verify the result.
err = tc.runTest(store, ask, bid, acct)
if (err == nil && tc.expectedErr != "") ||
(err != nil && err.Error() != tc.expectedErr) {
t.Fatalf("unexpected error '%s', expected '%s'",
err.Error(), tc.expectedErr)
}
})
}
}