Skip to content

Commit d02ff04

Browse files
committed
add unit tests for the submit half batch
1 parent 8f43c2e commit d02ff04

File tree

2 files changed

+156
-5
lines changed

2 files changed

+156
-5
lines changed

block/submitter.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,10 @@ func submitWithRecursiveSplitting[T any](
498498
return 0, nil
499499
}
500500

501-
// Base case: single item that's too big - skip it
501+
// Base case: single item that's too big - return error
502502
if len(items) == 1 {
503503
m.logger.Error().Str("itemType", itemType).Msg("single item exceeds DA blob size limit")
504-
return 0, nil
504+
return 0, fmt.Errorf("single %s item exceeds DA blob size limit", itemType)
505505
}
506506

507507
// Split and submit recursively - we know the batch is too big
@@ -573,9 +573,9 @@ func submitHalfBatch[T any](
573573
return submitWithRecursiveSplitting[T](m, ctx, items, marshaled, gasPrice, postSubmit, itemType)
574574

575575
case batchActionSkip:
576-
// Single item too big - skip it
577-
m.logger.Error().Str("itemType", itemType).Msg("skipping item that exceeds DA blob size limit")
578-
return 0, nil
576+
// Single item too big - return error
577+
m.logger.Error().Str("itemType", itemType).Msg("single item exceeds DA blob size limit")
578+
return 0, fmt.Errorf("single %s item exceeds DA blob size limit", itemType)
579579

580580
case batchActionFail:
581581
// Unrecoverable error - stop processing

block/submitter_test.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,3 +936,154 @@ func TestRetryStrategy(t *testing.T) {
936936
})
937937

938938
}
939+
940+
// TestSubmitHalfBatch tests all scenarios for submitHalfBatch function using table-driven tests
941+
func TestSubmitHalfBatch(t *testing.T) {
942+
tests := []struct {
943+
name string
944+
items []string
945+
marshaled [][]byte
946+
mockSetup func(*mocks.MockDA)
947+
expectedSubmitted int
948+
expectError bool
949+
expectedErrorMsg string
950+
postSubmitValidator func(*testing.T, [][]string) // validates postSubmit calls
951+
}{
952+
{
953+
name: "EmptyItems",
954+
items: []string{},
955+
marshaled: [][]byte{},
956+
mockSetup: func(da *mocks.MockDA) {}, // no DA calls expected
957+
expectedSubmitted: 0,
958+
expectError: false,
959+
postSubmitValidator: func(t *testing.T, calls [][]string) {
960+
assert.Empty(t, calls, "postSubmit should not be called for empty items")
961+
},
962+
},
963+
{
964+
name: "FullSuccess",
965+
items: []string{"item1", "item2", "item3"},
966+
marshaled: [][]byte{[]byte("m1"), []byte("m2"), []byte("m3")},
967+
mockSetup: func(da *mocks.MockDA) {
968+
da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
969+
Return([]coreda.ID{getDummyID(1, []byte("id1")), getDummyID(1, []byte("id2")), getDummyID(1, []byte("id3"))}, nil).Once()
970+
},
971+
expectedSubmitted: 3,
972+
expectError: false,
973+
postSubmitValidator: func(t *testing.T, calls [][]string) {
974+
require.Len(t, calls, 1, "postSubmit should be called once")
975+
assert.Equal(t, []string{"item1", "item2", "item3"}, calls[0])
976+
},
977+
},
978+
{
979+
name: "PartialSuccess",
980+
items: []string{"item1", "item2", "item3"},
981+
marshaled: [][]byte{[]byte("m1"), []byte("m2"), []byte("m3")},
982+
mockSetup: func(da *mocks.MockDA) {
983+
// First call: submit 2 out of 3 items
984+
da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
985+
Return([]coreda.ID{getDummyID(1, []byte("id1")), getDummyID(1, []byte("id2"))}, nil).Once()
986+
// Second call (recursive): submit remaining 1 item
987+
da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
988+
Return([]coreda.ID{getDummyID(1, []byte("id3"))}, nil).Once()
989+
},
990+
expectedSubmitted: 3,
991+
expectError: false,
992+
postSubmitValidator: func(t *testing.T, calls [][]string) {
993+
require.Len(t, calls, 2, "postSubmit should be called twice")
994+
assert.Equal(t, []string{"item1", "item2"}, calls[0])
995+
assert.Equal(t, []string{"item3"}, calls[1])
996+
},
997+
},
998+
{
999+
name: "PartialSuccessWithRecursionError",
1000+
items: []string{"item1", "item2", "item3"},
1001+
marshaled: [][]byte{[]byte("m1"), []byte("m2"), []byte("m3")},
1002+
mockSetup: func(da *mocks.MockDA) {
1003+
// First call: submit 2 out of 3 items successfully
1004+
da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
1005+
Return([]coreda.ID{getDummyID(1, []byte("id1")), getDummyID(1, []byte("id2"))}, nil).Once()
1006+
// Second call (recursive): remaining item is too big
1007+
da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
1008+
Return(nil, coreda.ErrBlobSizeOverLimit).Once()
1009+
},
1010+
expectedSubmitted: 2,
1011+
expectError: true,
1012+
expectedErrorMsg: "single test item exceeds DA blob size limit",
1013+
postSubmitValidator: func(t *testing.T, calls [][]string) {
1014+
require.Len(t, calls, 1, "postSubmit should be called once for successful part")
1015+
assert.Equal(t, []string{"item1", "item2"}, calls[0])
1016+
},
1017+
},
1018+
{
1019+
name: "SingleItemTooLarge",
1020+
items: []string{"large_item"},
1021+
marshaled: [][]byte{[]byte("large_marshaled_data")},
1022+
mockSetup: func(da *mocks.MockDA) {
1023+
da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
1024+
Return(nil, coreda.ErrBlobSizeOverLimit).Once()
1025+
},
1026+
expectedSubmitted: 0,
1027+
expectError: true,
1028+
expectedErrorMsg: "single test item exceeds DA blob size limit",
1029+
postSubmitValidator: func(t *testing.T, calls [][]string) {
1030+
assert.Empty(t, calls, "postSubmit should not be called on error")
1031+
},
1032+
},
1033+
{
1034+
name: "UnrecoverableError",
1035+
items: []string{"item1", "item2"},
1036+
marshaled: [][]byte{[]byte("m1"), []byte("m2")},
1037+
mockSetup: func(da *mocks.MockDA) {
1038+
da.On("SubmitWithOptions", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
1039+
Return(nil, fmt.Errorf("network timeout")).Once()
1040+
},
1041+
expectedSubmitted: 0,
1042+
expectError: true,
1043+
expectedErrorMsg: "unrecoverable error during test batch submission",
1044+
postSubmitValidator: func(t *testing.T, calls [][]string) {
1045+
assert.Empty(t, calls, "postSubmit should not be called on failure")
1046+
},
1047+
},
1048+
}
1049+
1050+
for _, tt := range tests {
1051+
t.Run(tt.name, func(t *testing.T) {
1052+
da := &mocks.MockDA{}
1053+
m := newTestManagerWithDA(t, da)
1054+
ctx := context.Background()
1055+
1056+
// Track postSubmit calls
1057+
var postSubmitCalls [][]string
1058+
postSubmit := func(submitted []string, res *coreda.ResultSubmit, gasPrice float64) {
1059+
postSubmitCalls = append(postSubmitCalls, submitted)
1060+
assert.Equal(t, float64(1.0), gasPrice, "gasPrice should be 1.0")
1061+
}
1062+
1063+
// Setup DA mock
1064+
tt.mockSetup(da)
1065+
1066+
// Call submitHalfBatch
1067+
submitted, err := submitHalfBatch(m, ctx, tt.items, tt.marshaled, 1.0, postSubmit, "test")
1068+
1069+
// Validate results
1070+
if tt.expectError {
1071+
assert.Error(t, err, "Expected error for test case %s", tt.name)
1072+
if tt.expectedErrorMsg != "" {
1073+
assert.Contains(t, err.Error(), tt.expectedErrorMsg, "Error message should contain expected text")
1074+
}
1075+
} else {
1076+
assert.NoError(t, err, "Expected no error for test case %s", tt.name)
1077+
}
1078+
1079+
assert.Equal(t, tt.expectedSubmitted, submitted, "Submitted count should match expected")
1080+
1081+
// Validate postSubmit calls
1082+
if tt.postSubmitValidator != nil {
1083+
tt.postSubmitValidator(t, postSubmitCalls)
1084+
}
1085+
1086+
da.AssertExpectations(t)
1087+
})
1088+
}
1089+
}

0 commit comments

Comments
 (0)