github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/voteaggregator/vote_aggregator_test.go (about)

     1  package voteaggregator
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/mock"
     9  	"github.com/stretchr/testify/require"
    10  	"github.com/stretchr/testify/suite"
    11  
    12  	"github.com/koko1123/flow-go-1/consensus/hotstuff/mocks"
    13  	"github.com/koko1123/flow-go-1/consensus/hotstuff/model"
    14  	"github.com/koko1123/flow-go-1/module/irrecoverable"
    15  	"github.com/koko1123/flow-go-1/utils/unittest"
    16  )
    17  
    18  func TestVoteAggregator(t *testing.T) {
    19  	suite.Run(t, new(VoteAggregatorTestSuite))
    20  }
    21  
    22  // VoteAggregatorTestSuite is a test suite for isolated testing of VoteAggregator.
    23  // Contains mocked state which is used to verify correct behavior of VoteAggregator.
    24  // Automatically starts and stops module.Startable in SetupTest and TearDownTest respectively.
    25  type VoteAggregatorTestSuite struct {
    26  	suite.Suite
    27  
    28  	aggregator     *VoteAggregator
    29  	collectors     *mocks.VoteCollectors
    30  	consumer       *mocks.Consumer
    31  	stopAggregator context.CancelFunc
    32  }
    33  
    34  func (s *VoteAggregatorTestSuite) SetupTest() {
    35  	var err error
    36  	s.collectors = &mocks.VoteCollectors{}
    37  	s.consumer = &mocks.Consumer{}
    38  
    39  	ready := func() <-chan struct{} {
    40  		channel := make(chan struct{})
    41  		close(channel)
    42  		return channel
    43  	}()
    44  
    45  	done := func() <-chan struct{} {
    46  		channel := make(chan struct{})
    47  		close(channel)
    48  		return channel
    49  	}()
    50  
    51  	s.collectors.On("Start", mock.Anything).Once()
    52  	s.collectors.On("Ready").Return(ready).Once()
    53  	s.collectors.On("Done").Return(done).Once()
    54  
    55  	s.aggregator, err = NewVoteAggregator(unittest.Logger(), s.consumer, 0, s.collectors)
    56  	require.NoError(s.T(), err)
    57  
    58  	ctx, cancel := context.WithCancel(context.Background())
    59  	signalerCtx, _ := irrecoverable.WithSignaler(ctx)
    60  	s.stopAggregator = cancel
    61  	s.aggregator.Start(signalerCtx)
    62  	unittest.RequireCloseBefore(s.T(), s.aggregator.Ready(), 100*time.Millisecond, "should close before timeout")
    63  }
    64  
    65  func (s *VoteAggregatorTestSuite) TearDownTest() {
    66  	s.stopAggregator()
    67  	unittest.RequireCloseBefore(s.T(), s.aggregator.Done(), time.Second, "should close before timeout")
    68  }
    69  
    70  // TestOnFinalizedBlock tests if finalized block gets processed when send through `VoteAggregator`.
    71  // Tests the whole processing pipeline.
    72  func (s *VoteAggregatorTestSuite) TestOnFinalizedBlock() {
    73  	finalizedBlock := unittest.BlockHeaderFixture(unittest.HeaderWithView(100))
    74  	s.collectors.On("PruneUpToView", finalizedBlock.View).Once()
    75  	s.aggregator.OnFinalizedBlock(model.BlockFromFlow(finalizedBlock, finalizedBlock.View-1))
    76  	require.Eventually(s.T(),
    77  		func() bool {
    78  			return s.collectors.AssertCalled(s.T(), "PruneUpToView", finalizedBlock.View)
    79  		}, time.Second, time.Millisecond*20)
    80  }