You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2018/04/23 05:46:48 UTC

[geode] 10/13: GEODE-1279: Rename RegisterInterestKeysValuesDistributedTest

This is an automated email from the ASF dual-hosted git repository.

klund pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git

commit fcc943602726a74be68ffefb5843726a7c0f4f00
Author: Kirk Lund <kl...@apache.org>
AuthorDate: Fri Apr 20 16:11:46 2018 -0700

    GEODE-1279: Rename RegisterInterestKeysValuesDistributedTest
    
    * Bug43684DUnitTest -> RegisterInterestKeysValuesDistributedTest
    * Add "boolean containsTombstone(Object key)" to InternalRegion
---
 .../geode/internal/cache/InternalRegion.java       |   2 +
 .../cache/partitioned/Bug43684DUnitTest.java       | 359 -------------------
 .../RegisterInterestKeysValuesDistributedTest.java | 394 +++++++++++++++++++++
 3 files changed, 396 insertions(+), 359 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java
index 7c5d722..65a2b73 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java
@@ -238,4 +238,6 @@ public interface InternalRegion extends Region, HasCachePerfStats, RegionEntryCo
    * @return boolean indicating whether to generate eventID or not
    */
   boolean generateEventID();
+
+  boolean containsTombstone(Object key);
 }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/Bug43684DUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/Bug43684DUnitTest.java
deleted file mode 100644
index 0f6ea80..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/Bug43684DUnitTest.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * 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.geode.internal.cache.partitioned;
-
-import static org.apache.geode.distributed.ConfigurationProperties.*;
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.cache.CacheFactory;
-import org.apache.geode.cache.PartitionAttributesFactory;
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionFactory;
-import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.cache.client.ClientCacheFactory;
-import org.apache.geode.cache.client.ClientRegionFactory;
-import org.apache.geode.cache.client.ClientRegionShortcut;
-import org.apache.geode.internal.AvailablePort;
-import org.apache.geode.internal.OSProcess;
-import org.apache.geode.internal.cache.CacheServerImpl;
-import org.apache.geode.internal.cache.GemFireCacheImpl;
-import org.apache.geode.internal.cache.LocalRegion;
-import org.apache.geode.internal.cache.RegionEntry;
-import org.apache.geode.internal.i18n.LocalizedStrings;
-import org.apache.geode.test.dunit.DistributedTestUtils;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.IgnoredException;
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
-import org.apache.geode.test.junit.categories.DistributedTest;
-
-/**
- * TODO This doesn't really test the optimised RI behaviour but only that RI works. But there must
- * be other tests doing the same.
- */
-@Category(DistributedTest.class)
-@SuppressWarnings("serial")
-public class Bug43684DUnitTest extends JUnit4DistributedTestCase {
-
-  private static final String REGION_NAME = Bug43684DUnitTest.class.getSimpleName();
-
-  private static GemFireCacheImpl cache;
-
-  private Host host;
-
-  private static VM server1;
-
-  private static VM server2;
-
-  private static VM server3;
-
-  private static VM client1;
-
-  private static int numBuckets = 11;
-
-  @Override
-  public final void postSetUp() throws Exception {
-    host = Host.getHost(0);
-    server1 = host.getVM(0);
-    server2 = host.getVM(1);
-    server3 = host.getVM(2);
-    client1 = host.getVM(3);
-    IgnoredException.addIgnoredException("Connection refused: connect");
-  }
-
-  @Override
-  public final void preTearDown() throws Exception {
-    closeCache();
-    client1.invoke(() -> Bug43684DUnitTest.closeCache());
-    server1.invoke(() -> Bug43684DUnitTest.closeCache());
-    server2.invoke(() -> Bug43684DUnitTest.closeCache());
-    server3.invoke(() -> Bug43684DUnitTest.closeCache());
-  }
-
-  public static void closeCache() {
-    if (cache != null && !cache.isClosed()) {
-      cache.close();
-    }
-    disconnectFromDS();
-  }
-
-  @Test
-  public void testRIWithSingleKeyOnRR() throws Exception {
-    doRegisterInterest("KEY_1", null, numBuckets, true, false);
-  }
-
-  @Test
-  public void testRIWithAllKeysOnRR() throws Exception {
-    doRegisterInterest(null, null, numBuckets, true, false);
-  }
-
-  @Test
-  public void testRIWithKeyListOnRR() throws Exception {
-    ArrayList<String> riKeys = new ArrayList<String>();
-    riKeys.add("KEY_0");
-    riKeys.add("KEY_1");
-    riKeys.add("KEY_2");
-    riKeys.add("KEY_5");
-    riKeys.add("KEY_6");
-    riKeys.add("KEY_7");
-    riKeys.add("KEY_9");
-
-    doRegisterInterest(riKeys, null, numBuckets, true, false);
-  }
-
-  @Test
-  public void testRIWithRegularExpressionOnRR() throws Exception {
-    doRegisterInterest(null, "^[X][_].*", numBuckets, true, false);
-  }
-
-  @Test
-  public void testRIWithSingleKeyOnPR() throws Exception {
-    doRegisterInterest("KEY_1", null);
-  }
-
-  @Test
-  public void testRIWithAllKeysOnPR() throws Exception {
-    doRegisterInterest(null, null);
-  }
-
-  @Test
-  public void testRIWithKeyListOnPR() throws Exception {
-    ArrayList<String> riKeys = new ArrayList<String>();
-    riKeys.add("KEY_0");
-    riKeys.add("KEY_1");
-    riKeys.add("KEY_2");
-    riKeys.add("KEY_5");
-    riKeys.add("KEY_6");
-    riKeys.add("KEY_7");
-    riKeys.add("KEY_9");
-
-    doRegisterInterest(riKeys, null);
-  }
-
-  @Test
-  public void testRIWithRegularExpressionOnPR() throws Exception {
-    doRegisterInterest(null, "^[X][_].*");
-  }
-
-  @Test
-  public void testRIWithMoreEntriesOnPR() throws Exception {
-    doRegisterInterest(null, null, 5147, false, false);
-  }
-
-  @Test
-  public void testRIWithSingleKeyOnEmptyPrimaryOnPR() throws Exception {
-    doRegisterInterest("KEY_1", null, numBuckets, false, true);
-  }
-
-  @Test
-  public void testRIWithAllKeysOnEmptyPrimaryOnPR() throws Exception {
-    doRegisterInterest(null, null, numBuckets, false, true);
-  }
-
-  @Test
-  public void testRIWithKeyListOnEmptyPrimaryOnPR() throws Exception {
-    ArrayList<String> riKeys = new ArrayList<String>();
-    riKeys.add("KEY_0");
-    riKeys.add("KEY_1");
-    riKeys.add("KEY_2");
-    riKeys.add("KEY_5");
-    riKeys.add("KEY_6");
-    riKeys.add("KEY_7");
-    riKeys.add("KEY_9");
-
-    doRegisterInterest(riKeys, null, numBuckets, false, true);
-  }
-
-  @Test
-  public void testRIWithRegularExpressionOnEmptyPrimaryOnPR() throws Exception {
-    doRegisterInterest(null, "^[X][_].*", numBuckets, false, true);
-  }
-
-  @Test
-  public void testNativeClientIssueOnPR() throws Exception {
-    ArrayList<String> riKeys = new ArrayList<String>();
-    riKeys.add("OPKEY_0");
-    riKeys.add("OPKEY_1");
-    riKeys.add("OPKEY_2");
-    riKeys.add("OPKEY_3");
-    riKeys.add("OPKEY_4");
-    riKeys.add("OPKEY_5");
-    riKeys.add("OPKEY_6");
-    riKeys.add("OPKEY_7");
-    riKeys.add("OPKEY_8");
-    riKeys.add("OPKEY_9");
-    riKeys.add("OPKEY_10");
-    riKeys.add("OPKEY_11");
-    riKeys.add("OPKEY_12");
-    riKeys.add("OPKEY_13");
-    doRegisterInterest2(riKeys, false, false);
-  }
-
-  private void doRegisterInterest(Object keys, String regEx) throws Exception {
-    doRegisterInterest(keys, regEx, numBuckets, false, false);
-  }
-
-  @SuppressWarnings("rawtypes")
-  private void doRegisterInterest(Object keys, String regEx, Integer numOfPuts,
-      Boolean isReplicated, Boolean isPrimaryEmpty) throws Exception {
-    int port1 = (Integer) server1
-        .invoke(() -> Bug43684DUnitTest.createServerCache(isReplicated, isPrimaryEmpty));
-    server2.invoke(() -> Bug43684DUnitTest.createServerCache(isReplicated, false));
-    server3.invoke(() -> Bug43684DUnitTest.createServerCache(isReplicated, false));
-
-    int regexNum = 20;
-    server1.invoke(() -> Bug43684DUnitTest.doPuts(numOfPuts, regEx, regexNum));
-
-    client1.invoke(() -> Bug43684DUnitTest.createClientCache(host, port1));
-    client1.invoke(() -> Bug43684DUnitTest.registerInterest(keys, regEx));
-
-    server1.invoke(() -> Bug43684DUnitTest.closeCache());
-    int size = keys != null ? (keys instanceof List ? ((List) keys).size() : 1)
-        : regEx == null ? numOfPuts : regexNum;
-    client1.invoke(() -> Bug43684DUnitTest.verifyResponse(size));
-  }
-
-  @SuppressWarnings("rawtypes")
-  private void doRegisterInterest2(Object keys, Boolean isReplicated, Boolean isPrimaryEmpty)
-      throws Exception {
-    int port1 = (Integer) server1
-        .invoke(() -> Bug43684DUnitTest.createServerCache(isReplicated, isPrimaryEmpty));
-    server2.invoke(() -> Bug43684DUnitTest.createServerCache(isReplicated, false));
-    server3.invoke(() -> Bug43684DUnitTest.createServerCache(isReplicated, false));
-
-    client1.invoke(() -> Bug43684DUnitTest.createClientCache(host, port1));
-    createClientCache(host, port1);
-    doOps();
-
-    client1.invoke(() -> Bug43684DUnitTest.registerInterest(keys, null));
-    client1.invoke(() -> Bug43684DUnitTest.verifyResponse2());
-  }
-
-  public static Integer createServerCache() throws Exception {
-    return createServerCache(false, false);
-  }
-
-  @SuppressWarnings("rawtypes")
-  public static Integer createServerCache(Boolean isReplicated, Boolean isPrimaryEmpty)
-      throws Exception {
-    disconnectFromDS();
-    Properties props = new Properties();
-    props.setProperty(LOCATORS, "localhost[" + DistributedTestUtils.getDUnitLocatorPort() + "]");
-    props.setProperty(STATISTIC_ARCHIVE_FILE, "server_" + OSProcess.getId() + ".gfs");
-    props.setProperty(STATISTIC_SAMPLING_ENABLED, "true");
-    CacheFactory cf = new CacheFactory(props);
-    cache = (GemFireCacheImpl) cf.create();
-
-    RegionFactory rf;
-    if (isReplicated) {
-      RegionShortcut rs =
-          isPrimaryEmpty ? RegionShortcut.REPLICATE_PROXY : RegionShortcut.REPLICATE;
-      rf = cache.createRegionFactory(rs);
-    } else {
-      RegionShortcut rs =
-          isPrimaryEmpty ? RegionShortcut.PARTITION_PROXY : RegionShortcut.PARTITION;
-      rf = cache.createRegionFactory(rs);
-      rf.setPartitionAttributes(
-          new PartitionAttributesFactory().setTotalNumBuckets(numBuckets).create());
-    }
-    rf.create(REGION_NAME);
-    CacheServerImpl server = (CacheServerImpl) cache.addCacheServer();
-    server.setPort(AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET));
-    server.start();
-    return server.getPort();
-  }
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public static void createClientCache(Host host, Integer port) {
-    disconnectFromDS();
-    Properties props = new Properties();
-    props.setProperty(STATISTIC_ARCHIVE_FILE, "client_" + OSProcess.getId() + ".gfs");
-    props.setProperty(STATISTIC_SAMPLING_ENABLED, "true");
-    ClientCacheFactory ccf = new ClientCacheFactory(props);
-    ccf.addPoolServer(host.getHostName(), port).setPoolSubscriptionEnabled(true);
-    cache = (GemFireCacheImpl) ccf.create();
-    ClientRegionFactory crf = cache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY);
-    crf.create(REGION_NAME);
-  }
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public static void registerInterest(Object keys, String regEx) {
-    Region region = cache.getRegion(REGION_NAME);
-    if (keys == null && regEx == null) {
-      region.registerInterest("ALL_KEYS");
-    } else if (keys != null) {
-      region.registerInterest(keys);
-      region.registerInterest("UNKNOWN_KEY");
-    } else if (regEx != null) {
-      region.registerInterestRegex(regEx);
-    }
-  }
-
-  @SuppressWarnings({"rawtypes", "unchecked"})
-  public static void doPuts(Integer num, String regex, int regexNum) throws Exception {
-    Region r = cache.getRegion(REGION_NAME);
-    for (int i = 0; i < num; i++) {
-      r.create("KEY_" + i, "VALUE__" + i);
-    }
-    if (regex != null) {
-      for (int i = 0; i < regexNum; i++) {
-        r.create("X_KEY_" + i, "X_VALUE__" + i);
-      }
-    }
-  }
-
-  @SuppressWarnings({"rawtypes", "unchecked"})
-  public static void doOps() throws Exception {
-    Region r = cache.getRegion(REGION_NAME);
-    for (int i = 0; i < 14; i++) {
-      r.create("OPKEY_" + i, "OPVALUE__" + i);
-    }
-
-    for (int i = 7; i < 14; i++) {
-      r.destroy("OPKEY_" + i);
-    }
-  }
-
-  public static void verifyResponse2() throws Exception {
-    LocalRegion r = (LocalRegion) cache.getRegion(REGION_NAME);
-    for (int i = 0; i < 7; i++) {
-      assertTrue(r.containsKey("OPKEY_" + i));
-    }
-    for (int i = 7; i < 14; i++) {
-      assertFalse(r.containsKey("OPKEY_" + i));
-      assertTrue(r.containsTombstone("OPKEY_" + i));
-    }
-  }
-
-  public static void verifyResponse(Integer size) throws Exception {
-    LocalRegion r = (LocalRegion) cache.getRegion(REGION_NAME);
-    assertEquals(size.intValue(), r.size());
-  }
-
-  public static void getLocally() throws Exception {
-    LocalRegion r = (LocalRegion) cache.getRegion(REGION_NAME);
-    for (int i = 0; i < numBuckets; i++) {
-      RegionEntry e = r.getRegionEntry("KEY_" + i);
-      cache.getLoggerI18n().info(LocalizedStrings.DEBUG, e.getValue());
-    }
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/RegisterInterestKeysValuesDistributedTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/RegisterInterestKeysValuesDistributedTest.java
new file mode 100644
index 0000000..2ff7edc
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/RegisterInterestKeysValuesDistributedTest.java
@@ -0,0 +1,394 @@
+/*
+ * 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.geode.internal.cache.partitioned;
+
+import static org.apache.geode.test.dunit.IgnoredException.addIgnoredException;
+import static org.apache.geode.test.dunit.VM.getHostName;
+import static org.apache.geode.test.dunit.VM.getVM;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.PartitionAttributesFactory;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionFactory;
+import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.cache.client.ClientCacheFactory;
+import org.apache.geode.cache.client.ClientRegionFactory;
+import org.apache.geode.cache.client.ClientRegionShortcut;
+import org.apache.geode.cache.client.internal.InternalClientCache;
+import org.apache.geode.cache.server.CacheServer;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.cache.InternalRegion;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.CacheRule;
+import org.apache.geode.test.dunit.rules.ClientCacheRule;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
+
+/**
+ * Functional distributed tests for Register Interest with KEYS_VALUES policy.
+ *
+ * <p>
+ * TRAC #43684: Register interest with policy KEYS_VALUES is inefficient
+ */
+@Category(DistributedTest.class)
+@SuppressWarnings("serial")
+public class RegisterInterestKeysValuesDistributedTest implements Serializable {
+
+  private VM server1;
+  private VM server2;
+  private VM server3;
+  private VM client1;
+
+  private String regionName;
+  private String hostName;
+  private int bucketCount;
+  private int regexCount;
+  private int port1;
+
+  @Rule
+  public DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+  @Rule
+  public CacheRule cacheRule = new CacheRule();
+
+  @Rule
+  public ClientCacheRule clientCacheRule = new ClientCacheRule();
+
+  @Rule
+  public SerializableTestName testName = new SerializableTestName();
+
+  @Before
+  public void setUp() throws Exception {
+    server1 = getVM(0);
+    server2 = getVM(1);
+    server3 = getVM(2);
+    client1 = getVM(3);
+
+    regionName = getClass().getSimpleName() + "_" + testName.getMethodName();
+    hostName = getHostName();
+    bucketCount = 11;
+    regexCount = 20;
+
+    addIgnoredException("Connection refused: connect");
+  }
+
+  @Test
+  public void testRIWithSingleKeyOnRR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(true, false));
+    server2.invoke(() -> createServerCache(true, false));
+    server3.invoke(() -> createServerCache(true, false));
+
+    doRegisterInterest("KEY_1", null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithAllKeysOnRR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(true, false));
+    server2.invoke(() -> createServerCache(true, false));
+    server3.invoke(() -> createServerCache(true, false));
+
+    doRegisterInterest(null, null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithKeyListOnRR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(true, false));
+    server2.invoke(() -> createServerCache(true, false));
+    server3.invoke(() -> createServerCache(true, false));
+
+    List<String> riKeys = new ArrayList<>();
+    riKeys.add("KEY_0");
+    riKeys.add("KEY_1");
+    riKeys.add("KEY_2");
+    riKeys.add("KEY_5");
+    riKeys.add("KEY_6");
+    riKeys.add("KEY_7");
+    riKeys.add("KEY_9");
+
+    doRegisterInterest(riKeys, null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithRegularExpressionOnRR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(true, false));
+    server2.invoke(() -> createServerCache(true, false));
+    server3.invoke(() -> createServerCache(true, false));
+
+    doRegisterInterest(null, "^[X][_].*", bucketCount);
+  }
+
+  @Test
+  public void testRIWithSingleKeyOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, false));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    doRegisterInterest("KEY_1", null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithAllKeysOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, false));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    doRegisterInterest(null, null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithKeyListOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, false));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    List<String> riKeys = new ArrayList<>();
+    riKeys.add("KEY_0");
+    riKeys.add("KEY_1");
+    riKeys.add("KEY_2");
+    riKeys.add("KEY_5");
+    riKeys.add("KEY_6");
+    riKeys.add("KEY_7");
+    riKeys.add("KEY_9");
+
+    doRegisterInterest(riKeys, null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithRegularExpressionOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, false));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    doRegisterInterest(null, "^[X][_].*", bucketCount);
+  }
+
+  @Test
+  public void testRIWithMoreEntriesOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, false));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    doRegisterInterest(null, null, 5147);
+  }
+
+  @Test
+  public void testRIWithSingleKeyOnEmptyPrimaryOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, true));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    doRegisterInterest("KEY_1", null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithAllKeysOnEmptyPrimaryOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, true));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    doRegisterInterest(null, null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithKeyListOnEmptyPrimaryOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, true));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    List<String> riKeys = new ArrayList<>();
+    riKeys.add("KEY_0");
+    riKeys.add("KEY_1");
+    riKeys.add("KEY_2");
+    riKeys.add("KEY_5");
+    riKeys.add("KEY_6");
+    riKeys.add("KEY_7");
+    riKeys.add("KEY_9");
+
+    doRegisterInterest(riKeys, null, bucketCount);
+  }
+
+  @Test
+  public void testRIWithRegularExpressionOnEmptyPrimaryOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, true));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    doRegisterInterest(null, "^[X][_].*", bucketCount);
+  }
+
+  @Test
+  public void testNativeClientIssueOnPR() throws Exception {
+    port1 = server1.invoke(() -> createServerCache(false, false));
+    server2.invoke(() -> createServerCache(false, false));
+    server3.invoke(() -> createServerCache(false, false));
+
+    List<String> keys = new ArrayList<>();
+    keys.add("OPKEY_0");
+    keys.add("OPKEY_1");
+    keys.add("OPKEY_2");
+    keys.add("OPKEY_3");
+    keys.add("OPKEY_4");
+    keys.add("OPKEY_5");
+    keys.add("OPKEY_6");
+    keys.add("OPKEY_7");
+    keys.add("OPKEY_8");
+    keys.add("OPKEY_9");
+    keys.add("OPKEY_10");
+    keys.add("OPKEY_11");
+    keys.add("OPKEY_12");
+    keys.add("OPKEY_13");
+
+    client1.invoke(() -> createClientCache(port1));
+    createClientCache(port1);
+    doOps();
+
+    client1.invoke(() -> {
+      Region region = clientCache().getRegion(regionName);
+      region.registerInterest(keys);
+      region.registerInterest("UNKNOWN_KEY");
+    });
+
+    client1.invoke(() -> {
+      InternalRegion region = (InternalRegion) clientCache().getRegion(regionName);
+      for (int i = 0; i < 7; i++) {
+        assertTrue(region.containsKey("OPKEY_" + i));
+      }
+      for (int i = 7; i < 14; i++) {
+        assertFalse(region.containsKey("OPKEY_" + i));
+        assertTrue(region.containsTombstone("OPKEY_" + i));
+      }
+    });
+  }
+
+  private void doRegisterInterest(Object keys, String regEx, int numOfPuts) {
+    server1.invoke(() -> doPuts(numOfPuts, regEx, regexCount));
+
+    client1.invoke(() -> createClientCache(port1));
+    client1.invoke(() -> registerInterest(keys, regEx));
+
+    server1.invoke(() -> cache().close());
+
+    // int size = getExpectedSize(keys, regEx, numOfPuts);
+    client1.invoke(() -> verifyResponse(getExpectedSize(keys, regEx, numOfPuts)));
+  }
+
+  private int getExpectedSize(Object keys, String regEx, int numOfPuts) {
+    return keys != null ? (keys instanceof List ? ((List) keys).size() : 1)
+        : regEx == null ? numOfPuts : regexCount;
+  }
+
+  private int createServerCache(boolean isReplicated, boolean isPrimaryEmpty) throws IOException {
+    createCache();
+
+    RegionFactory rf;
+    if (isReplicated) {
+      RegionShortcut rs =
+          isPrimaryEmpty ? RegionShortcut.REPLICATE_PROXY : RegionShortcut.REPLICATE;
+      rf = cache().createRegionFactory(rs);
+    } else {
+      RegionShortcut rs =
+          isPrimaryEmpty ? RegionShortcut.PARTITION_PROXY : RegionShortcut.PARTITION;
+      rf = cache().createRegionFactory(rs);
+      rf.setPartitionAttributes(
+          new PartitionAttributesFactory().setTotalNumBuckets(bucketCount).create());
+    }
+    rf.create(regionName);
+
+    CacheServer server = cache().addCacheServer();
+    server.setPort(0);
+    server.start();
+    return server.getPort();
+  }
+
+  private void createClientCache(int port) {
+    ClientCacheFactory ccf = new ClientCacheFactory();
+    ccf.addPoolServer(hostName, port).setPoolSubscriptionEnabled(true);
+
+    createClientCache(ccf);
+
+    ClientRegionFactory crf =
+        clientCache().createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY);
+    crf.create(regionName);
+  }
+
+  private void registerInterest(Object keys, String regEx) {
+    Region region = clientCache().getRegion(regionName);
+    if (keys == null && regEx == null) {
+      region.registerInterest("ALL_KEYS");
+    } else if (keys != null) {
+      region.registerInterest(keys);
+      region.registerInterest("UNKNOWN_KEY");
+    } else if (regEx != null) {
+      region.registerInterestRegex(regEx);
+    }
+  }
+
+  private void doPuts(int count, String regex, int regexNum) {
+    Region region = cache().getRegion(regionName);
+    for (int i = 0; i < count; i++) {
+      region.create("KEY_" + i, "VALUE__" + i);
+    }
+    if (regex != null) {
+      for (int i = 0; i < regexNum; i++) {
+        region.create("X_KEY_" + i, "X_VALUE__" + i);
+      }
+    }
+  }
+
+  private void doOps() {
+    Region region = clientCache().getRegion(regionName);
+    for (int i = 0; i < 14; i++) {
+      region.create("OPKEY_" + i, "OPVALUE__" + i);
+    }
+
+    for (int i = 7; i < 14; i++) {
+      region.destroy("OPKEY_" + i);
+    }
+  }
+
+  private void verifyResponse(int size) {
+    Region region = clientCache().getRegion(regionName);
+    assertEquals(size, region.size());
+  }
+
+  private InternalCache cache() {
+    return cacheRule.getCache();
+  }
+
+  private InternalClientCache clientCache() {
+    return clientCacheRule.getClientCache();
+  }
+
+  private void createCache() {
+    cacheRule.createCache();
+  }
+
+  private void createClientCache(ClientCacheFactory ccf) {
+    clientCacheRule.createClientCache(ccf);
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
klund@apache.org.