1818
1919package org .apache .amoro .server .scheduler .inline ;
2020
21+ import org .apache .amoro .AmoroTable ;
2122import org .apache .amoro .ServerTableIdentifier ;
2223import org .apache .amoro .TableFormat ;
2324import org .apache .amoro .TableRuntime ;
2425import org .apache .amoro .config .TableConfiguration ;
2526import org .apache .amoro .process .ProcessStatus ;
27+ import org .apache .amoro .server .catalog .InternalCatalog ;
2628import org .apache .amoro .server .persistence .PersistentBase ;
2729import org .apache .amoro .server .persistence .TableRuntimeMeta ;
2830import org .apache .amoro .server .persistence .mapper .TableMetaMapper ;
3133import org .apache .amoro .server .process .TableProcessMeta ;
3234import org .apache .amoro .server .table .DefaultTableRuntime ;
3335import org .apache .amoro .server .table .DefaultTableRuntimeStore ;
34- import org .apache .amoro .server .table .TableRuntimeHandler ;
36+ import org .apache .amoro .server .table .RuntimeHandlerChain ;
37+ import org .apache .amoro .server .table .TableService ;
3538import org .apache .amoro .server .table .cleanup .CleanupOperation ;
3639import org .apache .amoro .table .TableRuntimeStore ;
3740import org .apache .amoro .table .TableSummary ;
4144import java .util .Arrays ;
4245import java .util .Collections ;
4346import java .util .List ;
47+ import java .util .concurrent .atomic .AtomicInteger ;
4448
4549/**
4650 * This class tests all aspects of cleanup operation handling in {@link
@@ -60,17 +64,51 @@ public class TestPeriodicTableSchedulerCleanup extends PersistentBase {
6064 }
6165 }
6266
63- private static final TableRuntimeHandler TEST_HANDLER =
64- new TableRuntimeHandler () {
65- @ Override
66- public void handleTableChanged (
67- TableRuntime tableRuntime ,
68- org .apache .amoro .server .optimizing .OptimizingStatus originalStatus ) {}
67+ private static class OneShotTableService implements TableService {
68+ private final TableRuntime tableRuntime ;
69+ private final AtomicInteger getRuntimeCalls = new AtomicInteger ();
6970
70- @ Override
71- public void handleTableChanged (
72- TableRuntime tableRuntime , TableConfiguration originalConfig ) {}
73- };
71+ private OneShotTableService (TableRuntime tableRuntime ) {
72+ this .tableRuntime = tableRuntime ;
73+ }
74+
75+ @ Override
76+ public void addHandlerChain (RuntimeHandlerChain handler ) {}
77+
78+ @ Override
79+ public void initialize () {}
80+
81+ @ Override
82+ public void dispose () {}
83+
84+ @ Override
85+ public void onTableCreated (InternalCatalog catalog , ServerTableIdentifier identifier ) {}
86+
87+ @ Override
88+ public void onTableDropped (InternalCatalog catalog , ServerTableIdentifier identifier ) {}
89+
90+ @ Override
91+ public TableRuntime getRuntime (Long tableId ) {
92+ return getRuntimeCalls .getAndIncrement () == 0
93+ && tableRuntime .getTableIdentifier ().getId () == tableId
94+ ? tableRuntime
95+ : null ;
96+ }
97+
98+ @ Override
99+ public AmoroTable <?> loadTable (ServerTableIdentifier identifier ) {
100+ throw new UnsupportedOperationException (
101+ "loadTable is not expected in cleanup scheduler tests" );
102+ }
103+
104+ @ Override
105+ public void handleTableChanged (
106+ TableRuntime tableRuntime ,
107+ org .apache .amoro .server .optimizing .OptimizingStatus originalStatus ) {}
108+
109+ @ Override
110+ public void handleTableChanged (TableRuntime tableRuntime , TableConfiguration originalConfig ) {}
111+ }
74112
75113 /**
76114 * Create a test server table identifier with the given ID
@@ -153,6 +191,15 @@ private PeriodicTableSchedulerTestBase createTestExecutor(
153191 return new PeriodicTableSchedulerTestBase (null , cleanupOperation , enabled );
154192 }
155193
194+ private PeriodicTableSchedulerTestBase createTestExecutor (
195+ TableService tableService ,
196+ CleanupOperation cleanupOperation ,
197+ boolean enabled ,
198+ RuntimeException executionException ) {
199+ return new PeriodicTableSchedulerTestBase (
200+ tableService , cleanupOperation , enabled , executionException );
201+ }
202+
156203 /**
157204 * Create a test table executor with default enabled state (true)
158205 *
@@ -299,7 +346,7 @@ public void testCleanupProcessPersistence() {
299346 executor .persistCleanupResultForTest (tableRuntime , operation , processMeta .copy (), null );
300347 TableProcessMeta persistedSuccess = getProcessMeta (processMeta .getProcessId ());
301348 Assert .assertEquals (ProcessStatus .SUCCESS , persistedSuccess .getStatus ());
302- Assert .assertTrue (persistedSuccess .getCreateTime () < persistedSuccess .getFinishTime ());
349+ Assert .assertTrue (persistedSuccess .getCreateTime () <= persistedSuccess .getFinishTime ());
303350
304351 // Scenario 3: Failure handling - verify error persistence
305352 processMeta = executor .createCleanupProcessInfoForTest (tableRuntime , operation );
@@ -308,8 +355,63 @@ public void testCleanupProcessPersistence() {
308355
309356 TableProcessMeta persistedFailure = getProcessMeta (processMeta .getProcessId ());
310357 Assert .assertEquals (ProcessStatus .FAILED , persistedFailure .getStatus ());
311- Assert .assertEquals (testError .getMessage (), persistedFailure .getFailMessage ());
358+ Assert .assertTrue (persistedFailure .getFailMessage ().contains (testError .getMessage ()));
359+ Assert .assertTrue (persistedFailure .getFailMessage ().length () <= 4000 );
360+
361+ cleanUpTableProcess (tableId );
362+ }
363+ }
364+
365+ @ Test
366+ public void testExecuteTaskPersistsSuccess () {
367+ long tableId = 300L ;
368+ CleanupOperation operation = CleanupOperation .ORPHAN_FILES_CLEANING ;
369+ prepareTestEnvironment (Collections .singletonList (tableId ));
370+
371+ ServerTableIdentifier identifier = createTableIdentifier (tableId );
372+ DefaultTableRuntime tableRuntime = createDefaultTableRuntime (identifier );
373+ PeriodicTableSchedulerTestBase executor =
374+ createTestExecutor (new OneShotTableService (tableRuntime ), operation , true , null );
312375
376+ try {
377+ executor .executeTaskForTest (tableRuntime );
378+
379+ List <TableProcessMeta > processMetas =
380+ getAs (TableProcessMapper .class , m -> m .listProcessMeta (tableId , operation .name (), null ));
381+ Assert .assertEquals (1 , processMetas .size ());
382+ Assert .assertEquals (ProcessStatus .SUCCESS , processMetas .get (0 ).getStatus ());
383+ Assert .assertTrue (processMetas .get (0 ).getFinishTime () >= processMetas .get (0 ).getCreateTime ());
384+ } finally {
385+ executor .gracefulShutdown ();
386+ cleanUpTableProcess (tableId );
387+ }
388+ }
389+
390+ @ Test
391+ public void testExecuteTaskPersistsFailureWhenExecutionThrows () {
392+ long tableId = 301L ;
393+ CleanupOperation operation = CleanupOperation .DATA_EXPIRING ;
394+ prepareTestEnvironment (Collections .singletonList (tableId ));
395+
396+ ServerTableIdentifier identifier = createTableIdentifier (tableId );
397+ DefaultTableRuntime tableRuntime = createDefaultTableRuntime (identifier );
398+ RuntimeException executionException = new RuntimeException ("Execute task failed" );
399+ PeriodicTableSchedulerTestBase executor =
400+ createTestExecutor (
401+ new OneShotTableService (tableRuntime ), operation , true , executionException );
402+
403+ try {
404+ executor .executeTaskForTest (tableRuntime );
405+
406+ List <TableProcessMeta > processMetas =
407+ getAs (TableProcessMapper .class , m -> m .listProcessMeta (tableId , operation .name (), null ));
408+ Assert .assertEquals (1 , processMetas .size ());
409+ Assert .assertEquals (ProcessStatus .FAILED , processMetas .get (0 ).getStatus ());
410+ Assert .assertTrue (
411+ processMetas .get (0 ).getFailMessage ().contains (executionException .getMessage ()));
412+ Assert .assertTrue (processMetas .get (0 ).getFailMessage ().length () <= 4000 );
413+ } finally {
414+ executor .gracefulShutdown ();
313415 cleanUpTableProcess (tableId );
314416 }
315417 }
@@ -322,10 +424,9 @@ private TableProcessMeta getProcessMeta(long processId) {
322424 private void cleanUpTableProcess (long tableId ) {
323425 doAs (
324426 TableProcessMapper .class ,
325- mapper -> {
326- mapper
327- .listProcessMeta (tableId , null , null )
328- .forEach (p -> mapper .deleteBefore (tableId , p .getProcessId ()));
329- });
427+ mapper ->
428+ mapper
429+ .listProcessMeta (tableId , null , null )
430+ .forEach (p -> mapper .deleteBefore (tableId , p .getProcessId ())));
330431 }
331432}
0 commit comments