From 369ae5e372eceaef2bfc52995e8e4b89f62662a7 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Mon, 26 Oct 2020 16:36:09 +0100 Subject: [PATCH] itest: move all test db files when using both etcd and bbolt In some tests we moved channeld.db to a temp location in order to "time travel". This commit extends the existing semantics by moving all files, including embedded etcd db too besides the channeld.db file. --- lntest/harness.go | 45 ++++++++++++++++++++++++++++++++++++++++ lntest/itest/lnd_test.go | 26 +++++++++-------------- lntest/node.go | 13 ++++++++++-- 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/lntest/harness.go b/lntest/harness.go index 417169dd..2b876116 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "net/http" "os" + "path/filepath" "strings" "sync" "time" @@ -1403,3 +1404,47 @@ func CopyFile(dest, src string) error { return d.Close() } + +// FileExists returns true if the file at path exists. +func FileExists(path string) bool { + if _, err := os.Stat(path); os.IsNotExist(err) { + return false + } + + return true +} + +// CopyAll copies all files and directories from srcDir to dstDir recursively. +// Note that this function does not support links. +func CopyAll(dstDir, srcDir string) error { + entries, err := ioutil.ReadDir(srcDir) + if err != nil { + return err + } + + for _, entry := range entries { + srcPath := filepath.Join(srcDir, entry.Name()) + dstPath := filepath.Join(dstDir, entry.Name()) + + info, err := os.Stat(srcPath) + if err != nil { + return err + } + + if info.IsDir() { + err := os.Mkdir(dstPath, info.Mode()) + if err != nil && !os.IsExist(err) { + return err + } + + err = CopyAll(dstPath, srcPath) + if err != nil { + return err + } + } else if err := CopyFile(dstPath, srcPath); err != nil { + return err + } + } + + return nil +} diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index 1f1360bb..c522798d 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -12,7 +12,6 @@ import ( "io/ioutil" "math" "os" - "path/filepath" "reflect" "strings" "sync" @@ -8241,13 +8240,12 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { if err != nil { t.Fatalf("unable to create temp db folder: %v", err) } - bobTempDbFile := filepath.Join(bobTempDbPath, "channel.db") defer os.Remove(bobTempDbPath) // With the temporary file created, copy Bob's current state into the // temporary file we created above. Later after more updates, we'll // restore this state. - if err := lntest.CopyFile(bobTempDbFile, net.Bob.DBPath()); err != nil { + if err := lntest.CopyAll(bobTempDbPath, net.Bob.DBDir()); err != nil { t.Fatalf("unable to copy database files: %v", err) } @@ -8273,7 +8271,7 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { // state. With this, we essentially force Bob to travel back in time // within the channel's history. if err = net.RestartNode(net.Bob, func() error { - return os.Rename(bobTempDbFile, net.Bob.DBPath()) + return lntest.CopyAll(net.Bob.DBDir(), bobTempDbPath) }); err != nil { t.Fatalf("unable to restart node: %v", err) } @@ -8496,13 +8494,12 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness if err != nil { t.Fatalf("unable to create temp db folder: %v", err) } - carolTempDbFile := filepath.Join(carolTempDbPath, "channel.db") defer os.Remove(carolTempDbPath) // With the temporary file created, copy Carol's current state into the // temporary file we created above. Later after more updates, we'll // restore this state. - if err := lntest.CopyFile(carolTempDbFile, carol.DBPath()); err != nil { + if err := lntest.CopyAll(carolTempDbPath, carol.DBDir()); err != nil { t.Fatalf("unable to copy database files: %v", err) } @@ -8527,7 +8524,7 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness // state. With this, we essentially force Carol to travel back in time // within the channel's history. if err = net.RestartNode(carol, func() error { - return os.Rename(carolTempDbFile, carol.DBPath()) + return lntest.CopyAll(carol.DBDir(), carolTempDbPath) }); err != nil { t.Fatalf("unable to restart node: %v", err) } @@ -8820,13 +8817,12 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness, if err != nil { t.Fatalf("unable to create temp db folder: %v", err) } - carolTempDbFile := filepath.Join(carolTempDbPath, "channel.db") defer os.Remove(carolTempDbPath) // With the temporary file created, copy Carol's current state into the // temporary file we created above. Later after more updates, we'll // restore this state. - if err := lntest.CopyFile(carolTempDbFile, carol.DBPath()); err != nil { + if err := lntest.CopyAll(carolTempDbPath, carol.DBDir()); err != nil { t.Fatalf("unable to copy database files: %v", err) } @@ -8860,7 +8856,7 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness, // state. With this, we essentially force Carol to travel back in time // within the channel's history. if err = net.RestartNode(carol, func() error { - return os.Rename(carolTempDbFile, carol.DBPath()) + return lntest.CopyAll(carol.DBDir(), carolTempDbPath) }); err != nil { t.Fatalf("unable to restart node: %v", err) } @@ -9222,13 +9218,12 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness, if err != nil { t.Fatalf("unable to create temp db folder: %v", err) } - carolTempDbFile := filepath.Join(carolTempDbPath, "channel.db") defer os.Remove(carolTempDbPath) // With the temporary file created, copy Carol's current state into the // temporary file we created above. Later after more updates, we'll // restore this state. - if err := lntest.CopyFile(carolTempDbFile, carol.DBPath()); err != nil { + if err := lntest.CopyAll(carolTempDbPath, carol.DBDir()); err != nil { t.Fatalf("unable to copy database files: %v", err) } @@ -9285,7 +9280,7 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness, // state. With this, we essentially force Carol to travel back in time // within the channel's history. if err = net.RestartNode(carol, func() error { - return os.Rename(carolTempDbFile, carol.DBPath()) + return lntest.CopyAll(carol.DBDir(), carolTempDbPath) }); err != nil { t.Fatalf("unable to restart node: %v", err) } @@ -9769,13 +9764,12 @@ func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) { if err != nil { t.Fatalf("unable to create temp db folder: %v", err) } - tempDbFile := filepath.Join(tempDbPath, "channel.db") defer os.Remove(tempDbPath) // With the temporary file created, copy the current state into // the temporary file we created above. Later after more // updates, we'll restore this state. - if err := lntest.CopyFile(tempDbFile, node.DBPath()); err != nil { + if err := lntest.CopyAll(tempDbPath, node.DBDir()); err != nil { t.Fatalf("unable to copy database files: %v", err) } @@ -9802,7 +9796,7 @@ func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) { // force the node to travel back in time within the channel's // history. if err = net.RestartNode(node, func() error { - return os.Rename(tempDbFile, node.DBPath()) + return lntest.CopyAll(node.DBDir(), tempDbPath) }); err != nil { t.Fatalf("unable to restart node: %v", err) } diff --git a/lntest/node.go b/lntest/node.go index ae3ebfc0..4fcbc78b 100644 --- a/lntest/node.go +++ b/lntest/node.go @@ -199,9 +199,13 @@ func (cfg NodeConfig) RESTAddr() string { return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.RESTPort)) } +// DBDir returns the holding directory path of the graph database. +func (cfg NodeConfig) DBDir() string { + return filepath.Join(cfg.DataDir, "graph", cfg.NetParams.Name) +} + func (cfg NodeConfig) DBPath() string { - return filepath.Join(cfg.DataDir, "graph", - fmt.Sprintf("%v/channel.db", cfg.NetParams.Name)) + return filepath.Join(cfg.DBDir(), "channel.db") } func (cfg NodeConfig) ChanBackupPath() string { @@ -440,6 +444,11 @@ func (hn *HarnessNode) DBPath() string { return hn.Cfg.DBPath() } +// DBDir returns the path for the directory holding channeldb file(s). +func (hn *HarnessNode) DBDir() string { + return hn.Cfg.DBDir() +} + // Name returns the name of this node set during initialization. func (hn *HarnessNode) Name() string { return hn.Cfg.Name