github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/mempool/herocache/execution_data_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/onflow/flow-go/module/executiondatasync/execution_data"
    12  	"github.com/onflow/flow-go/module/mempool/herocache"
    13  	"github.com/onflow/flow-go/module/metrics"
    14  	"github.com/onflow/flow-go/utils/unittest"
    15  )
    16  
    17  func TestBlockExecutionDataPool(t *testing.T) {
    18  	ed1 := unittest.BlockExecutionDatEntityFixture()
    19  	ed2 := unittest.BlockExecutionDatEntityFixture()
    20  
    21  	cache := herocache.NewBlockExecutionData(1000, unittest.Logger(), metrics.NewNoopCollector())
    22  
    23  	t.Run("should be able to add first", func(t *testing.T) {
    24  		added := cache.Add(ed1)
    25  		assert.True(t, added)
    26  	})
    27  
    28  	t.Run("should be able to add second", func(t *testing.T) {
    29  		added := cache.Add(ed2)
    30  		assert.True(t, added)
    31  	})
    32  
    33  	t.Run("should be able to get size", func(t *testing.T) {
    34  		size := cache.Size()
    35  		assert.EqualValues(t, 2, size)
    36  	})
    37  
    38  	t.Run("should be able to get first by blockID", func(t *testing.T) {
    39  		actual, exists := cache.ByID(ed1.BlockID)
    40  		assert.True(t, exists)
    41  		assert.Equal(t, ed1, actual)
    42  	})
    43  
    44  	t.Run("should be able to remove second by blockID", func(t *testing.T) {
    45  		ok := cache.Remove(ed2.BlockID)
    46  		assert.True(t, ok)
    47  	})
    48  
    49  	t.Run("should be able to retrieve all", func(t *testing.T) {
    50  		items := cache.All()
    51  		assert.Len(t, items, 1)
    52  		assert.Equal(t, ed1, items[0])
    53  	})
    54  
    55  	t.Run("should be able to clear", func(t *testing.T) {
    56  		assert.True(t, cache.Size() > 0)
    57  		cache.Clear()
    58  		assert.Equal(t, uint(0), cache.Size())
    59  	})
    60  }
    61  
    62  // TestConcurrentWriteAndRead checks correctness of cache mempool under concurrent read and write.
    63  func TestBlockExecutionDataConcurrentWriteAndRead(t *testing.T) {
    64  	total := 100
    65  	execDatas := unittest.BlockExecutionDatEntityListFixture(total)
    66  	cache := herocache.NewBlockExecutionData(uint32(total), unittest.Logger(), metrics.NewNoopCollector())
    67  
    68  	wg := sync.WaitGroup{}
    69  	wg.Add(total)
    70  
    71  	// storing all cache
    72  	for i := 0; i < total; i++ {
    73  		go func(ed *execution_data.BlockExecutionDataEntity) {
    74  			require.True(t, cache.Add(ed))
    75  
    76  			wg.Done()
    77  		}(execDatas[i])
    78  	}
    79  
    80  	unittest.RequireReturnsBefore(t, wg.Wait, 100*time.Millisecond, "could not write all cache on time")
    81  	require.Equal(t, cache.Size(), uint(total))
    82  
    83  	wg.Add(total)
    84  	// reading all cache
    85  	for i := 0; i < total; i++ {
    86  		go func(ed *execution_data.BlockExecutionDataEntity) {
    87  			actual, ok := cache.ByID(ed.BlockID)
    88  			require.True(t, ok)
    89  			require.Equal(t, ed, actual)
    90  
    91  			wg.Done()
    92  		}(execDatas[i])
    93  	}
    94  	unittest.RequireReturnsBefore(t, wg.Wait, 100*time.Millisecond, "could not read all cache on time")
    95  }
    96  
    97  // TestAllReturnsInOrder checks All method of the HeroCache-based cache mempool returns all
    98  // cache in the same order as they are returned.
    99  func TestBlockExecutionDataAllReturnsInOrder(t *testing.T) {
   100  	total := 100
   101  	execDatas := unittest.BlockExecutionDatEntityListFixture(total)
   102  	cache := herocache.NewBlockExecutionData(uint32(total), unittest.Logger(), metrics.NewNoopCollector())
   103  
   104  	// storing all cache
   105  	for i := 0; i < total; i++ {
   106  		require.True(t, cache.Add(execDatas[i]))
   107  		ed, ok := cache.ByID(execDatas[i].BlockID)
   108  		require.True(t, ok)
   109  		require.Equal(t, execDatas[i], ed)
   110  	}
   111  
   112  	// all cache must be retrieved in the same order as they are added
   113  	all := cache.All()
   114  	for i := 0; i < total; i++ {
   115  		require.Equal(t, execDatas[i], all[i])
   116  	}
   117  }