Skip to content

Commit

Permalink
mining: Improve tests for prio queue. (btcsuite#667)
Browse files Browse the repository at this point in the history
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%.
  • Loading branch information
davecgh authored and cjepson committed Sep 21, 2016
1 parent e57e73f commit fffe22d
Showing 1 changed file with 74 additions and 41 deletions.
115 changes: 74 additions & 41 deletions mining_test.go
Expand Up @@ -11,56 +11,95 @@ import (
"testing"

"github.com/decred/dcrd/blockchain/stake"
"github.com/decred/dcrutil"
)

// TestTxFeePrioHeap ensures the priority queue for transaction fees and
// priorities works as expected.
// priorities works as expected. It doesn't set anything for the stake
// priority, so this test only tests sorting by fee and then priority.
func TestTxFeePrioHeap(t *testing.T) {
// Create priority items with random fees and priorites.
const numItems = 1000
prioItems := make([]*txPrioItem, numItems)
highestFeePerKB := float64(0)
highestPrio := float64(0)
for i := 0; i < 1000; i++ {
randPrio := rand.Float64() * 100
if randPrio > highestPrio {
highestPrio = randPrio
// Create some fake priority items that exercise the expected sort
// edge conditions.
testItems := []*txPrioItem{
{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
}
numItems := len(testItems)

// 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)
}
randFeePerKB := rand.Float64() * 1e8
if randFeePerKB > highestFeePerKB {
highestFeePerKB = randFeePerKB
}()
prng := rand.New(rand.NewSource(randSeed))
for i := 0; i < 1000; i++ {
testItems = append(testItems, &txPrioItem{
feePerKB: prng.Float64() * dcrutil.AtomsPerCoin,
priority: prng.Float64() * 100,
})
}

// Test sorting by fee per KB then priority.
var highest *txPrioItem
priorityQueue := newTxPriorityQueue(len(testItems),
txPQByStakeAndFeeAndThenPriority)
for i := 0; i < len(testItems); i++ {
prioItem := testItems[i]
if highest == nil {
highest = prioItem
}
prioItems[i] = &txPrioItem{
tx: nil,
priority: randPrio,
feePerKB: randFeePerKB,
if prioItem.feePerKB >= highest.feePerKB &&
prioItem.priority > highest.priority {
highest = prioItem
}
heap.Push(priorityQueue, prioItem)
}

// Test sorting by fee per KB.
priorityQueue := newTxPriorityQueue(numItems, txPQByFee)
for i := 0; i < numItems; i++ {
heap.Push(priorityQueue, prioItems[i])
}
for i := 0; i < numItems; i++ {
for i := 0; i < len(testItems); i++ {
prioItem := heap.Pop(priorityQueue).(*txPrioItem)
if prioItem.feePerKB > highestFeePerKB {
t.Fatalf("bad pop: %v fee per KB was more than last of %v",
prioItem.feePerKB, highestFeePerKB)
if prioItem.feePerKB >= highest.feePerKB &&
prioItem.priority > highest.priority {

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)
}
highestFeePerKB = prioItem.feePerKB
highest = prioItem
}

// Test sorting by priority.
priorityQueue = newTxPriorityQueue(numItems, txPQByPriority)
for i := 0; i < numItems; i++ {
heap.Push(priorityQueue, prioItems[i])
// Test sorting by priority then fee per KB.
priorityQueue = newTxPriorityQueue(numItems, txPQByStakeAndFeeAndThenPriority)
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 < numItems; i++ {

for i := 0; i < len(testItems); i++ {
prioItem := heap.Pop(priorityQueue).(*txPrioItem)
if prioItem.priority > highestPrio {
t.Fatalf("bad pop: %v priority was more than last of %v",
prioItem.priority, highestPrio)
if prioItem.priority >= highest.priority &&
prioItem.feePerKB > highest.feePerKB {

}
}
}
Expand Down Expand Up @@ -104,8 +143,6 @@ func TestStakeTxFeePrioHeap(t *testing.T) {
txpi.feePerKB, last.feePerKB, txpi.txType, last.txType)
}
last = txpi
} else {
t.Fatalf("casting failure")
}
}

Expand Down Expand Up @@ -141,8 +178,6 @@ func TestStakeTxFeePrioHeap(t *testing.T) {
txpi.feePerKB, last.feePerKB, txpi.txType, last.txType)
}
last = txpi
} else {
t.Fatalf("casting failure")
}
}

Expand Down Expand Up @@ -192,8 +227,6 @@ func TestStakeTxFeePrioHeap(t *testing.T) {
}
}
last = txpi
} else {
t.Fatalf("casting failure")
}
}
}

0 comments on commit fffe22d

Please sign in to comment.