github.com/decred/dcrlnd@v0.7.6/channeldb/payments_inflight_test.go (about)

     1  package channeldb
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/decred/dcrlnd/kvdb"
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  // assertFetchesInflight asserts that calling FetchInFlightPayments returns
    11  // the required info.
    12  func assertFetchesInflight(t *testing.T, pControl *PaymentControl, info *PaymentCreationInfo) {
    13  	inFlight, err := pControl.FetchInFlightPayments()
    14  	require.Nil(t, err)
    15  	require.Len(t, inFlight, 1)
    16  	require.Equal(t, inFlight[0].Info.PaymentIdentifier, info.PaymentIdentifier)
    17  }
    18  
    19  // testPaymentInflightIndexCase is a test case for fetching inflight payments.
    20  // noIndex determines if the index is used from the start of the test case.
    21  // recreateIndex determines if the index is re-created halfway through the
    22  // test case.
    23  func testPaymentInflightIndexCase(t *testing.T, noIndex, recreateIndex bool) {
    24  	db, cleanup, err := MakeTestDB()
    25  	defer cleanup()
    26  
    27  	if err != nil {
    28  		t.Fatalf("unable to init db: %v", err)
    29  	}
    30  
    31  	pControl := NewPaymentControl(db)
    32  
    33  	// If this test case is to run without the payments inflight index, manually drop it.
    34  	if noIndex {
    35  		err = kvdb.Update(db, func(tx kvdb.RwTx) error {
    36  			return tx.DeleteTopLevelBucket(paymentsInflightIndexBucket)
    37  		}, func() {})
    38  		require.Nil(t, err)
    39  	}
    40  
    41  	// Init and settle a sample payment.
    42  	settledInfo, settledAttempt, settlePreimage, err := genInfo()
    43  	require.Nil(t, err)
    44  	err = pControl.InitPayment(settledInfo.PaymentIdentifier, settledInfo)
    45  	require.Nil(t, err)
    46  	_, err = pControl.RegisterAttempt(settledInfo.PaymentIdentifier, settledAttempt)
    47  	require.Nil(t, err)
    48  	_, err = pControl.SettleAttempt(
    49  		settledInfo.PaymentIdentifier, settledAttempt.AttemptID,
    50  		&HTLCSettleInfo{
    51  			Preimage: settlePreimage,
    52  		},
    53  	)
    54  	require.Nil(t, err)
    55  
    56  	// Init and fail a sample payment.
    57  	failedInfo, failedAttempt, _, err := genInfo()
    58  	require.Nil(t, err)
    59  	err = pControl.InitPayment(failedInfo.PaymentIdentifier, failedInfo)
    60  	require.Nil(t, err)
    61  	_, err = pControl.RegisterAttempt(failedInfo.PaymentIdentifier, failedAttempt)
    62  	require.Nil(t, err)
    63  	_, err = pControl.FailAttempt(failedInfo.PaymentIdentifier, failedAttempt.AttemptID,
    64  		&HTLCFailInfo{Reason: HTLCFailUnreadable})
    65  	require.Nil(t, err)
    66  	_, err = pControl.Fail(failedInfo.PaymentIdentifier, FailureReasonNoRoute)
    67  	require.Nil(t, err)
    68  
    69  	// Setup the test inflight payment.
    70  	info, attempt, preimg, err := genInfo()
    71  	require.Nil(t, err)
    72  
    73  	// Init the payment.
    74  	err = pControl.InitPayment(info.PaymentIdentifier, info)
    75  	require.Nil(t, err)
    76  
    77  	// We should find one payment inflight.
    78  	assertFetchesInflight(t, pControl, info)
    79  
    80  	// Register an attempt. Still inflight.
    81  	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
    82  	require.Nil(t, err)
    83  	assertFetchesInflight(t, pControl, info)
    84  
    85  	// Fail the attempt. Still inflight.
    86  	_, err = pControl.FailAttempt(info.PaymentIdentifier, attempt.AttemptID,
    87  		&HTLCFailInfo{Reason: HTLCFailUnreadable})
    88  	require.Nil(t, err)
    89  	assertFetchesInflight(t, pControl, info)
    90  
    91  	// Make a second attempt.
    92  	attempt.AttemptID += 1
    93  	_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
    94  	require.Nil(t, err)
    95  	assertFetchesInflight(t, pControl, info)
    96  
    97  	// If the test case requires it, recreate the index and test there's
    98  	// still one inflight.
    99  	if recreateIndex {
   100  		err = kvdb.Update(db, func(tx kvdb.RwTx) error {
   101  			return recreatePaymentsInflightIndex(tx)
   102  		}, func() {})
   103  		require.Nil(t, err)
   104  		assertFetchesInflight(t, pControl, info)
   105  	}
   106  
   107  	// Settle. No more inflight.
   108  	_, err = pControl.SettleAttempt(
   109  		info.PaymentIdentifier, attempt.AttemptID,
   110  		&HTLCSettleInfo{
   111  			Preimage: preimg,
   112  		},
   113  	)
   114  	require.Nil(t, err)
   115  	inFlight, err := pControl.FetchInFlightPayments()
   116  	require.Nil(t, err)
   117  	require.Len(t, inFlight, 0)
   118  }
   119  
   120  func TestPaymentInflightIndex(t *testing.T) {
   121  	t.Parallel()
   122  	tests := []struct {
   123  		name     string
   124  		noIndex  bool
   125  		recreate bool
   126  	}{{
   127  		name:    "no index",
   128  		noIndex: true,
   129  	}, {
   130  		name: "index",
   131  	}, {
   132  		name:     "index and recreate",
   133  		recreate: true,
   134  	}, {
   135  		name:     "no index and recreate",
   136  		noIndex:  true,
   137  		recreate: true,
   138  	}}
   139  
   140  	for _, tc := range tests {
   141  		tc := tc
   142  		t.Run(tc.name, func(t *testing.T) {
   143  			t.Parallel()
   144  			testPaymentInflightIndexCase(t, tc.noIndex, tc.recreate)
   145  		})
   146  	}
   147  }