This is an automated email from the ASF dual-hosted git repository.

apolovtsev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 8251265a628 IGNITE-24397 Add tests for table removal for colocation 
(#5568)
8251265a628 is described below

commit 8251265a628922482ab2abba648b405ba2cdf924
Author: Alexander Polovtcev <[email protected]>
AuthorDate: Fri Apr 4 15:40:41 2025 +0300

    IGNITE-24397 Add tests for table removal for colocation (#5568)
---
 .../replicator/ItAbstractColocationTest.java       | 15 ++---
 .../replicator/ItReplicaLifecycleTest.java         | 65 +++++++++++++++++-----
 .../partition/replicator/fixtures/Node.java        |  2 +-
 .../PartitionReplicaLifecycleManager.java          |  5 +-
 .../replicator/ZonePartitionReplicaListener.java   | 35 +++++++++---
 .../replicator/raft/ZonePartitionRaftListener.java | 17 +++++-
 .../ignite/internal/table/InternalTable.java       |  1 +
 .../internal/table/distributed/TableManager.java   | 11 +---
 .../table/distributed/TableManagerTest.java        | 18 +++---
 9 files changed, 118 insertions(+), 51 deletions(-)

diff --git 
a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItAbstractColocationTest.java
 
b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItAbstractColocationTest.java
index 40f39368a82..29e82b56ebd 100644
--- 
a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItAbstractColocationTest.java
+++ 
b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItAbstractColocationTest.java
@@ -17,15 +17,15 @@
 
 package org.apache.ignite.internal.partition.replicator;
 
-import static java.util.Objects.requireNonNull;
 import static java.util.concurrent.CompletableFuture.allOf;
 import static java.util.stream.Collectors.toList;
 import static 
org.apache.ignite.internal.TestDefaultProfilesNames.DEFAULT_AIMEM_PROFILE_NAME;
 import static 
org.apache.ignite.internal.TestDefaultProfilesNames.DEFAULT_TEST_PROFILE_NAME;
 import static 
org.apache.ignite.internal.catalog.CatalogService.DEFAULT_STORAGE_PROFILE;
-import static 
org.apache.ignite.internal.distributionzones.DistributionZonesTestUtil.getZoneId;
+import static 
org.apache.ignite.internal.distributionzones.DistributionZonesTestUtil.getZoneIdStrict;
 import static 
org.apache.ignite.internal.lang.IgniteSystemProperties.COLOCATION_FEATURE_FLAG;
 import static org.apache.ignite.internal.sql.SqlCommon.DEFAULT_SCHEMA_NAME;
+import static org.apache.ignite.internal.table.TableTestUtils.getTableIdStrict;
 import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.waitForCondition;
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
 import static org.apache.ignite.internal.util.IgniteUtils.closeAll;
@@ -278,15 +278,14 @@ abstract class ItAbstractColocationTest extends 
IgniteAbstractTest {
                 String.join(",", profiles)
         );
 
-        Integer zoneId = getZoneId(node.catalogManager, zoneName, 
node.hybridClock.nowLong());
-        return requireNonNull(zoneId, "No zone found with name " + zoneName);
+        return getZoneIdStrict(node.catalogManager, zoneName, 
node.hybridClock.nowLong());
     }
 
-    static void createTable(Node node, String zoneName, String tableName) {
-        createTable(node, zoneName, tableName, null);
+    static int createTable(Node node, String zoneName, String tableName) {
+        return createTable(node, zoneName, tableName, null);
     }
 
-    static void createTable(Node node, String zoneName, String tableName, 
String storageProfile) {
+    static int createTable(Node node, String zoneName, String tableName, 
String storageProfile) {
         node.waitForMetadataCompletenessAtNow();
 
         TableTestUtils.createTable(
@@ -301,6 +300,8 @@ abstract class ItAbstractColocationTest extends 
IgniteAbstractTest {
                 List.of("KEY"),
                 storageProfile
         );
+
+        return getTableIdStrict(node.catalogManager, tableName, 
node.hybridClock.nowLong());
     }
 
     Node getNode(int nodeIndex) {
diff --git 
a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItReplicaLifecycleTest.java
 
b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItReplicaLifecycleTest.java
index 9553c81881e..442002137b7 100644
--- 
a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItReplicaLifecycleTest.java
+++ 
b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/ItReplicaLifecycleTest.java
@@ -26,6 +26,8 @@ import static 
org.apache.ignite.internal.distributionzones.rebalance.ZoneRebalan
 import static 
org.apache.ignite.internal.lang.IgniteSystemProperties.COLOCATION_FEATURE_FLAG;
 import static 
org.apache.ignite.internal.lang.IgniteSystemProperties.enabledColocation;
 import static 
org.apache.ignite.internal.partitiondistribution.PartitionDistributionUtils.calculateAssignmentForPartition;
+import static org.apache.ignite.internal.sql.SqlCommon.DEFAULT_SCHEMA_NAME;
+import static org.apache.ignite.internal.table.TableTestUtils.dropTable;
 import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.waitForCondition;
 import static 
org.apache.ignite.internal.testframework.flow.TestFlowUtils.subscribeToPublisher;
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
@@ -66,19 +68,24 @@ import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.metastorage.MetaStorageManager;
 import org.apache.ignite.internal.metastorage.dsl.Operation;
 import org.apache.ignite.internal.partition.replicator.fixtures.Node;
+import org.apache.ignite.internal.partition.replicator.raft.RaftTableProcessor;
+import 
org.apache.ignite.internal.partition.replicator.raft.ZonePartitionRaftListener;
 import org.apache.ignite.internal.partitiondistribution.Assignment;
 import org.apache.ignite.internal.partitiondistribution.Assignments;
+import org.apache.ignite.internal.raft.Peer;
+import org.apache.ignite.internal.raft.RaftNodeId;
+import org.apache.ignite.internal.raft.server.impl.JraftServerImpl;
 import org.apache.ignite.internal.replicator.Replica;
 import org.apache.ignite.internal.replicator.ZonePartitionId;
 import org.apache.ignite.internal.schema.BinaryRow;
 import org.apache.ignite.internal.table.InternalTable;
-import org.apache.ignite.internal.table.TableTestUtils;
 import org.apache.ignite.internal.table.TableViewInternal;
 import 
org.apache.ignite.internal.table.distributed.replicator.RemoteResourceIds;
 import 
org.apache.ignite.internal.table.distributed.storage.PartitionScanPublisher;
 import org.apache.ignite.internal.tx.InternalTransaction;
 import org.apache.ignite.internal.tx.impl.FullyQualifiedResourceId;
 import 
org.apache.ignite.internal.tx.impl.RemotelyTriggeredResourceRegistry.RemotelyTriggeredResource;
+import org.apache.ignite.raft.jraft.RaftGroupService;
 import org.apache.ignite.table.KeyValueView;
 import org.apache.ignite.table.Table;
 import org.junit.jupiter.api.Test;
@@ -113,8 +120,7 @@ public class ItReplicaLifecycleTest extends 
ItAbstractColocationTest {
         long key = 1;
 
         {
-            createTable(node, "test_zone", "test_table");
-            int tableId = TableTestUtils.getTableId(node.catalogManager, 
"test_table", node.hybridClock.nowLong());
+            int tableId = createTable(node, "test_zone", "test_table");
 
             KeyValueView<Long, Integer> keyValueView = 
node.tableManager.table(tableId).keyValueView(Long.class, Integer.class);
 
@@ -133,8 +139,7 @@ public class ItReplicaLifecycleTest extends 
ItAbstractColocationTest {
         }
 
         {
-            createTable(node, "test_zone", "test_table1");
-            int tableId = TableTestUtils.getTableId(node.catalogManager, 
"test_table1", node.hybridClock.nowLong());
+            int tableId = createTable(node, "test_zone", "test_table1");
 
             KeyValueView<Long, Integer> keyValueView = 
node.tableManager.table(tableId).keyValueView(Long.class, Integer.class);
 
@@ -544,11 +549,9 @@ public class ItReplicaLifecycleTest extends 
ItAbstractColocationTest {
         createZone(node, "test_zone", 2, 1);
 
         {
-            createTable(node, "test_zone", "test_table_1");
-            int tableId1 = TableTestUtils.getTableId(node.catalogManager, 
"test_table_1", node.hybridClock.nowLong());
+            int tableId1 = createTable(node, "test_zone", "test_table_1");
 
-            createTable(node, "test_zone", "test_table_2");
-            int tableId2 = TableTestUtils.getTableId(node.catalogManager, 
"test_table_2", node.hybridClock.nowLong());
+            int tableId2 = createTable(node, "test_zone", "test_table_2");
 
             KeyValueView<Long, Integer> keyValueView1 = 
node.tableManager.table(tableId1).keyValueView(Long.class, Integer.class);
             KeyValueView<Long, Integer> keyValueView2 = 
node.tableManager.table(tableId2).keyValueView(Long.class, Integer.class);
@@ -590,8 +593,7 @@ public class ItReplicaLifecycleTest extends 
ItAbstractColocationTest {
 
         // Create a table to work with.
         String tableName = "test_table";
-        createTable(node, zoneName, tableName);
-        int tableId = TableTestUtils.getTableId(node.catalogManager, 
tableName, node.hybridClock.nowLong());
+        int tableId = createTable(node, zoneName, tableName);
         TableViewInternal tableViewInternal = node.tableManager.table(tableId);
         KeyValueView<Long, Integer> tableView = 
tableViewInternal.keyValueView(Long.class, Integer.class);
 
@@ -669,6 +671,28 @@ public class ItReplicaLifecycleTest extends 
ItAbstractColocationTest {
         checkSafeTimeWasAdjustedForZoneGroup(node1, zoneId, partId);
     }
 
+    @Test
+    public void testListenersAreRemovedOnTableDestruction() throws Exception {
+        startCluster(1);
+        Node node = getNode(0);
+
+        String zoneName = "test_zone";
+        int zoneId = createZone(node, zoneName, 1, 1);
+
+        String tableName = "test_table";
+        int tableId = createTable(node, zoneName, tableName);
+
+        assertTrue(waitForCondition(() -> assertTableListenersCount(node, 
zoneId, 1), AWAIT_TIMEOUT_MILLIS));
+        assertTrue(waitForCondition(() -> raftTableProcessorExists(node, 
zoneId, tableId), AWAIT_TIMEOUT_MILLIS));
+
+        dropTable(node.catalogManager, DEFAULT_SCHEMA_NAME, tableName);
+
+        node.lowWatermark.updateLowWatermark(node.hybridClock.now());
+
+        assertTrue(waitForCondition(() -> assertTableListenersCount(node, 
zoneId, 0), AWAIT_TIMEOUT_MILLIS));
+        assertTrue(waitForCondition(() -> !raftTableProcessorExists(node, 
zoneId, tableId), AWAIT_TIMEOUT_MILLIS));
+    }
+
     private static void waitForZoneReplicaStartedOnNode(Node node, int zoneId, 
int partId) throws InterruptedException {
         ZonePartitionId zoneReplicationId = new ZonePartitionId(zoneId, 
partId);
 
@@ -697,8 +721,7 @@ public class ItReplicaLifecycleTest extends 
ItAbstractColocationTest {
 
         // Create a table to work with.
         String tableName = "test_table";
-        createTable(node, zoneName, tableName);
-        int tableId = TableTestUtils.getTableId(node.catalogManager, 
tableName, node.hybridClock.nowLong());
+        int tableId = createTable(node, zoneName, tableName);
         InternalTable internalTable = 
node.tableManager.table(tableId).internalTable();
 
         // Stop the node
@@ -735,6 +758,22 @@ public class ItReplicaLifecycleTest extends 
ItAbstractColocationTest {
         }
     }
 
+    private static boolean raftTableProcessorExists(Node node, int zoneId, int 
tableId) {
+        var server = (JraftServerImpl) node.raftManager.server();
+
+        var groupId = new ZonePartitionId(zoneId, 0);
+
+        Peer serverPeer = server.localPeers(groupId).get(0);
+
+        RaftGroupService grp = server.raftGroupService(new RaftNodeId(groupId, 
serverPeer));
+
+        var fsm = (JraftServerImpl.DelegatingStateMachine) 
grp.getRaftNode().getOptions().getFsm();
+
+        RaftTableProcessor tableProcessor = ((ZonePartitionRaftListener) 
fsm.getListener()).tableProcessor(tableId);
+
+        return tableProcessor != null;
+    }
+
     private static InternalTable getInternalTable(Node node, String tableName) 
{
         Table table = assertTimeoutPreemptively(Duration.ofSeconds(10), () -> 
node.tableManager.table(tableName));
 
diff --git 
a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java
 
b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java
index d3e7212404c..dcd8ab9f7e7 100644
--- 
a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java
+++ 
b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java
@@ -257,7 +257,7 @@ public class Node {
 
     private final ConfigurationTreeGenerator clusterCfgGenerator;
 
-    private final LowWatermarkImpl lowWatermark;
+    public final LowWatermarkImpl lowWatermark;
 
     public final RemotelyTriggeredResourceRegistry resourcesRegistry;
 
diff --git 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/PartitionReplicaLifecycleManager.java
 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/PartitionReplicaLifecycleManager.java
index 1e7342b5925..c5abb746a10 100644
--- 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/PartitionReplicaLifecycleManager.java
+++ 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/PartitionReplicaLifecycleManager.java
@@ -1517,10 +1517,7 @@ public class PartitionReplicaLifecycleManager extends
      * @param zonePartitionId Zone partition id.
      * @param tableId Table's identifier.
      */
-    public void unloadTableResourcesFromZoneReplica(
-            ZonePartitionId zonePartitionId,
-            int tableId
-    ) {
+    public void unloadTableResourcesFromZoneReplica(ZonePartitionId 
zonePartitionId, int tableId) {
         zoneResourcesManager.removeTableResources(zonePartitionId, tableId);
     }
 
diff --git 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/ZonePartitionReplicaListener.java
 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/ZonePartitionReplicaListener.java
index 1e85169d055..4ce78d3f7bb 100644
--- 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/ZonePartitionReplicaListener.java
+++ 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/ZonePartitionReplicaListener.java
@@ -68,7 +68,7 @@ public class ZonePartitionReplicaListener implements 
ReplicaListener {
     private static final IgniteLogger LOG = 
Loggers.forClass(ZonePartitionReplicaListener.class);
 
     // tableId -> tableProcessor.
-    private final Map<Integer, ReplicaTableProcessor> replicas = new 
ConcurrentHashMap<>();
+    private final Map<Integer, ReplicaTableProcessor> replicaProcessors = new 
ConcurrentHashMap<>();
 
     /** Raft client. */
     private final RaftCommandRunner raftClient;
@@ -148,7 +148,7 @@ public class ZonePartitionReplicaListener implements 
ReplicaListener {
                 replicationGroupId);
 
         writeIntentSwitchRequestHandler = new WriteIntentSwitchRequestHandler(
-                replicas::get,
+                replicaProcessors::get,
                 clockService,
                 schemaSyncService,
                 catalogService,
@@ -239,10 +239,27 @@ public class ZonePartitionReplicaListener implements 
ReplicaListener {
             ReplicaPrimacy replicaPrimacy,
             UUID senderId
     ) {
-        int tableId = ((TableAware) request).tableId();
-
         return 
tableAwareReplicaRequestPreProcessor.preProcessTableAwareRequest(request, 
replicaPrimacy, senderId)
-                .thenCompose(ignored -> replicas.get(tableId).process(request, 
replicaPrimacy, senderId));
+                .thenCompose(ignored -> {
+                    int tableId = ((TableAware) request).tableId();
+
+                    ReplicaTableProcessor replicaProcessor = 
replicaProcessors.get(tableId);
+
+                    // TODO: this code is commented out for debugging 
purposes, uncomment after
+                    //  https://issues.apache.org/jira/browse/IGNITE-24991
+                    // if (replicaProcessor == null) {
+                    //     // Most of the times this condition should be 
false. This logging message is added in case a request got stuck
+                    //     // somewhere while being replicated and arrived on 
this node after the target table had been removed.
+                    //     // In this case we ignore the command, which should 
be safe to do, because the underlying storage was destroyed
+                    //     // anyway.
+                    //     LOG.warn("Replica processor for table ID {} not 
found. Command will be ignored: {}", tableId,
+                    //             request.toStringForLightLogging());
+
+                    //     return completedFuture(new ReplicaResult(null, 
null));
+                    // }
+
+                    return replicaProcessor.process(request, replicaPrimacy, 
senderId);
+                });
     }
 
     /**
@@ -277,7 +294,7 @@ public class ZonePartitionReplicaListener implements 
ReplicaListener {
      * @param replicaListener Table replica listener.
      */
     public void addTableReplicaProcessor(int tableId, 
Function<RaftCommandRunner, ReplicaTableProcessor> replicaListener) {
-        replicas.put(tableId, replicaListener.apply(raftClient));
+        replicaProcessors.put(tableId, replicaListener.apply(raftClient));
     }
 
     /**
@@ -286,7 +303,7 @@ public class ZonePartitionReplicaListener implements 
ReplicaListener {
      * @param tableId Table's identifier.
      */
     public void removeTableReplicaProcessor(int tableId) {
-        replicas.remove(tableId);
+        replicaProcessors.remove(tableId);
     }
 
     /**
@@ -296,12 +313,12 @@ public class ZonePartitionReplicaListener implements 
ReplicaListener {
      */
     @VisibleForTesting
     public Map<Integer, ReplicaTableProcessor> tableReplicaProcessors() {
-        return replicas;
+        return replicaProcessors;
     }
 
     @Override
     public void onShutdown() {
-        replicas.forEach((tableId, listener) -> {
+        replicaProcessors.forEach((tableId, listener) -> {
                     try {
                         listener.onShutdown();
                     } catch (Throwable th) {
diff --git 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/raft/ZonePartitionRaftListener.java
 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/raft/ZonePartitionRaftListener.java
index ae2b58103d5..f16d574e71c 100644
--- 
a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/raft/ZonePartitionRaftListener.java
+++ 
b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/raft/ZonePartitionRaftListener.java
@@ -297,7 +297,20 @@ public class ZonePartitionRaftListener implements 
RaftGroupListener {
             long commandTerm,
             @Nullable HybridTimestamp safeTimestamp
     ) {
-        return tableProcessors.get(tableId).processCommand(command, 
commandIndex, commandTerm, safeTimestamp);
+        RaftTableProcessor tableProcessor = tableProcessors.get(tableId);
+
+        // TODO: this code is commented out for debugging purposes, uncomment 
after https://issues.apache.org/jira/browse/IGNITE-24991
+        // if (tableProcessor == null) {
+        //     // Most of the times this condition should be false. This 
logging message is added in case a Raft command got stuck somewhere
+        //     // while being replicated and arrived on this node after the 
target table had been removed. In this case we ignore the
+        //     // command, which should be safe to do, because the underlying 
storage was destroyed anyway.
+        //     LOG.warn("Table processor for table ID {} not found. Command 
will be ignored: {}",
+        //     tableId, command.toStringForLightLogging());
+
+        //     return EMPTY_APPLIED_RESULT;
+        // }
+
+        return tableProcessor.processCommand(command, commandIndex, 
commandTerm, safeTimestamp);
     }
 
     private boolean updateLeaseInfoInTxStorage(PrimaryReplicaChangeCommand 
command, long commandIndex, long commandTerm) {
@@ -449,7 +462,7 @@ public class ZonePartitionRaftListener implements 
RaftGroupListener {
 
     /** Returns the table processor associated with the given table ID. */
     @TestOnly
-    public RaftTableProcessor tableProcessor(int tableId) {
+    public @Nullable RaftTableProcessor tableProcessor(int tableId) {
         synchronized (tableProcessorsStateLock) {
             return tableProcessors.get(tableId);
         }
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
index 43be04b0d26..8931812115f 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
@@ -490,6 +490,7 @@ public interface InternalTable extends ManuallyCloseable {
      *
      * @return Transaction states' storage.
      */
+    // TODO: remove this method as a part of 
https://issues.apache.org/jira/browse/IGNITE-22522.
     TxStateStorage txStateStorage();
 
     // TODO: IGNITE-14488. Add invoke() methods.
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
index 46929d0f9b7..f8f5413395f 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
@@ -27,7 +27,6 @@ import static 
java.util.concurrent.CompletableFuture.failedFuture;
 import static java.util.concurrent.CompletableFuture.runAsync;
 import static java.util.concurrent.CompletableFuture.supplyAsync;
 import static java.util.function.Function.identity;
-import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toSet;
 import static 
org.apache.ignite.internal.causality.IncrementalVersionedValue.dependingOn;
 import static 
org.apache.ignite.internal.distributionzones.rebalance.RebalanceUtil.ASSIGNMENTS_SWITCH_REDUCE_PREFIX_BYTES;
@@ -1060,11 +1059,11 @@ public class TableManager implements 
IgniteTablesInternal, IgniteComponent {
         try {
             int newEarliestCatalogVersion = 
catalogService.activeCatalogVersion(parameters.newLowWatermark().longValue());
 
-            List<CompletableFuture<Void>> futures = 
destructionEventsQueue.drainUpTo(newEarliestCatalogVersion).stream()
+            CompletableFuture<?>[] futures = 
destructionEventsQueue.drainUpTo(newEarliestCatalogVersion).stream()
                     .map(event -> destroyTableLocally(event.tableId()))
-                    .collect(toList());
+                    .toArray(CompletableFuture[]::new);
 
-            return 
allOf(futures.toArray(CompletableFuture[]::new)).thenApply(unused -> false);
+            return allOf(futures).thenApply(unused -> false);
         } catch (Throwable t) {
             return failedFuture(t);
         } finally {
@@ -2744,10 +2743,6 @@ public class TableManager implements 
IgniteTablesInternal, IgniteComponent {
     }
 
     private CompletableFuture<Void> destroyPartitionStorages(TablePartitionId 
tablePartitionId, TableImpl table) {
-        if (table == null) {
-            return nullCompletedFuture();
-        }
-
         InternalTable internalTable = table.internalTable();
 
         int partitionId = tablePartitionId.partitionId();
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
index acb0f134599..7b6abd8fe05 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/TableManagerTest.java
@@ -21,6 +21,7 @@ import static 
java.util.concurrent.CompletableFuture.completedFuture;
 import static 
org.apache.ignite.internal.catalog.events.CatalogEvent.TABLE_CREATE;
 import static 
org.apache.ignite.internal.catalog.events.CatalogEvent.TABLE_DROP;
 import static 
org.apache.ignite.internal.lang.IgniteSystemProperties.COLOCATION_FEATURE_FLAG;
+import static 
org.apache.ignite.internal.lang.IgniteSystemProperties.enabledColocation;
 import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureExceptionMatcher.willThrow;
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
@@ -49,11 +50,11 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyList;
 import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
@@ -436,8 +437,6 @@ public class TableManagerTest extends IgniteAbstractTest {
      * @throws Exception If failed.
      */
     @Test
-    // TODO: https://issues.apache.org/jira/browse/IGNITE-24397 - remove 
@WithSystemProperty.
-    @WithSystemProperty(key = COLOCATION_FEATURE_FLAG, value = "false")
     public void testDropTable() throws Exception {
         mockManagersAndCreateTable(DYNAMIC_TABLE_FOR_DROP_NAME, tblManagerFut);
 
@@ -448,15 +447,20 @@ public class TableManagerTest extends IgniteAbstractTest {
         assertNull(tableManager.table(DYNAMIC_TABLE_FOR_DROP_NAME));
         assertEquals(0, tableManager.tables().size());
 
-        verify(mvTableStorage, atMost(0)).destroy();
-        verify(txStateStorage, atMost(0)).destroy();
-        verify(replicaMgr, atMost(0)).stopReplica(any());
+        verify(mvTableStorage, never()).destroy();
+        verify(txStateStorage, never()).destroy();
+        verify(replicaMgr, never()).stopReplica(any());
 
         assertThat(fireDestroyEvent(), willCompleteSuccessfully());
 
         verify(mvTableStorage, 
timeout(TimeUnit.SECONDS.toMillis(10))).destroy();
         verify(txStateStorage, 
timeout(TimeUnit.SECONDS.toMillis(10))).destroy();
-        verify(replicaMgr, 
timeout(TimeUnit.SECONDS.toMillis(10)).times(PARTITIONS)).stopReplica(any());
+
+        if (enabledColocation()) {
+            verify(replicaMgr, never()).stopReplica(any());
+        } else {
+            verify(replicaMgr, 
timeout(TimeUnit.SECONDS.toMillis(10)).times(PARTITIONS)).stopReplica(any());
+        }
     }
 
     /**

Reply via email to