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

     1  package votecollector
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  
     7  	"github.com/rs/zerolog"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/koko1123/flow-go-1/consensus/hotstuff"
    11  	"github.com/koko1123/flow-go-1/consensus/hotstuff/helper"
    12  	mockhotstuff "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/utils/unittest"
    15  )
    16  
    17  // TestVoteProcessorFactory_CreateWithValidProposal checks if VoteProcessorFactory checks the proposer vote
    18  // based on submitted proposal
    19  func TestVoteProcessorFactory_CreateWithValidProposal(t *testing.T) {
    20  	mockedFactory := mockhotstuff.VoteProcessorFactory{}
    21  
    22  	proposal := helper.MakeProposal()
    23  	mockedProcessor := &mockhotstuff.VerifyingVoteProcessor{}
    24  	mockedProcessor.On("Process", proposal.ProposerVote()).Return(nil).Once()
    25  	mockedFactory.On("Create", unittest.Logger(), proposal).Return(mockedProcessor, nil).Once()
    26  
    27  	voteProcessorFactory := &VoteProcessorFactory{
    28  		baseFactory: func(log zerolog.Logger, block *model.Block) (hotstuff.VerifyingVoteProcessor, error) {
    29  			return mockedFactory.Create(log, proposal)
    30  		},
    31  	}
    32  
    33  	processor, err := voteProcessorFactory.Create(unittest.Logger(), proposal)
    34  	require.NoError(t, err)
    35  	require.NotNil(t, processor)
    36  
    37  	mockedProcessor.AssertExpectations(t)
    38  	mockedFactory.AssertExpectations(t)
    39  }
    40  
    41  // TestVoteProcessorFactory_CreateWithInvalidVote tests that processing proposal with invalid vote doesn't return
    42  // vote processor and returns correct error(sentinel or exception).
    43  func TestVoteProcessorFactory_CreateWithInvalidVote(t *testing.T) {
    44  	mockedFactory := mockhotstuff.VoteProcessorFactory{}
    45  
    46  	t.Run("invalid-vote", func(t *testing.T) {
    47  		proposal := helper.MakeProposal()
    48  		mockedProcessor := &mockhotstuff.VerifyingVoteProcessor{}
    49  		mockedProcessor.On("Process", proposal.ProposerVote()).Return(model.NewInvalidVoteErrorf(proposal.ProposerVote(), "")).Once()
    50  		mockedFactory.On("Create", unittest.Logger(), proposal).Return(mockedProcessor, nil).Once()
    51  
    52  		voteProcessorFactory := &VoteProcessorFactory{
    53  			baseFactory: func(log zerolog.Logger, block *model.Block) (hotstuff.VerifyingVoteProcessor, error) {
    54  				return mockedFactory.Create(log, proposal)
    55  			},
    56  		}
    57  
    58  		processor, err := voteProcessorFactory.Create(unittest.Logger(), proposal)
    59  		require.Error(t, err)
    60  		require.Nil(t, processor)
    61  		require.True(t, model.IsInvalidBlockError(err))
    62  
    63  		mockedProcessor.AssertExpectations(t)
    64  	})
    65  	t.Run("process-vote-exception", func(t *testing.T) {
    66  		proposal := helper.MakeProposal()
    67  		mockedProcessor := &mockhotstuff.VerifyingVoteProcessor{}
    68  		exception := errors.New("process-exception")
    69  		mockedProcessor.On("Process", proposal.ProposerVote()).Return(exception).Once()
    70  
    71  		mockedFactory.On("Create", unittest.Logger(), proposal).Return(mockedProcessor, nil).Once()
    72  
    73  		voteProcessorFactory := &VoteProcessorFactory{
    74  			baseFactory: func(log zerolog.Logger, block *model.Block) (hotstuff.VerifyingVoteProcessor, error) {
    75  				return mockedFactory.Create(log, proposal)
    76  			},
    77  		}
    78  
    79  		processor, err := voteProcessorFactory.Create(unittest.Logger(), proposal)
    80  		require.ErrorIs(t, err, exception)
    81  		require.Nil(t, processor)
    82  		// an unexpected exception should _not_ be interpreted as the block being invalid
    83  		require.False(t, model.IsInvalidBlockError(err))
    84  
    85  		mockedProcessor.AssertExpectations(t)
    86  	})
    87  
    88  	mockedFactory.AssertExpectations(t)
    89  }
    90  
    91  // TestVoteProcessorFactory_CreateProcessException tests that VoteProcessorFactory correctly handles exception
    92  // while creating processor for requested proposal.
    93  func TestVoteProcessorFactory_CreateProcessException(t *testing.T) {
    94  	mockedFactory := mockhotstuff.VoteProcessorFactory{}
    95  
    96  	proposal := helper.MakeProposal()
    97  	exception := errors.New("create-exception")
    98  
    99  	mockedFactory.On("Create", unittest.Logger(), proposal).Return(nil, exception).Once()
   100  	voteProcessorFactory := &VoteProcessorFactory{
   101  		baseFactory: func(log zerolog.Logger, block *model.Block) (hotstuff.VerifyingVoteProcessor, error) {
   102  			return mockedFactory.Create(log, proposal)
   103  		},
   104  	}
   105  
   106  	processor, err := voteProcessorFactory.Create(unittest.Logger(), proposal)
   107  	require.ErrorIs(t, err, exception)
   108  	require.Nil(t, processor)
   109  	// an unexpected exception should _not_ be interpreted as the block being invalid
   110  	require.False(t, model.IsInvalidBlockError(err))
   111  
   112  	mockedFactory.AssertExpectations(t)
   113  }