@Test
  public void testDeleteTableIdentifierFailure() {
    createTable();
    ServerTableIdentifier tableIdentifier = serverTableIdentifier();

    // test list tables
    List<TableRuntimeMeta> tableRuntimeMetaListAfterAddTable = persistency.getTableRuntimeMetas();
    List<TableRuntimeMeta> tableRuntimeMetaListForOptimizerGroupAfterAddTable =
        persistency.getTableRuntimeMetasForOptimizerGroup(defaultResourceGroup().getName());
    Assert.assertEquals(1, tableRuntimeMetaListForOptimizerGroupAfterAddTable.size());
    Assert.assertEquals(1, tableRuntimeMetaListAfterAddTable.size());

    // create a tableIdentifier that throw exceptions when calling the getTableName() method, which
    // can lead to exceptions when deleting tableIdentifier in disposeTable().
    MockitoAnnotations.openMocks(this);
    when(tableIdentifierWithException.getId()).thenReturn(tableIdentifier.getId());
    when(tableIdentifierWithException.getIdentifier()).thenReturn(tableIdentifier.getIdentifier());
    when(tableIdentifierWithException.getCatalog()).thenReturn(tableIdentifier.getCatalog());
    when(tableIdentifierWithException.getDatabase()).thenReturn(tableIdentifier.getDatabase());
    when(tableIdentifierWithException.getTableName())
        .thenThrow(new RuntimeException("get TableName error"));

    Assert.assertThrows(
        "get TableName error",
        RuntimeException.class,
        () -> tableService().disposeTable(tableIdentifierWithException));

    // test list tables after disposing table
    // Because the doAsTransaction() method is used, when a tableIdentifier deletion exception
    // occurs, the tableRuntime and tableIdentifier will remain consistent and neither will actually
    // be deleted.
    List<TableRuntimeMeta> tableRuntimeMetaListAfterDropTable = persistency.getTableRuntimeMetas();
    List<TableRuntimeMeta> tableRuntimeMetaListForOptimizerGroupAfterDropTable =
        persistency.getTableRuntimeMetasForOptimizerGroup(defaultResourceGroup().getName());
    Assert.assertEquals(1, tableRuntimeMetaListForOptimizerGroupAfterDropTable.size());
    Assert.assertEquals(1, tableRuntimeMetaListAfterDropTable.size());

    dropTable();
    dropDatabase();
  }
Test synchronization in the anomaly scenario where the tableIdentifier is remained in
persistence and the tableRuntime is remained in memory but iceberg table does not exist.
amoro-ams/src/test/java/org/apache/amoro/server/table/TestSyncTableOfExternalCatalog.java