geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From upthewatersp...@apache.org
Subject [1/3] incubator-geode git commit: GEODE-1760, GEODE-1762: Tests of function exceptions from clients
Date Wed, 17 Aug 2016 21:36:08 GMT
Repository: incubator-geode
Updated Branches:
  refs/heads/develop 7d830c5b0 -> a5daa924a


GEODE-1760, GEODE-1762: Tests of function exceptions from clients

Extending FunctionServiceBase with tests that use a client server
topology. Added tests of onRegion with PRs as well as onServers.

Adding tests of P2P onRegion with multiple members and PRs.

Adding a temporary workaround for GEODE-1762 to let the function service
tests pass even if a Execution.execute throws an exception. This lets us
at least run the same tests against these different topologies even
though they are throwing different exceptions.

Added a test that result collectors receive partial results even after a
failure.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/6a91b9d0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/6a91b9d0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/6a91b9d0

Branch: refs/heads/develop
Commit: 6a91b9d08c35bf3c3b7cc38e4a4a0d5906e21dbb
Parents: 7d830c5
Author: Dan Smith <upthewaterspout@apache.org>
Authored: Thu Aug 11 13:46:41 2016 -0700
Committer: Dan Smith <upthewaterspout@apache.org>
Committed: Wed Aug 17 14:20:45 2016 -0700

----------------------------------------------------------------------
 .../cache/execute/FunctionServiceBase.java      | 176 +++++++++++++------
 .../FunctionServiceClientAccessorPRBase.java    | 145 +++++++++++++++
 ...unctionServiceClientAccessorPRDUnitTest.java |  46 +++++
 ...lientAccessorPRMultipleMembersDUnitTest.java |  59 +++++++
 ...essorPRMultipleMembersMultihopDUnitTest.java |  44 +++++
 .../execute/FunctionServiceClientBase.java      |  61 +++++++
 ...nServiceClientMultipleOnServerDUnitTest.java |  42 +++++
 .../FunctionServiceClientOnServerBase.java      |  40 +++++
 .../FunctionServiceClientOnServerDUnitTest.java |  32 ++++
 .../FunctionServicePeerAccessorPRBase.java      |  66 +++++++
 .../FunctionServicePeerAccessorPRDUnitTest.java |  37 +---
 ...ePeerAccessorPRMultipleMembersDUnitTest.java |  43 +++++
 12 files changed, 701 insertions(+), 90 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceBase.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceBase.java
index eeb7d8d..dad9e97 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceBase.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceBase.java
@@ -16,22 +16,27 @@
  */
 package com.gemstone.gemfire.internal.cache.execute;
 
+import static com.gemstone.gemfire.test.dunit.Wait.pause;
 import static org.hamcrest.Matchers.isA;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.*;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Stream;
 
+import com.gemstone.gemfire.cache.CacheClosedException;
 import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
 import com.gemstone.gemfire.cache.execute.FunctionException;
 import com.gemstone.gemfire.cache.execute.ResultCollector;
 import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
 import com.gemstone.gemfire.test.dunit.Host;
 import com.gemstone.gemfire.test.dunit.cache.internal.JUnit4CacheTestCase;
-import com.gemstone.gemfire.test.dunit.internal.JUnit4DistributedTestCase;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -43,14 +48,14 @@ import org.junit.rules.ExpectedException;
  * Base class for tests of FunctionService that are agnostic to the
  * type of Execution that they are running on. The goal is to completely
  * cover all common behavior of sending results and sending exceptions
- * here.
+ * here and have them run with all topologies in child classes.
  */
 public abstract class FunctionServiceBase extends JUnit4CacheTestCase {
 
   @Rule
   public transient ExpectedException thrown = ExpectedException.none();
 
-  private transient CustomCollector customCollector;
+  protected transient CustomCollector customCollector;
 
   @Before
   public void createCollector() {
@@ -72,8 +77,6 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase {
 
   @Test
   public void defaultCollectorReturnsSingleResult() {
-    final Host host = Host.getHost(0);
-
     ResultCollector rc = getExecution().execute((context) -> {context.getResultSender().lastResult("done");});
     List<String> results = (List<String>) rc.getResult();
     assertEquals(numberOfExecutions(), results.size());
@@ -81,22 +84,31 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
   }
 
   @Test()
-  public void defaultCollectorThrowsExceptionAfterFunctionThrowsIllegalState() {
-    final Host host = Host.getHost(0);
+  public void defaultCollectorReturnsAllIntermediateResults() {
+    ResultCollector rc = getExecution().execute((context) -> {
+      context.getResultSender().sendResult("one");
+      context.getResultSender().lastResult("two");
+    });
+    final List<String> result = (List<String>) rc.getResult();
+    assertEquals(numberOfExecutions(), result.stream().filter(s -> s.equals("one")).count());
+    assertEquals(numberOfExecutions(), result.stream().filter(s -> s.equals("two")).count());
+  }
 
-    ResultCollector rc = getExecution().execute((context) -> {throw new IllegalStateException();});
+  @Test()
+  public void defaultCollectorThrowsExceptionAfterFunctionThrowsIllegalState() {
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
     thrown.expect(FunctionException.class);
-    thrown.expectCause(isA(IllegalStateException.class));
+    //GEODE-1762 - clients wrap cause in a ServerOperationException
+//    thrown.expectCause(isA(IllegalStateException.class));
+    ResultCollector rc = getExecution().execute((context) -> {throw new IllegalStateException();});
     final Object result = rc.getResult();
   }
 
   @Test()
   public void defaultCollectorThrowsExceptionAfterFunctionThrowsFunctionException() {
-    final Host host = Host.getHost(0);
-
-    ResultCollector rc = getExecution().execute((context) -> {throw new FunctionException();});
-
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
     thrown.expect(FunctionException.class);
+    ResultCollector rc = getExecution().execute((context) -> {throw new FunctionException();});
     final Object result = rc.getResult();
   }
 
@@ -107,55 +119,52 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
    */
   @Test()
   public void defaultCollectorThrowsExceptionAfterFunctionReturnsIllegalStateException()
{
-    final Host host = Host.getHost(0);
-
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
+    //GEODE-1762 - clients throw a ServerOperationException
+    thrown.expect(Exception.class);
+//    thrown.expect(FunctionException.class);
+//    thrown.expectCause(isA(IllegalStateException.class));
     ResultCollector rc = getExecution().execute((context) -> {context.getResultSender().lastResult(new
IllegalStateException());});
-
-    thrown.expect(FunctionException.class);
-    thrown.expectCause(isA(IllegalStateException.class));
     final Object result = rc.getResult();
   }
 
   @Test()
   public void defaultCollectorThrowsExceptionAfterFunctionReturnsFunctionException() {
-    final Host host = Host.getHost(0);
-
-    ResultCollector rc = getExecution().execute((context) -> {context.getResultSender().lastResult(new
FunctionException());});
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
     thrown.expect(FunctionException.class);
     thrown.expectCause(is((Throwable) null));
+    ResultCollector rc = getExecution().execute((context) -> {context.getResultSender().lastResult(new
FunctionException());});
     final Object result = rc.getResult();
   }
 
   @Test()
   public void defaultCollectorThrowsExceptionAfterFunctionReturnsIllegalStateExceptionAsIntermediateResult()
{
-    final Host host = Host.getHost(0);
-
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
+    //GEODE-1762 - client throws a ServerOperationException
+    thrown.expect(Exception.class);
+//    thrown.expect(FunctionException.class);
+//    thrown.expectCause(isA(IllegalStateException.class));
     ResultCollector rc = getExecution().execute((context) -> {
         context.getResultSender().sendResult(new IllegalStateException());
         context.getResultSender().lastResult("done");
       });
-    thrown.expect(FunctionException.class);
-    thrown.expectCause(isA(IllegalStateException.class));
     final Object result = rc.getResult();
   }
 
   @Test()
   public void defaultCollectorThrowsExceptionAfterFunctionReturnsFunctionExceptionAsIntermediateResult()
{
-    final Host host = Host.getHost(0);
-
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
+    thrown.expect(FunctionException.class);
+    thrown.expectCause(is((Throwable) null));
     ResultCollector rc = getExecution().execute((context) -> {
         context.getResultSender().sendResult(new FunctionException());
         context.getResultSender().lastResult("done");
     });
-    thrown.expect(FunctionException.class);
-    thrown.expectCause(is((Throwable) null));
     final Object result = rc.getResult();
   }
 
   @Test
   public void defaultCollectorReturnsResultOfSendException() {
-    final Host host = Host.getHost(0);
-
     ResultCollector rc = getExecution().execute((context) -> {
       context.getResultSender().sendException(new IllegalStateException());
     });
@@ -166,8 +175,6 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
 
   @Test
   public void defaultCollectorReturnsResultOfSendFunctionException() {
-    final Host host = Host.getHost(0);
-
     ResultCollector rc = getExecution().execute((context) -> {
       context.getResultSender().sendException(new FunctionException());
     });
@@ -178,10 +185,9 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
 
   @Test
   public void customCollectorDoesNotSeeExceptionFunctionThrowsIllegalState() {
-    final Host host = Host.getHost(0);
-
-    ResultCollector rc = getExecution().withCollector(customCollector).execute((context)
-> {throw new IllegalStateException();});
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
     try {
+      ResultCollector rc = getExecution().withCollector(customCollector).execute((context)
-> {throw new IllegalStateException();});
       rc.getResult();
       fail("should have received an exception");
     } catch (FunctionException expected) {}
@@ -191,10 +197,9 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
 
   @Test
   public void customCollectorDoesNotSeeExceptionFunctionThrowsFunctionException() {
-    final Host host = Host.getHost(0);
-
-    ResultCollector rc = getExecution().withCollector(customCollector).execute((context)
-> {throw new FunctionException();});
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
     try {
+      ResultCollector rc = getExecution().withCollector(customCollector).execute((context)
-> {throw new FunctionException();});
       rc.getResult();
       fail("should have received an exception");
     } catch (FunctionException expected) {}
@@ -204,35 +209,33 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
 
   @Test
   public void customCollectorDoesNotSeeExceptionAfterFunctionReturnsIllegalStateException()
{
-    final Host host = Host.getHost(0);
-
-    ResultCollector rc = getExecution().execute((context) -> {context.getResultSender().lastResult(new
IllegalStateException());});
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
     try {
+      ResultCollector rc = getExecution().execute((context) -> {context.getResultSender().lastResult(new
IllegalStateException());});
       rc.getResult();
       fail("should have received an exception");
-    } catch (FunctionException expected) {}
+      //GEODE-1762 - clients throw a ServerOperationException
+    } catch (Exception expected) {}
     Assert.assertEquals(0, customCollector.getResult().size());
   }
 
   @Test
   public void customCollectorDoesNotSeeExceptionAfterFunctionReturnsIllegalStateExceptionAsIntermediateResult()
{
-    final Host host = Host.getHost(0);
-
-    ResultCollector rc = getExecution().execute((context) -> {
-      context.getResultSender().sendResult(new IllegalStateException());
-      context.getResultSender().lastResult("done");
-    });
+    //GEODE-1762 - clients throw from execute, but peers throw from rc.getResult
     try {
+      ResultCollector rc = getExecution().execute((context) -> {
+        context.getResultSender().sendResult(new IllegalStateException());
+        context.getResultSender().lastResult("done");
+      });
       rc.getResult();
       fail("should have received an exception");
-    } catch (FunctionException expected) {}
+      //GEODE-1762 - clients throw a ServerOperationException
+    } catch (Exception expected) {}
     Assert.assertEquals(0, customCollector.getResult().size());
   }
 
   @Test
   public void customCollectorReturnsResultOfSendException() {
-    final Host host = Host.getHost(0);
-
     ResultCollector rc = getExecution().withCollector(customCollector).execute((context)
-> {
       context.getResultSender().sendException(new IllegalStateException());
     });
@@ -244,8 +247,6 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
 
   @Test
   public void customCollectorReturnsResultOfSendFunctionException() {
-    final Host host = Host.getHost(0);
-
     ResultCollector rc = getExecution().withCollector(customCollector).execute((context)
-> {
       context.getResultSender().sendException(new FunctionException());
     });
@@ -255,7 +256,40 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
     assertEquals(result, customCollector.getResult());
   }
 
-  private static class CustomCollector implements ResultCollector<Object, List<Object>>
{
+  /**
+   * Test that a custom result collector will still receive all partial
+   * results from other members when one member fails
+   */
+  @Test
+  public void nonHAFunctionResultCollectorIsPassedPartialResultsAfterCloseCache() {
+    List<InternalDistributedMember> members = getAllMembers();
+
+    InternalDistributedMember firstMember = members.iterator().next();
+
+    //Execute a function which will close the cache on one member.
+    try {
+      ResultCollector rc = getExecution()
+        .withCollector(customCollector)
+        .execute(new CacheClosingNonHAFunction(firstMember));
+      rc.getResult();
+      fail("Should have thrown an exception");
+    } catch(Exception expected) {
+      //do nothing
+    }
+    members.remove(firstMember);
+    assertEquals(members, customCollector.getResult());
+    assertEquals(numberOfExecutions() - 1, customCollector.getResult().size());
+  }
+
+  protected List<InternalDistributedMember> getAllMembers() {
+    //Get a list of all of the members
+    ResultCollector rs = getExecution().execute(functionContext -> {
+      functionContext.getResultSender().lastResult(InternalDistributedSystem.getAnyInstance().getDistributedMember());
+    });
+    return (List<InternalDistributedMember>) rs.getResult();
+  }
+
+  public static class CustomCollector implements ResultCollector<Object, List<Object>>
{
     private ArrayList<Object> results = new ArrayList<Object>();
 
     @Override
@@ -284,4 +318,34 @@ public abstract class FunctionServiceBase extends JUnit4CacheTestCase
{
       results.clear();
     }
   }
+
+  /**
+   * A function which will close the cache if the given member matches
+   * the member executing this function
+   */
+  private class CacheClosingNonHAFunction implements Function {
+
+    private final InternalDistributedMember member;
+
+    public CacheClosingNonHAFunction(final InternalDistributedMember member) {
+      this.member = member;
+    }
+
+    @Override
+    public void execute(FunctionContext context) {
+      final InternalDistributedMember myId = InternalDistributedSystem.getAnyInstance().getDistributedMember();
+      if (myId.equals(member)) {
+        getCache().close();
+        throw new CacheClosedException();
+      }
+      pause(1000);
+      context.getResultSender().lastResult(myId);
+    }
+
+    @Override
+    public boolean isHA() {
+      return false;
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRBase.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRBase.java
new file mode 100644
index 0000000..525db3e
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRBase.java
@@ -0,0 +1,145 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import static com.gemstone.gemfire.test.dunit.Wait.pause;
+import static org.junit.Assert.*;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+public abstract class FunctionServiceClientAccessorPRBase extends FunctionServiceClientBase
{
+
+  public static final String REGION = "region";
+  protected transient Region<Object, Object> region;
+
+  @Before
+  public void createRegions() {
+    ClientCache cache = createServersAndClient(numberOfExecutions());
+
+    Host host = Host.getHost(0);
+    VM vm0 = host.getVM(0);
+
+    for(int i =0; i < numberOfExecutions(); i++) {
+      VM vm = host.getVM(i);
+      createRegion(vm);
+    }
+
+    vm0.invoke(() -> {
+      Region region = getCache().getRegion(REGION);
+      PartitionRegionHelper.assignBucketsToPartitions(region);
+    });
+
+    region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY)
+      .create(REGION);
+  }
+
+  private void createRegion(final VM vm) {
+    vm.invoke(() -> {
+      getCache().createRegionFactory(RegionShortcut.PARTITION)
+        .create(REGION);
+      });
+  }
+
+  @Override
+  public Execution getExecution() {
+    return FunctionService.onRegion(region);
+  }
+
+
+
+  /**
+   * Test that a custom result collector will still receive all partial
+   * results from other members when one source fails
+   */
+  @Test
+  public void nonHAFunctionResultCollectorIsPassedPartialResultsAfterBucketMove() {
+    List<InternalDistributedMember> members = getAllMembers();
+    //Only run this test if there is more than two members
+    Assume.assumeTrue(members.size() >= 2);
+
+    final Iterator<InternalDistributedMember> iterator = members.iterator();
+    InternalDistributedMember firstMember = iterator.next();
+    InternalDistributedMember secondMember = iterator.next();
+
+    //Execute a function which will close the cache on one source.
+    try {
+      ResultCollector rc = getExecution()
+        .withCollector(customCollector)
+        .execute(new BucketMovingNonHAFunction(firstMember, secondMember));
+      rc.getResult();
+      fail("Should have thrown an exception");
+    } catch(Exception expected) {
+      //do nothing
+    }
+    assertEquals(new HashSet(members), new HashSet(customCollector.getResult()));
+    assertEquals(numberOfExecutions(), customCollector.getResult().size());
+  }
+
+  /**
+   * A function which will close the cache if the given source matches
+   * the source executing this function
+   */
+  private class BucketMovingNonHAFunction implements Function {
+
+    private final InternalDistributedMember source;
+    private final InternalDistributedMember destination;
+
+    public BucketMovingNonHAFunction(final InternalDistributedMember source, final InternalDistributedMember
destination) {
+      this.source = source;
+      this.destination = destination;
+    }
+
+    @Override
+    public void execute(FunctionContext context) {
+      RegionFunctionContext regionFunctionContext = (RegionFunctionContext) context;
+      final InternalDistributedMember myId = InternalDistributedSystem.getAnyInstance().getDistributedMember();
+      //Move all buckets to the destination
+      if (myId.equals(source)) {
+        PartitionRegionHelper.moveData(regionFunctionContext.getDataSet(), source, destination,
100);
+      }
+      pause(1000);
+      context.getResultSender().lastResult(myId);
+    }
+
+    @Override
+    public boolean isHA() {
+      return false;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRDUnitTest.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRDUnitTest.java
new file mode 100644
index 0000000..433df2e
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRDUnitTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+import org.junit.Before;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Tests function execution with a client accessing a single member with a PR
+ * using onRegion calls.
+ */
+@Category(DistributedTest.class)
+public class FunctionServiceClientAccessorPRDUnitTest extends FunctionServiceClientAccessorPRBase
{
+
+  @Override
+  public int numberOfExecutions() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersDUnitTest.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersDUnitTest.java
new file mode 100644
index 0000000..3db770b
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersDUnitTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.client.internal.ClientMetadataService;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Tests function execution with a client accessing multiple members with a PR with redundancy
0
+ * using onRegion calls.
+ */
+@Category(DistributedTest.class)
+public class FunctionServiceClientAccessorPRMultipleMembersDUnitTest extends FunctionServiceClientAccessorPRBase
{
+
+  @Override public void createRegions() {
+    super.createRegions();
+    //Make sure the client is consistently using singlehop by proactively getting
+    //the server location metadata.
+    GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
+    ClientMetadataService clientMetadataService = cache.getClientMetadataService();
+    clientMetadataService.getClientPRMetadata((LocalRegion) region);
+  }
+
+  @Override
+  public int numberOfExecutions() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersMultihopDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersMultihopDUnitTest.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersMultihopDUnitTest.java
new file mode 100644
index 0000000..6025f91
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientAccessorPRMultipleMembersMultihopDUnitTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+import org.junit.Ignore;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Tests onRegion using multiple servers from a single client that has single hop disabled
+ */
+@Category(DistributedTest.class)
+public class FunctionServiceClientAccessorPRMultipleMembersMultihopDUnitTest extends FunctionServiceClientAccessorPRBase
{
+
+  @Override public void configureClient(final ClientCacheFactory cacheFactory) {
+    cacheFactory.setPoolPRSingleHopEnabled(false);
+    super.configureClient(cacheFactory);
+  }
+
+  @Override public int numberOfExecutions() {
+    return 2;
+  }
+
+  @Ignore("Multihop clients don't support returning partial results after a cache close")
+  @Override
+  public void nonHAFunctionResultCollectorIsPassedPartialResultsAfterCloseCache() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientBase.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientBase.java
new file mode 100644
index 0000000..8df9c9e
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientBase.java
@@ -0,0 +1,61 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import java.util.Arrays;
+
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+
+/**
+ * Base class for function tests that use client server. This
+ * class takes care of setting up the client server topology.
+ */
+public abstract class FunctionServiceClientBase extends FunctionServiceBase {
+
+  public ClientCache createServersAndClient(int numberOfServers) {
+    int[] ports = new int[numberOfServers];
+    Host host = Host.getHost(0);
+    for(int i =0; i < numberOfServers; i++) {
+      VM vm = host.getVM(i);
+      ports[i] = createServer(vm);
+    }
+
+    ClientCacheFactory clientCacheFactory = new ClientCacheFactory();
+    Arrays.stream(ports).forEach(port -> {
+      clientCacheFactory.addPoolServer("localhost", port);
+    });
+    configureClient(clientCacheFactory);
+    return getClientCache(clientCacheFactory);
+  }
+
+  protected Integer createServer(final VM vm) {
+    return vm.invoke(() -> {
+      CacheServer server = getCache().addCacheServer();
+      server.setPort(0);
+      server.start();
+      return server.getPort();
+    });
+  }
+
+  public void configureClient(ClientCacheFactory cacheFactory) {
+    //do nothing
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientMultipleOnServerDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientMultipleOnServerDUnitTest.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientMultipleOnServerDUnitTest.java
new file mode 100644
index 0000000..ccd33e8
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientMultipleOnServerDUnitTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+import org.junit.Before;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Tests onServers using multiple servers from a single client.
+ */
+@Category(DistributedTest.class)
+public class FunctionServiceClientMultipleOnServerDUnitTest extends FunctionServiceClientOnServerBase
{
+
+  @Override public int numberOfExecutions() {
+    return 2;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerBase.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerBase.java
new file mode 100644
index 0000000..8a561ce
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerBase.java
@@ -0,0 +1,40 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+
+import org.junit.Before;
+
+public abstract class FunctionServiceClientOnServerBase extends FunctionServiceClientBase
{
+
+  @Before
+  public void createServers() {
+    Host host = Host.getHost(0);
+    VM vm0 = host.getVM(0);
+    VM vm1 = host.getVM(1);
+    ClientCache cache = createServersAndClient(numberOfExecutions());
+  }
+
+  @Override public Execution getExecution() {
+    return FunctionService.onServers(getCache());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerDUnitTest.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerDUnitTest.java
new file mode 100644
index 0000000..33dd62c
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServiceClientOnServerDUnitTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+import org.junit.experimental.categories.Category;
+
+/**
+ * Tests onServers using a single server from a single client.
+ */
+@Category(DistributedTest.class)
+public class FunctionServiceClientOnServerDUnitTest extends FunctionServiceClientOnServerBase
{
+
+  @Override public int numberOfExecutions() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRBase.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRBase.java
new file mode 100644
index 0000000..66824ba
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRBase.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+
+import org.junit.Before;
+import org.junit.Ignore;
+
+public abstract class FunctionServicePeerAccessorPRBase extends FunctionServiceBase {
+
+  public static final String REGION = "region";
+  private transient Region<Object, Object> region;
+
+  @Before
+  public void createRegions() {
+    region = getCache().createRegionFactory(RegionShortcut.PARTITION_PROXY)
+      .create(REGION);
+    Host host = Host.getHost(0);
+    for(int i =0; i < numberOfExecutions(); i++) {
+      VM vm = host.getVM(i);
+      createRegion(vm);
+    }
+
+    PartitionRegionHelper.assignBucketsToPartitions(region);
+  }
+
+  private void createRegion(final VM vm) {
+    vm.invoke(() -> {
+      getCache().createRegionFactory(RegionShortcut.PARTITION)
+        .create(REGION);
+      });
+  }
+
+  @Override public Execution getExecution() {
+    return FunctionService.onRegion(region);
+  }
+
+  @Ignore("GEODE-1348 - With this topology, the exception is not wrapped in FunctionException")
+  @Override public void defaultCollectorThrowsExceptionAfterFunctionThrowsIllegalState()
{
+  }
+
+  @Ignore("GEODE-1348 - With this topology, the exception is not wrapped in FunctionException")
+  @Override public void customCollectorDoesNotSeeExceptionFunctionThrowsIllegalState() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRDUnitTest.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRDUnitTest.java
index e5bf2d2..1ffdd7f 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRDUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRDUnitTest.java
@@ -33,41 +33,10 @@ import org.junit.experimental.categories.Category;
  * Test of the behavior of a custom ResultCollector when handling exceptions
  */
 @Category(DistributedTest.class)
-public class FunctionServicePeerAccessorPRDUnitTest extends FunctionServiceBase {
+public class FunctionServicePeerAccessorPRDUnitTest extends FunctionServicePeerAccessorPRBase
{
 
-  public static final String REGION = "region";
-
-  private transient Region<Object, Object> region;
-
-  @Before
-  public void createRegions() {
-    region = getCache().createRegionFactory(RegionShortcut.PARTITION_PROXY)
-      .create(REGION);
-    Host host = Host.getHost(0);
-    VM vm0 = host.getVM(0);
-    vm0.invoke(() -> {
-
-      getCache().createRegionFactory(RegionShortcut.PARTITION)
-        .create(REGION);
-
-      });
-
-    PartitionRegionHelper.assignBucketsToPartitions(region);
-  }
-
-  @Override public Execution getExecution() {
-    return FunctionService.onRegion(region);
-  }
-
-  @Override public int numberOfExecutions() {
+  @Override
+  public int numberOfExecutions() {
     return 1;
   }
-
-  @Ignore("GEODE-1348 - With this topology, the exception is not wrapped in FunctionException")
-  @Override public void defaultCollectorThrowsExceptionAfterFunctionThrowsIllegalState()
{
-  }
-
-  @Ignore("GEODE-1348 - With this topology, the exception is not wrapped in FunctionException")
-  @Override public void customCollectorDoesNotSeeExceptionFunctionThrowsIllegalState() {
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/6a91b9d0/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRMultipleMembersDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRMultipleMembersDUnitTest.java
b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRMultipleMembersDUnitTest.java
new file mode 100644
index 0000000..0e0351c
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/execute/FunctionServicePeerAccessorPRMultipleMembersDUnitTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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 com.gemstone.gemfire.internal.cache.execute;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.partition.PartitionRegionHelper;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test of the behavior of a custom ResultCollector when handling exceptions
+ */
+@Category(DistributedTest.class)
+public class FunctionServicePeerAccessorPRMultipleMembersDUnitTest extends FunctionServicePeerAccessorPRBase
{
+
+  @Override
+  public int numberOfExecutions() {
+    return 2;
+  }
+
+}


Mime
View raw message