2017-03-19 22:06:08 +01:00
|
|
|
package routing
|
|
|
|
|
|
|
|
import (
|
|
|
|
"container/heap"
|
|
|
|
prand "math/rand"
|
|
|
|
"reflect"
|
|
|
|
"sort"
|
|
|
|
"testing"
|
2019-06-19 04:26:09 +02:00
|
|
|
|
|
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
2017-03-19 22:06:08 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// TestHeapOrdering ensures that the items inserted into the heap are properly
|
|
|
|
// retrieved in minimum order of distance.
|
|
|
|
func TestHeapOrdering(t *testing.T) {
|
2017-06-17 00:59:20 +02:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-03-19 22:06:08 +01:00
|
|
|
// First, create a blank heap, we'll use this to push on randomly
|
|
|
|
// generated items.
|
2019-08-23 17:27:02 +02:00
|
|
|
nodeHeap := newDistanceHeap(0)
|
2017-03-19 22:06:08 +01:00
|
|
|
|
2019-06-19 04:26:09 +02:00
|
|
|
prand.Seed(1)
|
2017-03-19 22:06:08 +01:00
|
|
|
|
|
|
|
// Create 100 random entries adding them to the heap created above, but
|
|
|
|
// also a list that we'll sort with the entries.
|
|
|
|
const numEntries = 100
|
2019-08-25 03:52:13 +02:00
|
|
|
sortedEntries := make([]*nodeWithDist, 0, numEntries)
|
2017-03-19 22:06:08 +01:00
|
|
|
for i := 0; i < numEntries; i++ {
|
2019-06-19 04:26:09 +02:00
|
|
|
var pubKey [33]byte
|
|
|
|
prand.Read(pubKey[:])
|
|
|
|
|
2019-08-25 03:52:13 +02:00
|
|
|
entry := &nodeWithDist{
|
2019-06-19 04:26:09 +02:00
|
|
|
node: route.Vertex(pubKey),
|
2018-02-13 01:44:35 +01:00
|
|
|
dist: prand.Int63(),
|
2017-03-19 22:06:08 +01:00
|
|
|
}
|
|
|
|
|
2019-06-19 04:26:09 +02:00
|
|
|
// Use the PushOrFix method for the initial push to test the scenario
|
|
|
|
// where entry doesn't exist on the heap.
|
|
|
|
nodeHeap.PushOrFix(entry)
|
|
|
|
|
|
|
|
// Re-generate this entry's dist field
|
|
|
|
entry.dist = prand.Int63()
|
|
|
|
|
|
|
|
// Reorder the heap with a PushOrFix call.
|
|
|
|
nodeHeap.PushOrFix(entry)
|
|
|
|
|
2017-03-19 22:06:08 +01:00
|
|
|
sortedEntries = append(sortedEntries, entry)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort the regular slice, we'll compare this against all the entries
|
|
|
|
// popped from the heap.
|
2017-09-04 19:48:09 +02:00
|
|
|
sort.Slice(sortedEntries, func(i, j int) bool {
|
|
|
|
return sortedEntries[i].dist < sortedEntries[j].dist
|
|
|
|
})
|
2017-03-19 22:06:08 +01:00
|
|
|
|
|
|
|
// One by one, pop of all the entries from the heap, they should come
|
|
|
|
// out in sorted order.
|
2019-08-25 03:52:13 +02:00
|
|
|
var poppedEntries []*nodeWithDist
|
2017-03-19 22:06:08 +01:00
|
|
|
for nodeHeap.Len() != 0 {
|
2019-08-25 03:52:13 +02:00
|
|
|
e := heap.Pop(&nodeHeap).(*nodeWithDist)
|
2017-03-19 22:06:08 +01:00
|
|
|
poppedEntries = append(poppedEntries, e)
|
|
|
|
}
|
|
|
|
|
2019-06-19 04:26:09 +02:00
|
|
|
// Assert that the pubkeyIndices map is empty after popping all of the
|
|
|
|
// items off of it.
|
|
|
|
if len(nodeHeap.pubkeyIndices) != 0 {
|
|
|
|
t.Fatalf("there are still %d pubkeys in the pubkeyIndices map",
|
|
|
|
len(nodeHeap.pubkeyIndices))
|
|
|
|
}
|
|
|
|
|
2017-03-19 22:06:08 +01:00
|
|
|
// Finally, ensure that the items popped from the heap and the items we
|
|
|
|
// sorted are identical at this rate.
|
|
|
|
if !reflect.DeepEqual(poppedEntries, sortedEntries) {
|
|
|
|
t.Fatalf("items don't match: expected %v, got %v", sortedEntries,
|
|
|
|
poppedEntries)
|
|
|
|
}
|
|
|
|
}
|