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 }