routing/payment_lifecycle_test+mock: set up listener for FailAttempt

Also rename Success to SettleAttempt in the tests.
This commit is contained in:
Johan T. Halseth 2020-04-01 00:13:26 +02:00
parent aa9c971dc0
commit 2e63b518b7
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
2 changed files with 77 additions and 43 deletions

@ -176,15 +176,19 @@ type initArgs struct {
c *channeldb.PaymentCreationInfo c *channeldb.PaymentCreationInfo
} }
type registerArgs struct { type registerAttemptArgs struct {
a *channeldb.HTLCAttemptInfo a *channeldb.HTLCAttemptInfo
} }
type successArgs struct { type settleAttemptArgs struct {
preimg lntypes.Preimage preimg lntypes.Preimage
} }
type failArgs struct { type failAttemptArgs struct {
reason *channeldb.HTLCFailInfo
}
type failPaymentArgs struct {
reason channeldb.FailureReason reason channeldb.FailureReason
} }
@ -199,9 +203,10 @@ type mockControlTower struct {
failed map[lntypes.Hash]channeldb.FailureReason failed map[lntypes.Hash]channeldb.FailureReason
init chan initArgs init chan initArgs
register chan registerArgs registerAttempt chan registerAttemptArgs
success chan successArgs settleAttempt chan settleAttemptArgs
fail chan failArgs failAttempt chan failAttemptArgs
failPayment chan failPaymentArgs
fetchInFlight chan struct{} fetchInFlight chan struct{}
sync.Mutex sync.Mutex
@ -254,8 +259,8 @@ func (m *mockControlTower) RegisterAttempt(phash lntypes.Hash,
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
if m.register != nil { if m.registerAttempt != nil {
m.register <- registerArgs{a} m.registerAttempt <- registerAttemptArgs{a}
} }
// Cannot register attempts for successful or failed payments. // Cannot register attempts for successful or failed payments.
@ -286,8 +291,8 @@ func (m *mockControlTower) SettleAttempt(phash lntypes.Hash,
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
if m.success != nil { if m.settleAttempt != nil {
m.success <- successArgs{settleInfo.Preimage} m.settleAttempt <- settleAttemptArgs{settleInfo.Preimage}
} }
// Only allow setting attempts if the payment is known. // Only allow setting attempts if the payment is known.
@ -325,6 +330,10 @@ func (m *mockControlTower) FailAttempt(phash lntypes.Hash, pid uint64,
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
if m.failAttempt != nil {
m.failAttempt <- failAttemptArgs{failInfo}
}
// Only allow failing attempts if the payment is known. // Only allow failing attempts if the payment is known.
p, ok := m.payments[phash] p, ok := m.payments[phash]
if !ok { if !ok {
@ -357,8 +366,8 @@ func (m *mockControlTower) Fail(phash lntypes.Hash,
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
if m.fail != nil { if m.failPayment != nil {
m.fail <- failArgs{reason} m.failPayment <- failPaymentArgs{reason}
} }
// Payment must be known. // Payment must be known.

@ -109,13 +109,18 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// tower. // tower.
routerRegisterAttempt = "Router:register-attempt" routerRegisterAttempt = "Router:register-attempt"
// routerSuccess is a test step where we expect the router to // routerSettleAttempt is a test step where we expect the
// call the Success method on the control tower. // router to call the SettleAttempt method on the control
routerSuccess = "Router:success" // tower.
routerSettleAttempt = "Router:settle-attempt"
// routerFail is a test step where we expect the router to call // routerFailAttempt is a test step where we expect the router
// the Fail method on the control tower. // to call the FailAttempt method on the control tower.
routerFail = "Router:fail" routerFailAttempt = "Router:fail-attempt"
// routerFailPayment is a test step where we expect the router
// to call the Fail method on the control tower.
routerFailPayment = "Router:fail-payment"
// sendToSwitchSuccess is a step where we expect the router to // sendToSwitchSuccess is a step where we expect the router to
// call send the payment attempt to the switch, and we will // call send the payment attempt to the switch, and we will
@ -178,7 +183,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
routerRegisterAttempt, routerRegisterAttempt,
sendToSwitchSuccess, sendToSwitchSuccess,
getPaymentResultSuccess, getPaymentResultSuccess,
routerSuccess, routerSettleAttempt,
paymentSuccess, paymentSuccess,
}, },
routes: []*route.Route{rt}, routes: []*route.Route{rt},
@ -193,6 +198,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// Make the first sent attempt fail. // Make the first sent attempt fail.
getPaymentResultFailure, getPaymentResultFailure,
routerFailAttempt,
// The router should retry. // The router should retry.
routerRegisterAttempt, routerRegisterAttempt,
@ -200,7 +206,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// Make the second sent attempt succeed. // Make the second sent attempt succeed.
getPaymentResultSuccess, getPaymentResultSuccess,
routerSuccess, routerSettleAttempt,
paymentSuccess, paymentSuccess,
}, },
routes: []*route.Route{rt, rt}, routes: []*route.Route{rt, rt},
@ -215,6 +221,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// Make the first sent attempt fail. // Make the first sent attempt fail.
sendToSwitchResultFailure, sendToSwitchResultFailure,
routerFailAttempt,
// The router should retry. // The router should retry.
routerRegisterAttempt, routerRegisterAttempt,
@ -222,7 +229,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// Make the second sent attempt succeed. // Make the second sent attempt succeed.
getPaymentResultSuccess, getPaymentResultSuccess,
routerSuccess, routerSettleAttempt,
paymentSuccess, paymentSuccess,
}, },
routes: []*route.Route{rt, rt}, routes: []*route.Route{rt, rt},
@ -238,10 +245,11 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// Make the first sent attempt fail. // Make the first sent attempt fail.
getPaymentResultFailure, getPaymentResultFailure,
routerFailAttempt,
// Since there are no more routes to try, the // Since there are no more routes to try, the
// payment should fail. // payment should fail.
routerFail, routerFailPayment,
paymentError, paymentError,
}, },
routes: []*route.Route{rt}, routes: []*route.Route{rt},
@ -251,7 +259,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// no routes to try. // no routes to try.
steps: []string{ steps: []string{
routerInitPayment, routerInitPayment,
routerFail, routerFailPayment,
paymentError, paymentError,
}, },
routes: []*route.Route{}, routes: []*route.Route{},
@ -286,7 +294,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// Notify about a success for the original // Notify about a success for the original
// payment. // payment.
getPaymentResultSuccess, getPaymentResultSuccess,
routerSuccess, routerSettleAttempt,
// Now that the original payment finished, // Now that the original payment finished,
// resend it again to ensure this is not // resend it again to ensure this is not
@ -316,7 +324,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// control tower. // control tower.
startRouter, startRouter,
getPaymentResultSuccess, getPaymentResultSuccess,
routerSuccess, routerSettleAttempt,
}, },
routes: []*route.Route{rt}, routes: []*route.Route{rt},
}, },
@ -336,10 +344,11 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// Make the first attempt fail. // Make the first attempt fail.
getPaymentResultFailure, getPaymentResultFailure,
routerFail, routerFailAttempt,
// Since we have no more routes to try, the // Since we have no more routes to try, the
// original payment should fail. // original payment should fail.
routerFailPayment,
paymentError, paymentError,
// Now resend the payment again. This should be // Now resend the payment again. This should be
@ -349,7 +358,7 @@ func TestRouterPaymentStateMachine(t *testing.T) {
routerRegisterAttempt, routerRegisterAttempt,
sendToSwitchSuccess, sendToSwitchSuccess,
getPaymentResultSuccess, getPaymentResultSuccess,
routerSuccess, routerSettleAttempt,
resentPaymentSuccess, resentPaymentSuccess,
}, },
routes: []*route.Route{rt}, routes: []*route.Route{rt},
@ -360,9 +369,10 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// synchronize and listen for events. // synchronize and listen for events.
control := makeMockControlTower() control := makeMockControlTower()
control.init = make(chan initArgs) control.init = make(chan initArgs)
control.register = make(chan registerArgs) control.registerAttempt = make(chan registerAttemptArgs)
control.success = make(chan successArgs) control.settleAttempt = make(chan settleAttemptArgs)
control.fail = make(chan failArgs) control.failAttempt = make(chan failAttemptArgs)
control.failPayment = make(chan failPaymentArgs)
control.fetchInFlight = make(chan struct{}) control.fetchInFlight = make(chan struct{})
quit := make(chan struct{}) quit := make(chan struct{})
@ -497,11 +507,12 @@ func TestRouterPaymentStateMachine(t *testing.T) {
// In this step we expect the router to make a call to // In this step we expect the router to make a call to
// register a new attempt with the ControlTower. // register a new attempt with the ControlTower.
case routerRegisterAttempt: case routerRegisterAttempt:
var args registerArgs var args registerAttemptArgs
select { select {
case args = <-control.register: case args = <-control.registerAttempt:
case <-time.After(1 * time.Second): case <-time.After(1 * time.Second):
t.Fatalf("not registered with control") t.Fatalf("attempt not registered " +
"with control")
} }
if args.a == nil { if args.a == nil {
@ -509,22 +520,35 @@ func TestRouterPaymentStateMachine(t *testing.T) {
} }
// In this step we expect the router to call the // In this step we expect the router to call the
// ControlTower's Succcess method with the preimage. // ControlTower's SettleAttempt method with the preimage.
case routerSuccess: case routerSettleAttempt:
select { select {
case <-control.success: case <-control.settleAttempt:
case <-time.After(1 * time.Second): case <-time.After(1 * time.Second):
t.Fatalf("not registered with control") t.Fatalf("attempt settle not " +
"registered with control")
}
// In this step we expect the router to call the
// ControlTower's FailAttempt method with a HTLC fail
// info.
case routerFailAttempt:
select {
case <-control.failAttempt:
case <-time.After(1 * time.Second):
t.Fatalf("attempt fail not " +
"registered with control")
} }
// In this step we expect the router to call the // In this step we expect the router to call the
// ControlTower's Fail method, to indicate that the // ControlTower's Fail method, to indicate that the
// payment failed. // payment failed.
case routerFail: case routerFailPayment:
select { select {
case <-control.fail: case <-control.failPayment:
case <-time.After(1 * time.Second): case <-time.After(1 * time.Second):
t.Fatalf("not registered with control") t.Fatalf("payment fail not " +
"registered with control")
} }
// In this step we expect the SendToSwitch method to be // In this step we expect the SendToSwitch method to be
@ -625,7 +649,8 @@ func TestRouterPaymentStateMachine(t *testing.T) {
select { select {
case err := <-paymentResult: case err := <-paymentResult:
if err != nil { if err != nil {
t.Fatalf("did not expecte error %v", err) t.Fatalf("did not expect "+
"error %v", err)
} }
case <-time.After(1 * time.Second): case <-time.After(1 * time.Second):