github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/cache/rcvcache_test.go (about) 1 package netcache_test 2 3 import ( 4 "fmt" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/onflow/flow-go/network/message" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 "github.com/stretchr/testify/suite" 14 15 "github.com/onflow/flow-go/network/channels" 16 17 "github.com/onflow/crypto/hash" 18 19 "github.com/onflow/flow-go/module/metrics" 20 netcache "github.com/onflow/flow-go/network/cache" 21 "github.com/onflow/flow-go/utils/unittest" 22 ) 23 24 type ReceiveCacheTestSuite struct { 25 suite.Suite 26 c *netcache.ReceiveCache 27 size int 28 } 29 30 func TestReceiveCacheTestSuite(t *testing.T) { 31 suite.Run(t, new(ReceiveCacheTestSuite)) 32 } 33 34 // SetupTest creates a new cache 35 func (r *ReceiveCacheTestSuite) SetupTest() { 36 const size = 10 37 38 c := netcache.NewHeroReceiveCache(size, unittest.Logger(), metrics.NewNoopCollector()) 39 40 r.c = c 41 r.size = size 42 } 43 44 // TestSingleElementAdd adds a single element to the cache and verifies its existence. 45 func (r *ReceiveCacheTestSuite) TestSingleElementAdd() { 46 eventID, err := message.EventId(channels.Channel("0"), []byte("event-1")) 47 require.NoError(r.T(), err) 48 49 assert.True(r.Suite.T(), r.c.Add(eventID)) 50 assert.False(r.Suite.T(), r.c.Add(eventID)) 51 52 // same channel but different event should be treated as unseen 53 eventID2, err := message.EventId(channels.Channel("0"), []byte("event-2")) 54 require.NoError(r.T(), err) 55 assert.True(r.Suite.T(), r.c.Add(eventID2)) 56 assert.False(r.Suite.T(), r.c.Add(eventID2)) 57 58 // same event but different channels should be treated as unseen 59 eventID3, err := message.EventId(channels.Channel("1"), []byte("event-2")) 60 require.NoError(r.T(), err) 61 assert.True(r.Suite.T(), r.c.Add(eventID3)) 62 assert.False(r.Suite.T(), r.c.Add(eventID3)) 63 } 64 65 // TestNoneExistence evaluates the correctness of cache operation against non-existing element 66 func (r *ReceiveCacheTestSuite) TestNoneExistence() { 67 eventID, err := message.EventId(channels.Channel("1"), []byte("non-existing event")) 68 require.NoError(r.T(), err) 69 70 // adding new event to cache should return true 71 assert.True(r.Suite.T(), r.c.Add(eventID)) 72 } 73 74 // TestMultipleElementAdd adds several eventIDs to th cache and evaluates their existence 75 func (r *ReceiveCacheTestSuite) TestMultipleElementAdd() { 76 // creates and populates slice of 10 events 77 eventIDs := make([]hash.Hash, 0) 78 for i := 0; i < r.size; i++ { 79 eventID, err := message.EventId(channels.Channel("1"), []byte(fmt.Sprintf("event-%d", i))) 80 require.NoError(r.T(), err) 81 82 eventIDs = append(eventIDs, eventID) 83 } 84 85 // adding non-existing even id must return true 86 wg := sync.WaitGroup{} 87 wg.Add(r.size) 88 for i := 0; i < r.size; i++ { 89 go func(i int) { 90 assert.True(r.Suite.T(), r.c.Add(eventIDs[i])) 91 92 wg.Done() 93 }(i) 94 95 } 96 97 unittest.RequireReturnsBefore(r.T(), wg.Wait, 100*time.Millisecond, "cannot add events to cache on time") 98 99 // adding duplicate event id must return false. 100 wg.Add(r.size) 101 for i := 0; i < r.size; i++ { 102 go func(i int) { 103 assert.False(r.Suite.T(), r.c.Add(eventIDs[i])) 104 105 wg.Done() 106 }(i) 107 } 108 109 unittest.RequireReturnsBefore(r.T(), wg.Wait, 100*time.Millisecond, "cannot add duplicate events to cache on time") 110 } 111 112 // TestLRU makes sure that received cache is configured in LRU mode. 113 func (r *ReceiveCacheTestSuite) TestLRU() { 114 eventIDs := make([]hash.Hash, 0) 115 total := r.size + 1 116 for i := 0; i < total; i++ { 117 eventID, err := message.EventId(channels.Channel("1"), []byte(fmt.Sprintf("event-%d", i))) 118 require.NoError(r.T(), err) 119 120 eventIDs = append(eventIDs, eventID) 121 } 122 123 // adding non-existing even id must return true 124 for i := 0; i < total; i++ { 125 assert.True(r.Suite.T(), r.c.Add(eventIDs[i])) 126 } 127 128 // when adding 11th element, cache goes beyond its size, 129 // and 1st element (i.e., index 0) is ejected. 130 // Now when trying to add 1st element again, it seems 131 // new to cache and replaces 2nd element (at index 1) with it. 132 require.True(r.T(), r.c.Add(eventIDs[0])) 133 134 }