package org.infinispan.remoting.transport;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.fail;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.math.FieldElement;
import org.infinispan.commons.CacheException;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.manager.EmbeddedCacheManagerStartupException;
import org.infinispan.test.Exceptions;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.fwk.CleanupAfterMethod;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.infinispan.test.fwk.TransportFlags;
import org.testng.annotations.Test;
@Test(testName = "transport.InitialClusterSizeTest", groups = "functional")
@CleanupAfterMethod
public class InitialClusterSizeTest extends MultipleCacheManagersTest {
public static final int CLUSTER_SIZE = 4;
public static final int CLUSTER_TIMEOUT_SECONDS = 5;
@Override
protected void createCacheManagers() throws Throwable {
for (int i = 0; i < CLUSTER_SIZE; i++) {
GlobalConfigurationBuilder gc = GlobalConfigurationBuilder.defaultClusteredBuilder();
gc.transport().initialClusterSize(CLUSTER_SIZE).initialClusterTimeout(CLUSTER_TIMEOUT_SECONDS, TimeUnit.SECONDS);
cacheManagers.add(TestCacheManagerFactory.createClusteredCacheManager(false, gc,
getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC), new TransportFlags().withPortRange(i), false));
}
}
public void testInitialClusterSize() throws ExecutionException, InterruptedException, TimeoutException {
Future<?>[] threads = new Future[CLUSTER_SIZE];
for (int i = 0; i < CLUSTER_SIZE; i++) {
final int index = i;
threads[i] = fork(() -> {
manager(index).start();
});
}
for(Future<?> f : threads) {
f.get(15, TimeUnit.SECONDS);
}
assertEquals(CLUSTER_SIZE, manager(0).getMembers().size());
}
public <T extends FieldElement<T>> void testInitialClusterSizeFail() throws Throwable {
List<Future<Void>> futures = new ArrayList<>();
for (int i = 0; i < CLUSTER_SIZE - 1; i++) {
EmbeddedCacheManager manager = manager(i);
futures.add(fork(() -> {
manager.start();
return null;
}));
}
for (Future<Void> future : futures) {
try {
// JGroupsTransport only starts counting down on initialClusterTimeout *after* it connects.
// The initial connection may take take 3 seconds (GMS.join_timeout) because of JGRP-2028
// Shutdown may also take 2 seconds (GMS.view_ack_collection_timeout) because of JGRP-2030
future.get(CLUSTER_TIMEOUT_SECONDS + 5, TimeUnit.SECONDS);
fail("Should have thrown an exception");
} catch (ExecutionException ee) {
Exceptions.assertException(EmbeddedCacheManagerStartupException.class, ee.getCause());
Exceptions.assertException(CacheException.class,
org.infinispan.util.concurrent.TimeoutException.class, "ISPN000399:.*",
ee.getCause().getCause());
}
}
}
}