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