You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2018/11/14 14:06:19 UTC
ignite git commit: IGNITE-10228 Fixed concurrent start caches race
leading to a missed cache context - Fixes #5377.
Repository: ignite
Updated Branches:
refs/heads/master 59a7986be -> d1a039d36
IGNITE-10228 Fixed concurrent start caches race leading to a missed cache context - Fixes #5377.
Signed-off-by: Alexey Goncharuk <al...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d1a039d3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d1a039d3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d1a039d3
Branch: refs/heads/master
Commit: d1a039d36787d1920b631d71e8228fa5c47e5d20
Parents: 59a7986
Author: Pavel Voronkin <pv...@gridgain.com>
Authored: Wed Nov 14 15:40:57 2018 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Nov 14 16:53:07 2018 +0300
----------------------------------------------------------------------
.../processors/cache/CacheGroupContext.java | 99 ++++-----
.../ignite/internal/util/IgniteUtils.java | 39 ++--
.../distributed/CacheParallelStartTest.java | 202 +++++++++++++++++++
.../internal/util/IgniteUtilsSelfTest.java | 61 +++---
.../testsuites/IgniteCacheTestSuite6.java | 3 +
5 files changed, 305 insertions(+), 99 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/d1a039d3/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
index b0d6c07..93ba69c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
@@ -20,7 +20,7 @@ package org.apache.ignite.internal.processors.cache;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Iterator;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -115,10 +115,9 @@ public class CacheGroupContext {
/** */
private final boolean storeCacheId;
- /** */
- private volatile List<GridCacheContext> caches;
+ /** We modify content under lock, by making defencive copy, field always contains unmodifiable list. */
+ private volatile List<GridCacheContext> caches = Collections.unmodifiableList(new ArrayList<>());
- /** */
private volatile List<GridCacheContext> contQryCaches;
/** */
@@ -152,16 +151,16 @@ public class CacheGroupContext {
private final ReuseList reuseList;
/** */
- private boolean drEnabled;
+ private volatile boolean drEnabled;
/** */
- private boolean qryEnabled;
+ private volatile boolean qryEnabled;
/** */
- private boolean mvccEnabled;
+ private final boolean mvccEnabled;
/** MXBean. */
- private CacheGroupMetricsMXBean mxBean;
+ private final CacheGroupMetricsMXBean mxBean;
/** */
private volatile boolean localWalEnabled;
@@ -236,8 +235,6 @@ public class CacheGroupContext {
log = ctx.kernalContext().log(getClass());
- caches = new ArrayList<>();
-
mxBean = new CacheGroupMetricsMXBeanImpl(this);
}
@@ -307,10 +304,9 @@ public class CacheGroupContext {
public boolean hasCache(String cacheName) {
List<GridCacheContext> caches = this.caches;
- for (int i = 0; i < caches.size(); i++) {
- if (caches.get(i).name().equals(cacheName))
+ for (GridCacheContext cacheContext : caches)
+ if (cacheContext.name().equals(cacheName))
return true;
- }
return false;
}
@@ -322,11 +318,17 @@ public class CacheGroupContext {
assert cacheType.userCache() == cctx.userCache() : cctx.name();
assert grpId == cctx.groupId() : cctx.name();
- ArrayList<GridCacheContext> caches = new ArrayList<>(this.caches);
+ final boolean add;
- assert sharedGroup() || caches.isEmpty();
+ synchronized (this) {
+ List<GridCacheContext> copy = new ArrayList<>(caches);
+
+ assert sharedGroup() || copy.isEmpty();
- boolean add = caches.add(cctx);
+ add = copy.add(cctx);
+
+ caches = Collections.unmodifiableList(copy);
+ }
assert add : cctx.name();
@@ -335,39 +337,39 @@ public class CacheGroupContext {
if (!drEnabled && cctx.isDrEnabled())
drEnabled = true;
-
- this.caches = caches;
}
/**
* @param cctx Cache context.
*/
private void removeCacheContext(GridCacheContext cctx) {
- ArrayList<GridCacheContext> caches = new ArrayList<>(this.caches);
+ final List<GridCacheContext> copy;
- // It is possible cache was not added in case of errors on cache start.
- for (Iterator<GridCacheContext> it = caches.iterator(); it.hasNext();) {
- GridCacheContext next = it.next();
+ synchronized (this) {
+ copy = new ArrayList<>(caches);
- if (next == cctx) {
- assert sharedGroup() || caches.size() == 1 : caches.size();
+ for (GridCacheContext next : copy) {
+ if (next == cctx) {
+ assert sharedGroup() || copy.size() == 1 : copy.size();
- it.remove();
+ copy.remove(next);
- break;
+ break;
+ }
}
+
+ caches = Collections.unmodifiableList(copy);
}
if (QueryUtils.isEnabled(cctx.config())) {
boolean qryEnabled = false;
- for (int i = 0; i < caches.size(); i++) {
- if (QueryUtils.isEnabled(caches.get(i).config())) {
+ for (GridCacheContext cacheContext : copy)
+ if (QueryUtils.isEnabled(cacheContext.config())) {
qryEnabled = true;
break;
}
- }
this.qryEnabled = qryEnabled;
}
@@ -375,18 +377,15 @@ public class CacheGroupContext {
if (cctx.isDrEnabled()) {
boolean drEnabled = false;
- for (int i = 0; i < caches.size(); i++) {
- if (caches.get(i).isDrEnabled()) {
+ for (GridCacheContext cacheContext : copy)
+ if (QueryUtils.isEnabled(cacheContext.config())) {
drEnabled = true;
break;
}
- }
this.drEnabled = drEnabled;
}
-
- this.caches = caches;
}
/**
@@ -408,11 +407,8 @@ public class CacheGroupContext {
public void unwindUndeploys() {
List<GridCacheContext> caches = this.caches;
- for (int i = 0; i < caches.size(); i++) {
- GridCacheContext cctx = caches.get(i);
-
+ for (GridCacheContext cctx : caches)
cctx.deploy().unwind(cctx);
- }
}
/**
@@ -450,9 +446,7 @@ public class CacheGroupContext {
List<GridCacheContext> caches = this.caches;
- for (int i = 0; i < caches.size(); i++) {
- GridCacheContext cctx = caches.get(i);
-
+ for (GridCacheContext cctx : caches)
if (!cctx.config().isEventsDisabled() && cctx.recordEvent(type)) {
cctx.gridEvents().record(new CacheRebalancingEvent(cctx.name(),
cctx.localNode(),
@@ -463,7 +457,6 @@ public class CacheGroupContext {
discoType,
discoTs));
}
- }
}
/**
@@ -478,9 +471,7 @@ public class CacheGroupContext {
List<GridCacheContext> caches = this.caches;
- for (int i = 0; i < caches.size(); i++) {
- GridCacheContext cctx = caches.get(i);
-
+ for (GridCacheContext cctx : caches)
if (!cctx.config().isEventsDisabled())
cctx.gridEvents().record(new CacheRebalancingEvent(cctx.name(),
cctx.localNode(),
@@ -490,7 +481,6 @@ public class CacheGroupContext {
null,
0,
0));
- }
}
/**
@@ -517,9 +507,7 @@ public class CacheGroupContext {
) {
List<GridCacheContext> caches = this.caches;
- for (int i = 0; i < caches.size(); i++) {
- GridCacheContext cctx = caches.get(i);
-
+ for (GridCacheContext cctx : caches)
if (!cctx.config().isEventsDisabled())
cctx.events().addEvent(part,
key,
@@ -535,7 +523,6 @@ public class CacheGroupContext {
null,
null,
keepBinary);
- }
}
/**
@@ -976,17 +963,19 @@ public class CacheGroupContext {
Set<Integer> ids = U.newHashSet(caches.size());
- for (int i = 0; i < caches.size(); i++)
- ids.add(caches.get(i).cacheId());
+ for (GridCacheContext cctx : caches)
+ ids.add(cctx.cacheId());
return ids;
}
/**
* @return Caches in this group.
+ *
+ * caches is already Unmodifiable list, so we don't need to explicitly wrap it here.
*/
public List<GridCacheContext> caches() {
- return this.caches;
+ return caches;
}
/**
@@ -1004,9 +993,7 @@ public class CacheGroupContext {
public void onPartitionEvicted(int part) {
List<GridCacheContext> caches = this.caches;
- for (int i = 0; i < caches.size(); i++) {
- GridCacheContext cctx = caches.get(i);
-
+ for (GridCacheContext cctx : caches) {
if (cctx.isDrEnabled())
cctx.dr().partitionEvicted(part);
http://git-wip-us.apache.org/repos/asf/ignite/blob/d1a039d3/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index f2be434..fc6be6d 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -249,7 +249,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import java.util.stream.IntStream;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -10783,26 +10782,19 @@ public abstract class IgniteUtils {
) throws IgniteCheckedException, IgniteInterruptedCheckedException {
if(srcDatas.isEmpty())
return Collections.emptyList();
+ int[] batchSizes = calculateOptimalBatchSizes(parallelismLvl, srcDatas.size());
- int batchSize = srcDatas.size() / parallelismLvl;
+ List<List<T>> batches = new ArrayList<>(batchSizes.length);
- final int finalBatchSize = batchSize == 0 ? srcDatas.size() : batchSize;
+ Iterator<T> iterator = srcDatas.iterator();
- List<List<T>> batches = IntStream.range(0, parallelismLvl)
- .mapToObj(i -> new ArrayList<T>(finalBatchSize))
- .collect(Collectors.toList());
-
- int batchIndex = 0;
-
- final int maxBatchIndex = batches.size() -1;
+ for (int batchSize : batchSizes) {
+ List<T> batch = new ArrayList<>(batchSize);
- List<T> currentBatch = batches.get(batchIndex);
+ for (int i = 0; i < batchSize; i++)
+ batch.add(iterator.next());
- for (T src : srcDatas) {
- currentBatch.add(src);
-
- if(currentBatch.size() >= batchSize && batchIndex < maxBatchIndex)
- currentBatch = batches.get(++batchIndex);
+ batches.add(batch);
}
List<Future<Collection<R>>> consumerFutures = batches.stream()
@@ -10861,6 +10853,21 @@ public abstract class IgniteUtils {
}
/**
+ * Split number of tasks into optimized batches.
+ * @param parallelismLvl Level of parallelism.
+ * @param size number of tasks to split.
+ * @return array of batch sizes.
+ */
+ public static int[] calculateOptimalBatchSizes(int parallelismLvl, int size) {
+ int[] batcheSizes = new int[Math.min(parallelismLvl, size)];
+
+ for (int i = 0; i < size; i++)
+ batcheSizes[i % batcheSizes.length]++;
+
+ return batcheSizes;
+ }
+
+ /**
* @param fut Future to wait for completion.
* @throws ExecutionException If the future
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/d1a039d3/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheParallelStartTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheParallelStartTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheParallelStartTest.java
new file mode 100644
index 0000000..2a64485
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheParallelStartTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.distributed;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Test covers parallel start and stop of caches.
+ */
+public class CacheParallelStartTest extends GridCommonAbstractTest {
+ /** */
+ private static final int CACHES_COUNT = 500;
+
+ /** */
+ private static final String STATIC_CACHE_PREFIX = "static-cache-";
+
+ /** */
+ private static final String STATIC_CACHE_CACHE_GROUP_NAME = "static-cache-group";
+
+ /** */
+ private static final TcpDiscoveryVmIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setSystemThreadPoolSize(Runtime.getRuntime().availableProcessors() * 3);
+
+ TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+ discoSpi.setIpFinder(IP_FINDER);
+
+ cfg.setDiscoverySpi(discoSpi);
+
+ long sz = 100 * 1024 * 1024;
+
+ DataStorageConfiguration memCfg = new DataStorageConfiguration().setPageSize(1024)
+ .setDefaultDataRegionConfiguration(
+ new DataRegionConfiguration().setPersistenceEnabled(false).setInitialSize(sz).setMaxSize(sz))
+ .setWalMode(WALMode.LOG_ONLY).setCheckpointFrequency(24L * 60 * 60 * 1000);
+
+ cfg.setDataStorageConfiguration(memCfg);
+
+ ArrayList<Object> staticCaches = new ArrayList<>(CACHES_COUNT);
+
+ for (int i = 0; i < CACHES_COUNT; i++)
+ staticCaches.add(cacheConfiguration(STATIC_CACHE_PREFIX + i));
+
+ cfg.setCacheConfiguration(staticCaches.toArray(new CacheConfiguration[CACHES_COUNT]));
+
+ return cfg;
+ }
+
+ /**
+ * @param cacheName Cache name.
+ * @return Cache configuration.
+ */
+ private CacheConfiguration cacheConfiguration(String cacheName) {
+ CacheConfiguration cfg = defaultCacheConfiguration();
+
+ cfg.setName(cacheName);
+ cfg.setBackups(1);
+ cfg.setGroupName(STATIC_CACHE_CACHE_GROUP_NAME);
+ cfg.setIndexedTypes(Long.class, Long.class);
+
+ return cfg;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ cleanupTestData();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ cleanupTestData();
+ }
+
+ /** */
+ private void cleanupTestData() throws Exception {
+ stopAllGrids();
+
+ cleanPersistenceDir();
+
+ System.clearProperty(IgniteSystemProperties.IGNITE_ALLOW_START_CACHES_IN_PARALLEL);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testParallelStartAndStop() throws Exception {
+ testParallelStartAndStop(true);
+ }
+
+ /**
+ * @throws Exception if failed.
+ */
+ public void testSequentialStartAndStop() throws Exception {
+ testParallelStartAndStop(false);
+ }
+
+ /**
+ *
+ */
+ private void testParallelStartAndStop(boolean parallel) throws Exception {
+ System.setProperty(IgniteSystemProperties.IGNITE_ALLOW_START_CACHES_IN_PARALLEL, String.valueOf(parallel));
+
+ IgniteEx igniteEx = startGrid(0);
+
+ IgniteEx igniteEx2 = startGrid(1);
+
+ igniteEx.cluster().active(true);
+
+ assertCaches(igniteEx);
+
+ assertCaches(igniteEx2);
+
+ igniteEx.cluster().active(false);
+
+ assertCachesAfterStop(igniteEx);
+
+ assertCachesAfterStop(igniteEx2);
+ }
+
+ /**
+ *
+ */
+ private void assertCachesAfterStop(IgniteEx igniteEx) {
+ assertNull(igniteEx
+ .context()
+ .cache()
+ .cacheGroup(CU.cacheId(STATIC_CACHE_CACHE_GROUP_NAME)));
+
+ assertTrue(igniteEx.context().cache().cacheGroups().isEmpty());
+
+ for (int i = 0; i < CACHES_COUNT; i++) {
+ assertNull(igniteEx.context().cache().cache(STATIC_CACHE_PREFIX + i));
+ assertNull(igniteEx.context().cache().internalCache(STATIC_CACHE_PREFIX + i));
+ }
+ }
+
+ /**
+ *
+ */
+ private void assertCaches(IgniteEx igniteEx) {
+ Collection<GridCacheContext> caches = igniteEx
+ .context()
+ .cache()
+ .cacheGroup(CU.cacheId(STATIC_CACHE_CACHE_GROUP_NAME))
+ .caches();
+
+ assertEquals(CACHES_COUNT, caches.size());
+
+ @Nullable CacheGroupContext cacheGroup = igniteEx
+ .context()
+ .cache()
+ .cacheGroup(CU.cacheId(STATIC_CACHE_CACHE_GROUP_NAME));
+
+ for (GridCacheContext cacheContext : caches)
+ assertEquals(cacheContext.group(), cacheGroup);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d1a039d3/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java
index 070fd4a..2f52b21 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java
@@ -943,39 +943,46 @@ public class IgniteUtilsSelfTest extends GridCommonAbstractTest {
}
/**
+ * Test optimal splitting on batch sizes.
+ */
+ public void testOptimalBatchSize() {
+ assertArrayEquals(new int[]{1}, IgniteUtils.calculateOptimalBatchSizes(1, 1));
+
+ assertArrayEquals(new int[]{2}, IgniteUtils.calculateOptimalBatchSizes(1, 2));
+
+ assertArrayEquals(new int[]{1, 1, 1, 1}, IgniteUtils.calculateOptimalBatchSizes(6, 4));
+
+ assertArrayEquals(new int[]{1}, IgniteUtils.calculateOptimalBatchSizes(4, 1));
+
+ assertArrayEquals(new int[]{1, 1}, IgniteUtils.calculateOptimalBatchSizes(4, 2));
+
+ assertArrayEquals(new int[]{1, 1, 1}, IgniteUtils.calculateOptimalBatchSizes(4, 3));
+
+ assertArrayEquals(new int[]{1, 1, 1, 1}, IgniteUtils.calculateOptimalBatchSizes(4, 4));
+
+ assertArrayEquals(new int[]{2, 1, 1, 1}, IgniteUtils.calculateOptimalBatchSizes(4, 5));
+
+ assertArrayEquals(new int[]{2, 2, 1, 1}, IgniteUtils.calculateOptimalBatchSizes(4, 6));
+
+ assertArrayEquals(new int[]{2, 2, 2, 1}, IgniteUtils.calculateOptimalBatchSizes(4, 7));
+
+ assertArrayEquals(new int[]{2, 2, 2, 2}, IgniteUtils.calculateOptimalBatchSizes(4, 8));
+
+ assertArrayEquals(new int[]{3, 2, 2, 2}, IgniteUtils.calculateOptimalBatchSizes(4, 9));
+
+ assertArrayEquals(new int[]{3, 3, 2, 2}, IgniteUtils.calculateOptimalBatchSizes(4, 10));
+ }
+
+ /**
* Test parallel execution in order.
*/
public void testDoInParallelResultsOrder() throws IgniteCheckedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
try {
- testOrder(executorService, 1, 1);
- testOrder(executorService, 2, 1);
- testOrder(executorService, 3, 1);
- testOrder(executorService, 9, 1);
- testOrder(executorService, 10, 1);
- testOrder(executorService, 9999, 1);
-
- testOrder(executorService, 1, 2);
- testOrder(executorService, 2, 2);
- testOrder(executorService, 3, 2);
- testOrder(executorService, 9, 2);
- testOrder(executorService, 10, 2);
- testOrder(executorService, 9999, 2);
-
- testOrder(executorService, 1, 3);
- testOrder(executorService, 2, 3);
- testOrder(executorService, 3, 3);
- testOrder(executorService, 3, 3);
- testOrder(executorService, 10, 3);
- testOrder(executorService, 9999, 3);
-
- testOrder(executorService, 1, 4);
- testOrder(executorService, 2, 4);
- testOrder(executorService, 3, 4);
- testOrder(executorService, 9, 4);
- testOrder(executorService, 10, 4);
- testOrder(executorService, 9999, 4);
+ for(int parallelism = 1; parallelism < 16; parallelism++)
+ for(int size = 0; size < 10_000; size++)
+ testOrder(executorService, size, parallelism);
} finally {
executorService.shutdownNow();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d1a039d3/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
index d601696..e9d9663 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
@@ -27,6 +27,7 @@ import org.apache.ignite.internal.processors.cache.ReplicatedTransactionalOptimi
import org.apache.ignite.internal.processors.cache.ReplicatedTransactionalPessimisticCacheGetsDistributionTest;
import org.apache.ignite.internal.processors.cache.datastructures.IgniteExchangeLatchManagerCoordinatorFailTest;
import org.apache.ignite.internal.processors.cache.distributed.CacheExchangeMergeTest;
+import org.apache.ignite.internal.processors.cache.distributed.CacheParallelStartTest;
import org.apache.ignite.internal.processors.cache.distributed.CachePartitionStateTest;
import org.apache.ignite.internal.processors.cache.distributed.CacheTryLockMultithreadedTest;
import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitionEvictionDuringReadThroughSelfTest;
@@ -109,6 +110,8 @@ public class IgniteCacheTestSuite6 extends TestSuite {
suite.addTestSuite(PartitionsExchangeCoordinatorFailoverTest.class);
suite.addTestSuite(CacheTryLockMultithreadedTest.class);
+ suite.addTestSuite(CacheParallelStartTest.class);
+
//suite.addTestSuite(CacheClientsConcurrentStartTest.class);
//suite.addTestSuite(GridCacheRebalancingOrderingTest.class);
//suite.addTestSuite(IgniteCacheClientMultiNodeUpdateTopologyLockTest.class);