Skip to content

Commit

Permalink
Fix flaky test in PaymentLifecycleSpec (#967)
Browse files Browse the repository at this point in the history
* Use local random pamentHash for each test in paymentlifecyclespec, intercept the route request before the router.
  • Loading branch information
araspitzu authored Apr 25, 2019
1 parent 1d486f4 commit 45a5b6f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.send(nodes("A").paymentInitiator, sendReq)
// A will first receive an error from C, then retry and route around C: A->B->E->C->D
sender.expectMsgType[UUID](5 seconds)
sender.expectMsgType[PaymentSucceeded] // the payment FSM will also reply to the sender after the payment is completed
}

test("send an HTLC A->D with an unknown payment hash") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,16 @@ import fr.acinq.eclair._

class PaymentLifecycleSpec extends BaseRouterSpec {

val initialBlockCount = 420000
Globals.blockCount.set(initialBlockCount)

val defaultAmountMsat = 142000000L
val defaultPaymentHash = randomBytes32


test("payment failed (route not found)") { fixture =>
import fixture._
val nodeParams = TestConstants.Alice.nodeParams
val defaultPaymentHash = randomBytes32
val nodeParams = TestConstants.Alice.nodeParams.copy(keyManager = testKeyManager)
val paymentDb = nodeParams.db.payments
val id = UUID.randomUUID()
val paymentFSM = TestFSMRef(new PaymentLifecycle(nodeParams, id, router, TestProbe().ref))
val routerForwarder = TestProbe()
val paymentFSM = system.actorOf(PaymentLifecycle.props(nodeParams, id, routerForwarder.ref, TestProbe().ref))
val monitor = TestProbe()
val sender = TestProbe()

Expand All @@ -64,9 +61,11 @@ class PaymentLifecycleSpec extends BaseRouterSpec {

val request = SendPayment(defaultAmountMsat, defaultPaymentHash, f, maxAttempts = 5)
sender.send(paymentFSM, request)
awaitCond(paymentDb.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.PENDING))
val Transition(_, WAITING_FOR_REQUEST, WAITING_FOR_ROUTE) = monitor.expectMsgClass(classOf[Transition[_]])
val routeRequest = routerForwarder.expectMsgType[RouteRequest]
awaitCond(paymentDb.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.PENDING))

routerForwarder.forward(router, routeRequest)
sender.expectMsg(PaymentFailed(id, request.paymentHash, LocalFailure(RouteNotFound) :: Nil))
awaitCond(paymentDb.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.FAILED))
}
Expand All @@ -83,7 +82,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
paymentFSM ! SubscribeTransitionCallBack(monitor.ref)
val CurrentState(_, WAITING_FOR_REQUEST) = monitor.expectMsgClass(classOf[CurrentState[_]])

val request = SendPayment(defaultAmountMsat, defaultPaymentHash, d, routeParams = Some(RouteParams(randomize = false, maxFeeBaseMsat = 100, maxFeePct = 0.0, routeMaxLength = 20, routeMaxCltv = 2016, ratios = None)), maxAttempts = 5)
val request = SendPayment(defaultAmountMsat, randomBytes32, d, routeParams = Some(RouteParams(randomize = false, maxFeeBaseMsat = 100, maxFeePct = 0.0, routeMaxLength = 20, routeMaxCltv = 2016, ratios = None)), maxAttempts = 5)
sender.send(paymentFSM, request)
val Transition(_, WAITING_FOR_REQUEST, WAITING_FOR_ROUTE) = monitor.expectMsgClass(classOf[Transition[_]])

Expand All @@ -93,6 +92,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {

test("payment failed (unparsable failure)") { fixture =>
import fixture._
val defaultPaymentHash = randomBytes32
val nodeParams = TestConstants.Alice.nodeParams.copy(keyManager = testKeyManager)
val paymentDb = nodeParams.db.payments
val relayer = TestProbe()
Expand Down Expand Up @@ -148,7 +148,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
paymentFSM ! SubscribeTransitionCallBack(monitor.ref)
val CurrentState(_, WAITING_FOR_REQUEST) = monitor.expectMsgClass(classOf[CurrentState[_]])

val request = SendPayment(defaultAmountMsat, defaultPaymentHash, d, maxAttempts = 2)
val request = SendPayment(defaultAmountMsat, randomBytes32, d, maxAttempts = 2)
sender.send(paymentFSM, request)
awaitCond(paymentFSM.stateName == WAITING_FOR_ROUTE && paymentDb.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.PENDING))

Expand All @@ -168,6 +168,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {

test("payment failed (first hop returns an UpdateFailMalformedHtlc)") { fixture =>
import fixture._
val defaultPaymentHash = randomBytes32
val nodeParams = TestConstants.Alice.nodeParams.copy(keyManager = testKeyManager)
val paymentDb = nodeParams.db.payments
val relayer = TestProbe()
Expand Down Expand Up @@ -211,7 +212,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
paymentFSM ! SubscribeTransitionCallBack(monitor.ref)
val CurrentState(_, WAITING_FOR_REQUEST) = monitor.expectMsgClass(classOf[CurrentState[_]])

val request = SendPayment(defaultAmountMsat, defaultPaymentHash, d, maxAttempts = 2)
val request = SendPayment(defaultAmountMsat, randomBytes32, d, maxAttempts = 2)
sender.send(paymentFSM, request)
awaitCond(paymentFSM.stateName == WAITING_FOR_ROUTE)
val WaitingForRoute(_, _, Nil) = paymentFSM.stateData
Expand Down Expand Up @@ -251,7 +252,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
paymentFSM ! SubscribeTransitionCallBack(monitor.ref)
val CurrentState(_, WAITING_FOR_REQUEST) = monitor.expectMsgClass(classOf[CurrentState[_]])

val request = SendPayment(defaultAmountMsat, defaultPaymentHash, d, maxAttempts = 5)
val request = SendPayment(defaultAmountMsat, randomBytes32, d, maxAttempts = 5)
sender.send(paymentFSM, request)
awaitCond(paymentFSM.stateName == WAITING_FOR_ROUTE && paymentDb.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.PENDING))

Expand Down Expand Up @@ -313,7 +314,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
paymentFSM ! SubscribeTransitionCallBack(monitor.ref)
val CurrentState(_, WAITING_FOR_REQUEST) = monitor.expectMsgClass(classOf[CurrentState[_]])

val request = SendPayment(defaultAmountMsat, defaultPaymentHash, d, maxAttempts = 2)
val request = SendPayment(defaultAmountMsat, randomBytes32, d, maxAttempts = 2)
sender.send(paymentFSM, request)
awaitCond(paymentFSM.stateName == WAITING_FOR_ROUTE && paymentDb.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.PENDING))

Expand All @@ -340,6 +341,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {

test("payment succeeded") { fixture =>
import fixture._
val defaultPaymentHash = randomBytes32
val nodeParams = TestConstants.Alice.nodeParams.copy(keyManager = testKeyManager)
val paymentDb = nodeParams.db.payments
val id = UUID.randomUUID()
Expand Down Expand Up @@ -369,6 +371,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
test("payment succeeded to a channel with fees=0") { fixture =>
import fixture._
import fr.acinq.eclair.randomKey
val defaultPaymentHash = randomBytes32
val nodeParams = TestConstants.Alice.nodeParams.copy(keyManager = testKeyManager)
// the network will be a --(1)--> b ---(2)--> c --(3)--> d and e --(4)--> f (we are a) and b -> g has fees=0
// \
Expand Down

0 comments on commit 45a5b6f

Please sign in to comment.