From 0714ffa0d7d2c34c092cc9b9c335759670762a10 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 22 Jan 2019 13:38:05 +0100 Subject: [PATCH 1/2] lntest/harness: add WaitNoError --- lntest/harness.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lntest/harness.go b/lntest/harness.go index 70ab825c6..bec7eb4c4 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -1155,6 +1155,28 @@ func WaitPredicate(pred func() bool, timeout time.Duration) error { } } +// WaitNoError is a wrapper around WaitPredicate that waits for the passed +// method f to execute without error, and returns the last error encountered if +// this doesn't happen within the timeout. +func WaitNoError(f func() error, timeout time.Duration) error { + var predErr error + pred := func() bool { + if err := f(); err != nil { + predErr = err + return false + } + return true + } + + // If f() doesn't succeed within the timeout, return the last + // encountered error. + if err := WaitPredicate(pred, timeout); err != nil { + return predErr + } + + return nil +} + // WaitInvariant is a helper test function that will wait for a timeout period // of time, verifying that a statement remains true for the entire duration. // This function is helpful as timing doesn't always line up well when running From 33b2d92b805e9b89d1fcb2bbbfdb4fdde53c57e0 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 22 Jan 2019 13:38:05 +0100 Subject: [PATCH 2/2] lnd_test: don't shadow predErr Would lead to the printed predErr not being set. We instead use the new WaitNoError method to avoid this. --- lnd_test.go | 69 +++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/lnd_test.go b/lnd_test.go index be94669d4..3b32492ba 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -2708,27 +2708,26 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { // Alice should see the channel in her set of pending force closed // channels with her funds still in limbo. - err = lntest.WaitPredicate(func() bool { + err = lntest.WaitNoError(func() error { ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) pendingChanResp, err := net.Alice.PendingChannels( ctxt, pendingChansRequest, ) if err != nil { - predErr = fmt.Errorf("unable to query for pending "+ + return fmt.Errorf("unable to query for pending "+ "channels: %v", err) - return false } - predErr = checkNumForceClosedChannels(pendingChanResp, 1) - if predErr != nil { - return false + err = checkNumForceClosedChannels(pendingChanResp, 1) + if err != nil { + return err } - forceClose, predErr := findForceClosedChannel( + forceClose, err := findForceClosedChannel( pendingChanResp, &op, ) - if predErr != nil { - return false + if err != nil { + return err } // At this point, the nursery should show that the commitment @@ -2736,29 +2735,27 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { // total, we have mined exactly defaultCSV blocks, so the htlc // outputs should also reflect that this many blocks have // passed. - predErr = checkCommitmentMaturity( + err = checkCommitmentMaturity( forceClose, commCsvMaturityHeight, 1, ) - if predErr != nil { - return false + if err != nil { + return err } // All funds should still be shown in limbo. if forceClose.LimboBalance == 0 { - predErr = errors.New("all funds should still be in " + + return errors.New("all funds should still be in " + "limbo") - return false } if forceClose.RecoveredBalance != 0 { - predErr = errors.New("no funds should yet be shown " + + return errors.New("no funds should yet be shown " + "as recovered") - return false } - return true + return nil }, 15*time.Second) if err != nil { - t.Fatalf(predErr.Error()) + t.Fatalf(err.Error()) } // Generate an additional block, which should cause the CSV delayed @@ -2878,40 +2875,39 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { // Alice should now see the channel in her set of pending force closed // channels with one pending HTLC. - err = lntest.WaitPredicate(func() bool { + err = lntest.WaitNoError(func() error { ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) pendingChanResp, err := net.Alice.PendingChannels( ctxt, pendingChansRequest, ) if err != nil { - predErr = fmt.Errorf("unable to query for pending "+ + return fmt.Errorf("unable to query for pending "+ "channels: %v", err) - return false } - predErr = checkNumForceClosedChannels(pendingChanResp, 1) - if predErr != nil { - return false + err = checkNumForceClosedChannels(pendingChanResp, 1) + if err != nil { + return err } - forceClose, predErr := findForceClosedChannel( + forceClose, err := findForceClosedChannel( pendingChanResp, &op, ) - if predErr != nil { - return false + if err != nil { + return err } // We should now be at the block just before the utxo nursery // will attempt to broadcast the htlc timeout transactions. - predErr = checkPendingChannelNumHtlcs(forceClose, numInvoices) - if predErr != nil { - return false + err = checkPendingChannelNumHtlcs(forceClose, numInvoices) + if err != nil { + return err } - predErr = checkPendingHtlcStageAndMaturity( + err = checkPendingHtlcStageAndMaturity( forceClose, 1, htlcExpiryHeight, 1, ) - if predErr != nil { - return false + if err != nil { + return err } // Now that our commitment confirmation depth has been @@ -2919,15 +2915,14 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) { // All htlc outputs are still left in limbo, so it should be // non-zero as well. if forceClose.LimboBalance == 0 { - predErr = errors.New("htlc funds should still be in " + + return errors.New("htlc funds should still be in " + "limbo") - return false } - return true + return nil }, 15*time.Second) if err != nil { - t.Fatalf(predErr.Error()) + t.Fatalf(err.Error()) } // Now, generate the block which will cause Alice to broadcast the