123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- 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)
- })
- }
- }
|