mining: Improve tests for prio queue. (#667)

This improves the tests of the priority queue to include the secondary
sort ordering as well as adds some manual entries to ensure the edge
conditions are properly tested.

This also brings the priority queue test coverage up to 100%.
This commit is contained in:
Dave Collins 2016-04-14 00:19:23 -05:00
parent 432ad76952
commit e15d3008cf

View File

@ -15,51 +15,96 @@ import (
// TestTxFeePrioHeap ensures the priority queue for transaction fees and // TestTxFeePrioHeap ensures the priority queue for transaction fees and
// priorities works as expected. // priorities works as expected.
func TestTxFeePrioHeap(t *testing.T) { func TestTxFeePrioHeap(t *testing.T) {
// Create priority items with random fees and priorites. // Create some fake priority items that exercise the expected sort
const numItems = 1000 // edge conditions.
prioItems := make([]*txPrioItem, numItems) testItems := []*txPrioItem{
highestFeePerKB := int64(0) {feePerKB: 5678, priority: 3},
highestPrio := float64(0) {feePerKB: 5678, priority: 1},
{feePerKB: 5678, priority: 1}, // Duplicate fee and prio
{feePerKB: 5678, priority: 5},
{feePerKB: 5678, priority: 2},
{feePerKB: 1234, priority: 3},
{feePerKB: 1234, priority: 1},
{feePerKB: 1234, priority: 5},
{feePerKB: 1234, priority: 5}, // Duplicate fee and prio
{feePerKB: 1234, priority: 2},
{feePerKB: 10000, priority: 0}, // Higher fee, smaller prio
{feePerKB: 0, priority: 10000}, // Higher prio, lower fee
}
// Add random data in addition to the edge conditions already manually
// specified.
randSeed := rand.Int63()
defer func() {
if t.Failed() {
t.Logf("Random numbers using seed: %v", randSeed)
}
}()
prng := rand.New(rand.NewSource(randSeed))
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
randPrio := rand.Float64() * 100 testItems = append(testItems, &txPrioItem{
if randPrio > highestPrio { feePerKB: int64(prng.Float64() * btcutil.SatoshiPerBitcoin),
highestPrio = randPrio priority: prng.Float64() * 100,
} })
randFeePerKB := int64(rand.Float64() * btcutil.SatoshiPerBitcoin)
if randFeePerKB > highestFeePerKB {
highestFeePerKB = randFeePerKB
}
prioItems[i] = &txPrioItem{
tx: nil,
priority: randPrio,
feePerKB: randFeePerKB,
}
} }
// Test sorting by fee per KB. // Test sorting by fee per KB then priority.
priorityQueue := newTxPriorityQueue(numItems, true) var highest *txPrioItem
for i := 0; i < numItems; i++ { priorityQueue := newTxPriorityQueue(len(testItems), true)
heap.Push(priorityQueue, prioItems[i]) for i := 0; i < len(testItems); i++ {
} prioItem := testItems[i]
for i := 0; i < numItems; i++ { if highest == nil {
prioItem := heap.Pop(priorityQueue).(*txPrioItem) highest = prioItem
if prioItem.feePerKB > highestFeePerKB {
t.Fatalf("bad pop: %v fee per KB was more than last of %v",
prioItem.feePerKB, highestFeePerKB)
} }
highestFeePerKB = prioItem.feePerKB if prioItem.feePerKB >= highest.feePerKB &&
prioItem.priority > highest.priority {
highest = prioItem
}
heap.Push(priorityQueue, prioItem)
} }
// Test sorting by priority. for i := 0; i < len(testItems); i++ {
priorityQueue = newTxPriorityQueue(numItems, false)
for i := 0; i < numItems; i++ {
heap.Push(priorityQueue, prioItems[i])
}
for i := 0; i < numItems; i++ {
prioItem := heap.Pop(priorityQueue).(*txPrioItem) prioItem := heap.Pop(priorityQueue).(*txPrioItem)
if prioItem.priority > highestPrio { if prioItem.feePerKB >= highest.feePerKB &&
t.Fatalf("bad pop: %v priority was more than last of %v", prioItem.priority > highest.priority {
prioItem.priority, highestPrio)
t.Fatalf("fee sort: item (fee per KB: %v, "+
"priority: %v) higher than than prev "+
"(fee per KB: %v, priority %v)",
prioItem.feePerKB, prioItem.priority,
highest.feePerKB, highest.priority)
} }
highest = prioItem
}
// Test sorting by priority then fee per KB.
highest = nil
priorityQueue = newTxPriorityQueue(len(testItems), false)
for i := 0; i < len(testItems); i++ {
prioItem := testItems[i]
if highest == nil {
highest = prioItem
}
if prioItem.priority >= highest.priority &&
prioItem.feePerKB > highest.feePerKB {
highest = prioItem
}
heap.Push(priorityQueue, prioItem)
}
for i := 0; i < len(testItems); i++ {
prioItem := heap.Pop(priorityQueue).(*txPrioItem)
if prioItem.priority >= highest.priority &&
prioItem.feePerKB > highest.feePerKB {
t.Fatalf("priority sort: item (fee per KB: %v, "+
"priority: %v) higher than than prev "+
"(fee per KB: %v, priority %v)",
prioItem.feePerKB, prioItem.priority,
highest.feePerKB, highest.priority)
}
highest = prioItem
} }
} }