Repository: ignite Updated Branches: refs/heads/master 469fb49e4 -> 0a23658e2
IGNITE-8927: SQL: correct handling of LOST partitions on mapper side. Note that for local queries this doesn't work still because partition state is not checked (see IGNITE-7039). This closes #4679. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0a23658e Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0a23658e Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0a23658e Branch: refs/heads/master Commit: 0a23658e2d5f12420ab021aa1d3ee1d08506d2f6 Parents: 469fb49 Author: devozerov <[email protected]> Authored: Fri Sep 7 12:19:55 2018 +0300 Committer: devozerov <[email protected]> Committed: Fri Sep 7 12:19:55 2018 +0300 ---------------------------------------------------------------------- .../twostep/messages/GridQueryFailResponse.java | 2 +- .../IgniteCachePartitionLossPolicySelfTest.java | 29 +++- .../query/h2/twostep/GridMapQueryExecutor.java | 123 +++++++++++----- .../h2/twostep/GridReduceQueryExecutor.java | 2 +- ...ndexingCachePartitionLossPolicySelfTest.java | 139 +++++++++++++++++++ ...niteCacheDistributedQueryCancelSelfTest.java | 2 +- .../h2/twostep/RetryCauseMessageSelfTest.java | 3 +- .../IgniteCacheQuerySelfTestSuite.java | 4 + 8 files changed, 261 insertions(+), 43 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryFailResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryFailResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryFailResponse.java index 1b759bb..ef26d2a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryFailResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/messages/GridQueryFailResponse.java @@ -59,7 +59,7 @@ public class GridQueryFailResponse implements Message { */ public GridQueryFailResponse(long qryReqId, Throwable err) { this.qryReqId = qryReqId; - this.errMsg = err.getClass() + ":" + err.getMessage(); + this.errMsg = err.getMessage(); this.failCode = err instanceof QueryCancelledException ? CANCELLED_BY_ORIGINATOR : GENERAL_ERROR; } http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCachePartitionLossPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCachePartitionLossPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCachePartitionLossPolicySelfTest.java index 0be8526..1aacc9c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCachePartitionLossPolicySelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCachePartitionLossPolicySelfTest.java @@ -72,7 +72,7 @@ public class IgniteCachePartitionLossPolicySelfTest extends GridCommonAbstractTe private PartitionLossPolicy partLossPlc; /** */ - private static final String CACHE_NAME = "partitioned"; + protected static final String CACHE_NAME = "partitioned"; /** */ private int backups = 0; @@ -101,6 +101,15 @@ public class IgniteCachePartitionLossPolicySelfTest extends GridCommonAbstractTe cfg.setClientMode(client); + cfg.setCacheConfiguration(cacheConfiguration()); + + return cfg; + } + + /** + * @return Cache configuration. + */ + protected CacheConfiguration<Integer, Integer> cacheConfiguration() { CacheConfiguration<Integer, Integer> cacheCfg = new CacheConfiguration<>(CACHE_NAME); cacheCfg.setCacheMode(PARTITIONED); @@ -109,9 +118,7 @@ public class IgniteCachePartitionLossPolicySelfTest extends GridCommonAbstractTe cacheCfg.setPartitionLossPolicy(partLossPlc); cacheCfg.setAffinity(new RendezvousAffinityFunction(false, 32)); - cfg.setCacheConfiguration(cacheCfg); - - return cfg; + return cacheCfg; } /** {@inheritDoc} */ @@ -294,6 +301,9 @@ public class IgniteCachePartitionLossPolicySelfTest extends GridCommonAbstractTe // Check that writing in recover mode does not clear partition state. verifyCacheOps(canWrite, safe, part, ig); + + // Validate queries. + validateQuery(safe, part, ig); } // Check that partition state does not change after we start a new node. @@ -410,6 +420,17 @@ public class IgniteCachePartitionLossPolicySelfTest extends GridCommonAbstractTe return parts; } + /** + * Validate query execution on a node. + * + * @param safe Safe flag. + * @param part Partition. + * @param node Node. + */ + protected void validateQuery(boolean safe, int part, Ignite node) { + // No-op. + } + /** */ class TopologyChanger { /** Flag to delay partition exchange */ http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java index b4d6f00..9166604 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java @@ -41,6 +41,7 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.IgniteSystemProperties; +import org.apache.ignite.cache.PartitionLossPolicy; import org.apache.ignite.cache.query.QueryCancelledException; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.cluster.ClusterNode; @@ -54,6 +55,7 @@ import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.managers.communication.GridMessageListener; import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheInvalidStateException; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.distributed.dht.CompoundLockFuture; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition; @@ -102,9 +104,12 @@ import org.h2.value.Value; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.IgniteSystemProperties.IGNITE_SQL_FORCE_LAZY_RESULT_SET; +import static org.apache.ignite.cache.PartitionLossPolicy.READ_ONLY_SAFE; +import static org.apache.ignite.cache.PartitionLossPolicy.READ_WRITE_SAFE; import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_EXECUTED; import static org.apache.ignite.internal.managers.communication.GridIoPolicy.QUERY_POOL; import static org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion.NONE; +import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.LOST; import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING; import static org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode.OFF; import static org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode.distributedJoinMode; @@ -335,11 +340,9 @@ public class GridMapQueryExecutor { // Cache was not found, probably was not deployed yet. if (cctx == null) { - final String res = String.format("Failed to reserve partitions for query (cache is not found on " + + return String.format("Failed to reserve partitions for query (cache is not found on " + "local node) [localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s]", ctx.localNodeId(), nodeId, reqId, topVer, cacheIds.get(i)); - - return res; } if (cctx.isLocal() || !cctx.rebalanceEnabled()) @@ -396,16 +399,39 @@ public class GridMapQueryExecutor { if (explicitParts == null) partIds = cctx.affinity().primaryPartitions(ctx.localNodeId(), topVer); + int reservedCnt = 0; + for (int partId : partIds) { GridDhtLocalPartition part = partition(cctx, partId); GridDhtPartitionState partState = part != null ? part.state() : null; - if (partState != OWNING || !part.reserve()) + if (partState != OWNING) { + if (partState == LOST) + ignoreLostPartitionIfPossible(cctx, part); + else { + return String.format("Failed to reserve partitions for query " + + "(partition of PARTITIONED cache is not found or not in OWNING state) [" + + "localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, " + + "cacheName=%s, part=%s, partFound=%s, partState=%s]", + ctx.localNodeId(), + nodeId, + reqId, + topVer, + cacheIds.get(i), + cctx.name(), + partId, + (part != null), + partState + ); + } + } + + if (!part.reserve()) { return String.format("Failed to reserve partitions for query " + - "(partition of PARTITIONED cache cannot be reserved) [" + - "localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, cacheName=%s, " + - "part=%s, partFound=%s, partState=%s]", + "(partition of PARTITIONED cache cannot be reserved) [" + + "localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, " + + "cacheName=%s, part=%s, partFound=%s, partState=%s]", ctx.localNodeId(), nodeId, reqId, @@ -413,36 +439,44 @@ public class GridMapQueryExecutor { cacheIds.get(i), cctx.name(), partId, - (part != null), + true, partState ); + } reserved.add(part); + reservedCnt++; + // Double check that we are still in owning state and partition contents are not cleared. partState = part.state(); - if (part.state() != OWNING) - return String.format("Failed to reserve partitions for query " + - "(partition of PARTITIONED cache is not in OWNING state after reservation) [" + - "localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, cacheName=%s, " + - "part=%s, partState=%s]", - ctx.localNodeId(), - nodeId, - reqId, - topVer, - cacheIds.get(i), - cctx.name(), - partId, - partState - ); + if (partState != OWNING) { + if (partState == LOST) + ignoreLostPartitionIfPossible(cctx, part); + else { + return String.format("Failed to reserve partitions for query " + + "(partition of PARTITIONED cache is not in OWNING state after reservation) [" + + "localNodeId=%s, rmtNodeId=%s, reqId=%s, affTopVer=%s, cacheId=%s, " + + "cacheName=%s, part=%s, partState=%s]", + ctx.localNodeId(), + nodeId, + reqId, + topVer, + cacheIds.get(i), + cctx.name(), + partId, + partState + ); + } + } } - if (explicitParts == null) { + if (explicitParts == null && reservedCnt > 0) { // We reserved all the primary partitions for cache, attempt to add group reservation. GridDhtPartitionsReservation grp = new GridDhtPartitionsReservation(topVer, cctx, "SQL"); - if (grp.register(reserved.subList(reserved.size() - partIds.size(), reserved.size()))) { + if (grp.register(reserved.subList(reserved.size() - reservedCnt, reserved.size()))) { if (reservations.putIfAbsent(grpKey, grp) != null) throw new IllegalStateException("Reservation already exists."); @@ -461,6 +495,25 @@ public class GridMapQueryExecutor { } /** + * Decide whether to ignore or proceed with lost partition. + * + * @param cctx Cache context. + * @param part Partition. + * @throws IgniteCheckedException If failed. + */ + private static void ignoreLostPartitionIfPossible(GridCacheContext cctx, GridDhtLocalPartition part) + throws IgniteCheckedException { + PartitionLossPolicy plc = cctx.config().getPartitionLossPolicy(); + + if (plc != null) { + if (plc == READ_ONLY_SAFE || plc == READ_WRITE_SAFE) { + throw new CacheInvalidStateException("Failed to execute query because cache partition has been " + + "lost [cacheName=" + cctx.name() + ", part=" + part + ']'); + } + } + } + + /** * @param ints Integers. * @return Collection wrapper. */ @@ -1045,22 +1098,22 @@ public class GridMapQueryExecutor { List<GridReservable> reserved = new ArrayList<>(); - String err = reservePartitions(cacheIds, topVer, parts, reserved, node.id(), reqId); + MapNodeResults nodeResults = resultsForNode(node.id()); - if (!F.isEmpty(err)) { - U.error(log, "Failed to reserve partitions for DML request. [localNodeId=" + ctx.localNodeId() + - ", nodeId=" + node.id() + ", reqId=" + req.requestId() + ", cacheIds=" + cacheIds + - ", topVer=" + topVer + ", parts=" + Arrays.toString(parts) + ']'); + try { + String err = reservePartitions(cacheIds, topVer, parts, reserved, node.id(), reqId); - sendUpdateResponse(node, reqId, null, - "Failed to reserve partitions for DML request. " + err); + if (!F.isEmpty(err)) { + U.error(log, "Failed to reserve partitions for DML request. [localNodeId=" + ctx.localNodeId() + + ", nodeId=" + node.id() + ", reqId=" + req.requestId() + ", cacheIds=" + cacheIds + + ", topVer=" + topVer + ", parts=" + Arrays.toString(parts) + ']'); - return; - } + sendUpdateResponse(node, reqId, null, + "Failed to reserve partitions for DML request. " + err); - MapNodeResults nodeResults = resultsForNode(node.id()); + return; + } - try { IndexingQueryFilter filter = h2.backupFilter(topVer, parts); GridQueryCancel cancel = nodeResults.putUpdate(reqId); http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java index 586fb51..96c88ff 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java @@ -884,7 +884,7 @@ public class GridReduceQueryExecutor { if (wasCancelled(err)) throw new QueryCancelledException(); // Throw correct exception. - throw new CacheException("Failed to run map query remotely: " + err.getMessage(), err); + throw err; } else { retry = true; http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IndexingCachePartitionLossPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IndexingCachePartitionLossPolicySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IndexingCachePartitionLossPolicySelfTest.java new file mode 100644 index 0000000..f208599 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IndexingCachePartitionLossPolicySelfTest.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.cache; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.internal.processors.cache.distributed.IgniteCachePartitionLossPolicySelfTest; + +import java.util.Collection; + +/** + * Partition loss policy test with enabled indexing. + */ +public class IndexingCachePartitionLossPolicySelfTest extends IgniteCachePartitionLossPolicySelfTest { + /** {@inheritDoc} */ + @Override protected CacheConfiguration<Integer, Integer> cacheConfiguration() { + CacheConfiguration<Integer, Integer> ccfg = super.cacheConfiguration(); + + ccfg.setIndexedTypes(Integer.class, Integer.class); + + return ccfg; + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override protected void validateQuery(boolean safe, int part, Ignite node) { + // Get node lost and remaining partitions. + IgniteCache cache = node.cache(CACHE_NAME); + + Collection<Integer> lostParts = cache.lostPartitions(); + + Integer remainingPart = null; + + for (int i = 0; i < node.affinity(CACHE_NAME).partitions(); i++) { + if (lostParts.contains(i)) + continue; + + remainingPart = i; + + break; + } + + // Determine whether local query should be executed on that node. + boolean execLocQry = false; + + for (int nodePrimaryPart : node.affinity(CACHE_NAME).primaryPartitions(node.cluster().localNode())) { + if (part == nodePrimaryPart) { + execLocQry = true; + + break; + } + } + + // 1. Check query against all partitions. + validateQuery0(safe, node, false); + + // TODO: https://issues.apache.org/jira/browse/IGNITE-7039 +// if (execLocQry) +// validateQuery0(safe, node, true); + + // 2. Check query against LOST partition. + validateQuery0(safe, node, false, part); + + // TODO: https://issues.apache.org/jira/browse/IGNITE-7039 +// if (execLocQry) +// validateQuery0(safe, node, true, part); + + // 3. Check query on remaining partition. + if (remainingPart != null) { + executeQuery(node, false, remainingPart); + + // 4. Check query over two partitions - normal and LOST. + validateQuery0(safe, node, false, part, remainingPart); + } + } + + /** + * Query validation routine. + * + * @param safe Safe flag. + * @param node Node. + * @param loc Local flag. + * @param parts Partitions. + */ + private void validateQuery0(boolean safe, Ignite node, boolean loc, int... parts) { + if (safe) { + try { + executeQuery(node, loc, parts); + + fail("Exception is not thrown."); + } + catch (Exception e) { + assertTrue(e.getMessage(), e.getMessage() != null && + e.getMessage().contains("Failed to execute query because cache partition has been lost")); + } + } + else { + executeQuery(node, loc, parts); + } + } + + /** + * Execute SQL query on a given node. + * + * @param parts Partitions. + * @param node Node. + * @param loc Local flag. + */ + private static void executeQuery(Ignite node, boolean loc, int... parts) { + IgniteCache cache = node.cache(CACHE_NAME); + + SqlFieldsQuery qry = new SqlFieldsQuery("SELECT * FROM Integer"); + + if (parts != null && parts.length != 0) + qry.setPartitions(parts); + + if (loc) + qry.setLocal(true); + + cache.query(qry).getAll(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryCancelSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryCancelSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryCancelSelfTest.java index e26b211..d5ee0e9 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryCancelSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryCancelSelfTest.java @@ -158,7 +158,7 @@ public class IgniteCacheDistributedQueryCancelSelfTest extends GridCommonAbstrac fail(); } catch (Exception e) { - assertTrue(e.getCause() instanceof CacheException); + assertTrue(e instanceof CacheException); } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/twostep/RetryCauseMessageSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/twostep/RetryCauseMessageSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/twostep/RetryCauseMessageSelfTest.java index 3269887..ce38511 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/twostep/RetryCauseMessageSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/twostep/RetryCauseMessageSelfTest.java @@ -250,7 +250,8 @@ public class RetryCauseMessageSelfTest extends GridCommonAbstractTest { personCache.query(qry).getAll(); } catch (CacheException e) { - assertTrue(e.getMessage().contains("Failed to reserve partitions for query (partition of PARTITIONED cache cannot be reserved) [")); + assertTrue(e.getMessage().contains("Failed to reserve partitions for query (partition of PARTITIONED " + + "cache is not found or not in OWNING state) ")); return; } http://git-wip-us.apache.org/repos/asf/ignite/blob/0a23658e/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java index 671db13..7f67b35 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java @@ -77,6 +77,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCheckClusterStateBefore import org.apache.ignite.internal.processors.cache.IgniteCrossCachesJoinsQueryTest; import org.apache.ignite.internal.processors.cache.IgniteDynamicSqlRestoreTest; import org.apache.ignite.internal.processors.cache.IncorrectQueryEntityTest; +import org.apache.ignite.internal.processors.cache.IndexingCachePartitionLossPolicySelfTest; import org.apache.ignite.internal.processors.cache.QueryEntityCaseMismatchTest; import org.apache.ignite.internal.processors.cache.SqlFieldsQuerySelfTest; import org.apache.ignite.internal.processors.cache.authentication.SqlUserCommandSelfTest; @@ -469,6 +470,9 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite { suite.addTestSuite(H2StatementCacheSelfTest.class); suite.addTestSuite(PreparedStatementExSelfTest.class); + // Partition loss. + suite.addTestSuite(IndexingCachePartitionLossPolicySelfTest.class); + return suite; } }
