package org.infinispan.commands; import static org.testng.AssertJUnit.assertEquals; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.infinispan.Cache; import org.infinispan.commons.executors.BlockingThreadPoolExecutorFactory; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.fwk.InCacheMode; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.test.fwk.TransportFlags; import org.testng.annotations.Test; /** * Stress test designed to test to verify that get many works properly under constant * topology changes * * @author wburns * @since 7.2 */ @Test(groups = "stress", testName = "commands.GetAllCommandStressTest", timeOut = 15*60*1000) @InCacheMode({ CacheMode.DIST_SYNC }) public class GetAllCommandStressTest extends StressTest { protected final String CACHE_NAME = getClass().getName(); protected final static int CACHE_COUNT = 6; protected final static int THREAD_MULTIPLIER = 4; protected final static int CACHE_ENTRY_COUNT = 50000; @Override protected void createCacheManagers() throws Throwable { builderUsed = new ConfigurationBuilder(); builderUsed.clustering().cacheMode(cacheMode); builderUsed.clustering().stateTransfer().chunkSize(25000); // Uncomment this line to make it transactional // builderUsed.transaction().transactionMode(TransactionMode.TRANSACTIONAL); // This is increased just for the put all command when doing full tracing builderUsed.clustering().remoteTimeout(30000); createClusteredCaches(CACHE_COUNT, CACHE_NAME, builderUsed); } protected EmbeddedCacheManager addClusterEnabledCacheManager(TransportFlags flags) { GlobalConfigurationBuilder gcb = GlobalConfigurationBuilder.defaultClusteredBuilder(); // Amend first so we can increase the transport thread pool TestCacheManagerFactory.amendGlobalConfiguration(gcb, flags); // we need to increase the transport and remote thread pools to default values BlockingThreadPoolExecutorFactory executorFactory = new BlockingThreadPoolExecutorFactory( 25, 25, 10000, 30000); gcb.transport().transportThreadPool().threadPoolFactory(executorFactory); gcb.transport().remoteCommandThreadPool().threadPoolFactory(executorFactory); EmbeddedCacheManager cm = TestCacheManagerFactory.newDefaultCacheManager(true, gcb, new ConfigurationBuilder(), false); cacheManagers.add(cm); return cm; } public void testStressNodesLeavingWhileMultipleIterators() throws Throwable { final Map<Integer, Integer> masterValues = new HashMap<Integer, Integer>(); int threadWorkerCount = THREAD_MULTIPLIER * (CACHE_COUNT - 1); final Set<Integer>[] keys = new Set[threadWorkerCount]; for (int i = 0; i < keys.length; ++i) { keys[i] = new HashSet<>(); } // First populate our caches for (int i = 0; i < CACHE_ENTRY_COUNT; ++i) { masterValues.put(i, i); keys[i % threadWorkerCount].add(i); } cache(0, CACHE_NAME).putAll(masterValues); for (int i = 0; i < keys.length; ++i) { keys[i] = Collections.unmodifiableSet(keys[i]); } List<Future<Void>> futures = forkWorkerThreads(CACHE_NAME, THREAD_MULTIPLIER, CACHE_COUNT, keys, this::workerLogic); // Then spawn a thread that just constantly kills the last cache and recreates over and over again futures.add(forkRestartingThread()); waitAndFinish(futures, 1, TimeUnit.MINUTES); } protected void workerLogic(Cache<Integer, Integer> cache, Set<Integer> threadKeys, int iteration) { Map<Integer, Integer> results = cache.getAdvancedCache().getAll(threadKeys); assertEquals("Keys: " + threadKeys + "\nResults: " + results, threadKeys.size(), results.size()); for (Integer key : threadKeys) { assertEquals(key, results.get(key)); } } }