Skip to content

Commit

Permalink
mempool: Refactor pool membership test logic.
Browse files Browse the repository at this point in the history
This introduces a new pool membership test function to the mempool
testing infrastructure and refactors the tests to make use of it.

It is useful since it is common logic that is not only needed in the
existing tests, but will be needed by most mempool-related tests.
  • Loading branch information
dnldd committed May 4, 2018
2 parents 0921280 + 6035525 commit afcf031
Showing 1 changed file with 55 additions and 58 deletions.
113 changes: 55 additions & 58 deletions mempool/mempool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"encoding/hex"
"fmt"
"reflect"
"runtime"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -428,6 +429,43 @@ func newPoolHarness(chainParams *chaincfg.Params) (*poolHarness, []spendableOutp
return &harness, outputs, nil
}

// testContext houses a test-related state that is useful to pass to helper
// functions as a single argument.
type testContext struct {
t *testing.T
harness *poolHarness
}

// testPoolMembership tests the transaction pool associated with the provided
// test context to determine if the passed transaction matches the provided
// orphan pool and transaction pool status. It also further determines if it
// should be reported as available by the HaveTransaction function based upon
// the two flags and tests that condition as well.
func testPoolMembership(tc *testContext, tx *dcrutil.Tx, inOrphanPool, inTxPool bool) {
txHash := tx.Hash()
gotOrphanPool := tc.harness.txPool.IsOrphanInPool(txHash)
if inOrphanPool != gotOrphanPool {
_, file, line, _ := runtime.Caller(1)
tc.t.Fatalf("%s:%d -- IsOrphanInPool: want %v, got %v", file,
line, inOrphanPool, gotOrphanPool)
}

gotTxPool := tc.harness.txPool.IsTransactionInPool(txHash)
if inTxPool != gotTxPool {
_, file, line, _ := runtime.Caller(1)
tc.t.Fatalf("%s:%d -- IsTransactionInPool: want %v, got %v",
file, line, inTxPool, gotTxPool)
}

gotHaveTx := tc.harness.txPool.HaveTransaction(txHash)
wantHaveTx := inOrphanPool || inTxPool
if wantHaveTx != gotHaveTx {
_, file, line, _ := runtime.Caller(1)
tc.t.Fatalf("%s:%d -- HaveTransaction: want %v, got %v", file,
line, wantHaveTx, gotHaveTx)
}
}

// TestSimpleOrphanChain ensures that a simple chain of orphans is handled
// properly. In particular, it generates a chain of single input, single output
// transactions and inserts them while skipping the first linking transaction so
Expand All @@ -440,6 +478,7 @@ func TestSimpleOrphanChain(t *testing.T) {
if err != nil {
t.Fatalf("unable to create test pool: %v", err)
}
tc := &testContext{t, harness}

// Create a chain of transactions rooted with the first spendable output
// provided by the harness.
Expand All @@ -466,20 +505,9 @@ func TestSimpleOrphanChain(t *testing.T) {
len(acceptedTxns))
}

// Ensure the transaction is in the orphan pool.
if !harness.txPool.IsOrphanInPool(tx.Hash()) {
t.Fatal("IsOrphanInPool: false for accepted orphan")
}

// Ensure the transaction is not in the transaction pool.
if harness.txPool.IsTransactionInPool(tx.Hash()) {
t.Fatal("IsTransactionInPool: true for accepted orphan")
}

// Ensure the transaction is reported as available.
if !harness.txPool.HaveTransaction(tx.Hash()) {
t.Fatal("HaveTransaction: false for accepted orphan")
}
// Ensure the transaction is in the orphan pool, is not in the
// transaction pool, and is reported as available.
testPoolMembership(tc, tx, true, false)
}

// Add the transaction which completes the orphan chain and ensure they
Expand All @@ -498,18 +526,9 @@ func TestSimpleOrphanChain(t *testing.T) {
len(acceptedTxns), len(chainedTxns))
}
for _, tx := range acceptedTxns {
// Ensure none of the transactions are still in the orphan pool.
if harness.txPool.IsOrphanInPool(tx.Hash()) {
t.Fatalf("IsOrphanInPool: true for accepted tx %v",
tx.Hash())
}

// Ensure all of the transactions are now in the transaction
// pool.
if !harness.txPool.IsTransactionInPool(tx.Hash()) {
t.Fatalf("IsTransactionInPool: false for accepted tx %v",
tx.Hash())
}
// Ensure the transaction is no longer in the orphan pool, is
// now in the transaction pool, and is reported as available.
testPoolMembership(tc, tx, false, true)
}
}

Expand All @@ -522,6 +541,7 @@ func TestOrphanReject(t *testing.T) {
if err != nil {
t.Fatalf("unable to create test pool: %v", err)
}
tc := &testContext{t, harness}

// Create a chain of transactions rooted with the first spendable output
// provided by the harness.
Expand Down Expand Up @@ -561,20 +581,9 @@ func TestOrphanReject(t *testing.T) {
len(acceptedTxns))
}

// Ensure the transaction is not in the orphan pool.
if harness.txPool.IsOrphanInPool(tx.Hash()) {
t.Fatal("IsOrphanInPool: true for rejected orphan")
}

// Ensure the transaction is not in the transaction pool.
if harness.txPool.IsTransactionInPool(tx.Hash()) {
t.Fatal("IsTransactionInPool: true for rejected orphan")
}

// Ensure the transaction is not reported as available.
if harness.txPool.HaveTransaction(tx.Hash()) {
t.Fatal("HaveTransaction: true for rejected orphan")
}
// Ensure the transaction is not in the orphan pool, not in the
// transaction pool, and not reported as available
testPoolMembership(tc, tx, false, false)
}
}

Expand All @@ -587,6 +596,7 @@ func TestOrphanEviction(t *testing.T) {
if err != nil {
t.Fatalf("unable to create test pool: %v", err)
}
tc := &testContext{t, harness}

// Create a chain of transactions rooted with the first spendable output
// provided by the harness that is long enough to be able to force
Expand Down Expand Up @@ -614,20 +624,9 @@ func TestOrphanEviction(t *testing.T) {
len(acceptedTxns))
}

// Ensure the transaction is in the orphan pool.
if !harness.txPool.IsOrphanInPool(tx.Hash()) {
t.Fatal("IsOrphanInPool: false for accepted orphan")
}

// Ensure the transaction is not in the transaction pool.
if harness.txPool.IsTransactionInPool(tx.Hash()) {
t.Fatal("IsTransactionInPool: true for accepted orphan")
}

// Ensure the transaction is reported as available.
if !harness.txPool.HaveTransaction(tx.Hash()) {
t.Fatal("HaveTransaction: false for accepted orphan")
}
// Ensure the transaction is in the orphan pool, is not in the
// transaction pool, and is reported as available.
testPoolMembership(tc, tx, true, false)
}

// Figure out which transactions were evicted and make sure the number
Expand All @@ -644,11 +643,9 @@ func TestOrphanEviction(t *testing.T) {
len(evictedTxns), expectedEvictions)
}

// Ensure none of the evicted transactioned ended up the transaction
// Ensure none of the evicted transactions ended up in the transaction
// pool.
for _, tx := range evictedTxns {
if harness.txPool.IsTransactionInPool(tx.Hash()) {
t.Fatalf("IsTransactionInPool: true for evicted orphan")
}
testPoolMembership(tc, tx, false, false)
}
}

0 comments on commit afcf031

Please sign in to comment.