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  }