itest: test for connection timeout

This commit is contained in:
yyforyongyu 2020-08-25 12:54:55 +08:00
parent 469aba9282
commit e8d9643f3a
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
3 changed files with 135 additions and 0 deletions

View File

@ -14378,6 +14378,10 @@ var testsCases = []*testCase{
name: "maximum channel size",
test: testMaxChannelSize,
},
{
name: "connection timeout",
test: testNetworkConnectionTimeout,
},
}
// TestLightningNetworkDaemon performs a series of integration tests amongst a

View File

@ -221,3 +221,9 @@
<time> [ERR] RPCS: [/lnrpc.Lightning/BakeMacaroon]: invalid permission entity. supported actions are [read write generate], supported entities are [onchain offchain address message peers info invoices signer macaroon uri]
<time> [ERR] RPCS: [/lnrpc.Lightning/BakeMacaroon]: permission list cannot be empty. specify at least one action/entity pair. supported actions are [read write generate], supported entities are [onchain offchain address message peers info invoices signer macaroon uri]
<time> [ERR] RPCS: [/lnrpc.Lightning/DeleteMacaroonID]: the specified ID cannot be deleted
<time> [ERR] RPCS: [/lnrpc.Lightning/ConnectPeer]: dial tcp <ip>: i/o timeout
<time> [ERR] RPCS: [connectpeer]: error connecting to peer: dial tcp <ip>: i/o timeout
<time> [ERR] SRVR: Unable to connect to <hex>@<ip>: dial tcp <ip>: i/o timeout
<time> [ERR] RPCS: [/lnrpc.Lightning/ConnectPeer]: dial tcp <ip>: i/o timeout
<time> [ERR] RPCS: [connectpeer]: error connecting to peer: dial tcp <ip>: i/o timeout
<time> [ERR] SRVR: Unable to connect to <hex>@<ip>: dial tcp <ip>: i/o timeout

125
lntest/itest/network.go Normal file
View File

@ -0,0 +1,125 @@
// +build rpctest
package itest
import (
"context"
"fmt"
"strings"
"time"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/stretchr/testify/require"
)
// testNetworkConnectionTimeout checks that the connectiontimeout is taking
// effect. It creates a node with a small connection timeout value, and connects
// it to a non-routable IP address.
func testNetworkConnectionTimeout(net *lntest.NetworkHarness, t *harnessTest) {
var (
ctxt, _ = context.WithTimeout(
context.Background(), defaultTimeout,
)
// testPub is a random public key for testing only.
testPub = "0332bda7da70fefe4b6ab92f53b3c4f4ee7999" +
"f312284a8e89c8670bb3f67dbee2"
// testHost is a non-routable IP address. It's used to cause a
// connection timeout.
testHost = "10.255.255.255"
)
// First, test the global timeout settings.
// Create Carol with a connection timeout of 1 millisecond.
carol, err := net.NewNode("Carol", []string{"--connectiontimeout=1ms"})
if err != nil {
t.Fatalf("unable to create new node carol: %v", err)
}
defer shutdownAndAssert(net, t, carol)
// Try to connect Carol to a non-routable IP address, which should give
// us a timeout error.
req := &lnrpc.ConnectPeerRequest{
Addr: &lnrpc.LightningAddress{
Pubkey: testPub,
Host: testHost,
},
}
assertTimeoutError(ctxt, t, carol, req)
// Second, test timeout on the connect peer request.
// Create Dave with the default timeout setting.
dave, err := net.NewNode("Dave", nil)
if err != nil {
t.Fatalf("unable to create new node dave: %v", err)
}
defer shutdownAndAssert(net, t, dave)
// Try to connect Dave to a non-routable IP address, using a timeout
// value of 1ms, which should give us a timeout error immediately.
req = &lnrpc.ConnectPeerRequest{
Addr: &lnrpc.LightningAddress{
Pubkey: testPub,
Host: testHost,
},
Timeout: 1,
}
assertTimeoutError(ctxt, t, dave, req)
}
// assertTimeoutError asserts that a connection timeout error is raised. A
// context with a default timeout is used to make the request. If our customized
// connection timeout is less than the default, we won't see the request context
// times out, instead a network connection timeout will be returned.
func assertTimeoutError(ctxt context.Context, t *harnessTest,
node *lntest.HarnessNode, req *lnrpc.ConnectPeerRequest) {
t.t.Helper()
// Create a context with a timeout value.
ctxt, cancel := context.WithTimeout(ctxt, defaultTimeout)
defer cancel()
err := connect(node, ctxt, req)
// a DeadlineExceeded error will appear in the context if the above
// ctxtTimeout value is reached.
require.NoError(t.t, ctxt.Err(), "context time out")
// Check that the network returns a timeout error.
require.Containsf(
t.t, err.Error(), "i/o timeout",
"expected to get a timeout error, instead got: %v", err,
)
}
func connect(node *lntest.HarnessNode, ctxt context.Context,
req *lnrpc.ConnectPeerRequest) error {
syncTimeout := time.After(15 * time.Second)
ticker := time.NewTicker(time.Millisecond * 100)
defer ticker.Stop()
for {
select {
case <-ticker.C:
_, err := node.ConnectPeer(ctxt, req)
// If there's no error, return nil
if err == nil {
return err
}
// If the error is no ErrServerNotActive, return it.
// Otherwise, we will retry until timeout.
if !strings.Contains(err.Error(),
lnd.ErrServerNotActive.Error()) {
return err
}
case <-syncTimeout:
return fmt.Errorf("chain backend did not " +
"finish syncing")
}
}
return nil
}