From 60355258a79e9acfef7bb8436e7673f105c826f2 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 24 Oct 2016 17:25:37 -0500 Subject: [PATCH] mempool: Refactor pool membership test logic. 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. --- mempool/mempool_test.go | 113 +++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 58 deletions(-) diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 4b8f577a..ec83b250 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -7,6 +7,7 @@ package mempool import ( "encoding/hex" "reflect" + "runtime" "sync" "testing" "time" @@ -331,6 +332,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 *btcutil.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 @@ -343,6 +381,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. @@ -369,20 +408,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 @@ -401,18 +429,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) } } @@ -425,6 +444,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. @@ -464,20 +484,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) } } @@ -490,6 +499,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 @@ -517,20 +527,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 @@ -547,11 +546,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) } }