diff --git a/lntest/node/config.go b/lntest/node/config.go index bd003eb01..694e26c3e 100644 --- a/lntest/node/config.go +++ b/lntest/node/config.go @@ -7,6 +7,7 @@ import ( "os" "path" "path/filepath" + "time" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/integration/rpctest" @@ -28,6 +29,10 @@ const ( ) var ( + // baseDirFlag is the default directory where all the node's data are + // saved. If not set, a temporary dir will be created. + baseDirFlag = flag.String("basedir", "", "default dir to save data") + // logOutput is a flag that can be set to append the output from the // seed nodes to log files. logOutput = flag.Bool("logoutput", false, @@ -162,6 +167,11 @@ type BaseNodeConfig struct { // compiled with all required itest flags. LndBinary string + // SkipCleanup specifies whether the harness will remove the base dir or + // not when the test finishes. When using customized BaseDir, the + // cleanup will be skipped. + SkipCleanup bool + // backupDBDir is the path where a database backup is stored, if any. backupDBDir string @@ -223,6 +233,38 @@ func (cfg *BaseNodeConfig) BaseConfig() *BaseNodeConfig { return cfg } +// GenBaseDir creates a base dir that's used for the test. +func (cfg *BaseNodeConfig) GenBaseDir() error { + // Exit early if the BaseDir is already set. + if cfg.BaseDir != "" { + return nil + } + + dirBaseName := fmt.Sprintf("itest-%v-%v-%v-%v", cfg.LogFilenamePrefix, + cfg.Name, cfg.NodeID, time.Now().Unix()) + + // Create a temporary directory for the node's data and logs. Use dash + // suffix as a separator between base name and node ID. + if *baseDirFlag == "" { + var err error + + cfg.BaseDir, err = os.MkdirTemp("", dirBaseName) + + return err + } + + // Create the customized base dir. + if err := os.MkdirAll(*baseDirFlag, 0700); err != nil { + return err + } + + // Use customized base dir and skip the cleanups. + cfg.BaseDir = filepath.Join(*baseDirFlag, dirBaseName) + cfg.SkipCleanup = true + + return nil +} + // GenArgs generates a slice of command line arguments from the lightning node // config struct. func (cfg *BaseNodeConfig) GenArgs() []string { diff --git a/lntest/node/harness_node.go b/lntest/node/harness_node.go index 4cfd9a501..87dfa9ce6 100644 --- a/lntest/node/harness_node.go +++ b/lntest/node/harness_node.go @@ -93,18 +93,10 @@ type HarnessNode struct { // NewHarnessNode creates a new test lightning node instance from the passed // config. func NewHarnessNode(t *testing.T, cfg *BaseNodeConfig) (*HarnessNode, error) { - if cfg.BaseDir == "" { - var err error - - // Create a temporary directory for the node's data and logs. - // Use dash suffix as a separator between base name and random - // suffix. - dirBaseName := fmt.Sprintf("lndtest-node-%s-", cfg.Name) - cfg.BaseDir, err = os.MkdirTemp("", dirBaseName) - if err != nil { - return nil, err - } + if err := cfg.GenBaseDir(); err != nil { + return nil, err } + cfg.DataDir = filepath.Join(cfg.BaseDir, "data") cfg.LogDir = filepath.Join(cfg.BaseDir, "logs") cfg.TLSCertPath = filepath.Join(cfg.BaseDir, "tls.cert") @@ -802,6 +794,13 @@ func (hn *HarnessNode) Shutdown() error { if err := hn.Stop(); err != nil { return err } + + // Exit if we want to skip the cleanup, which happens when a customized + // base dir is used. + if hn.Cfg.SkipCleanup { + return nil + } + if err := hn.cleanup(); err != nil { return err } diff --git a/make/testing_flags.mk b/make/testing_flags.mk index 1826e00ea..7e4ba5b0e 100644 --- a/make/testing_flags.mk +++ b/make/testing_flags.mk @@ -34,6 +34,11 @@ ifneq ($(shuffleseed),) SHUFFLE_SEED = $(shuffleseed) endif +# Set the base dir if specified. +ifneq ($(basedir),) +ITEST_FLAGS += -basedir=$(basedir) +endif + # Windows needs to append a .exe suffix to all executable files, otherwise it # won't run them. ifneq ($(windows),)