lntemp: fix context inheritance

This commit changes how the context is created and inherited to better
reflex the relationship of the components. We now have the following
context structure,
```
For ephemeral nodes, the context chain is,
main HarnessTest -> sub HarnessTest -> HarnessNode -> HarnessRPC

For standby nodes, the context chain is,
main HarnessTest -> standby HarnessNode -> HarnessRPC
```
This commit is contained in:
yyforyongyu 2022-07-28 17:28:09 +08:00
parent 352be086a1
commit f9453cbe97
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
3 changed files with 51 additions and 54 deletions

View File

@ -408,9 +408,13 @@ func (h *HarnessTest) SetTestName(name string) {
func (h *HarnessTest) NewNode(name string, func (h *HarnessTest) NewNode(name string,
extraArgs []string) *node.HarnessNode { extraArgs []string) *node.HarnessNode {
node, err := h.manager.newNode(h.T, name, extraArgs, false, nil, false) node, err := h.manager.newNode(h.T, name, extraArgs, nil, false)
require.NoErrorf(h, err, "unable to create new node for %s", name) require.NoErrorf(h, err, "unable to create new node for %s", name)
// Start the node.
err = node.Start(h.runCtx)
require.NoError(h, err, "failed to start node %s", node.Name())
return node return node
} }
@ -428,7 +432,7 @@ func (h *HarnessTest) Shutdown(node *node.HarnessNode) {
func (h *HarnessTest) RestartNode(hn *node.HarnessNode, func (h *HarnessTest) RestartNode(hn *node.HarnessNode,
chanBackups ...*lnrpc.ChanBackupSnapshot) { chanBackups ...*lnrpc.ChanBackupSnapshot) {
err := h.manager.restartNode(hn, nil, chanBackups...) err := h.manager.restartNode(h.runCtx, hn, nil, chanBackups...)
require.NoErrorf(h, err, "failed to restart node %s", hn.Name()) require.NoErrorf(h, err, "failed to restart node %s", hn.Name())
// Give the node some time to catch up with the chain before we // Give the node some time to catch up with the chain before we

View File

@ -1,6 +1,7 @@
package lntemp package lntemp
import ( import (
"context"
"fmt" "fmt"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -70,7 +71,7 @@ func (nm *nodeManager) nextNodeID() uint32 {
// node can be used immediately. Otherwise, the node will require an additional // node can be used immediately. Otherwise, the node will require an additional
// initialization phase where the wallet is either created or restored. // initialization phase where the wallet is either created or restored.
func (nm *nodeManager) newNode(t *testing.T, name string, extraArgs []string, func (nm *nodeManager) newNode(t *testing.T, name string, extraArgs []string,
useSeed bool, password []byte, cmdOnly bool, password []byte, useSeed bool,
opts ...node.Option) (*node.HarnessNode, error) { opts ...node.Option) (*node.HarnessNode, error) {
cfg := &node.BaseNodeConfig{ cfg := &node.BaseNodeConfig{
@ -84,6 +85,7 @@ func (nm *nodeManager) newNode(t *testing.T, name string, extraArgs []string,
NodeID: nm.nextNodeID(), NodeID: nm.nextNodeID(),
LndBinary: nm.lndBinary, LndBinary: nm.lndBinary,
NetParams: harnessNetParams, NetParams: harnessNetParams,
HasSeed: useSeed,
} }
for _, opt := range opts { for _, opt := range opts {
opt(cfg) opt(cfg)
@ -96,27 +98,7 @@ func (nm *nodeManager) newNode(t *testing.T, name string, extraArgs []string,
// Put node in activeNodes to ensure Shutdown is called even if start // Put node in activeNodes to ensure Shutdown is called even if start
// returns an error. // returns an error.
defer nm.registerNode(node) nm.registerNode(node)
switch {
// If the node uses seed to start, we'll need to create the wallet and
// unlock the wallet later.
case useSeed:
err = node.StartWithSeed()
// Start the node only with the lnd process without creating the grpc
// connection, which is used in testing etcd leader selection.
case cmdOnly:
err = node.StartLndCmd()
// By default, we'll create a node with wallet being unlocked.
default:
err = node.Start()
}
if err != nil {
return nil, fmt.Errorf("failed to start: %w", err)
}
return node, nil return node, nil
} }
@ -153,10 +135,10 @@ func (nm *nodeManager) shutdownNode(node *node.HarnessNode) error {
// crashes, etc. Additionally, each time the node is restarted, the caller can // crashes, etc. Additionally, each time the node is restarted, the caller can
// pass a set of SCBs to pass in via the Unlock method allowing them to restore // pass a set of SCBs to pass in via the Unlock method allowing them to restore
// channels during restart. // channels during restart.
func (nm *nodeManager) restartNode(node *node.HarnessNode, func (nm *nodeManager) restartNode(ctxt context.Context, node *node.HarnessNode,
callback func() error, chanBackups ...*lnrpc.ChanBackupSnapshot) error { callback func() error, chanBackups ...*lnrpc.ChanBackupSnapshot) error {
err := nm.restartNodeNoUnlock(node, callback) err := nm.restartNodeNoUnlock(ctxt, node, callback)
if err != nil { if err != nil {
return err return err
} }
@ -193,8 +175,8 @@ func (nm *nodeManager) restartNode(node *node.HarnessNode,
// blocking. If the callback parameter is non-nil, then the function will be // blocking. If the callback parameter is non-nil, then the function will be
// executed after the node shuts down, but *before* the process has been // executed after the node shuts down, but *before* the process has been
// started up again. // started up again.
func (nm *nodeManager) restartNodeNoUnlock(node *node.HarnessNode, func (nm *nodeManager) restartNodeNoUnlock(ctxt context.Context,
callback func() error) error { node *node.HarnessNode, callback func() error) error {
if err := node.Stop(); err != nil { if err := node.Stop(); err != nil {
return fmt.Errorf("restart node got error: %w", err) return fmt.Errorf("restart node got error: %w", err)
@ -206,5 +188,9 @@ func (nm *nodeManager) restartNodeNoUnlock(node *node.HarnessNode,
} }
} }
return node.Start() if node.Cfg.HasSeed {
return node.StartWithSeed(ctxt)
}
return node.Start(ctxt)
} }

View File

@ -332,9 +332,9 @@ func (hn *HarnessNode) SetExtraArgs(extraArgs []string) {
// StartLndCmd handles the startup of lnd, creating log files, and possibly // StartLndCmd handles the startup of lnd, creating log files, and possibly
// kills the process when needed. // kills the process when needed.
func (hn *HarnessNode) StartLndCmd() error { func (hn *HarnessNode) StartLndCmd(ctxb context.Context) error {
// Init the runCtx. // Init the run context.
hn.runCtx, hn.cancel = context.WithCancel(context.Background()) hn.runCtx, hn.cancel = context.WithCancel(ctxb)
args := hn.Cfg.GenArgs() args := hn.Cfg.GenArgs()
hn.cmd = exec.Command(hn.Cfg.LndBinary, args...) //nolint:gosec hn.cmd = exec.Command(hn.Cfg.LndBinary, args...) //nolint:gosec
@ -365,9 +365,9 @@ func (hn *HarnessNode) StartLndCmd() error {
// start. // start.
// //
// NOTE: caller needs to take extra step to create and unlock the wallet. // NOTE: caller needs to take extra step to create and unlock the wallet.
func (hn *HarnessNode) StartWithSeed() error { func (hn *HarnessNode) StartWithSeed(ctxt context.Context) error {
// Start lnd process and prepare logs. // Start lnd process and prepare logs.
if err := hn.StartLndCmd(); err != nil { if err := hn.StartLndCmd(ctxt); err != nil {
return fmt.Errorf("start lnd error: %w", err) return fmt.Errorf("start lnd error: %w", err)
} }
@ -388,9 +388,9 @@ func (hn *HarnessNode) StartWithSeed() error {
// Start will start the lnd process, creates the grpc connection, and waits // Start will start the lnd process, creates the grpc connection, and waits
// until the server is fully started. // until the server is fully started.
func (hn *HarnessNode) Start() error { func (hn *HarnessNode) Start(ctxt context.Context) error {
// Start lnd process and prepare logs. // Start lnd process and prepare logs.
if err := hn.StartLndCmd(); err != nil { if err := hn.StartLndCmd(ctxt); err != nil {
return fmt.Errorf("start lnd error: %w", err) return fmt.Errorf("start lnd error: %w", err)
} }
@ -500,7 +500,7 @@ func (hn *HarnessNode) waitTillServerState(
func (hn *HarnessNode) initLightningClient() error { func (hn *HarnessNode) initLightningClient() error {
// Wait until the server is fully started. // Wait until the server is fully started.
if err := hn.WaitUntilServerActive(); err != nil { if err := hn.WaitUntilServerActive(); err != nil {
return err return fmt.Errorf("waiting for server active: %v", err)
} }
// Set the harness node's pubkey to what the node claims in GetInfo. // Set the harness node's pubkey to what the node claims in GetInfo.
@ -677,6 +677,16 @@ func (hn *HarnessNode) Stop() error {
// Close any attempts at further grpc connections. // Close any attempts at further grpc connections.
if hn.conn != nil { if hn.conn != nil {
if err := hn.CloseConn(); err != nil {
return err
}
}
return nil
}
// CloseConn closes the grpc connection.
func (hn *HarnessNode) CloseConn() error {
err := status.Code(hn.conn.Close()) err := status.Code(hn.conn.Close())
switch err { switch err {
case codes.OK: case codes.OK:
@ -695,9 +705,6 @@ func (hn *HarnessNode) Stop() error {
return fmt.Errorf("error attempting to stop "+ return fmt.Errorf("error attempting to stop "+
"grpc client: %v", err) "grpc client: %v", err)
} }
}
return nil
} }
// Shutdown stops the active lnd process and cleans up any temporary // Shutdown stops the active lnd process and cleans up any temporary