mirror of
https://github.com/lightningnetwork/lnd.git
synced 2026-08-13 12:32:48 +02:00
229 lines
4.9 KiB
Go
229 lines
4.9 KiB
Go
//go:build test_db_sqlite || test_db_postgres
|
|
|
|
package paymentsdb
|
|
|
|
import (
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestComputePaymentStatus tests the SQL to domain type conversion logic in
|
|
// computePaymentStatusFromResolutions. This is a pure unit test with no
|
|
// database interaction. However the function is only used in the SQL store and
|
|
// used sql data types so we test it in a sql specific file.
|
|
func TestComputePaymentStatus(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
resolutionTypes []sql.NullInt32
|
|
failReason sql.NullInt32
|
|
expectedStatus PaymentStatus
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "all NULL resolutions means in-flight",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{Valid: false}, // NULL = in-flight
|
|
{Valid: false},
|
|
},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusInFlight,
|
|
},
|
|
{
|
|
name: "settled resolution without fail reason",
|
|
resolutionTypes: []sql.NullInt32{{
|
|
Int32: int32(HTLCAttemptResolutionSettled),
|
|
Valid: true,
|
|
}},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusSucceeded,
|
|
},
|
|
{
|
|
name: "failed resolution without fail reason",
|
|
resolutionTypes: []sql.NullInt32{{
|
|
Int32: int32(HTLCAttemptResolutionFailed),
|
|
Valid: true,
|
|
}},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusInFlight,
|
|
},
|
|
{
|
|
name: "failed resolution with fail reason",
|
|
resolutionTypes: []sql.NullInt32{{
|
|
Int32: int32(HTLCAttemptResolutionFailed),
|
|
Valid: true,
|
|
}},
|
|
failReason: sql.NullInt32{
|
|
Int32: int32(FailureReasonNoRoute),
|
|
Valid: true,
|
|
},
|
|
expectedStatus: StatusFailed,
|
|
},
|
|
{
|
|
name: "mixed: in-flight and settled",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{Valid: false}, // in-flight
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionSettled,
|
|
),
|
|
Valid: true,
|
|
},
|
|
},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusInFlight,
|
|
},
|
|
{
|
|
name: "mixed: in-flight and failed",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{Valid: false}, // in-flight
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionFailed,
|
|
),
|
|
Valid: true,
|
|
},
|
|
},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusInFlight,
|
|
},
|
|
{
|
|
name: "mixed: settled and failed",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionSettled,
|
|
),
|
|
Valid: true,
|
|
},
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionFailed,
|
|
),
|
|
Valid: true,
|
|
},
|
|
},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusSucceeded,
|
|
},
|
|
{
|
|
name: "no resolutions, no fail reason, " +
|
|
"means initiated",
|
|
resolutionTypes: []sql.NullInt32{},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusInitiated,
|
|
},
|
|
{
|
|
name: "no resolutions with fail reason, " +
|
|
"means failed",
|
|
resolutionTypes: []sql.NullInt32{},
|
|
failReason: sql.NullInt32{
|
|
Int32: int32(FailureReasonNoRoute),
|
|
Valid: true,
|
|
},
|
|
expectedStatus: StatusFailed,
|
|
},
|
|
{
|
|
name: "unknown resolution type returns error",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{Int32: 999, Valid: true}, // invalid type
|
|
},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "all three states: in-flight, settled, failed",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{
|
|
Valid: false, // in-flight
|
|
},
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionSettled,
|
|
),
|
|
Valid: true,
|
|
},
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionFailed,
|
|
),
|
|
Valid: true,
|
|
},
|
|
},
|
|
failReason: sql.NullInt32{
|
|
Int32: int32(FailureReasonTimeout),
|
|
Valid: true,
|
|
},
|
|
expectedStatus: StatusInFlight,
|
|
},
|
|
{
|
|
name: "multiple settled HTLCs",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionSettled,
|
|
),
|
|
Valid: true,
|
|
},
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionSettled,
|
|
),
|
|
Valid: true,
|
|
},
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionSettled,
|
|
),
|
|
Valid: true,
|
|
},
|
|
},
|
|
failReason: sql.NullInt32{Valid: false},
|
|
expectedStatus: StatusSucceeded,
|
|
},
|
|
{
|
|
name: "multiple failed HTLCs with fail reason",
|
|
resolutionTypes: []sql.NullInt32{
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionFailed,
|
|
),
|
|
Valid: true,
|
|
},
|
|
{
|
|
Int32: int32(
|
|
HTLCAttemptResolutionFailed,
|
|
),
|
|
Valid: true,
|
|
},
|
|
},
|
|
failReason: sql.NullInt32{
|
|
Int32: int32(FailureReasonNoRoute),
|
|
Valid: true,
|
|
},
|
|
expectedStatus: StatusFailed,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
status, err := computePaymentStatusFromResolutions(
|
|
tc.resolutionTypes, tc.failReason,
|
|
)
|
|
|
|
if tc.expectError {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, tc.expectedStatus, status,
|
|
"got %s, want %s", status, tc.expectedStatus)
|
|
})
|
|
}
|
|
}
|