lntest: export base node config for re-use

This commit is contained in:
Oliver Gugger 2022-01-06 12:52:02 +01:00
parent 8c3f2eaba0
commit 5401b12402
No known key found for this signature in database
GPG key ID: 8E4256593F177720
4 changed files with 57 additions and 38 deletions

View file

@ -35,7 +35,7 @@ import (
const DefaultCSV = 4 const DefaultCSV = 4
// NodeOption is a function for updating a node's configuration. // NodeOption is a function for updating a node's configuration.
type NodeOption func(*NodeConfig) type NodeOption func(*BaseNodeConfig)
// NetworkHarness is an integration testing harness for the lightning network. // NetworkHarness is an integration testing harness for the lightning network.
// Building on top of HarnessNode, it is responsible for handling interactions // Building on top of HarnessNode, it is responsible for handling interactions
@ -489,7 +489,7 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool,
password []byte, dbBackend DatabaseBackend, wait bool, opts ...NodeOption) ( password []byte, dbBackend DatabaseBackend, wait bool, opts ...NodeOption) (
*HarnessNode, error) { *HarnessNode, error) {
cfg := &NodeConfig{ cfg := &BaseNodeConfig{
Name: name, Name: name,
LogFilenamePrefix: n.currentTestCase, LogFilenamePrefix: n.currentTestCase,
HasSeed: hasSeed, HasSeed: hasSeed,
@ -504,7 +504,7 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool,
opt(cfg) opt(cfg)
} }
node, err := newNode(*cfg) node, err := newNode(cfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -67,24 +67,6 @@ func postgresDatabaseDsn(dbName string) string {
return fmt.Sprintf(postgresDsn, dbName) return fmt.Sprintf(postgresDsn, dbName)
} }
// generateListeningPorts returns four ints representing ports to listen on
// designated for the current lightning network test. This returns the next
// available ports for the p2p, rpc, rest and profiling services.
func generateListeningPorts(cfg *NodeConfig) {
if cfg.P2PPort == 0 {
cfg.P2PPort = NextAvailablePort()
}
if cfg.RPCPort == 0 {
cfg.RPCPort = NextAvailablePort()
}
if cfg.RESTPort == 0 {
cfg.RESTPort = NextAvailablePort()
}
if cfg.ProfilePort == 0 {
cfg.ProfilePort = NextAvailablePort()
}
}
// BackendConfig is an interface that abstracts away the specific chain backend // BackendConfig is an interface that abstracts away the specific chain backend
// node implementation. // node implementation.
type BackendConfig interface { type BackendConfig interface {
@ -102,10 +84,25 @@ type BackendConfig interface {
Name() string Name() string
} }
type NodeConfig struct { // NodeConfig is the basic interface a node configuration must implement.
type NodeConfig interface {
// BaseConfig returns the base node configuration struct.
BaseConfig() *BaseNodeConfig
// GenerateListeningPorts generates the ports to listen on designated
// for the current lightning network test.
GenerateListeningPorts()
// GenArgs generates a slice of command line arguments from the
// lightning node config struct.
GenArgs() []string
}
// BaseNodeConfig is the base node configuration.
type BaseNodeConfig struct {
Name string Name string
// LogFilenamePrefix is is used to prefix node log files. Can be used // LogFilenamePrefix is used to prefix node log files. Can be used
// to store the current test case for simpler postmortem debugging. // to store the current test case for simpler postmortem debugging.
LogFilenamePrefix string LogFilenamePrefix string
@ -139,28 +136,28 @@ type NodeConfig struct {
PostgresDsn string PostgresDsn string
} }
func (cfg NodeConfig) P2PAddr() string { func (cfg BaseNodeConfig) P2PAddr() string {
return fmt.Sprintf(ListenerFormat, cfg.P2PPort) return fmt.Sprintf(ListenerFormat, cfg.P2PPort)
} }
func (cfg NodeConfig) RPCAddr() string { func (cfg BaseNodeConfig) RPCAddr() string {
return fmt.Sprintf(ListenerFormat, cfg.RPCPort) return fmt.Sprintf(ListenerFormat, cfg.RPCPort)
} }
func (cfg NodeConfig) RESTAddr() string { func (cfg BaseNodeConfig) RESTAddr() string {
return fmt.Sprintf(ListenerFormat, cfg.RESTPort) return fmt.Sprintf(ListenerFormat, cfg.RESTPort)
} }
// DBDir returns the holding directory path of the graph database. // DBDir returns the holding directory path of the graph database.
func (cfg NodeConfig) DBDir() string { func (cfg BaseNodeConfig) DBDir() string {
return filepath.Join(cfg.DataDir, "graph", cfg.NetParams.Name) return filepath.Join(cfg.DataDir, "graph", cfg.NetParams.Name)
} }
func (cfg NodeConfig) DBPath() string { func (cfg BaseNodeConfig) DBPath() string {
return filepath.Join(cfg.DBDir(), "channel.db") return filepath.Join(cfg.DBDir(), "channel.db")
} }
func (cfg NodeConfig) ChanBackupPath() string { func (cfg BaseNodeConfig) ChanBackupPath() string {
return filepath.Join( return filepath.Join(
cfg.DataDir, "chain", "bitcoin", cfg.DataDir, "chain", "bitcoin",
fmt.Sprintf( fmt.Sprintf(
@ -170,9 +167,31 @@ func (cfg NodeConfig) ChanBackupPath() string {
) )
} }
// genArgs generates a slice of command line arguments from the lightning node // GenerateListeningPorts generates the ports to listen on designated for the
// current lightning network test.
func (cfg *BaseNodeConfig) GenerateListeningPorts() {
if cfg.P2PPort == 0 {
cfg.P2PPort = NextAvailablePort()
}
if cfg.RPCPort == 0 {
cfg.RPCPort = NextAvailablePort()
}
if cfg.RESTPort == 0 {
cfg.RESTPort = NextAvailablePort()
}
if cfg.ProfilePort == 0 {
cfg.ProfilePort = NextAvailablePort()
}
}
// BaseConfig returns the base node configuration struct.
func (cfg *BaseNodeConfig) BaseConfig() *BaseNodeConfig {
return cfg
}
// GenArgs generates a slice of command line arguments from the lightning node
// config struct. // config struct.
func (cfg NodeConfig) genArgs() []string { func (cfg *BaseNodeConfig) GenArgs() []string {
var args []string var args []string
switch cfg.NetParams { switch cfg.NetParams {
@ -283,7 +302,7 @@ type policyUpdateMap map[string]map[string][]*lnrpc.RoutingPolicy
// harness. Each HarnessNode instance also fully embeds an RPC client in // harness. Each HarnessNode instance also fully embeds an RPC client in
// order to pragmatically drive the node. // order to pragmatically drive the node.
type HarnessNode struct { type HarnessNode struct {
Cfg *NodeConfig Cfg *BaseNodeConfig
// NodeID is a unique identifier for the node within a NetworkHarness. // NodeID is a unique identifier for the node within a NetworkHarness.
NodeID int NodeID int
@ -377,7 +396,7 @@ func nextNodeID() int {
} }
// newNode creates a new test lightning node instance from the passed config. // newNode creates a new test lightning node instance from the passed config.
func newNode(cfg NodeConfig) (*HarnessNode, error) { func newNode(cfg *BaseNodeConfig) (*HarnessNode, error) {
if cfg.BaseDir == "" { if cfg.BaseDir == "" {
var err error var err error
cfg.BaseDir, err = ioutil.TempDir("", "lndtest-node") cfg.BaseDir, err = ioutil.TempDir("", "lndtest-node")
@ -397,7 +416,7 @@ func newNode(cfg NodeConfig) (*HarnessNode, error) {
cfg.ReadMacPath = filepath.Join(networkDir, "readonly.macaroon") cfg.ReadMacPath = filepath.Join(networkDir, "readonly.macaroon")
cfg.InvoiceMacPath = filepath.Join(networkDir, "invoice.macaroon") cfg.InvoiceMacPath = filepath.Join(networkDir, "invoice.macaroon")
generateListeningPorts(&cfg) cfg.GenerateListeningPorts()
// Run all tests with accept keysend. The keysend code is very isolated // Run all tests with accept keysend. The keysend code is very isolated
// and it is highly unlikely that it would affect regular itests when // and it is highly unlikely that it would affect regular itests when
@ -416,7 +435,7 @@ func newNode(cfg NodeConfig) (*HarnessNode, error) {
} }
return &HarnessNode{ return &HarnessNode{
Cfg: &cfg, Cfg: cfg,
NodeID: nextNodeID(), NodeID: nextNodeID(),
chanWatchRequests: make(chan *chanWatchRequest), chanWatchRequests: make(chan *chanWatchRequest),
openChans: make(map[wire.OutPoint]int), openChans: make(map[wire.OutPoint]int),
@ -569,7 +588,7 @@ func (hn *HarnessNode) InvoiceMacPath() string {
// startLnd handles the startup of lnd, creating log files, and possibly kills // startLnd handles the startup of lnd, creating log files, and possibly kills
// the process when needed. // the process when needed.
func (hn *HarnessNode) startLnd(lndBinary string, lndError chan<- error) error { func (hn *HarnessNode) startLnd(lndBinary string, lndError chan<- error) error {
args := hn.Cfg.genArgs() args := hn.Cfg.GenArgs()
hn.cmd = exec.Command(lndBinary, args...) hn.cmd = exec.Command(lndBinary, args...)
// Redirect stderr output to buffer // Redirect stderr output to buffer

View file

@ -1372,7 +1372,7 @@ func chanRestoreViaRPC(net *lntest.NetworkHarness, password []byte,
// copyPorts returns a node option function that copies the ports of an existing // copyPorts returns a node option function that copies the ports of an existing
// node over to the newly created one. // node over to the newly created one.
func copyPorts(oldNode *lntest.HarnessNode) lntest.NodeOption { func copyPorts(oldNode *lntest.HarnessNode) lntest.NodeOption {
return func(cfg *lntest.NodeConfig) { return func(cfg *lntest.BaseNodeConfig) {
cfg.P2PPort = oldNode.Cfg.P2PPort cfg.P2PPort = oldNode.Cfg.P2PPort
cfg.RPCPort = oldNode.Cfg.RPCPort cfg.RPCPort = oldNode.Cfg.RPCPort
cfg.RESTPort = oldNode.Cfg.RESTPort cfg.RESTPort = oldNode.Cfg.RESTPort

View file

@ -109,7 +109,7 @@ func testReconnectAfterIPChange(net *lntest.NetworkHarness, t *harnessTest) {
// withP2PPort is a helper closure used to set the P2P port that a node // withP2PPort is a helper closure used to set the P2P port that a node
// should use. // should use.
var withP2PPort = func(port int) lntest.NodeOption { var withP2PPort = func(port int) lntest.NodeOption {
return func(cfg *lntest.NodeConfig) { return func(cfg *lntest.BaseNodeConfig) {
cfg.P2PPort = port cfg.P2PPort = port
} }
} }