lnd.xprv/channeldb/reports_test.go
Andras Banki-Horvath cbce8e8872
channeldb: move makeTestDB out of test to make it available for other tests
This commit moves makeTestDB to db.go and exports it so that we'll be
able to use this function in other unit tests to make them testable with
etcd if needed.
2020-07-28 17:57:29 +02:00

219 lines
5.0 KiB
Go

package channeldb
import (
"bytes"
"testing"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb/kvdb"
"github.com/stretchr/testify/require"
)
var (
testChainHash = [chainhash.HashSize]byte{
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
0x2d, 0xe7, 0x93, 0xe4,
}
testChanPoint1 = wire.OutPoint{
Hash: chainhash.Hash{
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
0x2d, 0xe7, 0x93, 0xe4,
},
Index: 1,
}
)
// TestPersistReport tests the writing and retrieval of a report on disk with
// and without a spend txid.
func TestPersistReport(t *testing.T) {
tests := []struct {
name string
spendTxID *chainhash.Hash
}{
{
name: "Non-nil spend txid",
spendTxID: &testChanPoint1.Hash,
},
{
name: "Nil spend txid",
spendTxID: nil,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
db, cleanup, err := MakeTestDB()
require.NoError(t, err)
defer cleanup()
channelOutpoint := testChanPoint1
testOutpoint := testChanPoint1
testOutpoint.Index++
report := &ResolverReport{
OutPoint: testOutpoint,
Amount: 2,
ResolverType: 1,
ResolverOutcome: 2,
SpendTxID: test.spendTxID,
}
// Write report to disk, and ensure it is identical when
// it is read.
err = db.PutResolverReport(
nil, testChainHash, &channelOutpoint, report,
)
require.NoError(t, err)
reports, err := db.FetchChannelReports(
testChainHash, &channelOutpoint,
)
require.NoError(t, err)
require.Equal(t, report, reports[0])
})
}
}
// TestFetchChannelReadBucket tests retrieval of the reports bucket for a
// channel, testing that the appropriate error is returned based on the state
// of the existing bucket.
func TestFetchChannelReadBucket(t *testing.T) {
db, cleanup, err := MakeTestDB()
require.NoError(t, err)
defer cleanup()
channelOutpoint := testChanPoint1
testOutpoint := testChanPoint1
testOutpoint.Index++
// If we attempt to get reports when we do not have any present, we
// expect to fail because our chain hash bucket is not present.
_, err = db.FetchChannelReports(
testChainHash, &channelOutpoint,
)
require.Equal(t, ErrNoChainHashBucket, err)
// Finally we write a report to disk and check that we can fetch it.
report := &ResolverReport{
OutPoint: testOutpoint,
Amount: 2,
ResolverOutcome: 1,
ResolverType: 2,
SpendTxID: nil,
}
err = db.PutResolverReport(
nil, testChainHash, &channelOutpoint, report,
)
require.NoError(t, err)
// Now that the channel bucket exists, we expect the channel to be
// successfully fetched, with no reports.
reports, err := db.FetchChannelReports(testChainHash, &testChanPoint1)
require.NoError(t, err)
require.Equal(t, report, reports[0])
}
// TestFetchChannelWriteBucket tests the creation of missing buckets when
// retrieving the reports bucket.
func TestFetchChannelWriteBucket(t *testing.T) {
createReportsBucket := func(tx kvdb.RwTx) (kvdb.RwBucket, error) {
return tx.CreateTopLevelBucket(closedChannelBucket)
}
createChainHashBucket := func(reports kvdb.RwBucket) (kvdb.RwBucket,
error) {
return reports.CreateBucketIfNotExists(testChainHash[:])
}
createChannelBucket := func(chainHash kvdb.RwBucket) (kvdb.RwBucket,
error) {
var chanPointBuf bytes.Buffer
err := writeOutpoint(&chanPointBuf, &testChanPoint1)
require.NoError(t, err)
return chainHash.CreateBucketIfNotExists(chanPointBuf.Bytes())
}
tests := []struct {
name string
setup func(tx kvdb.RwTx) error
}{
{
name: "no existing buckets",
setup: func(tx kvdb.RwTx) error {
return nil
},
},
{
name: "reports bucket exists",
setup: func(tx kvdb.RwTx) error {
_, err := createReportsBucket(tx)
return err
},
},
{
name: "chainhash bucket exists",
setup: func(tx kvdb.RwTx) error {
reports, err := createReportsBucket(tx)
if err != nil {
return err
}
_, err = createChainHashBucket(reports)
return err
},
},
{
name: "channel bucket exists",
setup: func(tx kvdb.RwTx) error {
reports, err := createReportsBucket(tx)
if err != nil {
return err
}
chainHash, err := createChainHashBucket(reports)
if err != nil {
return err
}
_, err = createChannelBucket(chainHash)
return err
},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
db, cleanup, err := MakeTestDB()
require.NoError(t, err)
defer cleanup()
// Update our db to the starting state we expect.
err = kvdb.Update(db, test.setup)
require.NoError(t, err)
// Try to get our report bucket.
err = kvdb.Update(db, func(tx kvdb.RwTx) error {
_, err := fetchReportWriteBucket(
tx, testChainHash, &testChanPoint1,
)
return err
})
require.NoError(t, err)
})
}
}