lntest: Refactor set up calls to NetworkHarness.

This commit is contained in:
Jim Posen 2017-11-16 17:31:41 -08:00 committed by Olaoluwa Osuntokun
parent 02177a3f1c
commit 84d7c7ee2c
2 changed files with 51 additions and 90 deletions

View File

@ -4478,29 +4478,33 @@ var testsCases = []*testCase{
func TestLightningNetworkDaemon(t *testing.T) {
ht := newHarnessTest(t)
var lndHarness *lntest.NetworkHarness
// First create an instance of the btcd's rpctest.Harness. This will be
// used to fund the wallets of the nodes within the test network and to
// drive blockchain related events within the network. Revert the default
// setting of accepting non-standard transactions on simnet to reject them.
// Transactions on the lightning network should always be standard to get
// better guarantees of getting included in to blocks.
args := []string{"--rejectnonstd"}
handlers := &rpcclient.NotificationHandlers{
OnTxAccepted: func(hash *chainhash.Hash, amt btcutil.Amount) {
lndHarness.OnTxAccepted(hash)
},
}
btcdHarness, err := rpctest.New(harnessNetParams, handlers, args)
if err != nil {
ht.Fatalf("unable to create mining node: %v", err)
}
defer btcdHarness.TearDown()
// First create the network harness to gain access to its
// 'OnTxAccepted' call back.
lndHarness, err := lntest.NewNetworkHarness()
lndHarness, err = lntest.NewNetworkHarness(btcdHarness)
if err != nil {
ht.Fatalf("unable to create lightning network harness: %v", err)
}
// Set up teardowns. While it's easier to set up the lnd harness before
// the btcd harness, they should be torn down in reverse order to
// prevent certain types of hangs.
var btcdHarness *rpctest.Harness
defer func() {
if lndHarness != nil {
lndHarness.TearDownAll()
}
if btcdHarness != nil {
btcdHarness.TearDown()
}
}()
handlers := &rpcclient.NotificationHandlers{
OnTxAccepted: lndHarness.OnTxAccepted,
}
defer lndHarness.TearDownAll()
// Spawn a new goroutine to watch for any fatal errors that any of the
// running lnd processes encounter. If an error occurs, then the test
@ -4518,18 +4522,6 @@ func TestLightningNetworkDaemon(t *testing.T) {
}
}()
// First create an instance of the btcd's rpctest.Harness. This will be
// used to fund the wallets of the nodes within the test network and to
// drive blockchain related events within the network. Revert the default
// setting of accepting non-standard transactions on simnet to reject them.
// Transactions on the lightning network should always be standard to get
// better guarantees of getting included in to blocks.
args := []string{"--rejectnonstd"}
btcdHarness, err = rpctest.New(harnessNetParams, handlers, args)
if err != nil {
ht.Fatalf("unable to create mining node: %v", err)
}
// Turn off the btcd rpc logging, otherwise it will lead to panic.
// TODO(andrew.shvv|roasbeef) Remove the hack after re-work the way the log
// rotator os work.
@ -4553,10 +4545,7 @@ func TestLightningNetworkDaemon(t *testing.T) {
// initialization of the network. args - list of lnd arguments,
// example: "--debuglevel=debug"
// TODO(roasbeef): create master balanced channel with all the monies?
if err := lndHarness.InitializeSeedNodes(btcdHarness, nil); err != nil {
ht.Fatalf("unable to initialize seed nodes: %v", err)
}
if err = lndHarness.SetUp(); err != nil {
if err = lndHarness.SetUp(nil); err != nil {
ht.Fatalf("unable to set up test lightning network: %v", err)
}

View File

@ -37,7 +37,7 @@ type NetworkHarness struct {
Alice *HarnessNode
Bob *HarnessNode
seenTxns chan chainhash.Hash
seenTxns chan *chainhash.Hash
bitcoinWatchRequests chan *txWatchRequest
// Channel for transmitting stderr output from failed lightning node
@ -46,51 +46,26 @@ type NetworkHarness struct {
quit chan struct{}
sync.Mutex
mtx sync.Mutex
}
// NewNetworkHarness creates a new network test harness.
// TODO(roasbeef): add option to use golang's build library to a binary of the
// current repo. This'll save developers from having to manually `go install`
// within the repo each time before changes
func NewNetworkHarness() (*NetworkHarness, error) {
return &NetworkHarness{
func NewNetworkHarness(r *rpctest.Harness) (*NetworkHarness, error) {
n := NetworkHarness{
activeNodes: make(map[int]*HarnessNode),
seenTxns: make(chan chainhash.Hash),
seenTxns: make(chan *chainhash.Hash),
bitcoinWatchRequests: make(chan *txWatchRequest),
lndErrorChan: make(chan error),
netParams: r.ActiveNet,
Miner: r,
rpcConfig: r.RPCConfig(),
quit: make(chan struct{}),
}, nil
}
// InitializeSeedNodes initializes alice and bob nodes given an already
// running instance of btcd's rpctest harness and extra command line flags,
// which should be formatted properly - "--arg=value".
func (n *NetworkHarness) InitializeSeedNodes(r *rpctest.Harness, lndArgs []string) error {
n.netParams = r.ActiveNet
n.Miner = r
n.rpcConfig = r.RPCConfig()
config := nodeConfig{
RPCConfig: &n.rpcConfig,
NetParams: n.netParams,
ExtraArgs: lndArgs,
}
var err error
n.Alice, err = newNode(config)
if err != nil {
return err
}
n.Bob, err = newNode(config)
if err != nil {
return err
}
n.activeNodes[n.Alice.NodeID] = n.Alice
n.activeNodes[n.Bob.NodeID] = n.Bob
return err
go n.networkWatcher()
return &n, nil
}
// ProcessErrors returns a channel used for reporting any fatal process errors.
@ -114,8 +89,9 @@ func (f *fakeLogger) Println(args ...interface{}) {}
// SetUp starts the initial seeder nodes within the test harness. The initial
// node's wallets will be funded wallets with ten 1 BTC outputs each. Finally
// rpc clients capable of communicating with the initial seeder nodes are
// created.
func (n *NetworkHarness) SetUp() error {
// created. Nodes are initialized with the given extra command line flags, which
// should be formatted properly - "--arg=value".
func (n *NetworkHarness) SetUp(lndArgs []string) error {
// Swap out grpc's default logger with out fake logger which drops the
// statements on the floor.
grpclog.SetLogger(&fakeLogger{})
@ -127,15 +103,21 @@ func (n *NetworkHarness) SetUp() error {
wg.Add(2)
go func() {
defer wg.Done()
if err := n.Alice.start(n.lndErrorChan); err != nil {
node, err := n.NewNode(lndArgs)
if err != nil {
errChan <- err
return
}
n.Alice = node
}()
go func() {
defer wg.Done()
if err := n.Bob.start(n.lndErrorChan); err != nil {
node, err := n.NewNode(lndArgs)
if err != nil {
errChan <- err
return
}
n.Bob = node
}()
wg.Wait()
select {
@ -214,10 +196,6 @@ out:
}
}
// Now that the initial test network has been initialized, launch the
// network watcher.
go n.networkWatcher()
return nil
}
@ -239,9 +217,6 @@ func (n *NetworkHarness) TearDownAll() error {
// current instance of the network harness. The created node is running, but
// not yet connected to other nodes within the network.
func (n *NetworkHarness) NewNode(extraArgs []string) (*HarnessNode, error) {
n.Lock()
defer n.Unlock()
node, err := newNode(nodeConfig{
RPCConfig: &n.rpcConfig,
NetParams: n.netParams,
@ -253,7 +228,9 @@ func (n *NetworkHarness) NewNode(extraArgs []string) (*HarnessNode, error) {
// Put node in activeNodes to ensure Shutdown is called even if Start
// returns an error.
n.mtx.Lock()
n.activeNodes[node.NodeID] = node
n.mtx.Unlock()
if err := node.start(n.lndErrorChan); err != nil {
return nil, err
@ -403,11 +380,11 @@ func (n *NetworkHarness) networkWatcher() {
// we're able to dispatch any notifications for this
// txid which arrive *after* it's seen within the
// network.
seenTxns[txid] = struct{}{}
seenTxns[*txid] = struct{}{}
// If there isn't a registered notification for this
// transaction then ignore it.
txClients, ok := clients[txid]
txClients, ok := clients[*txid]
if !ok {
continue
}
@ -417,24 +394,19 @@ func (n *NetworkHarness) networkWatcher() {
for _, client := range txClients {
close(client)
}
delete(clients, txid)
delete(clients, *txid)
}
}
}
// OnTxAccepted is a callback to be called each time a new transaction has been
// broadcast on the network.
func (n *NetworkHarness) OnTxAccepted(hash *chainhash.Hash, amt btcutil.Amount) {
// Return immediately if harness has been torn down.
func (n *NetworkHarness) OnTxAccepted(hash *chainhash.Hash) {
select {
case n.seenTxns <- hash:
case <-n.quit:
return
default:
}
go func() {
n.seenTxns <- *hash
}()
}
// WaitForTxBroadcast blocks until the target txid is seen on the network. If