github.com/koko1123/flow-go-1@v0.29.6/module/mempool/herocache/transactions_test.go (about)

     1  package herocache_test
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/koko1123/flow-go-1/model/flow"
    12  	"github.com/koko1123/flow-go-1/module/mempool/herocache"
    13  	"github.com/koko1123/flow-go-1/module/metrics"
    14  	"github.com/koko1123/flow-go-1/utils/unittest"
    15  )
    16  
    17  func TestTransactionPool(t *testing.T) {
    18  	tx1 := unittest.TransactionBodyFixture()
    19  	tx2 := unittest.TransactionBodyFixture()
    20  
    21  	transactions := herocache.NewTransactions(1000, unittest.Logger(), metrics.NewNoopCollector())
    22  
    23  	t.Run("should be able to add first", func(t *testing.T) {
    24  		added := transactions.Add(&tx1)
    25  		assert.True(t, added)
    26  	})
    27  
    28  	t.Run("should be able to add second", func(t *testing.T) {
    29  		added := transactions.Add(&tx2)
    30  		assert.True(t, added)
    31  	})
    32  
    33  	t.Run("should be able to get size", func(t *testing.T) {
    34  		size := transactions.Size()
    35  		assert.EqualValues(t, 2, size)
    36  	})
    37  
    38  	t.Run("should be able to get first", func(t *testing.T) {
    39  		actual, exists := transactions.ByID(tx1.ID())
    40  		assert.True(t, exists)
    41  		assert.Equal(t, &tx1, actual)
    42  	})
    43  
    44  	t.Run("should be able to remove second", func(t *testing.T) {
    45  		ok := transactions.Remove(tx2.ID())
    46  		assert.True(t, ok)
    47  	})
    48  
    49  	t.Run("should be able to retrieve all", func(t *testing.T) {
    50  		items := transactions.All()
    51  		assert.Len(t, items, 1)
    52  		assert.Equal(t, &tx1, items[0])
    53  	})
    54  
    55  	t.Run("should be able to clear", func(t *testing.T) {
    56  		assert.True(t, transactions.Size() > 0)
    57  		transactions.Clear()
    58  		assert.Equal(t, uint(0), transactions.Size())
    59  	})
    60  }
    61  
    62  // TestConcurrentWriteAndRead checks correctness of transactions mempool under concurrent read and write.
    63  func TestConcurrentWriteAndRead(t *testing.T) {
    64  	total := 100
    65  	txs := unittest.TransactionBodyListFixture(total)
    66  	transactions := herocache.NewTransactions(uint32(total), unittest.Logger(), metrics.NewNoopCollector())
    67  
    68  	wg := sync.WaitGroup{}
    69  	wg.Add(total)
    70  
    71  	// storing all transactions
    72  	for i := 0; i < total; i++ {
    73  		go func(tx flow.TransactionBody) {
    74  			require.True(t, transactions.Add(&tx))
    75  
    76  			wg.Done()
    77  		}(txs[i])
    78  	}
    79  
    80  	unittest.RequireReturnsBefore(t, wg.Wait, 100*time.Millisecond, "could not write all transactions on time")
    81  	require.Equal(t, transactions.Size(), uint(total))
    82  
    83  	wg.Add(total)
    84  	// reading all transactions
    85  	for i := 0; i < total; i++ {
    86  		go func(tx flow.TransactionBody) {
    87  			actual, ok := transactions.ByID(tx.ID())
    88  			require.True(t, ok)
    89  			require.Equal(t, tx, *actual)
    90  
    91  			wg.Done()
    92  		}(txs[i])
    93  	}
    94  	unittest.RequireReturnsBefore(t, wg.Wait, 100*time.Millisecond, "could not read all transactions on time")
    95  }
    96  
    97  // TestAllReturnsInOrder checks All method of the HeroCache-based transactions mempool returns all
    98  // transactions in the same order as they are returned.
    99  func TestAllReturnsInOrder(t *testing.T) {
   100  	total := 100
   101  	txs := unittest.TransactionBodyListFixture(total)
   102  	transactions := herocache.NewTransactions(uint32(total), unittest.Logger(), metrics.NewNoopCollector())
   103  
   104  	// storing all transactions
   105  	for i := 0; i < total; i++ {
   106  		require.True(t, transactions.Add(&txs[i]))
   107  		tx, ok := transactions.ByID(txs[i].ID())
   108  		require.True(t, ok)
   109  		require.Equal(t, txs[i], *tx)
   110  	}
   111  
   112  	// all transactions must be retrieved in the same order as they are added
   113  	all := transactions.All()
   114  	for i := 0; i < total; i++ {
   115  		require.Equal(t, txs[i], *all[i])
   116  	}
   117  }