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 }