github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/common/synchronization/engine_suite_test.go (about) 1 package synchronization 2 3 import ( 4 "io" 5 "testing" 6 7 "github.com/rs/zerolog" 8 "github.com/stretchr/testify/mock" 9 "github.com/stretchr/testify/require" 10 "github.com/stretchr/testify/suite" 11 12 mockconsensus "github.com/onflow/flow-go/engine/consensus/mock" 13 "github.com/onflow/flow-go/model/flow" 14 "github.com/onflow/flow-go/model/flow/filter" 15 "github.com/onflow/flow-go/module/id" 16 "github.com/onflow/flow-go/module/metrics" 17 module "github.com/onflow/flow-go/module/mock" 18 netint "github.com/onflow/flow-go/network" 19 "github.com/onflow/flow-go/network/channels" 20 "github.com/onflow/flow-go/network/mocknetwork" 21 "github.com/onflow/flow-go/network/p2p/cache" 22 protocolint "github.com/onflow/flow-go/state/protocol" 23 protocolEvents "github.com/onflow/flow-go/state/protocol/events" 24 protocol "github.com/onflow/flow-go/state/protocol/mock" 25 storerr "github.com/onflow/flow-go/storage" 26 storage "github.com/onflow/flow-go/storage/mock" 27 "github.com/onflow/flow-go/utils/unittest" 28 ) 29 30 func TestSyncEngine(t *testing.T) { 31 suite.Run(t, new(SyncSuite)) 32 } 33 34 type SyncSuite struct { 35 suite.Suite 36 myID flow.Identifier 37 participants flow.IdentityList 38 head *flow.Header 39 heights map[uint64]*flow.Block 40 blockIDs map[flow.Identifier]*flow.Block 41 net *mocknetwork.Network 42 con *mocknetwork.Conduit 43 me *module.Local 44 state *protocol.State 45 snapshot *protocol.Snapshot 46 blocks *storage.Blocks 47 comp *mockconsensus.Compliance 48 core *module.SyncCore 49 e *Engine 50 } 51 52 func (ss *SyncSuite) SetupTest() { 53 // generate own ID 54 ss.participants = unittest.IdentityListFixture(3, unittest.WithRole(flow.RoleConsensus)) 55 keys := unittest.NetworkingKeys(len(ss.participants)) 56 57 for i, p := range ss.participants { 58 p.NetworkPubKey = keys[i].PublicKey() 59 } 60 ss.myID = ss.participants[0].NodeID 61 62 // generate a header for the final state 63 header := unittest.BlockHeaderFixture() 64 ss.head = header 65 66 // create maps to enable block returns 67 ss.heights = make(map[uint64]*flow.Block) 68 ss.blockIDs = make(map[flow.Identifier]*flow.Block) 69 70 // set up the network module mock 71 ss.net = &mocknetwork.Network{} 72 ss.net.On("Register", mock.Anything, mock.Anything).Return( 73 func(channel channels.Channel, engine netint.MessageProcessor) netint.Conduit { 74 return ss.con 75 }, 76 nil, 77 ) 78 79 // set up the network conduit mock 80 ss.con = &mocknetwork.Conduit{} 81 82 // set up the local module mock 83 ss.me = &module.Local{} 84 ss.me.On("NodeID").Return( 85 func() flow.Identifier { 86 return ss.myID 87 }, 88 ) 89 90 // set up the protocol state mock 91 ss.state = &protocol.State{} 92 ss.state.On("Final").Return( 93 func() protocolint.Snapshot { 94 return ss.snapshot 95 }, 96 ) 97 ss.state.On("AtBlockID", mock.Anything).Return( 98 func(blockID flow.Identifier) protocolint.Snapshot { 99 if ss.head.ID() == blockID { 100 return ss.snapshot 101 } else { 102 return unittest.StateSnapshotForUnknownBlock() 103 } 104 }, 105 ).Maybe() 106 107 // set up the snapshot mock 108 ss.snapshot = &protocol.Snapshot{} 109 ss.snapshot.On("Head").Return( 110 func() *flow.Header { 111 return ss.head 112 }, 113 nil, 114 ) 115 ss.snapshot.On("Identities", mock.Anything).Return( 116 func(selector flow.IdentityFilter[flow.Identity]) flow.IdentityList { 117 return ss.participants.Filter(selector) 118 }, 119 nil, 120 ) 121 122 // set up blocks storage mock 123 ss.blocks = &storage.Blocks{} 124 ss.blocks.On("ByHeight", mock.Anything).Return( 125 func(height uint64) *flow.Block { 126 return ss.heights[height] 127 }, 128 func(height uint64) error { 129 _, enabled := ss.heights[height] 130 if !enabled { 131 return storerr.ErrNotFound 132 } 133 return nil 134 }, 135 ) 136 ss.blocks.On("ByID", mock.Anything).Return( 137 func(blockID flow.Identifier) *flow.Block { 138 return ss.blockIDs[blockID] 139 }, 140 func(blockID flow.Identifier) error { 141 _, enabled := ss.blockIDs[blockID] 142 if !enabled { 143 return storerr.ErrNotFound 144 } 145 return nil 146 }, 147 ) 148 149 // set up compliance engine mock 150 ss.comp = mockconsensus.NewCompliance(ss.T()) 151 ss.comp.On("Process", mock.Anything, mock.Anything, mock.Anything).Return(nil).Maybe() 152 153 // set up sync core 154 ss.core = &module.SyncCore{} 155 156 // initialize the engine 157 log := zerolog.New(io.Discard) 158 metrics := metrics.NewNoopCollector() 159 160 idCache, err := cache.NewProtocolStateIDCache(log, ss.state, protocolEvents.NewDistributor()) 161 require.NoError(ss.T(), err, "could not create protocol state identity cache") 162 spamConfig, err := NewSpamDetectionConfig() 163 require.NoError(ss.T(), err, "could not create spam detection config") 164 e, err := New(log, metrics, ss.net, ss.me, ss.state, ss.blocks, ss.comp, ss.core, 165 id.NewIdentityFilterIdentifierProvider( 166 filter.And( 167 filter.HasRole[flow.Identity](flow.RoleConsensus), 168 filter.Not(filter.HasNodeID[flow.Identity](ss.me.NodeID())), 169 ), 170 idCache, 171 ), 172 spamConfig) 173 require.NoError(ss.T(), err, "should pass engine initialization") 174 ss.e = e 175 }