postgres: add itest

This commit is contained in:
Joost Jager committed 2021-09-21 10:44:23 +02:00
1 parent ae6cf72b46
commit daeb96fe0a
12 files changed
+174 -25

No files matched your search

+58 -16
View File
@@ -88,6 +88,7 @@ type DatabaseBackend int
const (
BackendBbolt DatabaseBackend = iota
BackendEtcd
BackendPostgres
)
// NewNetworkHarness creates a new network test harness.
@@ -1641,36 +1642,77 @@ func (n *NetworkHarness) BackupDb(hn *HarnessNode) error {
return errors.New("backup already created")
}
// Backup files.
tempDir, err := ioutil.TempDir("", "past-state")
restart, err := n.SuspendNode(hn)
if err != nil {
return fmt.Errorf("unable to create temp db folder: %v", err)
return err
}
if err := copyAll(tempDir, hn.DBDir()); err != nil {
return fmt.Errorf("unable to copy database files: %v", err)
if hn.postgresDbName != "" {
// Backup database.
backupDbName := hn.postgresDbName + "_backup"
err := executePgQuery(
"CREATE DATABASE " + backupDbName + " WITH TEMPLATE " +
hn.postgresDbName,
)
if err != nil {
return err
}
} else {
// Backup files.
tempDir, err := ioutil.TempDir("", "past-state")
if err != nil {
return fmt.Errorf("unable to create temp db folder: %v",
err)
}
if err := copyAll(tempDir, hn.DBDir()); err != nil {
return fmt.Errorf("unable to copy database files: %v",
err)
}
hn.backupDbDir = tempDir
}
hn.backupDbDir = tempDir
err = restart()
if err != nil {
return err
}
return nil
}
// RestoreDb restores a database backup.
func (n *NetworkHarness) RestoreDb(hn *HarnessNode) error {
if hn.backupDbDir == "" {
return errors.New("no database backup created")
}
if hn.postgresDbName != "" {
// Restore database.
backupDbName := hn.postgresDbName + "_backup"
err := executePgQuery(
"DROP DATABASE " + hn.postgresDbName,
)
if err != nil {
return err
}
err = executePgQuery(
"ALTER DATABASE " + backupDbName + " RENAME TO " + hn.postgresDbName,
)
if err != nil {
return err
}
} else {
// Restore files.
if hn.backupDbDir == "" {
return errors.New("no database backup created")
}
// Restore files.
if err := copyAll(hn.DBDir(), hn.backupDbDir); err != nil {
return fmt.Errorf("unable to copy database files: %v", err)
}
if err := copyAll(hn.DBDir(), hn.backupDbDir); err != nil {
return fmt.Errorf("unable to copy database files: %v", err)
}
if err := os.RemoveAll(hn.backupDbDir); err != nil {
return fmt.Errorf("unable to remove backup dir: %v", err)
if err := os.RemoveAll(hn.backupDbDir); err != nil {
return fmt.Errorf("unable to remove backup dir: %v", err)
}
hn.backupDbDir = ""
}
hn.backupDbDir = ""
return nil
}
+4
View File
@@ -927,6 +927,10 @@ func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to copy database files: %v", err)
}
// Reconnect the peers after the restart that was needed for the db
// backup.
net.EnsureConnected(t.t, carol, node)
// Finally, send more payments from , using the remaining
// payment hashes.
err = completePaymentRequests(
+16
View File
@@ -122,6 +122,10 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to copy database files: %v", err)
}
// Reconnect the peers after the restart that was needed for the db
// backup.
net.EnsureConnected(t.t, carol, net.Bob)
// Finally, send payments from Carol to Bob, consuming Bob's remaining
// payment hashes.
err = completePaymentRequests(
@@ -338,6 +342,10 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness
t.Fatalf("unable to copy database files: %v", err)
}
// Reconnect the peers after the restart that was needed for the db
// backup.
net.EnsureConnected(t.t, dave, carol)
// Finally, send payments from Dave to Carol, consuming Carol's
// remaining payment hashes.
err = completePaymentRequests(
@@ -617,6 +625,10 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
t.Fatalf("unable to copy database files: %v", err)
}
// Reconnect the peers after the restart that was needed for the db
// backup.
net.EnsureConnected(t.t, dave, carol)
// Finally, send payments from Dave to Carol, consuming Carol's
// remaining payment hashes.
err = completePaymentRequests(
@@ -1036,6 +1048,10 @@ func testRevokedCloseRetributionAltruistWatchtowerCase(
t.Fatalf("unable to copy database files: %v", err)
}
// Reconnect the peers after the restart that was needed for the db
// backup.
net.EnsureConnected(t.t, dave, carol)
// Finally, send payments from Dave to Carol, consuming Carol's remaining
// payment hashes.
err = completePaymentRequests(
+5 -1
View File
@@ -44,7 +44,8 @@ var (
)
// dbBackendFlag specifies the backend to use
dbBackendFlag = flag.String("dbbackend", "bbolt", "Database backend (bbolt, etcd)")
dbBackendFlag = flag.String("dbbackend", "bbolt", "Database backend "+
"(bbolt, etcd, postgres)")
)
// getTestCaseSplitTranche returns the sub slice of the test cases that should
@@ -153,6 +154,9 @@ func TestLightningNetworkDaemon(t *testing.T) {
case "etcd":
dbBackend = lntest.BackendEtcd
case "postgres":
dbBackend = lntest.BackendPostgres
default:
require.Fail(t, "unknown db backend")
}
+65 -2
View File
@@ -3,6 +3,7 @@ package lntest
import (
"bytes"
"context"
"crypto/rand"
"encoding/hex"
"encoding/json"
"flag"
@@ -26,6 +27,7 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/go-errors/errors"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
@@ -63,6 +65,8 @@ const (
// NeutrinoBackendName is the name of the neutrino backend.
NeutrinoBackendName = "neutrino"
postgresDsn = "postgres://postgres:postgres@localhost:6432/%s?sslmode=disable"
)
var (
@@ -94,6 +98,10 @@ var (
)
)
func postgresDatabaseDsn(dbName string) string {
return fmt.Sprintf(postgresDsn, dbName)
}
// NextAvailablePort returns the first port that is available for listening by
// a new node. It panics if no port is found and the maximum available TCP port
// is reached.
@@ -223,7 +231,8 @@ type NodeConfig struct {
FeeURL string
DbBackend DatabaseBackend
DbBackend DatabaseBackend
PostgresDsn string
}
func (cfg NodeConfig) P2PAddr() string {
@@ -311,7 +320,8 @@ func (cfg NodeConfig) genArgs() []string {
args = append(args, "--accept-amp")
}
if cfg.DbBackend == BackendEtcd {
switch cfg.DbBackend {
case BackendEtcd:
args = append(args, "--db.backend=etcd")
args = append(args, "--db.etcd.embedded")
args = append(
@@ -332,6 +342,10 @@ func (cfg NodeConfig) genArgs() []string {
path.Join(cfg.LogDir, "etcd.log"),
),
)
case BackendPostgres:
args = append(args, "--db.backend=postgres")
args = append(args, "--db.postgres.dsn="+cfg.PostgresDsn)
}
if cfg.FeeURL != "" {
@@ -421,6 +435,10 @@ type HarnessNode struct {
// backupDbDir is the path where a database backup is stored, if any.
backupDbDir string
// postgresDbName is the name of the postgres database where lnd data is
// stored in.
postgresDbName string
}
// Assert *HarnessNode implements the lnrpc.LightningClient interface.
@@ -456,6 +474,17 @@ func newNode(cfg NodeConfig) (*HarnessNode, error) {
// enabled.
cfg.AcceptKeySend = true
// Create temporary database.
var dbName string
if cfg.DbBackend == BackendPostgres {
var err error
dbName, err = createTempPgDb()
if err != nil {
return nil, err
}
cfg.PostgresDsn = postgresDatabaseDsn(dbName)
}
numActiveNodesMtx.Lock()
nodeNum := numActiveNodes
numActiveNodes++
@@ -472,9 +501,43 @@ func newNode(cfg NodeConfig) (*HarnessNode, error) {
closeChanWatchers: make(map[wire.OutPoint][]chan struct{}),
policyUpdates: policyUpdateMap{},
postgresDbName: dbName,
}, nil
}
func createTempPgDb() (string, error) {
// Create random database name.
randBytes := make([]byte, 8)
_, err := rand.Read(randBytes)
if err != nil {
return "", err
}
dbName := "itest_" + hex.EncodeToString(randBytes)
// Create database.
err = executePgQuery("CREATE DATABASE " + dbName)
if err != nil {
return "", err
}
return dbName, nil
}
func executePgQuery(query string) error {
pool, err := pgxpool.Connect(
context.Background(),
postgresDatabaseDsn("postgres"),
)
if err != nil {
return fmt.Errorf("unable to connect to database: %v", err)
}
defer pool.Close()
_, err = pool.Exec(context.Background(), query)
return err
}
// NewMiner creates a new miner using btcd backend. The baseLogDir specifies
// the miner node's log dir. When tests are finished, during clean up, its log
// files, including any compressed log files from logrotate, are copied to
+1 -1
View File
@@ -1,4 +1,4 @@
// +build !darwin,!kvdb_etcd
// +build !darwin,!kvdb_etcd,!kvdb_postgres
package lntest
+1 -1
View File
@@ -1,4 +1,4 @@
// +build darwin,!kvdb_etcd
// +build darwin,!kvdb_etcd,!kvdb_postgres
package lntest
@@ -1,4 +1,4 @@
// +build kvdb_etcd
// +build kvdb_etcd kvdb_postgres
package lntest
@@ -23,7 +23,7 @@ const (
// AsyncBenchmarkTimeout is the timeout used when running the async
// payments benchmark.
AsyncBenchmarkTimeout = 2 * time.Minute
AsyncBenchmarkTimeout = 3 * time.Minute
// NodeStartTimeout is the timeout value when waiting for a node to
// become fully started.