github.com/koko1123/flow-go-1@v0.29.6/module/buffer/backend_test.go (about) 1 package buffer 2 3 import ( 4 "math/rand" 5 "testing" 6 7 "github.com/stretchr/testify/suite" 8 9 "github.com/koko1123/flow-go-1/model/flow" 10 "github.com/koko1123/flow-go-1/utils/unittest" 11 ) 12 13 type BackendSuite struct { 14 suite.Suite 15 backend *backend 16 } 17 18 func TestBackendSuite(t *testing.T) { 19 suite.Run(t, new(BackendSuite)) 20 } 21 22 func (suite *BackendSuite) SetupTest() { 23 suite.backend = newBackend() 24 } 25 26 func (suite *BackendSuite) Item() *item { 27 parent := unittest.BlockHeaderFixture() 28 return suite.ItemWithParent(parent) 29 } 30 31 func (suite *BackendSuite) ItemWithParent(parent *flow.Header) *item { 32 header := unittest.BlockHeaderWithParentFixture(parent) 33 return &item{ 34 header: header, 35 payload: unittest.IdentifierFixture(), 36 originID: unittest.IdentifierFixture(), 37 } 38 } 39 40 func (suite *BackendSuite) Add(item *item) { 41 suite.backend.add(item.originID, item.header, item.payload) 42 } 43 44 func (suite *BackendSuite) TestAdd() { 45 expected := suite.Item() 46 suite.backend.add(expected.originID, expected.header, expected.payload) 47 48 actual, ok := suite.backend.byID(expected.header.ID()) 49 suite.Assert().True(ok) 50 suite.Assert().Equal(expected, actual) 51 52 byParent, ok := suite.backend.byParentID(expected.header.ParentID) 53 suite.Assert().True(ok) 54 suite.Assert().Len(byParent, 1) 55 suite.Assert().Equal(expected, byParent[0]) 56 } 57 58 func (suite *BackendSuite) TestChildIndexing() { 59 60 parent := suite.Item() 61 child1 := suite.ItemWithParent(parent.header) 62 child2 := suite.ItemWithParent(parent.header) 63 grandchild := suite.ItemWithParent(child1.header) 64 unrelated := suite.Item() 65 66 suite.Add(child1) 67 suite.Add(child2) 68 suite.Add(grandchild) 69 suite.Add(unrelated) 70 71 suite.Run("retrieve by parent ID", func() { 72 byParent, ok := suite.backend.byParentID(parent.header.ID()) 73 suite.Assert().True(ok) 74 // should only include direct children 75 suite.Assert().Len(byParent, 2) 76 suite.Assert().Contains(byParent, child1) 77 suite.Assert().Contains(byParent, child2) 78 }) 79 80 suite.Run("drop for parent ID", func() { 81 suite.backend.dropForParent(parent.header.ID()) 82 83 // should only drop direct children 84 _, exists := suite.backend.byID(child1.header.ID()) 85 suite.Assert().False(exists) 86 _, exists = suite.backend.byID(child2.header.ID()) 87 suite.Assert().False(exists) 88 89 // grandchildren should be unaffected 90 _, exists = suite.backend.byParentID(child1.header.ID()) 91 suite.Assert().True(exists) 92 _, exists = suite.backend.byID(grandchild.header.ID()) 93 suite.Assert().True(exists) 94 95 // nothing else should be affected 96 _, exists = suite.backend.byID(unrelated.header.ID()) 97 suite.Assert().True(exists) 98 }) 99 } 100 101 func (suite *BackendSuite) TestPruneByView() { 102 103 const N = 100 // number of items we're testing with 104 items := make([]*item, 0, N) 105 106 // build a pending buffer 107 for i := 0; i < N; i++ { 108 109 // 10% of the time, add a new unrelated pending block 110 if i%10 == 0 { 111 item := suite.Item() 112 suite.Add(item) 113 items = append(items, item) 114 continue 115 } 116 117 // 90% of the time, build on an existing block 118 if i%2 == 1 { 119 parent := items[rand.Intn(len(items))] 120 item := suite.ItemWithParent(parent.header) 121 suite.Add(item) 122 items = append(items, item) 123 } 124 } 125 126 // pick a height to prune that's guaranteed to prune at least one item 127 pruneAt := items[rand.Intn(len(items))].header.View 128 suite.backend.pruneByView(pruneAt) 129 130 for _, item := range items { 131 view := item.header.View 132 id := item.header.ID() 133 parentID := item.header.ParentID 134 135 // check that items below the prune view were removed 136 if view <= pruneAt { 137 _, exists := suite.backend.byID(id) 138 suite.Assert().False(exists) 139 _, exists = suite.backend.byParentID(parentID) 140 suite.Assert().False(exists) 141 } 142 143 // check that other items were not removed 144 if view > item.header.View { 145 _, exists := suite.backend.byID(id) 146 suite.Assert().True(exists) 147 _, exists = suite.backend.byParentID(parentID) 148 suite.Assert().True(exists) 149 } 150 } 151 }