github.com/koko1123/flow-go-1@v0.29.6/engine/execution/ingestion/stop_control_test.go (about) 1 package ingestion 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/koko1123/flow-go-1/storage" 8 9 testifyMock "github.com/stretchr/testify/mock" 10 "github.com/stretchr/testify/require" 11 12 "github.com/koko1123/flow-go-1/engine/execution/state/mock" 13 14 "github.com/koko1123/flow-go-1/utils/unittest" 15 ) 16 17 // If stopping mechanism has caused any changes to execution flow (skipping execution of blocks) 18 // we disallow setting new values 19 func TestCannotSetNewValuesAfterStoppingCommenced(t *testing.T) { 20 21 t.Run("when processing block at stop height", func(t *testing.T) { 22 sc := NewStopControl(unittest.Logger(), false, 0) 23 24 require.Equal(t, sc.GetState(), StopControlOff) 25 26 // first update is always successful 27 _, _, err := sc.SetStopHeight(21, false) 28 require.NoError(t, err) 29 30 require.Equal(t, sc.GetState(), StopControlSet) 31 32 // no stopping has started yet, block below stop height 33 header := unittest.BlockHeaderFixture(unittest.WithHeaderHeight(20)) 34 sc.blockProcessable(header) 35 36 require.Equal(t, sc.GetState(), StopControlSet) 37 38 _, _, err = sc.SetStopHeight(37, false) 39 require.NoError(t, err) 40 41 // block at stop height, it should be skipped 42 header = unittest.BlockHeaderFixture(unittest.WithHeaderHeight(37)) 43 sc.blockProcessable(header) 44 45 require.Equal(t, sc.GetState(), StopControlCommenced) 46 47 _, _, err = sc.SetStopHeight(2137, false) 48 require.Error(t, err) 49 50 // state did not change 51 require.Equal(t, sc.GetState(), StopControlCommenced) 52 }) 53 54 t.Run("when processing finalized blocks", func(t *testing.T) { 55 56 execState := new(mock.ReadOnlyExecutionState) 57 58 sc := NewStopControl(unittest.Logger(), false, 0) 59 60 require.Equal(t, sc.GetState(), StopControlOff) 61 62 // first update is always successful 63 _, _, err := sc.SetStopHeight(21, false) 64 require.NoError(t, err) 65 require.Equal(t, sc.GetState(), StopControlSet) 66 67 // make execution check pretends block has been executed 68 execState.On("StateCommitmentByBlockID", testifyMock.Anything, testifyMock.Anything).Return(nil, nil) 69 70 // no stopping has started yet, block below stop height 71 header := unittest.BlockHeaderFixture(unittest.WithHeaderHeight(20)) 72 sc.blockFinalized(context.TODO(), execState, header) 73 74 _, _, err = sc.SetStopHeight(37, false) 75 require.NoError(t, err) 76 require.Equal(t, sc.GetState(), StopControlSet) 77 78 // block at stop height, it should be trigger stop 79 header = unittest.BlockHeaderFixture(unittest.WithHeaderHeight(37)) 80 sc.blockFinalized(context.TODO(), execState, header) 81 82 // since we set crash to false, execution should be paused 83 require.Equal(t, sc.GetState(), StopControlPaused) 84 85 _, _, err = sc.SetStopHeight(2137, false) 86 require.Error(t, err) 87 88 execState.AssertExpectations(t) 89 }) 90 } 91 92 // TestExecutionFallingBehind check if StopControl behaves properly even if EN runs behind 93 // and blocks are finalized before they are executed 94 func TestExecutionFallingBehind(t *testing.T) { 95 96 execState := new(mock.ReadOnlyExecutionState) 97 98 headerA := unittest.BlockHeaderFixture(unittest.WithHeaderHeight(20)) 99 headerB := unittest.BlockHeaderWithParentFixture(headerA) // 21 100 headerC := unittest.BlockHeaderWithParentFixture(headerB) // 22 101 headerD := unittest.BlockHeaderWithParentFixture(headerC) // 23 102 103 sc := NewStopControl(unittest.Logger(), false, 0) 104 105 require.Equal(t, sc.GetState(), StopControlOff) 106 107 // set stop at 22, so 21 is the last height which should be processed 108 _, _, err := sc.SetStopHeight(22, false) 109 require.NoError(t, err) 110 require.Equal(t, sc.GetState(), StopControlSet) 111 112 execState.On("StateCommitmentByBlockID", testifyMock.Anything, headerC.ParentID).Return(nil, storage.ErrNotFound) 113 114 // finalize blocks first 115 sc.blockFinalized(context.TODO(), execState, headerA) 116 require.Equal(t, StopControlSet, sc.GetState()) 117 118 sc.blockFinalized(context.TODO(), execState, headerB) 119 require.Equal(t, StopControlSet, sc.GetState()) 120 121 sc.blockFinalized(context.TODO(), execState, headerC) 122 require.Equal(t, StopControlSet, sc.GetState()) 123 124 sc.blockFinalized(context.TODO(), execState, headerD) 125 require.Equal(t, StopControlSet, sc.GetState()) 126 127 // simulate execution 128 sc.blockExecuted(headerA) 129 require.Equal(t, StopControlSet, sc.GetState()) 130 131 sc.blockExecuted(headerB) 132 require.Equal(t, StopControlPaused, sc.GetState()) 133 134 execState.AssertExpectations(t) 135 } 136 137 // TestCannotSetHeightBelowLastExecuted check if StopControl 138 // tracks last executed height and prevents from setting stop height 139 // below or too close to it 140 func TestCannotSetHeightBelowLastExecuted(t *testing.T) { 141 142 sc := NewStopControl(unittest.Logger(), false, 0) 143 144 require.Equal(t, sc.GetState(), StopControlOff) 145 146 sc.executingBlockHeight(20) 147 require.Equal(t, StopControlOff, sc.GetState()) 148 149 _, _, err := sc.SetStopHeight(20, false) 150 require.Error(t, err) 151 require.Equal(t, StopControlOff, sc.GetState()) 152 153 _, _, err = sc.SetStopHeight(25, false) 154 require.NoError(t, err) 155 require.Equal(t, StopControlSet, sc.GetState()) 156 } 157 158 // StopControl started as paused will keep the state 159 func TestStartingPaused(t *testing.T) { 160 161 sc := NewStopControl(unittest.Logger(), true, 0) 162 require.Equal(t, StopControlPaused, sc.GetState()) 163 } 164 165 func TestPausedStateRejectsAllBlocksAndChanged(t *testing.T) { 166 167 sc := NewStopControl(unittest.Logger(), true, 0) 168 require.Equal(t, StopControlPaused, sc.GetState()) 169 170 _, _, err := sc.SetStopHeight(2137, true) 171 require.Error(t, err) 172 173 // make sure we don't even query executed status if paused 174 // mock should fail test on any method call 175 execState := new(mock.ReadOnlyExecutionState) 176 177 header := unittest.BlockHeaderFixture(unittest.WithHeaderHeight(20)) 178 179 sc.blockFinalized(context.TODO(), execState, header) 180 require.Equal(t, StopControlPaused, sc.GetState()) 181 182 execState.AssertExpectations(t) 183 }