mirror of https://github.com/guggero/chantools
multi: add unit tests
parent
e6fcb580a3
commit
fa62a57e95
@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
backupContent = "FundingOutpoint: (string) (len=66) \"10279f626196340" +
|
||||
"58b6133cb7ac6c1693a8e6df7caa91c6263ca3d0bf704ad4d:0\""
|
||||
)
|
||||
|
||||
func TestChanBackupAndDumpBackup(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Create a channel backup from a channel DB file.
|
||||
makeBackup := &chanBackupCommand{
|
||||
ChannelDB: h.testdataFile("channel.db"),
|
||||
MultiFile: h.tempFile("extracted.backup"),
|
||||
rootKey: &rootKey{RootKey: rootKeyAezeed},
|
||||
}
|
||||
|
||||
err := makeBackup.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Decrypt and dump the channel backup file.
|
||||
dumpBackup := &dumpBackupCommand{
|
||||
MultiFile: makeBackup.MultiFile,
|
||||
rootKey: &rootKey{RootKey: rootKeyAezeed},
|
||||
}
|
||||
|
||||
err = dumpBackup.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(backupContent)
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCompactDBAndDumpChannels(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Compact the test DB.
|
||||
compact := &compactDBCommand{
|
||||
SourceDB: h.testdataFile("channel.db"),
|
||||
DestDB: h.tempFile("compacted.db"),
|
||||
}
|
||||
|
||||
err := compact.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.FileExists(t, compact.DestDB)
|
||||
|
||||
// Compacting small DBs actually increases the size slightly. But we
|
||||
// just want to make sure the contents match.
|
||||
require.GreaterOrEqual(
|
||||
t, h.fileSize(compact.DestDB), h.fileSize(compact.SourceDB),
|
||||
)
|
||||
|
||||
// Compare the content of the source and destination DB by looking at
|
||||
// the logged dump.
|
||||
dump := &dumpChannelsCommand{
|
||||
ChannelDB: compact.SourceDB,
|
||||
}
|
||||
h.clearLog()
|
||||
err = dump.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
sourceDump := h.getLog()
|
||||
|
||||
h.clearLog()
|
||||
dump.ChannelDB = compact.DestDB
|
||||
err = dump.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
destDump := h.getLog()
|
||||
|
||||
h.assertLogEqual(sourceDump, destDump)
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/guggero/chantools/btc"
|
||||
"github.com/guggero/chantools/lnd"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
testPath = "m/123'/45'/67'/8/9"
|
||||
keyContent = "bcrt1qnl5qfvpfcmj7y56nugpermluu46x79sfz0ku70"
|
||||
keyContentBIP39 = "bcrt1q3pae32m7jdqm5ulf80yc3n59xy4s4xm5a28ekr"
|
||||
)
|
||||
|
||||
func TestDeriveKey(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Derive a specific key from the serialized root key.
|
||||
derive := &deriveKeyCommand{
|
||||
Path: testPath,
|
||||
rootKey: &rootKey{RootKey: rootKeyAezeed},
|
||||
}
|
||||
|
||||
err := derive.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(keyContent)
|
||||
}
|
||||
|
||||
func TestDeriveKeyAezeedNoPassphrase(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Derive a specific key from the serialized root key.
|
||||
derive := &deriveKeyCommand{
|
||||
Path: testPath,
|
||||
rootKey: &rootKey{},
|
||||
}
|
||||
|
||||
err := os.Setenv(lnd.MnemonicEnvName, seedAezeedNoPassphrase)
|
||||
require.NoError(t, err)
|
||||
err = os.Setenv(lnd.PassphraseEnvName, "-")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = derive.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(keyContent)
|
||||
}
|
||||
|
||||
func TestDeriveKeyAezeedWithPassphrase(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Derive a specific key from the serialized root key.
|
||||
derive := &deriveKeyCommand{
|
||||
Path: testPath,
|
||||
rootKey: &rootKey{},
|
||||
}
|
||||
|
||||
err := os.Setenv(lnd.MnemonicEnvName, seedAezeedWithPassphrase)
|
||||
require.NoError(t, err)
|
||||
err = os.Setenv(lnd.PassphraseEnvName, testPassPhrase)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = derive.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(keyContent)
|
||||
}
|
||||
|
||||
func TestDeriveKeySeedBip39(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Derive a specific key from the serialized root key.
|
||||
derive := &deriveKeyCommand{
|
||||
Path: testPath,
|
||||
rootKey: &rootKey{BIP39: true},
|
||||
}
|
||||
|
||||
err := os.Setenv(btc.BIP39MnemonicEnvName, seedBip39)
|
||||
require.NoError(t, err)
|
||||
err = os.Setenv(btc.BIP39PassphraseEnvName, "-")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = derive.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(keyContentBIP39)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package main
|
||||
|
||||
// This file is empty for now, the dumpbackup command is covered by the test in
|
||||
// chanbackup_test.go.
|
@ -0,0 +1,4 @@
|
||||
package main
|
||||
|
||||
// This file is empty for now, the dumpchannels command is covered by the test
|
||||
// in compactdb_test.go.
|
@ -0,0 +1,117 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btclog"
|
||||
"github.com/lightningnetwork/lnd/chanbackup"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
seedAezeedNoPassphrase = "abandon kangaroo tribe spell brass entry " +
|
||||
"argue buzz muffin total rug title autumn wish use bubble " +
|
||||
"alarm rent machine hockey fork slam gaze tobacco"
|
||||
seedAezeedWithPassphrase = "able pause keen exhibit duck olympic " +
|
||||
"foot donor hire omit earth ribbon rotate cruise door orbit " +
|
||||
"nephew mixture machine hockey fork scorpion shell door"
|
||||
testPassPhrase = "testnet3"
|
||||
seedBip39 = "uncover bargain diesel boss local host over divide " +
|
||||
"orient cradle good crumble"
|
||||
|
||||
rootKeyAezeed = "tprv8ZgxMBicQKsPejNXQLJKe3dBBs9Zrt53EZrsBzVLQ8rZji3" +
|
||||
"hVb3wcoRvgrjvTmjPG2ixoGUUkCyC6yBEy9T5gbLdvD2a5VmJbcFd5Q9pkAs"
|
||||
rootKeyBip39 = "tprv8ZgxMBicQKsPdoVEZRN2MyzEgxGTqJepzhMc66b26zL1siLi" +
|
||||
"WRQAGh9rAgPPJuQeHWWpgcDcS45yi6KBTFeGkQMEb2RNTrP11evJcB4UVSh"
|
||||
rootKeyBip39Passphrase = ""
|
||||
)
|
||||
|
||||
var (
|
||||
datePattern = regexp.MustCompile(
|
||||
"\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} ",
|
||||
)
|
||||
addressPattern = regexp.MustCompile("\\(0x[0-9a-f]{10}\\)")
|
||||
)
|
||||
|
||||
type harness struct {
|
||||
t *testing.T
|
||||
logBuffer *bytes.Buffer
|
||||
logger btclog.Logger
|
||||
tempDir string
|
||||
}
|
||||
|
||||
func newHarness(t *testing.T) *harness {
|
||||
buf := &bytes.Buffer{}
|
||||
logBackend := btclog.NewBackend(buf)
|
||||
tempDir, err := ioutil.TempDir("", "chantools")
|
||||
require.NoError(t, err)
|
||||
|
||||
h := &harness{
|
||||
t: t,
|
||||
logBuffer: buf,
|
||||
logger: logBackend.Logger("CHAN"),
|
||||
tempDir: tempDir,
|
||||
}
|
||||
|
||||
h.logger.SetLevel(btclog.LevelTrace)
|
||||
log = h.logger
|
||||
channeldb.UseLogger(h.logger)
|
||||
chanbackup.UseLogger(h.logger)
|
||||
|
||||
os.Clearenv()
|
||||
chainParams = &chaincfg.RegressionNetParams
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func (h *harness) getLog() string {
|
||||
return h.logBuffer.String()
|
||||
}
|
||||
|
||||
func (h *harness) clearLog() {
|
||||
h.logBuffer.Reset()
|
||||
}
|
||||
|
||||
func (h *harness) assertLogContains(format string, args ...interface{}) {
|
||||
h.t.Helper()
|
||||
|
||||
require.Contains(h.t, h.logBuffer.String(), fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func (h *harness) assertLogEqual(a, b string) {
|
||||
// Remove all timestamps and all memory addresses from dumps as those
|
||||
// are always different.
|
||||
a = datePattern.ReplaceAllString(a, "")
|
||||
a = addressPattern.ReplaceAllString(a, "")
|
||||
|
||||
b = datePattern.ReplaceAllString(b, "")
|
||||
b = addressPattern.ReplaceAllString(b, "")
|
||||
|
||||
require.Equal(h.t, a, b)
|
||||
}
|
||||
|
||||
func (h *harness) testdataFile(name string) string {
|
||||
workingDir, err := os.Getwd()
|
||||
require.NoError(h.t, err)
|
||||
|
||||
return path.Join(workingDir, "testdata", name)
|
||||
}
|
||||
|
||||
func (h *harness) tempFile(name string) string {
|
||||
return path.Join(h.tempDir, name)
|
||||
}
|
||||
|
||||
func (h *harness) fileSize(name string) int64 {
|
||||
stat, err := os.Stat(name)
|
||||
require.NoError(h.t, err)
|
||||
|
||||
return stat.Size()
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/guggero/chantools/btc"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/guggero/chantools/lnd"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestShowRootKey(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Derive the root key from the aezeed.
|
||||
show := &showRootKeyCommand{
|
||||
rootKey: &rootKey{},
|
||||
}
|
||||
|
||||
err := os.Setenv(lnd.MnemonicEnvName, seedAezeedNoPassphrase)
|
||||
require.NoError(t, err)
|
||||
err = os.Setenv(lnd.PassphraseEnvName, "-")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = show.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(rootKeyAezeed)
|
||||
}
|
||||
|
||||
func TestShowRootKeyBIP39(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Derive the root key from the BIP39 seed.
|
||||
show := &showRootKeyCommand{
|
||||
rootKey: &rootKey{BIP39: true},
|
||||
}
|
||||
|
||||
err := os.Setenv(btc.BIP39MnemonicEnvName, seedBip39)
|
||||
require.NoError(t, err)
|
||||
err = os.Setenv(btc.BIP39PassphraseEnvName, "-")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = show.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(rootKeyBip39)
|
||||
}
|
||||
|
||||
func TestShowRootKeyBIP39WithPassphre(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Derive the root key from the BIP39 seed.
|
||||
show := &showRootKeyCommand{
|
||||
rootKey: &rootKey{BIP39: true},
|
||||
}
|
||||
|
||||
err := os.Setenv(btc.BIP39MnemonicEnvName, seedBip39)
|
||||
require.NoError(t, err)
|
||||
err = os.Setenv(btc.BIP39PassphraseEnvName, testPassPhrase)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = show.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(rootKeyBip39Passphrase)
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
walletContent = "03b99ab108e39e9e4cf565c1b706480180a70a4fdc4828e44c50" +
|
||||
"4530c056be5b5f"
|
||||
)
|
||||
|
||||
func TestWalletInfo(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
// Dump the wallet information.
|
||||
info := &walletInfoCommand{
|
||||
WalletDB: h.testdataFile("wallet.db"),
|
||||
WithRootKey: true,
|
||||
}
|
||||
|
||||
err := os.Setenv(passwordEnvName, testPassPhrase)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = info.Execute(nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
h.assertLogContains(walletContent)
|
||||
h.assertLogContains(rootKeyAezeed)
|
||||
}
|
Loading…
Reference in New Issue