github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/state/protocol/events/gadgets/views_test.go (about)

     1  package gadgets
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"pgregory.net/rapid"
     8  
     9  	"github.com/onflow/flow-go/model/flow"
    10  	"github.com/onflow/flow-go/utils/unittest"
    11  )
    12  
    13  // viewsMachine is a wrapper around Views which provides conditional actions
    14  // for rapid property-based testing.
    15  type viewsMachine struct {
    16  	views         *Views
    17  	callbacks     map[uint64]int // # of callbacks at each view
    18  	calls         int            // incremented each time a callback is invoked
    19  	expectedCalls int            // expected value of calls at any given time
    20  }
    21  
    22  func (m *viewsMachine) init(_ *rapid.T) {
    23  	m.views = NewViews()
    24  	m.callbacks = make(map[uint64]int)
    25  	m.calls = 0
    26  	m.expectedCalls = 0
    27  }
    28  
    29  func (m *viewsMachine) OnView(t *rapid.T) {
    30  	view := rapid.Uint64().Draw(t, "view")
    31  	m.views.OnView(view, func(_ *flow.Header) {
    32  		m.calls++ // count actual number of calls invoked by Views
    33  	})
    34  
    35  	count := m.callbacks[view]
    36  	m.callbacks[view] = count + 1
    37  }
    38  
    39  func (m *viewsMachine) BlockFinalized(t *rapid.T) {
    40  	view := rapid.Uint64().Draw(t, "view")
    41  
    42  	block := unittest.BlockHeaderFixture()
    43  	block.View = view
    44  	m.views.BlockFinalized(block)
    45  
    46  	// increase the number of expected calls and remove those callbacks from our model
    47  	for indexedView, nCallbacks := range m.callbacks {
    48  		if indexedView <= view {
    49  			m.expectedCalls += nCallbacks
    50  			delete(m.callbacks, indexedView)
    51  		}
    52  	}
    53  }
    54  
    55  func (m *viewsMachine) Check(t *rapid.T) {
    56  	// the expected number of callbacks should be invoked
    57  	assert.Equal(t, m.expectedCalls, m.calls)
    58  }
    59  
    60  func TestViewsRapid(t *testing.T) {
    61  	rapid.Check(t, func(t *rapid.T) {
    62  		sm := new(viewsMachine)
    63  		sm.init(t)
    64  		t.Repeat(rapid.StateMachineActions(sm))
    65  	})
    66  }