141 lines
2.6 KiB
Go
141 lines
2.6 KiB
Go
|
package routing
|
||
|
|
||
|
import (
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||
|
|
||
|
"github.com/coreos/bbolt"
|
||
|
"github.com/lightningnetwork/lnd/routing/route"
|
||
|
)
|
||
|
|
||
|
const testMaxRecords = 2
|
||
|
|
||
|
func TestMissionControlStore(t *testing.T) {
|
||
|
// Set time zone explictly to keep test deterministic.
|
||
|
time.Local = time.UTC
|
||
|
|
||
|
file, err := ioutil.TempFile("", "*.db")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
dbPath := file.Name()
|
||
|
|
||
|
db, err := bbolt.Open(dbPath, 0600, nil)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer db.Close()
|
||
|
defer os.Remove(dbPath)
|
||
|
|
||
|
store, err := newMissionControlStore(db, testMaxRecords)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
results, err := store.fetchAll()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if len(results) != 0 {
|
||
|
t.Fatal("expected no results")
|
||
|
}
|
||
|
|
||
|
testRoute := route.Route{
|
||
|
SourcePubKey: route.Vertex{1},
|
||
|
Hops: []*route.Hop{
|
||
|
{
|
||
|
PubKeyBytes: route.Vertex{2},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
failureSourceIdx := 1
|
||
|
|
||
|
result1 := paymentResult{
|
||
|
route: &testRoute,
|
||
|
failure: lnwire.NewFailUnknownPaymentHash(100),
|
||
|
failureSourceIdx: &failureSourceIdx,
|
||
|
id: 99,
|
||
|
timeReply: testTime,
|
||
|
timeFwd: testTime.Add(-time.Minute),
|
||
|
}
|
||
|
|
||
|
result2 := result1
|
||
|
result2.timeReply = result1.timeReply.Add(time.Hour)
|
||
|
result2.timeFwd = result1.timeReply.Add(time.Hour)
|
||
|
result2.id = 2
|
||
|
|
||
|
// Store result.
|
||
|
err = store.AddResult(&result2)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Store again to test idempotency.
|
||
|
err = store.AddResult(&result2)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Store second result which has an earlier timestamp.
|
||
|
err = store.AddResult(&result1)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
results, err = store.fetchAll()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if len(results) != 2 {
|
||
|
t.Fatal("expected two results")
|
||
|
}
|
||
|
|
||
|
// Check that results are stored in chronological order.
|
||
|
if !reflect.DeepEqual(&result1, results[0]) {
|
||
|
t.Fatal()
|
||
|
}
|
||
|
if !reflect.DeepEqual(&result2, results[1]) {
|
||
|
t.Fatal()
|
||
|
}
|
||
|
|
||
|
// Recreate store to test pruning.
|
||
|
store, err = newMissionControlStore(db, testMaxRecords)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Add a newer result.
|
||
|
result3 := result1
|
||
|
result3.timeReply = result1.timeReply.Add(2 * time.Hour)
|
||
|
result3.timeFwd = result1.timeReply.Add(2 * time.Hour)
|
||
|
result3.id = 3
|
||
|
|
||
|
err = store.AddResult(&result3)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Check that results are pruned.
|
||
|
results, err = store.fetchAll()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if len(results) != 2 {
|
||
|
t.Fatal("expected two results")
|
||
|
}
|
||
|
|
||
|
if !reflect.DeepEqual(&result2, results[0]) {
|
||
|
t.Fatal()
|
||
|
}
|
||
|
if !reflect.DeepEqual(&result3, results[1]) {
|
||
|
t.Fatal()
|
||
|
}
|
||
|
}
|