From 606837f2cbb2616b7b4038c7c0e0b82412a18ded Mon Sep 17 00:00:00 2001 From: klion26 Date: Sun, 20 Oct 2024 17:02:01 +0800 Subject: [PATCH] [AMORO-3279] Get the total result when retrieve the optimizing tables from db Before the change, the total number of optimizing tables with the given filter will be retrieved from memory, this means that we'll retrieve info from two different place, after the change, we'll retrieve the optimizing tables and total result both frm db by using PageHelper. --- .../controller/OptimizerGroupController.java | 36 ++- .../server/optimizing/OptimizingStatus.java | 9 + .../persistence/mapper/TableMetaMapper.java | 12 +- .../server/table/DefaultTableService.java | 62 ++-- .../amoro/server/table/TableManager.java | 7 - .../amoro/server/table/TableService.java | 8 +- .../server/TestDefaultOptimizingService.java | 279 ++++++++++++++++++ .../optimizing/OptimizingStatusTest.java | 13 + 8 files changed, 371 insertions(+), 55 deletions(-) diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/OptimizerGroupController.java b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/OptimizerGroupController.java index 5a58a90beb..0d9a37da85 100644 --- a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/OptimizerGroupController.java +++ b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/controller/OptimizerGroupController.java @@ -37,6 +37,9 @@ import org.apache.amoro.server.table.TableRuntime; import org.apache.amoro.server.table.TableService; import org.apache.amoro.shade.guava32.com.google.common.base.Preconditions; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.ws.rs.BadRequestException; @@ -52,6 +55,8 @@ /** The controller that handles optimizer requests. */ public class OptimizerGroupController { + private static final Logger LOG = LoggerFactory.getLogger(OptimizerGroupController.class); + private static final String ALL_GROUP = "all"; private final TableService tableService; private final DefaultOptimizingService optimizerManager; @@ -82,17 +87,32 @@ public void getOptimizerTables(Context ctx) { String optimizerGroupUsedInDbFilter = ALL_GROUP.equals(optimizerGroup) ? null : optimizerGroup; // get all info from underlying table table_runtime - List tableRuntimeBeans = + List statusCodes = new ArrayList<>(actionFilter.size()); + for (String action : actionFilter) { + OptimizingStatus status = OptimizingStatus.ofDisplayValue(action); + if (status == null) { + LOG.warn("Can't find optimizer status for action:{}, skip it.", action); + } else { + statusCodes.add(status.getCode()); + } + } + + // use null to mark the filter as null filter + if (statusCodes.isEmpty()) { + statusCodes = null; + } + Pair, Integer> tableRuntimeBeans = tableService.getTableRuntimes( - optimizerGroupUsedInDbFilter, dbFilterStr, tableFilterStr, pageSize, offset); + optimizerGroupUsedInDbFilter, + dbFilterStr, + tableFilterStr, + statusCodes, + pageSize, + offset); List tableRuntimes = - tableRuntimeBeans.stream() + tableRuntimeBeans.getLeft().stream() .map(meta -> tableService.getRuntime(meta.getTableId())) - .filter( - tableRuntime -> - actionFilter.isEmpty() - || actionFilter.contains(tableRuntime.getOptimizingStatus().displayValue())) .collect(Collectors.toList()); PageResult amsPageResult = @@ -100,7 +120,7 @@ public void getOptimizerTables(Context ctx) { tableRuntimes.stream() .map(OptimizingUtil::buildTableOptimizeInfo) .collect(Collectors.toList()), - tableService.listRuntimes(dbFilterStr, tableFilterStr).size()); + tableRuntimeBeans.getRight()); ctx.json(OkResponse.of(amsPageResult)); } diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/optimizing/OptimizingStatus.java b/amoro-ams/src/main/java/org/apache/amoro/server/optimizing/OptimizingStatus.java index 5e34be9ea9..d9624a7f39 100644 --- a/amoro-ams/src/main/java/org/apache/amoro/server/optimizing/OptimizingStatus.java +++ b/amoro-ams/src/main/java/org/apache/amoro/server/optimizing/OptimizingStatus.java @@ -58,4 +58,13 @@ public static OptimizingStatus ofCode(int code) { } return null; } + + public static OptimizingStatus ofDisplayValue(String displayValue) { + for (OptimizingStatus status : values()) { + if (status.displayValue.equals(displayValue)) { + return status; + } + } + return null; + } } diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java b/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java index ead0b70066..10e4c2d543 100644 --- a/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java +++ b/amoro-ams/src/main/java/org/apache/amoro/server/persistence/mapper/TableMetaMapper.java @@ -469,9 +469,12 @@ List selectTableIdentifiersByCatalog( + " AND db_name like '%' || #{fuzzyDbName, jdbcType=VARCHAR} || '%' " + " AND table_name like CONCAT('%', #{fuzzyTableName, jdbcType=VARCHAR}, '%') " + " AND table_name like '%' || #{fuzzyTableName, jdbcType=VARCHAR} || '%' " + + "" + + "AND optimizing_status_code IN (" + + "" + + "#{item}" + + " ) " + "ORDER BY optimizing_status_code, optimizing_status_start_time DESC " - + " LIMIT #{limitCount} OFFSET #{offsetNum} " - + " OFFSET #{offsetNum} ROWS FETCH FIRST #{limitCount} ROWS ONLY " + "") @Results({ @Result(property = "tableId", column = "table_id"), @@ -523,6 +526,7 @@ List selectTableRuntimesForOptimizerGroup( @Param("optimizerGroup") String optimizerGroup, @Param("fuzzyDbName") String fuzzyDbName, @Param("fuzzyTableName") String fuzzyTableName, - @Param("limitCount") int limitCount, - @Param("offsetNum") int offset); + @Param("statusCodeFilter") List statusCodeFilter, + @Param("pageNum") int pageNum, + @Param("pageSize") int pageSize); } diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/table/DefaultTableService.java b/amoro-ams/src/main/java/org/apache/amoro/server/table/DefaultTableService.java index c5c613228e..71055ceb3e 100644 --- a/amoro-ams/src/main/java/org/apache/amoro/server/table/DefaultTableService.java +++ b/amoro-ams/src/main/java/org/apache/amoro/server/table/DefaultTableService.java @@ -18,6 +18,9 @@ package org.apache.amoro.server.table; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; import org.apache.amoro.AmoroTable; import org.apache.amoro.NoSuchTableException; import org.apache.amoro.ServerTableIdentifier; @@ -56,15 +59,14 @@ import org.apache.amoro.shade.guava32.com.google.common.util.concurrent.ThreadFactoryBuilder; import org.apache.amoro.utils.TablePropertyUtil; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -344,18 +346,35 @@ public List getBlockers(TableIdentifier tableIdentifier) { } @Override - public List getTableRuntimes( + public Pair, Integer> getTableRuntimes( String optimizerGroup, @Nullable String fuzzyDbName, @Nullable String fuzzyTableName, + @Nullable List statusCodeFilters, int limit, int offset) { checkStarted(); - return getAs( - TableMetaMapper.class, - mapper -> - mapper.selectTableRuntimesForOptimizerGroup( - optimizerGroup, fuzzyDbName, fuzzyTableName, limit, offset)); + + // page helper is 1-based + int pageNumber = (offset / limit) + 1; + + try (Page ignore = PageHelper.startPage(pageNumber, limit, true)) { + int total = 0; + List ret = + getAs( + TableMetaMapper.class, + mapper -> + mapper.selectTableRuntimesForOptimizerGroup( + optimizerGroup, + fuzzyDbName, + fuzzyTableName, + statusCodeFilters, + limit, + offset)); + PageInfo pageInfo = new PageInfo<>(ret); + total = (int) pageInfo.getTotal(); + return Pair.of(ret, total); + } } public InternalCatalog getInternalCatalog(String catalogName) { @@ -473,33 +492,6 @@ public TableRuntime getRuntime(Long tableId) { return tableRuntimeMap.get(tableId); } - public Map listRuntimes( - @Nullable String dbFilter, @Nullable String tableFilter) { - checkStarted(); - // no filter, will return all the table runtime. - if (dbFilter == null && tableFilter == null) { - return Collections.unmodifiableMap(tableRuntimeMap); - } - - Map filteredRuntimes = new HashMap<>(); - for (Map.Entry entry : tableRuntimeMap.entrySet()) { - ServerTableIdentifier identifier = entry.getValue().getTableIdentifier(); - // skip the runtime which fails the db filter. - if (dbFilter != null && !identifier.getDatabase().contains(dbFilter)) { - continue; - } - - // skip the runtime which fails the table filter. - if (tableFilter != null && !identifier.getTableName().contains(tableFilter)) { - continue; - } - - filteredRuntimes.put(entry.getKey(), entry.getValue()); - } - - return filteredRuntimes; - } - @Override public boolean contains(Long tableId) { checkStarted(); diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/table/TableManager.java b/amoro-ams/src/main/java/org/apache/amoro/server/table/TableManager.java index cf5c2f57f3..4735bca2d7 100644 --- a/amoro-ams/src/main/java/org/apache/amoro/server/table/TableManager.java +++ b/amoro-ams/src/main/java/org/apache/amoro/server/table/TableManager.java @@ -21,10 +21,6 @@ import org.apache.amoro.AmoroTable; import org.apache.amoro.ServerTableIdentifier; -import javax.annotation.Nullable; - -import java.util.Map; - public interface TableManager extends TableRuntimeHandler { /** @@ -37,9 +33,6 @@ public interface TableManager extends TableRuntimeHandler { TableRuntime getRuntime(Long tableId); - /** Return the table runtimes associated to the given filter. */ - Map listRuntimes(@Nullable String dbFilter, @Nullable String tableFilter); - default boolean contains(Long tableId) { return getRuntime(tableId) != null; } diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/table/TableService.java b/amoro-ams/src/main/java/org/apache/amoro/server/table/TableService.java index 5cbd257018..e069f235f7 100644 --- a/amoro-ams/src/main/java/org/apache/amoro/server/table/TableService.java +++ b/amoro-ams/src/main/java/org/apache/amoro/server/table/TableService.java @@ -24,6 +24,7 @@ import org.apache.amoro.api.TableIdentifier; import org.apache.amoro.server.catalog.CatalogService; import org.apache.amoro.server.persistence.TableRuntimeMeta; +import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nullable; @@ -100,13 +101,18 @@ Blocker block( * @param fuzzyDbName the fuzzy db name used to filter the result, will be null if no filter set. * @param fuzzyTableName the fuzzy table name used to filter the result, will be null if no filter * set. + * @param statusCodeFilters the status code used to filter the result, wil be null if no filter + * set. * @param limit How many entries we want to retrieve. * @param offset The entries we'll skip when retrieving the entries. + * @return A pair with the first entry is the actual list under the filters with the offset and + * limit, and second value will be the number of total entries under the filters. */ - List getTableRuntimes( + Pair, Integer> getTableRuntimes( String optimizerGroup, @Nullable String fuzzyDbName, @Nullable String fuzzyTableName, + @Nullable List statusCodeFilters, int limit, int offset); } diff --git a/amoro-ams/src/test/java/org/apache/amoro/server/TestDefaultOptimizingService.java b/amoro-ams/src/test/java/org/apache/amoro/server/TestDefaultOptimizingService.java index 0c15cbf6f0..78a68b3dfb 100644 --- a/amoro-ams/src/test/java/org/apache/amoro/server/TestDefaultOptimizingService.java +++ b/amoro-ams/src/test/java/org/apache/amoro/server/TestDefaultOptimizingService.java @@ -18,8 +18,12 @@ package org.apache.amoro.server; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + import org.apache.amoro.BasicTableTestHelper; import org.apache.amoro.OptimizerProperties; +import org.apache.amoro.ServerTableIdentifier; import org.apache.amoro.TableFormat; import org.apache.amoro.TableTestHelper; import org.apache.amoro.api.OptimizerRegisterInfo; @@ -34,21 +38,29 @@ import org.apache.amoro.optimizing.RewriteFilesOutput; import org.apache.amoro.optimizing.TableOptimizing; import org.apache.amoro.process.ProcessStatus; +import org.apache.amoro.server.optimizing.OptimizingProcess; import org.apache.amoro.server.optimizing.OptimizingStatus; +import org.apache.amoro.server.optimizing.OptimizingType; import org.apache.amoro.server.optimizing.TaskRuntime; +import org.apache.amoro.server.optimizing.plan.OptimizingEvaluator; +import org.apache.amoro.server.persistence.TableRuntimeMeta; import org.apache.amoro.server.resource.OptimizerInstance; import org.apache.amoro.server.table.AMSTableTestBase; import org.apache.amoro.server.table.TableRuntime; +import org.apache.amoro.server.table.TableService; import org.apache.amoro.server.table.executor.TableRuntimeRefreshExecutor; import org.apache.amoro.shade.guava32.com.google.common.collect.Lists; import org.apache.amoro.shade.guava32.com.google.common.collect.Maps; import org.apache.amoro.table.MixedTable; +import org.apache.amoro.table.TableProperties; import org.apache.amoro.table.UnkeyedTable; import org.apache.amoro.utils.SerializationUtil; +import org.apache.commons.lang3.tuple.Pair; import org.apache.iceberg.AppendFiles; import org.apache.iceberg.DataFile; import org.apache.iceberg.data.Record; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.Assertions; @@ -56,6 +68,8 @@ import org.junit.runners.Parameterized; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -344,6 +358,271 @@ public void testReloadFailedTask() { assertTaskStatus(TaskRuntime.Status.PLANNED); } + /** Test the logic for {@link TableService#getTableRuntimes}. */ + @Test + public void testGetRuntimes() { + String catalog = "catalog"; + String db1 = "db1"; + + String optimizerGroup1 = "opGroup1"; + + // 1 add some tables + + // table in opGroup1 + Map properties = new HashMap<>(); + properties.put(TableProperties.SELF_OPTIMIZING_GROUP, optimizerGroup1); + + // 1.1 add tables with IDLE status + // the status will be OptimizingStatus.IDLE default + String idle1InGroup1 = "idle1InGroup1"; + TableRuntime idle1 = + new TableRuntime( + ServerTableIdentifier.of(10001L, catalog, db1, idle1InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + + // the status will be OptimizingStatus.IDLE default + String idle2InGroup1 = "idle2InGroup1"; + TableRuntime idle2 = + new TableRuntime( + ServerTableIdentifier.of(10002L, catalog, db1, idle2InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + + // 1.2 add tables with PENDING status + String pending1InGroup1 = "pending1InGroup1"; + TableRuntime pending1 = + new TableRuntime( + ServerTableIdentifier.of(10003L, catalog, db1, pending1InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + // update status + pending1.setPendingInput(new OptimizingEvaluator.PendingInput()); + + String pending2InGroup1 = "pending2InGroup1"; + TableRuntime pending2 = + new TableRuntime( + ServerTableIdentifier.of(10004L, catalog, db1, pending2InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + // update status + pending2.setPendingInput(new OptimizingEvaluator.PendingInput()); + + // 1.3 add tables with PLANNING status + String db2 = "db2"; + String plan1InGroup1 = "plan1InGroup1"; + TableRuntime plan1 = + new TableRuntime( + ServerTableIdentifier.of(10005L, catalog, db2, plan1InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + plan1.beginPlanning(); + + String plan2InGroup1 = "plan2InGroup1"; + TableRuntime plan2 = + new TableRuntime( + ServerTableIdentifier.of(10006L, catalog, db2, plan2InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + plan2.beginPlanning(); + + // 1.4 add tables with COMMITTING status + String committing1InGroup1 = "committing1InGroup1"; + TableRuntime committing1 = + new TableRuntime( + ServerTableIdentifier.of( + 10007L, catalog, db2, committing1InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + committing1.beginCommitting(); + + String commiting2InGroup1 = "committing2InGroup1"; + TableRuntime committing2 = + new TableRuntime( + ServerTableIdentifier.of(10008L, catalog, db2, commiting2InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + committing2.beginCommitting(); + + // 1.5 add tables with MINOR_OPTIMIZING status + String minor1InGroup1 = "minor1InGroup1"; + TableRuntime minor1 = + new TableRuntime( + ServerTableIdentifier.of(10009L, catalog, db2, minor1InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process = mock(OptimizingProcess.class); + doReturn(1L).when(process).getProcessId(); + doReturn(OptimizingType.MINOR).when(process).getOptimizingType(); + minor1.beginProcess(process); + + String minor2InGroup1 = "minor2InGroup1"; + TableRuntime minor2 = + new TableRuntime( + ServerTableIdentifier.of(10010L, catalog, db2, minor2InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process2 = mock(OptimizingProcess.class); + doReturn(2L).when(process2).getProcessId(); + doReturn(OptimizingType.MINOR).when(process2).getOptimizingType(); + minor2.beginProcess(process2); + + // 1.6 add tables with MAJOR_OPTIMIZING status + String major1InGroup1 = "major1InGroup1"; + TableRuntime major1 = + new TableRuntime( + ServerTableIdentifier.of(10011L, catalog, db1, major1InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process3 = mock(OptimizingProcess.class); + doReturn(3L).when(process3).getProcessId(); + doReturn(OptimizingType.MAJOR).when(process3).getOptimizingType(); + major1.beginProcess(process3); + + String major2InGroup1 = "major2InGroup1"; + TableRuntime major2 = + new TableRuntime( + ServerTableIdentifier.of(10012L, catalog, db1, major2InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process4 = mock(OptimizingProcess.class); + doReturn(4L).when(process4).getProcessId(); + doReturn(OptimizingType.MAJOR).when(process4).getOptimizingType(); + major2.beginProcess(process4); + + // 1.7 add tables with FULL_OPTIMIZING status + String full1InGroup1 = "full1InGroup1"; + TableRuntime full1 = + new TableRuntime( + ServerTableIdentifier.of(10013L, catalog, db1, full1InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process5 = mock(OptimizingProcess.class); + doReturn(5L).when(process5).getProcessId(); + doReturn(OptimizingType.FULL).when(process5).getOptimizingType(); + full1.beginProcess(process5); + + String full2InGroup1 = "full2InGroup1"; + TableRuntime full2 = + new TableRuntime( + ServerTableIdentifier.of(10014L, catalog, db1, full2InGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process6 = mock(OptimizingProcess.class); + doReturn(6L).when(process6).getProcessId(); + doReturn(OptimizingType.FULL).when(process6).getOptimizingType(); + full2.beginProcess(process6); + + // 1.8 add tables in other group with MINOR_OPTIMIZING status + // table in other group. + String opGroup2 = "opGroup2-other"; + properties.put(TableProperties.SELF_OPTIMIZING_GROUP, opGroup2); + String minor1InOtherGroup1 = "minor1-InOtherGroup"; + TableRuntime minor1Other = + new TableRuntime( + ServerTableIdentifier.of( + 10015L, catalog, db1, minor1InOtherGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process7 = mock(OptimizingProcess.class); + doReturn(7L).when(process7).getProcessId(); + doReturn(OptimizingType.MINOR).when(process7).getOptimizingType(); + minor1Other.beginProcess(process7); + + String minor2InOtherGroup1 = "minor2-InOtherGroup"; + TableRuntime minor2Other = + new TableRuntime( + ServerTableIdentifier.of( + 10016L, catalog, db1, minor2InOtherGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process8 = mock(OptimizingProcess.class); + doReturn(8L).when(process8).getProcessId(); + doReturn(OptimizingType.MINOR).when(process8).getOptimizingType(); + minor2Other.beginProcess(process8); + + String minor3InOtherGroup1 = "minor3-InOtherGroup"; + TableRuntime minor3Other = + new TableRuntime( + ServerTableIdentifier.of( + 10017L, catalog, db1, minor3InOtherGroup1, TableFormat.ICEBERG), + tableService(), + properties); + OptimizingProcess process9 = mock(OptimizingProcess.class); + doReturn(9L).when(process9).getProcessId(); + doReturn(OptimizingType.MINOR).when(process9).getOptimizingType(); + minor3Other.beginProcess(process9); + + // 2 test and assert the result + // 2.1 only optimize group filter set + Pair, Integer> res = + tableService() + .getTableRuntimes(optimizerGroup1, null, null, Collections.emptyList(), 10, 0); + Integer expectedTotalinGroup1 = 14; + Assert.assertEquals(expectedTotalinGroup1, res.getRight()); + Assert.assertEquals(10, res.getLeft().size()); + + // 2.2 set optimize group and db filter + res = + tableService().getTableRuntimes(optimizerGroup1, db1, null, Collections.emptyList(), 5, 0); + // there are 8 tables in db1 in optimizerGroup1 + Integer expectedTotalGroup1Db1 = 8; + Assert.assertEquals(expectedTotalGroup1Db1, res.getRight()); + Assert.assertEquals(5, res.getLeft().size()); + + // 2.3 set optimize group and table filter + // there are 3 tables with suffix "-InOtherGroup" in opGroup2 + String fuzzyDbName = "InOtherGroup"; + res = + tableService().getTableRuntimes(opGroup2, null, fuzzyDbName, Collections.emptyList(), 2, 0); + Integer expectedTotalWithFuzzyDbName = 3; + Assert.assertEquals(expectedTotalWithFuzzyDbName, res.getRight()); + Assert.assertEquals(2, res.getLeft().size()); + + res = + tableService().getTableRuntimes(opGroup2, null, fuzzyDbName, Collections.emptyList(), 5, 0); + Assert.assertEquals(expectedTotalWithFuzzyDbName, res.getRight()); + // there are only 3 tables with the suffix in opGroup2 + Assert.assertEquals(3, res.getLeft().size()); + + // 2.4 set optimize group and status filter, with only one status + List statusCode = new ArrayList<>(); + statusCode.add(OptimizingStatus.MAJOR_OPTIMIZING.getCode()); + res = tableService().getTableRuntimes(optimizerGroup1, null, null, statusCode, 10, 0); + Integer expectedTotalInGroup1WithMajorStatus = 2; + Assert.assertEquals(expectedTotalInGroup1WithMajorStatus, res.getRight()); + Assert.assertEquals(2, res.getLeft().size()); + + // 2.5 set optimize group and status filter with two statuses + statusCode.clear(); + statusCode.add(OptimizingStatus.MINOR_OPTIMIZING.getCode()); + statusCode.add(OptimizingStatus.MAJOR_OPTIMIZING.getCode()); + res = tableService().getTableRuntimes(optimizerGroup1, null, null, statusCode, 3, 0); + Integer expectedTotalInGroup1WithMinorMajorStatus = 4; + Assert.assertEquals(expectedTotalInGroup1WithMinorMajorStatus, res.getRight()); + Assert.assertEquals(3, res.getLeft().size()); + + // 2.6 all filter set which contains result + statusCode.clear(); + statusCode.add(OptimizingStatus.PENDING.getCode()); + statusCode.add(OptimizingStatus.FULL_OPTIMIZING.getCode()); + String tableFilter = "pending"; + res = tableService().getTableRuntimes(optimizerGroup1, db1, tableFilter, statusCode, 10, 0); + Integer expectedTotalInGroup1InDb1WithTableFilterAndStatus = 2; + Assert.assertEquals(expectedTotalInGroup1InDb1WithTableFilterAndStatus, res.getRight()); + Assert.assertEquals(2, res.getLeft().size()); + + // 2.7 all filters with no result + statusCode.clear(); + statusCode.add(OptimizingStatus.PENDING.getCode()); + statusCode.add(OptimizingStatus.FULL_OPTIMIZING.getCode()); + String wrongTableFilter2 = "noTableWithName"; + res = + tableService().getTableRuntimes(optimizerGroup1, db1, wrongTableFilter2, statusCode, 10, 0); + Assert.assertEquals(0, (int) res.getRight()); + Assert.assertTrue(res.getLeft().isEmpty()); + } + private OptimizerRegisterInfo buildRegisterInfo() { OptimizerRegisterInfo registerInfo = new OptimizerRegisterInfo(); Map registerProperties = Maps.newHashMap(); diff --git a/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/OptimizingStatusTest.java b/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/OptimizingStatusTest.java index cadce03273..812122fdd5 100644 --- a/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/OptimizingStatusTest.java +++ b/amoro-ams/src/test/java/org/apache/amoro/server/optimizing/OptimizingStatusTest.java @@ -35,4 +35,17 @@ public void testOptimizingStatusCodeValue() { assertEquals(OptimizingStatus.PENDING, OptimizingStatus.ofCode(600)); assertEquals(OptimizingStatus.IDLE, OptimizingStatus.ofCode(700)); } + + @Test + public void testOptimizingStatusDisplayValue() { + assertEquals(7, OptimizingStatus.values().length); + + assertEquals(OptimizingStatus.FULL_OPTIMIZING, OptimizingStatus.ofDisplayValue("full")); + assertEquals(OptimizingStatus.MAJOR_OPTIMIZING, OptimizingStatus.ofDisplayValue("major")); + assertEquals(OptimizingStatus.MINOR_OPTIMIZING, OptimizingStatus.ofDisplayValue("minor")); + assertEquals(OptimizingStatus.COMMITTING, OptimizingStatus.ofDisplayValue("committing")); + assertEquals(OptimizingStatus.PLANNING, OptimizingStatus.ofDisplayValue("planning")); + assertEquals(OptimizingStatus.PENDING, OptimizingStatus.ofDisplayValue("pending")); + assertEquals(OptimizingStatus.IDLE, OptimizingStatus.ofDisplayValue("idle")); + } }