Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/GEODE-10228 DurableClientTestCase.testDurableHAFailover is failing #7608

Merged
merged 12 commits into from Apr 28, 2022
Merged
Expand Up @@ -19,20 +19,16 @@
import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
Expand All @@ -45,21 +41,17 @@
import org.apache.geode.cache.server.ClientSubscriptionConfig;
import org.apache.geode.cache.util.CacheListenerAdapter;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.SerializableCallable;
import org.apache.geode.test.dunit.SerializableRunnable;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.junit.categories.ClientSubscriptionTest;

/**
* The ClientServerRegisterInterestsDUnitTest class is a test suite of test cases testing the
* interaction between a client and a server in a Register Interests scenario.
*
* @since GemFire 8.0
*/
@Category({ClientSubscriptionTest.class})
@Tag("ClientSubscriptionTest")
public class ClientServerRegisterInterestsDUnitTest extends JUnit4DistributedTestCase {

protected static final long WAIT_TIME_MILLISECONDS = TimeUnit.SECONDS.toMillis(5);
Expand All @@ -68,89 +60,78 @@ public class ClientServerRegisterInterestsDUnitTest extends JUnit4DistributedTes

private final AtomicInteger serverPort = new AtomicInteger(0);

private final Stack entryEvents = new Stack();
private final Stack<EntryEvent<String, String>> entryEvents = new Stack<>();

private VM gemfireServerVm;

@Override
public final void postSetUp() throws Exception {
public final void postSetUp() {
disconnectAllFromDS();
setupGemFireCacheServer();
IgnoredException.addIgnoredException("java.net.ConnectException");
}

@Override
public final void preTearDown() throws Exception {
public final void preTearDown() {
serverPort.set(0);
entryEvents.clear();
gemfireServerVm.invoke(new SerializableRunnable() {
@Override
public void run() {
CacheFactory.getAnyInstance().close();
}
});
gemfireServerVm.invoke(() -> CacheFactory.getAnyInstance().close());
gemfireServerVm = null;
}

private void setupGemFireCacheServer() {
Host localhost = Host.getHost(0);

gemfireServerVm = localhost.getVM(0);

gemfireServerVm = VM.getVM(0);
serverPort.set(AvailablePortHelper.getRandomAvailableTCPPort());

gemfireServerVm.invoke(new SerializableRunnable() {
@Override
public void run() {
try {
Cache cache = new CacheFactory()
.set("name", "ClientServerRegisterInterestsTestGemFireServer").set(MCAST_PORT, "0")
.set(LOG_FILE, "clientServerRegisterInterestsTest.log").set(LOG_LEVEL, "config")
// .set("jmx-manager", "true")
// .set("jmx-manager-http-port", "0")
// .set("jmx-manager-port", "1199")
// .set("jmx-manager-start", "true")
.create();
gemfireServerVm.invoke(() -> {
try {
Cache cache = new CacheFactory()
.set("name", "ClientServerRegisterInterestsTestGemFireServer").set(MCAST_PORT, "0")
.set(LOG_FILE, "clientServerRegisterInterestsTest.log").set(LOG_LEVEL, "config")
.create();

RegionFactory<String, String> regionFactory = cache.createRegionFactory();
RegionFactory<String, String> regionFactory = cache.createRegionFactory();

regionFactory.setDataPolicy(DataPolicy.REPLICATE);
regionFactory.setKeyConstraint(String.class);
regionFactory.setValueConstraint(String.class);
regionFactory.setDataPolicy(DataPolicy.REPLICATE);
regionFactory.setKeyConstraint(String.class);
regionFactory.setValueConstraint(String.class);

Region<String, String> example = regionFactory.create("Example");
Region<String, String> example = regionFactory.create("Example");

assertNotNull("The 'Example' Region was not properly configured and initialized!",
example);
assertEquals(SEPARATOR + "Example", example.getFullPath());
assertEquals("Example", example.getName());
assertTrue(example.isEmpty());
assertThat(example)
.describedAs("The 'Example' Region was not properly configured and initialized!")
.isNotNull();
assertThat(example.getFullPath()).isEqualTo(SEPARATOR + "Example");
assertThat(example.getName()).isEqualTo("Example");
assertThat(example).isEmpty();

example.put("1", "ONE");
example.put("1", "ONE");

assertFalse(example.isEmpty());
assertEquals(1, example.size());
assertThat(example).isNotEmpty();
assertThat(example).hasSize(1);

CacheServer cacheServer = cache.addCacheServer();
CacheServer cacheServer = cache.addCacheServer();

cacheServer.setPort(serverPort.get());
cacheServer.setMaxConnections(10);
cacheServer.setPort(serverPort.get());
cacheServer.setMaxConnections(10);

ClientSubscriptionConfig clientSubscriptionConfig =
cacheServer.getClientSubscriptionConfig();
ClientSubscriptionConfig clientSubscriptionConfig =
cacheServer.getClientSubscriptionConfig();

clientSubscriptionConfig.setCapacity(100);
clientSubscriptionConfig.setEvictionPolicy("entry");
clientSubscriptionConfig.setCapacity(100);
clientSubscriptionConfig.setEvictionPolicy("entry");

cacheServer.start();
cacheServer.start();

assertTrue("Cache Server is not running!", cacheServer.isRunning());
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(String.format(
"Failed to start the GemFire Cache Server listening on port (%1$d) due to IO error!",
serverPort.get()), e);
}
assertThat(cacheServer.isRunning()).describedAs("Cache Server is not running!").isTrue();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(String.format(
"Failed to start the GemFire Cache Server listening on port (%1$d) due to IO error!",
serverPort.get()), e);
}
});
}
Expand All @@ -169,7 +150,9 @@ private ClientCache setupGemFireClientCache() {

Pool pool = poolFactory.create("serverConnectionPool");

assertNotNull("The 'serverConnectionPool' was not properly configured and initialized!", pool);
assertThat(pool)
.describedAs("The 'serverConnectionPool' was not properly configured and initialized!")
.isNotNull();

ClientRegionFactory<String, String> regionFactory =
clientCache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY);
Expand All @@ -181,8 +164,9 @@ private ClientCache setupGemFireClientCache() {

Region<String, String> exampleCachingProxy = regionFactory.create("Example");

assertNotNull("The 'Example' Client Region was not properly configured and initialized",
exampleCachingProxy);
assertThat(exampleCachingProxy)
.describedAs("The 'Example' Client Region was not properly configured and initialized")
.isNotNull();

clientCache.readyForEvents();

Expand All @@ -191,25 +175,23 @@ private ClientCache setupGemFireClientCache() {
return clientCache;
}

@SuppressWarnings("unchecked")
protected <K, V> V put(final String regionName, final K key, final V value) {
return (V) gemfireServerVm.invoke(new SerializableCallable() {
@Override
public Object call() throws Exception {
Cache cache = CacheFactory.getAnyInstance();
cache.getRegion(regionName).put(key, value);
return cache.getRegion(regionName).get(key);
}
protected <V> V put() {
return (V) gemfireServerVm.invoke(() -> {
Cache cache = CacheFactory.getAnyInstance();
cache.getRegion("/Example").put("2", "TWO");
return cache.getRegion("/Example").get("2");
});
}
Comment on lines +180 to 186
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warnings here can be fixed by using:

  protected String put() {
    return gemfireServerVm.invoke(() -> {
      Cache cache = CacheFactory.getAnyInstance();
      cache.getRegion("/Example").put("2", "TWO");
      return cache.<String, String>getRegion("/Example").get("2");
    });
  }

Since we explicitly create the Region as <String, String>, there's no need to use generics here.


protected void waitOnEvent(final long waitTimeMilliseconds) {
final long timeout = (System.currentTimeMillis() + waitTimeMilliseconds);
protected void waitOnEvent() {
final long timeout = (System.currentTimeMillis()
+ ClientServerRegisterInterestsDUnitTest.WAIT_TIME_MILLISECONDS);

while (entryEvents.empty() && (System.currentTimeMillis() < timeout)) {
synchronized (this) {
try {
TimeUnit.MILLISECONDS.timedWait(this, Math.min(500, waitTimeMilliseconds));
TimeUnit.MILLISECONDS.timedWait(this, Math.min(500,
ClientServerRegisterInterestsDUnitTest.WAIT_TIME_MILLISECONDS));
} catch (InterruptedException ignore) {
}
Comment on lines +189 to 198
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole method should probably just be replaced with:

      await().untilAsserted(() -> assertThat(entryEvents).isNotEmpty());

}
Expand All @@ -218,35 +200,33 @@ protected void waitOnEvent(final long waitTimeMilliseconds) {

@Test
public void testClientRegisterInterests() {
ClientCache clientCache = setupGemFireClientCache();

try {
try (ClientCache clientCache = setupGemFireClientCache()) {
Region<String, String> example = clientCache.getRegion(SEPARATOR + "Example");

assertNotNull("'Example' Region in Client Cache was not found!", example);
assertEquals(1, example.size());
assertTrue(example.containsKey("1"));
assertEquals("ONE", example.get("1"));
assertTrue(entryEvents.empty());
assertThat(example).describedAs("'Example' Region in Client Cache was not found!")
.isNotNull();
assertThat(example).hasSize(1);
assertThat(example).containsKey("1");
assertThat(example.get("1")).isEqualTo("ONE");
jake-at-work marked this conversation as resolved.
Show resolved Hide resolved
assertThat(entryEvents).isEmpty();

String value = put(SEPARATOR + "Example", "2", "TWO");
String value = put();

assertEquals("TWO", value);
assertThat(value).isEqualTo("TWO");

waitOnEvent(WAIT_TIME_MILLISECONDS);
waitOnEvent();

assertFalse(entryEvents.empty());
assertThat(entryEvents).isNotEmpty();

EntryEvent entryEvent = (EntryEvent) entryEvents.pop();
EntryEvent<String, String> entryEvent = entryEvents.pop();

assertEquals("2", entryEvent.getKey());
assertEquals("TWO", entryEvent.getNewValue());
assertNull(entryEvent.getOldValue());
assertEquals(2, example.size());
assertTrue(example.containsKey("2"));
assertEquals("TWO", example.get("2"));
} finally {
clientCache.close();
assertThat(entryEvent.getKey()).isEqualTo("2");
assertThat(entryEvent.getNewValue()).isEqualTo("TWO");
assertThat(entryEvent.getOldValue()).isNull();
assertThat(example).hasSize(2);
assertThat(example).containsKey("2");
assertThat(example.get("2")).isEqualTo("TWO");
}
}

Expand Down