github.com/koko1123/flow-go-1@v0.29.6/engine/consensus/ingestion/engine_test.go (about) 1 // (c) 2019 Dapper Labs - ALL RIGHTS RESERVED 2 3 package ingestion 4 5 import ( 6 "context" 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/mock" 12 "github.com/stretchr/testify/require" 13 "github.com/stretchr/testify/suite" 14 "go.uber.org/atomic" 15 16 "github.com/koko1123/flow-go-1/engine" 17 "github.com/koko1123/flow-go-1/module/irrecoverable" 18 "github.com/koko1123/flow-go-1/module/metrics" 19 mockmodule "github.com/koko1123/flow-go-1/module/mock" 20 netint "github.com/koko1123/flow-go-1/network" 21 "github.com/koko1123/flow-go-1/network/channels" 22 "github.com/koko1123/flow-go-1/network/mocknetwork" 23 "github.com/koko1123/flow-go-1/utils/unittest" 24 ) 25 26 func TestIngestionEngine(t *testing.T) { 27 suite.Run(t, new(IngestionSuite)) 28 } 29 30 type IngestionSuite struct { 31 IngestionCoreSuite 32 33 con *mocknetwork.Conduit 34 net *mocknetwork.Network 35 cancel context.CancelFunc 36 37 ingest *Engine 38 } 39 40 func (s *IngestionSuite) SetupTest() { 41 s.IngestionCoreSuite.SetupTest() 42 43 s.con = &mocknetwork.Conduit{} 44 45 // set up network module mock 46 s.net = &mocknetwork.Network{} 47 s.net.On("Register", channels.ReceiveGuarantees, mock.Anything).Return( 48 func(channel channels.Channel, engine netint.MessageProcessor) netint.Conduit { 49 return s.con 50 }, 51 nil, 52 ) 53 54 // setup my own identity 55 me := &mockmodule.Local{} 56 me.On("NodeID").Return(s.conID) // we use the first consensus node as our local identity 57 58 ctx, cancel := context.WithCancel(context.Background()) 59 s.cancel = cancel 60 signalerCtx, _ := irrecoverable.WithSignaler(ctx) 61 62 metrics := metrics.NewNoopCollector() 63 ingest, err := New(unittest.Logger(), metrics, s.net, me, s.core) 64 require.NoError(s.T(), err) 65 s.ingest = ingest 66 s.ingest.Start(signalerCtx) 67 <-s.ingest.Ready() 68 } 69 70 func (s *IngestionSuite) TearDownTest() { 71 s.cancel() 72 <-s.ingest.Done() 73 } 74 75 // TestSubmittingMultipleEntries tests processing of multiple collection guarantees in concurrent way. 76 // In happy path we expect that all messages are dispatched to worker goroutines and executed by core. 77 func (s *IngestionSuite) TestSubmittingMultipleEntries() { 78 originID := s.collID 79 count := uint64(15) 80 81 processed := atomic.NewUint64(0) 82 83 var wg sync.WaitGroup 84 wg.Add(1) 85 go func() { 86 for i := 0; i < int(count); i++ { 87 guarantee := s.validGuarantee() 88 s.pool.On("Has", guarantee.ID()).Return(false) 89 s.pool.On("Add", guarantee).Run(func(args mock.Arguments) { 90 processed.Add(1) 91 }).Return(true) 92 93 // execute the vote submission 94 _ = s.ingest.Process(channels.ProvideCollections, originID, guarantee) 95 } 96 wg.Done() 97 }() 98 99 wg.Wait() 100 101 require.Eventually(s.T(), func() bool { 102 return processed.Load() == count 103 }, time.Millisecond*200, time.Millisecond*20) 104 105 s.pool.AssertExpectations(s.T()) 106 } 107 108 // TestProcessUnsupportedMessageType tests that Process and ProcessLocal correctly handle a case where invalid message type 109 // was submitted from network layer. 110 func (s *IngestionSuite) TestProcessUnsupportedMessageType() { 111 invalidEvent := uint64(42) 112 err := s.ingest.Process("ch", unittest.IdentifierFixture(), invalidEvent) 113 // shouldn't result in error since byzantine inputs are expected 114 require.NoError(s.T(), err) 115 // in case of local processing error cannot be consumed since all inputs are trusted 116 err = s.ingest.ProcessLocal(invalidEvent) 117 require.Error(s.T(), err) 118 require.True(s.T(), engine.IsIncompatibleInputTypeError(err)) 119 }