sweep: use testify/mock for MockSweeperStore

This commit is contained in:
yyforyongyu committed 2024-04-19 21:33:20 +08:00
1 parent 8b9d5e0548
commit f13a3a8053
3 files changed
+53 -69

No files matched your search

+22 -18
View File
@@ -2,54 +2,58 @@ package sweep
import ( import (
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/stretchr/testify/mock"
) )
// MockSweeperStore is a mock implementation of sweeper store. This type is // MockSweeperStore is a mock implementation of sweeper store. This type is
// exported, because it is currently used in nursery tests too. // exported, because it is currently used in nursery tests too.
type MockSweeperStore struct { type MockSweeperStore struct {
ourTxes map[chainhash.Hash]struct{} mock.Mock
} }
// NewMockSweeperStore returns a new instance. // NewMockSweeperStore returns a new instance.
func NewMockSweeperStore() *MockSweeperStore { func NewMockSweeperStore() *MockSweeperStore {
return &MockSweeperStore{ return &MockSweeperStore{}
ourTxes: make(map[chainhash.Hash]struct{}),
}
} }
// IsOurTx determines whether a tx is published by us, based on its // IsOurTx determines whether a tx is published by us, based on its hash.
// hash.
func (s *MockSweeperStore) IsOurTx(hash chainhash.Hash) (bool, error) { func (s *MockSweeperStore) IsOurTx(hash chainhash.Hash) (bool, error) {
_, ok := s.ourTxes[hash] args := s.Called(hash)
return ok, nil
return args.Bool(0), args.Error(1)
} }
// StoreTx stores a tx we are about to publish. // StoreTx stores a tx we are about to publish.
func (s *MockSweeperStore) StoreTx(tr *TxRecord) error { func (s *MockSweeperStore) StoreTx(tr *TxRecord) error {
s.ourTxes[tr.Txid] = struct{}{} args := s.Called(tr)
return args.Error(0)
return nil
} }
// ListSweeps lists all the sweeps we have successfully published. // ListSweeps lists all the sweeps we have successfully published.
func (s *MockSweeperStore) ListSweeps() ([]chainhash.Hash, error) { func (s *MockSweeperStore) ListSweeps() ([]chainhash.Hash, error) {
var txns []chainhash.Hash args := s.Called()
for tx := range s.ourTxes {
txns = append(txns, tx)
}
return txns, nil return args.Get(0).([]chainhash.Hash), args.Error(1)
} }
// GetTx queries the database to find the tx that matches the given txid. // GetTx queries the database to find the tx that matches the given txid.
// Returns ErrTxNotFound if it cannot be found. // Returns ErrTxNotFound if it cannot be found.
func (s *MockSweeperStore) GetTx(hash chainhash.Hash) (*TxRecord, error) { func (s *MockSweeperStore) GetTx(hash chainhash.Hash) (*TxRecord, error) {
return nil, ErrTxNotFound args := s.Called(hash)
tr := args.Get(0)
if tr != nil {
return args.Get(0).(*TxRecord), args.Error(1)
}
return nil, args.Error(1)
} }
// DeleteTx removes the given tx from db. // DeleteTx removes the given tx from db.
func (s *MockSweeperStore) DeleteTx(txid chainhash.Hash) error { func (s *MockSweeperStore) DeleteTx(txid chainhash.Hash) error {
return nil args := s.Called(txid)
return args.Error(0)
} }
// Compile-time constraint to ensure MockSweeperStore implements SweeperStore. // Compile-time constraint to ensure MockSweeperStore implements SweeperStore.
+8 -32
View File
@@ -14,35 +14,13 @@ import (
// TestStore asserts that the store persists the presented data to disk and is // TestStore asserts that the store persists the presented data to disk and is
// able to retrieve it again. // able to retrieve it again.
func TestStore(t *testing.T) { func TestStore(t *testing.T) {
t.Run("bolt", func(t *testing.T) { // Create new store.
cdb, err := channeldb.MakeTestDB(t)
require.NoError(t, err)
// Create new store. var chain chainhash.Hash
cdb, err := channeldb.MakeTestDB(t) store, err := NewSweeperStore(cdb, &chain)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to open channel db: %v", err)
}
testStore(t, func() (SweeperStore, error) {
var chain chainhash.Hash
return NewSweeperStore(cdb, &chain)
})
})
t.Run("mock", func(t *testing.T) {
store := NewMockSweeperStore()
testStore(t, func() (SweeperStore, error) {
// Return same store, because the mock has no real
// persistence.
return store, nil
})
})
}
func testStore(t *testing.T, createStore func() (SweeperStore, error)) {
store, err := createStore()
if err != nil {
t.Fatal(err)
}
// Notify publication of tx1 // Notify publication of tx1
tx1 := wire.MsgTx{} tx1 := wire.MsgTx{}
@@ -75,10 +53,8 @@ func testStore(t *testing.T, createStore func() (SweeperStore, error)) {
require.NoError(t, err) require.NoError(t, err)
// Recreate the sweeper store // Recreate the sweeper store
store, err = createStore() store, err = NewSweeperStore(cdb, &chain)
if err != nil { require.NoError(t, err)
t.Fatal(err)
}
// Assert that both txes are recognized as our own. // Assert that both txes are recognized as our own.
ours, err := store.IsOurTx(tx1.TxHash()) ours, err := store.IsOurTx(tx1.TxHash())
+23 -19
View File
@@ -16,6 +16,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lntest/mock" "github.com/lightningnetwork/lnd/lntest/mock"
@@ -41,7 +42,7 @@ type sweeperTestContext struct {
notifier *MockNotifier notifier *MockNotifier
estimator *mockFeeEstimator estimator *mockFeeEstimator
backend *mockBackend backend *mockBackend
store *MockSweeperStore store SweeperStore
publishChan chan wire.MsgTx publishChan chan wire.MsgTx
} }
@@ -102,7 +103,13 @@ func init() {
func createSweeperTestContext(t *testing.T) *sweeperTestContext { func createSweeperTestContext(t *testing.T) *sweeperTestContext {
notifier := NewMockNotifier(t) notifier := NewMockNotifier(t)
store := NewMockSweeperStore() // Create new store.
cdb, err := channeldb.MakeTestDB(t)
require.NoError(t, err)
var chain chainhash.Hash
store, err := NewSweeperStore(cdb, &chain)
require.NoError(t, err)
backend := newMockBackend(t, notifier) backend := newMockBackend(t, notifier)
backend.walletUtxos = []*lnwallet.Utxo{ backend.walletUtxos = []*lnwallet.Utxo{
@@ -682,7 +689,6 @@ func TestIdempotency(t *testing.T) {
// Timer is still running, but spend notification was delivered before // Timer is still running, but spend notification was delivered before
// it expired. // it expired.
ctx.finish(1) ctx.finish(1)
} }
@@ -701,9 +707,8 @@ func TestRestart(t *testing.T) {
// Sweep input and expect sweep tx. // Sweep input and expect sweep tx.
input1 := spendableInputs[0] input1 := spendableInputs[0]
if _, err := ctx.sweeper.SweepInput(input1, defaultFeePref); err != nil { _, err := ctx.sweeper.SweepInput(input1, defaultFeePref)
t.Fatal(err) require.NoError(t, err)
}
ctx.receiveTx() ctx.receiveTx()
@@ -758,23 +763,20 @@ func TestRestart(t *testing.T) {
ctx.finish(1) ctx.finish(1)
} }
// TestRestartRemoteSpend asserts that the sweeper picks up sweeping properly after // TestRestartRemoteSpend asserts that the sweeper picks up sweeping properly
// a restart with remote spend. // after a restart with remote spend.
func TestRestartRemoteSpend(t *testing.T) { func TestRestartRemoteSpend(t *testing.T) {
ctx := createSweeperTestContext(t) ctx := createSweeperTestContext(t)
// Sweep input. // Sweep input.
input1 := spendableInputs[0] input1 := spendableInputs[0]
if _, err := ctx.sweeper.SweepInput(input1, defaultFeePref); err != nil { _, err := ctx.sweeper.SweepInput(input1, defaultFeePref)
t.Fatal(err) require.NoError(t, err)
}
// Sweep another input. // Sweep another input.
input2 := spendableInputs[1] input2 := spendableInputs[1]
if _, err := ctx.sweeper.SweepInput(input2, defaultFeePref); err != nil { _, err = ctx.sweeper.SweepInput(input2, defaultFeePref)
t.Fatal(err) require.NoError(t, err)
}
sweepTx := ctx.receiveTx() sweepTx := ctx.receiveTx()
@@ -798,7 +800,8 @@ func TestRestartRemoteSpend(t *testing.T) {
// Mine remote spending tx. // Mine remote spending tx.
ctx.backend.mine() ctx.backend.mine()
// Simulate other subsystem (e.g. contract resolver) re-offering input 0. // Simulate other subsystem (e.g. contract resolver) re-offering input
// 0.
spendChan, err := ctx.sweeper.SweepInput(input1, defaultFeePref) spendChan, err := ctx.sweeper.SweepInput(input1, defaultFeePref)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -815,8 +818,8 @@ func TestRestartRemoteSpend(t *testing.T) {
ctx.finish(1) ctx.finish(1)
} }
// TestRestartConfirmed asserts that the sweeper picks up sweeping properly after // TestRestartConfirmed asserts that the sweeper picks up sweeping properly
// a restart with a confirm of our own sweep tx. // after a restart with a confirm of our own sweep tx.
func TestRestartConfirmed(t *testing.T) { func TestRestartConfirmed(t *testing.T) {
ctx := createSweeperTestContext(t) ctx := createSweeperTestContext(t)
@@ -834,7 +837,8 @@ func TestRestartConfirmed(t *testing.T) {
// Mine the sweep tx. // Mine the sweep tx.
ctx.backend.mine() ctx.backend.mine()
// Simulate other subsystem (e.g. contract resolver) re-offering input 0. // Simulate other subsystem (e.g. contract resolver) re-offering input
// 0.
spendChan, err := ctx.sweeper.SweepInput(input, defaultFeePref) spendChan, err := ctx.sweeper.SweepInput(input, defaultFeePref)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)