Skip to content

Commit

Permalink
Merge pull request #6139 from guggero/itest-refactor
Browse files Browse the repository at this point in the history
itest: refactor for re-use in LiT
  • Loading branch information
Roasbeef authored Jan 8, 2022
2 parents 61bffa7 + d039822 commit 8b00e3c
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 48 deletions.
3 changes: 3 additions & 0 deletions docs/release-notes/release-notes-0.14.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
using itest harness outside of
lnd](https://github.com/lightningnetwork/lnd/pull/6050).

* [Export `lntest` base node config so it can be re-used in LiT integration
tests](https://github.com/lightningnetwork/lnd/pull/6139).

## Bug fixes

* [Return the nearest known fee rate when a given conf target cannot be found
Expand Down
6 changes: 3 additions & 3 deletions lntest/harness_net.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
const DefaultCSV = 4

// 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.
// Building on top of HarnessNode, it is responsible for handling interactions
Expand Down Expand Up @@ -489,7 +489,7 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool,
password []byte, dbBackend DatabaseBackend, wait bool, opts ...NodeOption) (
*HarnessNode, error) {

cfg := &NodeConfig{
cfg := &BaseNodeConfig{
Name: name,
LogFilenamePrefix: n.currentTestCase,
HasSeed: hasSeed,
Expand All @@ -504,7 +504,7 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool,
opt(cfg)
}

node, err := newNode(*cfg)
node, err := newNode(cfg)
if err != nil {
return nil, err
}
Expand Down
95 changes: 57 additions & 38 deletions lntest/harness_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,6 @@ func postgresDatabaseDsn(dbName string) string {
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
// node implementation.
type BackendConfig interface {
Expand All @@ -102,10 +84,25 @@ type BackendConfig interface {
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

// 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.
LogFilenamePrefix string

Expand Down Expand Up @@ -139,28 +136,28 @@ type NodeConfig struct {
PostgresDsn string
}

func (cfg NodeConfig) P2PAddr() string {
return fmt.Sprintf(listenerFormat, cfg.P2PPort)
func (cfg BaseNodeConfig) P2PAddr() string {
return fmt.Sprintf(ListenerFormat, cfg.P2PPort)
}

func (cfg NodeConfig) RPCAddr() string {
return fmt.Sprintf(listenerFormat, cfg.RPCPort)
func (cfg BaseNodeConfig) RPCAddr() string {
return fmt.Sprintf(ListenerFormat, cfg.RPCPort)
}

func (cfg NodeConfig) RESTAddr() string {
return fmt.Sprintf(listenerFormat, cfg.RESTPort)
func (cfg BaseNodeConfig) RESTAddr() string {
return fmt.Sprintf(ListenerFormat, cfg.RESTPort)
}

// 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)
}

func (cfg NodeConfig) DBPath() string {
func (cfg BaseNodeConfig) DBPath() string {
return filepath.Join(cfg.DBDir(), "channel.db")
}

func (cfg NodeConfig) ChanBackupPath() string {
func (cfg BaseNodeConfig) ChanBackupPath() string {
return filepath.Join(
cfg.DataDir, "chain", "bitcoin",
fmt.Sprintf(
Expand All @@ -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.
func (cfg NodeConfig) genArgs() []string {
func (cfg *BaseNodeConfig) GenArgs() []string {
var args []string

switch cfg.NetParams {
Expand Down Expand Up @@ -283,7 +302,7 @@ type policyUpdateMap map[string]map[string][]*lnrpc.RoutingPolicy
// harness. Each HarnessNode instance also fully embeds an RPC client in
// order to pragmatically drive the node.
type HarnessNode struct {
Cfg *NodeConfig
Cfg *BaseNodeConfig

// NodeID is a unique identifier for the node within a NetworkHarness.
NodeID int
Expand Down Expand Up @@ -377,7 +396,7 @@ func nextNodeID() int {
}

// 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 == "" {
var err error
cfg.BaseDir, err = ioutil.TempDir("", "lndtest-node")
Expand All @@ -397,7 +416,7 @@ func newNode(cfg NodeConfig) (*HarnessNode, error) {
cfg.ReadMacPath = filepath.Join(networkDir, "readonly.macaroon")
cfg.InvoiceMacPath = filepath.Join(networkDir, "invoice.macaroon")

generateListeningPorts(&cfg)
cfg.GenerateListeningPorts()

// Run all tests with accept keysend. The keysend code is very isolated
// and it is highly unlikely that it would affect regular itests when
Expand All @@ -416,7 +435,7 @@ func newNode(cfg NodeConfig) (*HarnessNode, error) {
}

return &HarnessNode{
Cfg: &cfg,
Cfg: cfg,
NodeID: nextNodeID(),
chanWatchRequests: make(chan *chanWatchRequest),
openChans: make(map[wire.OutPoint]int),
Expand Down Expand Up @@ -511,12 +530,12 @@ func (hn *HarnessNode) String() string {
nodeState.ClosedChans[outpoint.String()] = count
}

bytes, err := json.MarshalIndent(nodeState, "", "\t")
stateBytes, err := json.MarshalIndent(nodeState, "", "\t")
if err != nil {
return fmt.Sprintf("\n encode node state with err: %v", err)
}

return fmt.Sprintf("\nnode state: %s", bytes)
return fmt.Sprintf("\nnode state: %s", stateBytes)
}

// DBPath returns the filepath to the channeldb database file for this node.
Expand Down Expand Up @@ -569,7 +588,7 @@ func (hn *HarnessNode) InvoiceMacPath() string {
// startLnd handles the startup of lnd, creating log files, and possibly kills
// the process when needed.
func (hn *HarnessNode) startLnd(lndBinary string, lndError chan<- error) error {
args := hn.Cfg.genArgs()
args := hn.Cfg.GenArgs()
hn.cmd = exec.Command(lndBinary, args...)

// Redirect stderr output to buffer
Expand Down
2 changes: 1 addition & 1 deletion lntest/itest/lnd_channel_backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,7 @@ func chanRestoreViaRPC(net *lntest.NetworkHarness, password []byte,
// copyPorts returns a node option function that copies the ports of an existing
// node over to the newly created one.
func copyPorts(oldNode *lntest.HarnessNode) lntest.NodeOption {
return func(cfg *lntest.NodeConfig) {
return func(cfg *lntest.BaseNodeConfig) {
cfg.P2PPort = oldNode.Cfg.P2PPort
cfg.RPCPort = oldNode.Cfg.RPCPort
cfg.RESTPort = oldNode.Cfg.RESTPort
Expand Down
2 changes: 1 addition & 1 deletion lntest/itest/lnd_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
// should use.
var withP2PPort = func(port int) lntest.NodeOption {
return func(cfg *lntest.NodeConfig) {
return func(cfg *lntest.BaseNodeConfig) {
cfg.P2PPort = port
}
}
Expand Down
10 changes: 5 additions & 5 deletions lntest/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ const (
// number and are determined by the results of nextAvailablePort().
defaultNodePort = 5555

// listenerFormat is the format string that is used to generate local
// ListenerFormat is the format string that is used to generate local
// listener addresses.
listenerFormat = "127.0.0.1:%d"
ListenerFormat = "127.0.0.1:%d"

// NeutrinoBackendName is the name of the neutrino backend.
NeutrinoBackendName = "neutrino"
Expand Down Expand Up @@ -73,7 +73,7 @@ func NextAvailablePort() int {
// the harness node, in practice in CI servers this seems much
// less likely than simply some other process already being
// bound at the start of the tests.
addr := fmt.Sprintf(listenerFormat, port)
addr := fmt.Sprintf(ListenerFormat, port)
l, err := net.Listen("tcp4", addr)
if err == nil {
err := l.Close()
Expand Down Expand Up @@ -117,8 +117,8 @@ func GetBtcdBinary() string {
// addresses with unique ports and should be used to overwrite rpctest's
// default generator which is prone to use colliding ports.
func GenerateBtcdListenerAddresses() (string, string) {
return fmt.Sprintf(listenerFormat, NextAvailablePort()),
fmt.Sprintf(listenerFormat, NextAvailablePort())
return fmt.Sprintf(ListenerFormat, NextAvailablePort()),
fmt.Sprintf(ListenerFormat, NextAvailablePort())
}

// MakeOutpoint returns the outpoint of the channel's funding transaction.
Expand Down

0 comments on commit 8b00e3c

Please sign in to comment.