github.com/koko1123/flow-go-1@v0.29.6/engine/testutil/mock/nodes.go (about) 1 package mock 2 3 import ( 4 "context" 5 "os" 6 "sync" 7 "testing" 8 "time" 9 10 "github.com/dgraph-io/badger/v3" 11 "github.com/rs/zerolog" 12 "github.com/stretchr/testify/require" 13 14 "github.com/koko1123/flow-go-1/engine/collection/epochmgr" 15 collectioningest "github.com/koko1123/flow-go-1/engine/collection/ingest" 16 "github.com/koko1123/flow-go-1/engine/collection/pusher" 17 followereng "github.com/koko1123/flow-go-1/engine/common/follower" 18 "github.com/koko1123/flow-go-1/engine/common/provider" 19 "github.com/koko1123/flow-go-1/engine/common/requester" 20 "github.com/koko1123/flow-go-1/engine/common/synchronization" 21 consensusingest "github.com/koko1123/flow-go-1/engine/consensus/ingestion" 22 "github.com/koko1123/flow-go-1/engine/consensus/matching" 23 "github.com/koko1123/flow-go-1/engine/consensus/sealing" 24 "github.com/koko1123/flow-go-1/engine/execution" 25 "github.com/koko1123/flow-go-1/engine/execution/computation" 26 "github.com/koko1123/flow-go-1/engine/execution/ingestion" 27 executionprovider "github.com/koko1123/flow-go-1/engine/execution/provider" 28 "github.com/koko1123/flow-go-1/engine/execution/state" 29 "github.com/koko1123/flow-go-1/engine/verification/assigner" 30 "github.com/koko1123/flow-go-1/engine/verification/assigner/blockconsumer" 31 "github.com/koko1123/flow-go-1/engine/verification/fetcher" 32 "github.com/koko1123/flow-go-1/engine/verification/fetcher/chunkconsumer" 33 verificationrequester "github.com/koko1123/flow-go-1/engine/verification/requester" 34 "github.com/koko1123/flow-go-1/engine/verification/verifier" 35 "github.com/koko1123/flow-go-1/fvm" 36 fvmState "github.com/koko1123/flow-go-1/fvm/state" 37 "github.com/koko1123/flow-go-1/ledger" 38 "github.com/koko1123/flow-go-1/ledger/complete" 39 "github.com/koko1123/flow-go-1/model/flow" 40 "github.com/koko1123/flow-go-1/module" 41 "github.com/koko1123/flow-go-1/module/finalizer/consensus" 42 "github.com/koko1123/flow-go-1/module/irrecoverable" 43 "github.com/koko1123/flow-go-1/module/mempool" 44 "github.com/koko1123/flow-go-1/module/mempool/entity" 45 epochpool "github.com/koko1123/flow-go-1/module/mempool/epochs" 46 "github.com/koko1123/flow-go-1/module/metrics" 47 "github.com/koko1123/flow-go-1/module/util" 48 "github.com/koko1123/flow-go-1/network/stub" 49 "github.com/koko1123/flow-go-1/state/protocol" 50 "github.com/koko1123/flow-go-1/state/protocol/events" 51 "github.com/koko1123/flow-go-1/storage" 52 bstorage "github.com/koko1123/flow-go-1/storage/badger" 53 "github.com/koko1123/flow-go-1/utils/unittest" 54 ) 55 56 // StateFixture is a test helper struct that encapsulates a flow protocol state 57 // as well as all of its backend dependencies. 58 type StateFixture struct { 59 DBDir string 60 PublicDB *badger.DB 61 SecretsDB *badger.DB 62 Storage *storage.All 63 ProtocolEvents *events.Distributor 64 State protocol.MutableState 65 } 66 67 // GenericNode implements a generic in-process node for tests. 68 type GenericNode struct { 69 // context and cancel function used to start/stop components 70 Ctx irrecoverable.SignalerContext 71 Cancel context.CancelFunc 72 73 Log zerolog.Logger 74 Metrics *metrics.NoopCollector 75 Tracer module.Tracer 76 PublicDB *badger.DB 77 SecretsDB *badger.DB 78 Headers storage.Headers 79 Guarantees storage.Guarantees 80 Seals storage.Seals 81 Payloads storage.Payloads 82 Blocks storage.Blocks 83 State protocol.MutableState 84 Index storage.Index 85 Me module.Local 86 Net *stub.Network 87 DBDir string 88 ChainID flow.ChainID 89 ProtocolEvents *events.Distributor 90 } 91 92 func (g *GenericNode) Done() { 93 _ = g.PublicDB.Close() 94 _ = os.RemoveAll(g.DBDir) 95 96 <-g.Tracer.Done() 97 } 98 99 // RequireGenericNodesDoneBefore invokes the done method of all input generic nodes concurrently, and 100 // fails the test if any generic node's shutdown takes longer than the specified duration. 101 func RequireGenericNodesDoneBefore(t testing.TB, duration time.Duration, nodes ...*GenericNode) { 102 wg := &sync.WaitGroup{} 103 wg.Add(len(nodes)) 104 105 for _, node := range nodes { 106 go func(n *GenericNode) { 107 n.Done() 108 wg.Done() 109 }(node) 110 } 111 112 unittest.RequireReturnsBefore(t, wg.Wait, duration, "failed to shutdown all components on time") 113 } 114 115 // CloseDB closes the badger database of the node 116 func (g *GenericNode) CloseDB() error { 117 return g.PublicDB.Close() 118 } 119 120 // CollectionNode implements an in-process collection node for tests. 121 type CollectionNode struct { 122 GenericNode 123 Collections storage.Collections 124 Transactions storage.Transactions 125 ClusterPayloads storage.ClusterPayloads 126 TxPools *epochpool.TransactionPools 127 Voter module.ClusterRootQCVoter 128 IngestionEngine *collectioningest.Engine 129 PusherEngine *pusher.Engine 130 ProviderEngine *provider.Engine 131 EpochManagerEngine *epochmgr.Engine 132 } 133 134 func (n CollectionNode) Ready() <-chan struct{} { 135 n.IngestionEngine.Start(n.Ctx) 136 return util.AllReady( 137 n.PusherEngine, 138 n.ProviderEngine, 139 n.IngestionEngine, 140 n.EpochManagerEngine, 141 ) 142 } 143 144 func (n CollectionNode) Done() <-chan struct{} { 145 done := make(chan struct{}) 146 go func() { 147 n.GenericNode.Cancel() 148 <-util.AllDone( 149 n.PusherEngine, 150 n.ProviderEngine, 151 n.IngestionEngine, 152 n.EpochManagerEngine, 153 ) 154 n.GenericNode.Done() 155 close(done) 156 }() 157 return done 158 } 159 160 // ConsensusNode implements an in-process consensus node for tests. 161 type ConsensusNode struct { 162 GenericNode 163 Guarantees mempool.Guarantees 164 Receipts mempool.ExecutionTree 165 Seals mempool.IncorporatedResultSeals 166 IngestionEngine *consensusingest.Engine 167 SealingEngine *sealing.Engine 168 MatchingEngine *matching.Engine 169 } 170 171 func (cn ConsensusNode) Ready() { 172 <-cn.IngestionEngine.Ready() 173 <-cn.SealingEngine.Ready() 174 } 175 176 func (cn ConsensusNode) Done() { 177 <-cn.IngestionEngine.Done() 178 <-cn.SealingEngine.Done() 179 } 180 181 type ComputerWrap struct { 182 *computation.Manager 183 OnComputeBlock func(ctx context.Context, block *entity.ExecutableBlock, view fvmState.View) 184 } 185 186 func (c *ComputerWrap) ComputeBlock( 187 ctx context.Context, 188 block *entity.ExecutableBlock, 189 view fvmState.View, 190 ) (*execution.ComputationResult, error) { 191 if c.OnComputeBlock != nil { 192 c.OnComputeBlock(ctx, block, view) 193 } 194 return c.Manager.ComputeBlock(ctx, block, view) 195 } 196 197 // ExecutionNode implements a mocked execution node for tests. 198 type ExecutionNode struct { 199 GenericNode 200 MutableState protocol.MutableState 201 IngestionEngine *ingestion.Engine 202 ExecutionEngine *ComputerWrap 203 RequestEngine *requester.Engine 204 ReceiptsEngine *executionprovider.Engine 205 FollowerEngine *followereng.Engine 206 SyncEngine *synchronization.Engine 207 Compactor *complete.Compactor 208 BadgerDB *badger.DB 209 VM fvm.VM 210 ExecutionState state.ExecutionState 211 Ledger ledger.Ledger 212 LevelDbDir string 213 Collections storage.Collections 214 Finalizer *consensus.Finalizer 215 MyExecutionReceipts storage.MyExecutionReceipts 216 } 217 218 func (en ExecutionNode) Ready(ctx context.Context) { 219 // TODO: receipt engine has been migrated to the new component interface, hence 220 // is using Start. Other engines' startup should be refactored once migrated to 221 // new interface. 222 irctx, _ := irrecoverable.WithSignaler(ctx) 223 en.ReceiptsEngine.Start(irctx) 224 225 <-util.AllReady( 226 en.Ledger, 227 en.ReceiptsEngine, 228 en.IngestionEngine, 229 en.FollowerEngine, 230 en.RequestEngine, 231 en.SyncEngine, 232 ) 233 } 234 235 func (en ExecutionNode) Done(cancelFunc context.CancelFunc) { 236 // to stop all components running with a component manager. 237 cancelFunc() 238 239 // to stop all (deprecated) ready-done-aware 240 <-util.AllDone( 241 en.IngestionEngine, 242 en.IngestionEngine, 243 en.ReceiptsEngine, 244 en.Ledger, 245 en.FollowerEngine, 246 en.RequestEngine, 247 en.SyncEngine, 248 en.Compactor, 249 ) 250 os.RemoveAll(en.LevelDbDir) 251 en.GenericNode.Done() 252 } 253 254 func (en ExecutionNode) AssertHighestExecutedBlock(t *testing.T, header *flow.Header) { 255 256 height, blockID, err := en.ExecutionState.GetHighestExecutedBlockID(context.Background()) 257 require.NoError(t, err) 258 259 require.Equal(t, header.ID(), blockID) 260 require.Equal(t, header.Height, height) 261 } 262 263 // VerificationNode implements an in-process verification node for tests. 264 type VerificationNode struct { 265 *GenericNode 266 ChunkStatuses mempool.ChunkStatuses 267 ChunkRequests mempool.ChunkRequests 268 Results storage.ExecutionResults 269 Receipts storage.ExecutionReceipts 270 271 // chunk consumer and processor for fetcher engine 272 ProcessedChunkIndex storage.ConsumerProgress 273 ChunksQueue *bstorage.ChunksQueue 274 ChunkConsumer *chunkconsumer.ChunkConsumer 275 276 // block consumer for chunk consumer 277 ProcessedBlockHeight storage.ConsumerProgress 278 BlockConsumer *blockconsumer.BlockConsumer 279 280 VerifierEngine *verifier.Engine 281 AssignerEngine *assigner.Engine 282 FetcherEngine *fetcher.Engine 283 RequesterEngine *verificationrequester.Engine 284 }