mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
channeldb: add unit test for decidePaymentStatus
This commit is contained in:
parent
390f3c8253
commit
fac6044501
248
channeldb/payment_status_test.go
Normal file
248
channeldb/payment_status_test.go
Normal file
@ -0,0 +1,248 @@
|
||||
package channeldb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestDecidePaymentStatus checks that given a set of HTLC and a failure
|
||||
// reason, the payment's current status is returned as expected.
|
||||
func TestDecidePaymentStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create two attempts used for testing.
|
||||
inflight := HTLCAttempt{}
|
||||
settled := HTLCAttempt{
|
||||
Settle: &HTLCSettleInfo{Preimage: lntypes.Preimage{}},
|
||||
}
|
||||
failed := HTLCAttempt{
|
||||
Failure: &HTLCFailInfo{FailureSourceIndex: 1},
|
||||
}
|
||||
|
||||
// Create a test failure reason and get the pointer.
|
||||
reason := FailureReasonNoRoute
|
||||
failure := &reason
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
htlcs []HTLCAttempt
|
||||
reason *FailureReason
|
||||
expectedStatus PaymentStatus
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
// Test when inflight=true, settled=true, failed=true,
|
||||
// reason=yes.
|
||||
name: "state 1111",
|
||||
htlcs: []HTLCAttempt{
|
||||
inflight, settled, failed,
|
||||
},
|
||||
reason: failure,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=true, settled=true, failed=true,
|
||||
// reason=no.
|
||||
name: "state 1110",
|
||||
htlcs: []HTLCAttempt{
|
||||
inflight, settled, failed,
|
||||
},
|
||||
reason: nil,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=true, settled=true, failed=false,
|
||||
// reason=yes.
|
||||
name: "state 1101",
|
||||
htlcs: []HTLCAttempt{inflight, settled},
|
||||
reason: failure,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=true, settled=true, failed=false,
|
||||
// reason=no.
|
||||
name: "state 1100",
|
||||
htlcs: []HTLCAttempt{inflight, settled},
|
||||
reason: nil,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=true, settled=false, failed=true,
|
||||
// reason=yes.
|
||||
name: "state 1011",
|
||||
htlcs: []HTLCAttempt{inflight, failed},
|
||||
reason: failure,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=true, settled=false, failed=true,
|
||||
// reason=no.
|
||||
name: "state 1010",
|
||||
htlcs: []HTLCAttempt{inflight, failed},
|
||||
reason: nil,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=true, settled=false, failed=false,
|
||||
// reason=yes.
|
||||
name: "state 1001",
|
||||
htlcs: []HTLCAttempt{inflight},
|
||||
reason: failure,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=true, settled=false, failed=false,
|
||||
// reason=no.
|
||||
name: "state 1000",
|
||||
htlcs: []HTLCAttempt{inflight},
|
||||
reason: nil,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=true, failed=true,
|
||||
// reason=yes.
|
||||
name: "state 0111",
|
||||
htlcs: []HTLCAttempt{settled, failed},
|
||||
reason: failure,
|
||||
expectedStatus: StatusSucceeded,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=true, failed=true,
|
||||
// reason=no.
|
||||
name: "state 0110",
|
||||
htlcs: []HTLCAttempt{settled, failed},
|
||||
reason: nil,
|
||||
expectedStatus: StatusSucceeded,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=true,
|
||||
// failed=false, reason=yes.
|
||||
name: "state 0101",
|
||||
htlcs: []HTLCAttempt{settled},
|
||||
reason: failure,
|
||||
expectedStatus: StatusSucceeded,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=true,
|
||||
// failed=false, reason=no.
|
||||
name: "state 0100",
|
||||
htlcs: []HTLCAttempt{settled},
|
||||
reason: nil,
|
||||
expectedStatus: StatusSucceeded,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=false,
|
||||
// failed=true, reason=yes.
|
||||
name: "state 0011",
|
||||
htlcs: []HTLCAttempt{failed},
|
||||
reason: failure,
|
||||
expectedStatus: StatusFailed,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=false,
|
||||
// failed=true, reason=no.
|
||||
name: "state 0010",
|
||||
htlcs: []HTLCAttempt{failed},
|
||||
reason: nil,
|
||||
expectedStatus: StatusInFlight,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=false,
|
||||
// failed=false, reason=yes.
|
||||
name: "state 0001",
|
||||
htlcs: []HTLCAttempt{},
|
||||
reason: failure,
|
||||
expectedStatus: StatusFailed,
|
||||
},
|
||||
{
|
||||
// Test when inflight=false, settled=false,
|
||||
// failed=false, reason=no.
|
||||
name: "state 0000",
|
||||
htlcs: []HTLCAttempt{},
|
||||
reason: nil,
|
||||
expectedStatus: StatusInitiated,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
status, err := decidePaymentStatus(tc.htlcs, tc.reason)
|
||||
require.Equalf(t, tc.expectedStatus, status,
|
||||
"got %s, want %s", status, tc.expectedStatus)
|
||||
require.ErrorIs(t, err, tc.expectedErr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestPaymentStatusActions checks whether a list of actions can be applied
|
||||
// against ALL possible payment statuses. Unlike normal unit tests where we
|
||||
// check against a single function, all the actions including `removable`,
|
||||
// `initable`, and `updatable` are tested together so this test can be used as
|
||||
// a reference of state transition.
|
||||
func TestPaymentStatusActions(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
status PaymentStatus
|
||||
initErr error
|
||||
updateErr error
|
||||
removeErr error
|
||||
}{
|
||||
{
|
||||
status: StatusInitiated,
|
||||
initErr: ErrPaymentExists,
|
||||
updateErr: nil,
|
||||
removeErr: nil,
|
||||
},
|
||||
{
|
||||
status: StatusInFlight,
|
||||
initErr: ErrPaymentInFlight,
|
||||
updateErr: nil,
|
||||
removeErr: ErrPaymentInFlight,
|
||||
},
|
||||
{
|
||||
status: StatusSucceeded,
|
||||
initErr: ErrAlreadyPaid,
|
||||
updateErr: ErrPaymentAlreadySucceeded,
|
||||
removeErr: nil,
|
||||
},
|
||||
{
|
||||
status: StatusFailed,
|
||||
initErr: nil,
|
||||
updateErr: ErrPaymentAlreadyFailed,
|
||||
removeErr: nil,
|
||||
},
|
||||
{
|
||||
status: 0,
|
||||
initErr: ErrUnknownPaymentStatus,
|
||||
updateErr: ErrUnknownPaymentStatus,
|
||||
removeErr: ErrUnknownPaymentStatus,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
i, tc := i, tc
|
||||
|
||||
ps := tc.status
|
||||
name := fmt.Sprintf("test_%d_%s", i, ps.String())
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.ErrorIs(t, ps.initializable(), tc.initErr,
|
||||
"initable under state %v", tc.status)
|
||||
|
||||
require.ErrorIs(t, ps.updatable(), tc.updateErr,
|
||||
"updatable under state %v", tc.status)
|
||||
|
||||
require.ErrorIs(t, ps.removable(), tc.removeErr,
|
||||
"removable under state %v", tc.status)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user