Skip to content

Commit 1463b26

Browse files
committed
test: add tests
1 parent 63779cd commit 1463b26

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

block/internal/executing/executor_logic_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package executing
33
import (
44
"context"
55
crand "crypto/rand"
6+
"errors"
67
"testing"
78
"time"
89

@@ -207,3 +208,114 @@ func TestPendingLimit_SkipsProduction(t *testing.T) {
207208
require.NoError(t, err)
208209
assert.Equal(t, h1, h2, "height should not change when production is skipped")
209210
}
211+
212+
func TestExecutor_executeTxsWithRetry(t *testing.T) {
213+
t.Parallel()
214+
215+
tests := []struct {
216+
name string
217+
setupMock func(*testmocks.MockExecutor)
218+
expectSuccess bool
219+
expectHash []byte
220+
expectError string
221+
}{
222+
{
223+
name: "success on first attempt",
224+
setupMock: func(exec *testmocks.MockExecutor) {
225+
exec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, mock.Anything).
226+
Return([]byte("new-hash"), uint64(0), nil).Once()
227+
},
228+
expectSuccess: true,
229+
expectHash: []byte("new-hash"),
230+
},
231+
{
232+
name: "success on second attempt",
233+
setupMock: func(exec *testmocks.MockExecutor) {
234+
exec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, mock.Anything).
235+
Return([]byte(nil), uint64(0), errors.New("temporary failure")).Once()
236+
exec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, mock.Anything).
237+
Return([]byte("new-hash"), uint64(0), nil).Once()
238+
},
239+
expectSuccess: true,
240+
expectHash: []byte("new-hash"),
241+
},
242+
{
243+
name: "success on third attempt",
244+
setupMock: func(exec *testmocks.MockExecutor) {
245+
exec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, mock.Anything).
246+
Return([]byte(nil), uint64(0), errors.New("temporary failure")).Times(2)
247+
exec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, mock.Anything).
248+
Return([]byte("new-hash"), uint64(0), nil).Once()
249+
},
250+
expectSuccess: true,
251+
expectHash: []byte("new-hash"),
252+
},
253+
{
254+
name: "failure after max retries",
255+
setupMock: func(exec *testmocks.MockExecutor) {
256+
exec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, mock.Anything).
257+
Return([]byte(nil), uint64(0), errors.New("persistent failure")).Times(common.MaxRetriesBeforeHalt)
258+
},
259+
expectSuccess: false,
260+
expectError: "failed to execute transactions",
261+
},
262+
{
263+
name: "context cancelled during retry",
264+
setupMock: func(exec *testmocks.MockExecutor) {
265+
exec.On("ExecuteTxs", mock.Anything, mock.Anything, uint64(100), mock.Anything, mock.Anything).
266+
Return([]byte(nil), uint64(0), errors.New("temporary failure")).Once()
267+
},
268+
expectSuccess: false,
269+
expectError: "context cancelled during retry",
270+
},
271+
}
272+
273+
for _, tt := range tests {
274+
t.Run(tt.name, func(t *testing.T) {
275+
t.Parallel()
276+
277+
ctx := context.Background()
278+
execCtx := ctx
279+
280+
// For context cancellation test, create a cancellable context
281+
if tt.name == "context cancelled during retry" {
282+
var cancel context.CancelFunc
283+
execCtx, cancel = context.WithCancel(ctx)
284+
// Cancel context after first failure to simulate cancellation during retry
285+
go func() {
286+
time.Sleep(100 * time.Millisecond)
287+
cancel()
288+
}()
289+
}
290+
291+
mockExec := testmocks.NewMockExecutor(t)
292+
tt.setupMock(mockExec)
293+
294+
e := &Executor{
295+
exec: mockExec,
296+
ctx: execCtx,
297+
logger: zerolog.Nop(),
298+
}
299+
300+
rawTxs := [][]byte{[]byte("tx1"), []byte("tx2")}
301+
header := types.Header{
302+
BaseHeader: types.BaseHeader{Height: 100, Time: uint64(time.Now().UnixNano())},
303+
}
304+
currentState := types.State{AppHash: []byte("current-hash")}
305+
306+
result, err := e.executeTxsWithRetry(ctx, rawTxs, header, currentState)
307+
308+
if tt.expectSuccess {
309+
require.NoError(t, err)
310+
assert.Equal(t, tt.expectHash, result)
311+
} else {
312+
require.Error(t, err)
313+
if tt.expectError != "" {
314+
assert.Contains(t, err.Error(), tt.expectError)
315+
}
316+
}
317+
318+
mockExec.AssertExpectations(t)
319+
})
320+
}
321+
}

0 commit comments

Comments
 (0)