Skip to content

Commit e885f8d

Browse files
committed
add
Signed-off-by: gengjun-git <gengjun@starrocks.com>
1 parent 01e0364 commit e885f8d

File tree

2 files changed

+242
-0
lines changed

2 files changed

+242
-0
lines changed

fe/fe-core/src/test/java/com/starrocks/transaction/DatabaseTransactionMgrTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.starrocks.lake.compaction.CompactionMgr;
6161
import com.starrocks.load.routineload.RLTaskTxnCommitAttachment;
6262
import com.starrocks.metric.MetricRepo;
63+
import com.starrocks.persist.EditLog;
6364
import com.starrocks.replication.ReplicationTxnCommitAttachment;
6465
import com.starrocks.server.GlobalStateMgr;
6566
import mockit.Mock;
@@ -83,6 +84,9 @@
8384
import static org.junit.jupiter.api.Assertions.assertNull;
8485
import static org.junit.jupiter.api.Assertions.assertThrows;
8586
import static org.junit.jupiter.api.Assertions.assertTrue;
87+
import static org.mockito.ArgumentMatchers.any;
88+
import static org.mockito.Mockito.doThrow;
89+
import static org.mockito.Mockito.spy;
8690

8791
public class DatabaseTransactionMgrTest {
8892

@@ -866,6 +870,41 @@ public boolean isCloudNativeTableOrMaterializedView() {
866870
assertEquals(4, masterDbTransMgr.getFinishedTxnNums());
867871
}
868872

873+
@Test
874+
public void testFinishTransactionBatchEditLogException() throws StarRocksException {
875+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
876+
DatabaseTransactionMgr masterDbTransMgr = masterTransMgr.getDatabaseTransactionMgr(GlobalStateMgrTestUtil.testDbId1);
877+
long txnId6 = lableToTxnId.get(GlobalStateMgrTestUtil.testTxnLable6);
878+
long txnId7 = lableToTxnId.get(GlobalStateMgrTestUtil.testTxnLable7);
879+
long txnId8 = lableToTxnId.get(GlobalStateMgrTestUtil.testTxnLable8);
880+
TransactionStateBatch stateBatch = new TransactionStateBatch(List.of(
881+
masterDbTransMgr.getTransactionState(txnId6),
882+
masterDbTransMgr.getTransactionState(txnId7),
883+
masterDbTransMgr.getTransactionState(txnId8)));
884+
885+
new MockUp<Table>() {
886+
@Mock
887+
public boolean isCloudNativeTableOrMaterializedView() {
888+
return true;
889+
}
890+
};
891+
892+
EditLog spyEditLog = spy(masterGlobalStateMgr.getEditLog());
893+
doThrow(new RuntimeException("EditLog write failed"))
894+
.when(spyEditLog).logInsertTransactionStateBatch(any(TransactionStateBatch.class), any());
895+
EditLog originalEditLog = replaceDatabaseTransactionMgrEditLog(masterDbTransMgr, spyEditLog);
896+
try {
897+
RuntimeException exception = Assertions.assertThrows(RuntimeException.class,
898+
() -> masterTransMgr.finishTransactionBatch(GlobalStateMgrTestUtil.testDbId1, stateBatch, null));
899+
assertEditLogWriteFailed(exception);
900+
assertEquals(TransactionStatus.COMMITTED, masterDbTransMgr.getTransactionState(txnId6).getTransactionStatus());
901+
assertEquals(TransactionStatus.COMMITTED, masterDbTransMgr.getTransactionState(txnId7).getTransactionStatus());
902+
assertEquals(TransactionStatus.COMMITTED, masterDbTransMgr.getTransactionState(txnId8).getTransactionStatus());
903+
} finally {
904+
replaceDatabaseTransactionMgrEditLog(masterDbTransMgr, originalEditLog);
905+
}
906+
}
907+
869908
@Test
870909
public void testPublishVersionMissing() throws StarRocksException {
871910
TransactionIdGenerator idGenerator = masterTransMgr.getTransactionIDGenerator();
@@ -1064,4 +1103,15 @@ public void testCanTxnFinishedWithLockTimeout() throws Exception {
10641103
Assertions.assertTrue(result);
10651104
});
10661105
}
1106+
1107+
private EditLog replaceDatabaseTransactionMgrEditLog(DatabaseTransactionMgr dbTransactionMgr, EditLog editLog) {
1108+
EditLog originalEditLog = Deencapsulation.getField(dbTransactionMgr, "editLog");
1109+
Deencapsulation.setField(dbTransactionMgr, "editLog", editLog);
1110+
return originalEditLog;
1111+
}
1112+
1113+
private void assertEditLogWriteFailed(RuntimeException exception) {
1114+
Assertions.assertTrue(exception.getMessage().contains("EditLog write failed")
1115+
|| exception.getCause() != null && exception.getCause().getMessage().contains("EditLog write failed"));
1116+
}
10671117
}

fe/fe-core/src/test/java/com/starrocks/transaction/GlobalTransactionMgrTest.java

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
import static org.junit.jupiter.api.Assertions.assertEquals;
105105
import static org.junit.jupiter.api.Assertions.assertNotNull;
106106
import static org.junit.jupiter.api.Assertions.assertTrue;
107+
import static org.mockito.ArgumentMatchers.any;
107108
import static org.mockito.Mockito.doReturn;
108109
import static org.mockito.Mockito.doThrow;
109110
import static org.mockito.Mockito.spy;
@@ -162,6 +163,47 @@ public void testBeginTransaction() throws LabelAlreadyUsedException, AnalysisExc
162163
assertEquals(transactionSource.toString(), transactionState.getCoordinator().toString());
163164
}
164165

166+
@Test
167+
public void testBeginTransactionEditLogAndReplay() throws Exception {
168+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
169+
String label = UUIDUtil.genUUID().toString();
170+
long transactionId = masterTransMgr
171+
.beginTransaction(GlobalStateMgrTestUtil.testDbId1, Lists.newArrayList(GlobalStateMgrTestUtil.testTableId1),
172+
label, transactionSource, LoadJobSourceType.FRONTEND, Config.stream_load_default_timeout_second);
173+
174+
TransactionState transactionState = fakeEditLog.getTransaction(transactionId);
175+
assertNotNull(transactionState);
176+
assertEquals(TransactionStatus.PREPARE, transactionState.getTransactionStatus());
177+
178+
FakeGlobalStateMgr.setGlobalStateMgr(slaveGlobalStateMgr);
179+
slaveTransMgr.replayUpsertTransactionState(transactionState);
180+
assertTrue(GlobalStateMgrTestUtil.compareState(masterGlobalStateMgr, slaveGlobalStateMgr));
181+
}
182+
183+
@Test
184+
public void testBeginTransactionEditLogException() throws Exception {
185+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
186+
EditLog spyEditLog = spy(masterGlobalStateMgr.getEditLog());
187+
doThrow(new RuntimeException("EditLog write failed"))
188+
.when(spyEditLog).logInsertTransactionState(any(TransactionState.class), any());
189+
EditLog originalEditLog = replaceDatabaseTransactionMgrEditLog(spyEditLog);
190+
191+
String label = UUIDUtil.genUUID().toString();
192+
try {
193+
RuntimeException exception = Assertions.assertThrows(RuntimeException.class,
194+
() -> masterTransMgr.beginTransaction(GlobalStateMgrTestUtil.testDbId1,
195+
Lists.newArrayList(GlobalStateMgrTestUtil.testTableId1),
196+
label, transactionSource, LoadJobSourceType.FRONTEND,
197+
Config.stream_load_default_timeout_second));
198+
assertEditLogWriteFailed(exception);
199+
assertEquals(0, masterTransMgr.getTransactionNum());
200+
assertEquals(TransactionStatus.UNKNOWN,
201+
masterTransMgr.getLabelStatus(GlobalStateMgrTestUtil.testDbId1, label).getStatus());
202+
} finally {
203+
replaceDatabaseTransactionMgrEditLog(originalEditLog);
204+
}
205+
}
206+
165207
@Test
166208
public void testBeginTransactionWithSameLabel() throws LabelAlreadyUsedException, AnalysisException,
167209
RunningTxnExceedException, DuplicatedRequestException {
@@ -197,6 +239,50 @@ public void testBeginTransactionWithSameLabel() throws LabelAlreadyUsedException
197239
}
198240
}
199241

242+
@Test
243+
public void testAbortTransactionEditLogAndReplay() throws Exception {
244+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
245+
String label = UUIDUtil.genUUID().toString();
246+
long transactionId = masterTransMgr
247+
.beginTransaction(GlobalStateMgrTestUtil.testDbId1, Lists.newArrayList(GlobalStateMgrTestUtil.testTableId1),
248+
label, transactionSource, LoadJobSourceType.FRONTEND, Config.stream_load_default_timeout_second);
249+
250+
masterTransMgr.abortTransaction(GlobalStateMgrTestUtil.testDbId1, transactionId, "artificial failure");
251+
252+
TransactionState transactionState = fakeEditLog.getTransaction(transactionId);
253+
assertNotNull(transactionState);
254+
assertEquals(TransactionStatus.ABORTED, transactionState.getTransactionStatus());
255+
assertEquals("artificial failure", transactionState.getReason());
256+
257+
FakeGlobalStateMgr.setGlobalStateMgr(slaveGlobalStateMgr);
258+
slaveTransMgr.replayUpsertTransactionState(transactionState);
259+
assertTrue(GlobalStateMgrTestUtil.compareState(masterGlobalStateMgr, slaveGlobalStateMgr));
260+
}
261+
262+
@Test
263+
public void testAbortTransactionEditLogException() throws Exception {
264+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
265+
String label = UUIDUtil.genUUID().toString();
266+
long transactionId = masterTransMgr
267+
.beginTransaction(GlobalStateMgrTestUtil.testDbId1, Lists.newArrayList(GlobalStateMgrTestUtil.testTableId1),
268+
label, transactionSource, LoadJobSourceType.FRONTEND, Config.stream_load_default_timeout_second);
269+
270+
EditLog spyEditLog = spy(masterGlobalStateMgr.getEditLog());
271+
doThrow(new RuntimeException("EditLog write failed"))
272+
.when(spyEditLog).logInsertTransactionState(any(TransactionState.class), any());
273+
EditLog originalEditLog = replaceDatabaseTransactionMgrEditLog(spyEditLog);
274+
try {
275+
RuntimeException exception = Assertions.assertThrows(RuntimeException.class,
276+
() -> masterTransMgr.abortTransaction(GlobalStateMgrTestUtil.testDbId1,
277+
transactionId, "artificial failure"));
278+
assertEditLogWriteFailed(exception);
279+
assertEquals(TransactionStatus.PREPARE, masterTransMgr
280+
.getTransactionState(GlobalStateMgrTestUtil.testDbId1, transactionId).getTransactionStatus());
281+
} finally {
282+
replaceDatabaseTransactionMgrEditLog(originalEditLog);
283+
}
284+
}
285+
200286
// all replica committed success
201287
@Test
202288
public void testCommitTransaction1() throws StarRocksException {
@@ -900,6 +986,93 @@ public void testPrepareTransaction() throws StarRocksException {
900986
assertTrue(GlobalStateMgrTestUtil.compareState(masterGlobalStateMgr, slaveGlobalStateMgr));
901987
}
902988

989+
@Test
990+
public void testPrepareTransactionEditLogException() throws Exception {
991+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
992+
long transactionId = masterTransMgr
993+
.beginTransaction(GlobalStateMgrTestUtil.testDbId1, Lists.newArrayList(GlobalStateMgrTestUtil.testTableId1),
994+
UUIDUtil.genUUID().toString(), transactionSource,
995+
LoadJobSourceType.FRONTEND, Config.stream_load_default_timeout_second);
996+
997+
EditLog spyEditLog = spy(masterGlobalStateMgr.getEditLog());
998+
doThrow(new RuntimeException("EditLog write failed"))
999+
.when(spyEditLog).logInsertTransactionState(any(TransactionState.class), any());
1000+
EditLog originalEditLog = replaceDatabaseTransactionMgrEditLog(spyEditLog);
1001+
try {
1002+
RuntimeException exception = Assertions.assertThrows(RuntimeException.class,
1003+
() -> masterTransMgr.prepareTransaction(GlobalStateMgrTestUtil.testDbId1, transactionId, -1,
1004+
buildTabletCommitInfos(), Lists.newArrayList(), null));
1005+
assertEditLogWriteFailed(exception);
1006+
TransactionState transactionState =
1007+
masterTransMgr.getTransactionState(GlobalStateMgrTestUtil.testDbId1, transactionId);
1008+
assertEquals(TransactionStatus.PREPARE, transactionState.getTransactionStatus());
1009+
assertTrue(transactionState.getIdToTableCommitInfos().isEmpty());
1010+
} finally {
1011+
replaceDatabaseTransactionMgrEditLog(originalEditLog);
1012+
}
1013+
}
1014+
1015+
@Test
1016+
public void testCommitPreparedTransactionEditLogException() throws Exception {
1017+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
1018+
long transactionId = masterTransMgr
1019+
.beginTransaction(GlobalStateMgrTestUtil.testDbId1, Lists.newArrayList(GlobalStateMgrTestUtil.testTableId1),
1020+
UUIDUtil.genUUID().toString(), transactionSource,
1021+
LoadJobSourceType.FRONTEND, Config.stream_load_default_timeout_second);
1022+
masterTransMgr.prepareTransaction(GlobalStateMgrTestUtil.testDbId1, transactionId, -1,
1023+
buildTabletCommitInfos(), Lists.newArrayList(), null);
1024+
assertEquals(TransactionStatus.PREPARED,
1025+
masterTransMgr.getTransactionState(GlobalStateMgrTestUtil.testDbId1, transactionId).getTransactionStatus());
1026+
1027+
EditLog spyEditLog = spy(masterGlobalStateMgr.getEditLog());
1028+
doThrow(new RuntimeException("EditLog write failed"))
1029+
.when(spyEditLog).logInsertTransactionState(any(TransactionState.class), any());
1030+
EditLog originalEditLog = replaceDatabaseTransactionMgrEditLog(spyEditLog);
1031+
try {
1032+
RuntimeException exception = Assertions.assertThrows(RuntimeException.class,
1033+
() -> masterTransMgr.commitPreparedTransaction(
1034+
masterGlobalStateMgr.getLocalMetastore().getDb(GlobalStateMgrTestUtil.testDbId1),
1035+
transactionId, 1000L));
1036+
assertEditLogWriteFailed(exception);
1037+
assertEquals(TransactionStatus.PREPARED, masterTransMgr
1038+
.getTransactionState(GlobalStateMgrTestUtil.testDbId1, transactionId).getTransactionStatus());
1039+
} finally {
1040+
replaceDatabaseTransactionMgrEditLog(originalEditLog);
1041+
}
1042+
}
1043+
1044+
@Test
1045+
public void testFinishTransactionEditLogException() throws Exception {
1046+
FakeGlobalStateMgr.setGlobalStateMgr(masterGlobalStateMgr);
1047+
long transactionId = masterTransMgr
1048+
.beginTransaction(GlobalStateMgrTestUtil.testDbId1, Lists.newArrayList(GlobalStateMgrTestUtil.testTableId1),
1049+
UUIDUtil.genUUID().toString(), transactionSource,
1050+
LoadJobSourceType.FRONTEND, Config.stream_load_default_timeout_second);
1051+
masterTransMgr.commitTransaction(GlobalStateMgrTestUtil.testDbId1, transactionId, buildTabletCommitInfos(),
1052+
Lists.newArrayList(), null);
1053+
1054+
Partition testPartition = masterGlobalStateMgr.getLocalMetastore()
1055+
.getTable(GlobalStateMgrTestUtil.testDbId1, GlobalStateMgrTestUtil.testTableId1)
1056+
.getPartition(GlobalStateMgrTestUtil.testPartition1);
1057+
long visibleVersionBefore = testPartition.getDefaultPhysicalPartition().getVisibleVersion();
1058+
1059+
EditLog spyEditLog = spy(masterGlobalStateMgr.getEditLog());
1060+
doThrow(new RuntimeException("EditLog write failed"))
1061+
.when(spyEditLog).logInsertTransactionState(any(TransactionState.class), any());
1062+
EditLog originalEditLog = replaceDatabaseTransactionMgrEditLog(spyEditLog);
1063+
try {
1064+
RuntimeException exception = Assertions.assertThrows(RuntimeException.class,
1065+
() -> masterTransMgr.finishTransaction(GlobalStateMgrTestUtil.testDbId1,
1066+
transactionId, Sets.newHashSet()));
1067+
assertEditLogWriteFailed(exception);
1068+
assertEquals(TransactionStatus.COMMITTED, masterTransMgr
1069+
.getTransactionState(GlobalStateMgrTestUtil.testDbId1, transactionId).getTransactionStatus());
1070+
assertEquals(visibleVersionBefore, testPartition.getDefaultPhysicalPartition().getVisibleVersion());
1071+
} finally {
1072+
replaceDatabaseTransactionMgrEditLog(originalEditLog);
1073+
}
1074+
}
1075+
9031076
@Test
9041077
public void testSaveLoadJsonFormatImage() throws Exception {
9051078
long transactionId = masterTransMgr
@@ -1083,4 +1256,23 @@ public void testGetLabelStatus() throws Exception {
10831256
Assertions.assertEquals(TransactionStatus.ABORTED, state3.getStatus());
10841257
Assertions.assertEquals("artificial failure", state3.getReason());
10851258
}
1259+
1260+
private List<TabletCommitInfo> buildTabletCommitInfos() {
1261+
return Lists.newArrayList(
1262+
new TabletCommitInfo(GlobalStateMgrTestUtil.testTabletId1, GlobalStateMgrTestUtil.testBackendId1),
1263+
new TabletCommitInfo(GlobalStateMgrTestUtil.testTabletId1, GlobalStateMgrTestUtil.testBackendId2),
1264+
new TabletCommitInfo(GlobalStateMgrTestUtil.testTabletId1, GlobalStateMgrTestUtil.testBackendId3));
1265+
}
1266+
1267+
private EditLog replaceDatabaseTransactionMgrEditLog(EditLog editLog) throws Exception {
1268+
DatabaseTransactionMgr dbTransactionMgr = masterTransMgr.getDatabaseTransactionMgr(GlobalStateMgrTestUtil.testDbId1);
1269+
EditLog originalEditLog = Deencapsulation.getField(dbTransactionMgr, "editLog");
1270+
Deencapsulation.setField(dbTransactionMgr, "editLog", editLog);
1271+
return originalEditLog;
1272+
}
1273+
1274+
private void assertEditLogWriteFailed(RuntimeException exception) {
1275+
Assertions.assertTrue(exception.getMessage().contains("EditLog write failed")
1276+
|| exception.getCause() != null && exception.getCause().getMessage().contains("EditLog write failed"));
1277+
}
10861278
}

0 commit comments

Comments
 (0)