@Ignore("this test is DISABLED due to intermittent failures.  See bug #52222")
  @Test
  public void testPRFunctionExecutionRejection() throws Exception {
    IgnoredException.addIgnoredException("LowMemoryException");
    final Host host = Host.getHost(0);
    final VM accessor = host.getVM(0);
    final VM server1 = host.getVM(1);
    final VM server2 = host.getVM(2);
    final VM client = host.getVM(3);
    final String regionName = "prFuncRej";

    final ServerPorts ports1 = startCacheServer(server1, 80f, 90f, regionName, true/* createPR */,
        false/* notifyBySubscription */, 0);
    ServerPorts ports2 = startCacheServer(server2, 80f, 90f, regionName, true/* createPR */,
        false/* notifyBySubscription */, 0);
    accessor.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        getSystem(getServerProperties());
        getCache();
        AttributesFactory factory = new AttributesFactory();
        PartitionAttributesFactory paf = new PartitionAttributesFactory();
        paf.setRedundantCopies(0);
        paf.setLocalMaxMemory(0);
        paf.setTotalNumBuckets(11);
        factory.setPartitionAttributes(paf.create());
        createRegion(regionName, factory.create());
        return null;
      }
    });

    startClient(client, server1, ports1.getPort(), regionName);

    registerTestMemoryThresholdListener(server1);
    registerTestMemoryThresholdListener(server2);

    final RejectFunction function = new RejectFunction();
    final RejectFunction function2 = new RejectFunction("noRejFunc", false);
    Invoke.invokeInEveryVM(new SerializableCallable("register function") {
      @Override
      public Object call() throws Exception {
        FunctionService.registerFunction(function);
        FunctionService.registerFunction(function2);
        return null;
      }
    });

    doPutAlls(accessor, regionName, false, false, Range.DEFAULT);
    doPuts(accessor, regionName, false, false);

    accessor.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function);
        FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function2);
        return null;
      }
    });
    // should not fail
    accessor.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        FunctionService.onMembers().execute(function);
        FunctionService.onMembers().execute(function2);
        return null;
      }
    });
    client.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function);
        FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function2);
        return null;
      }
    });

    setUsageAboveCriticalThreshold(server2);

    verifyListenerValue(server1, MemoryState.CRITICAL, 1, true);

    accessor.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        try {
          getCache().getLogger().fine(addExpectedFunctionExString);
          FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function);
          getCache().getLogger().fine(removeExpectedFunctionExString);
          fail("expected low memory exception was not thrown");
        } catch (LowMemoryException e) {
          // expected
        }
        FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function2);
        return null;
      }
    });

    accessor.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        try {
          getCache().getLogger().fine(addExpectedFunctionExString);
          FunctionService.onMembers().execute(function);
          getCache().getLogger().fine(removeExpectedFunctionExString);
          fail("expected low memory exception was not thrown");
        } catch (LowMemoryException e) {
          // expected
        }
        FunctionService.onMembers().execute(function2);
        return null;
      }
    });

    server1.invoke(addExpectedFunctionException);
    server2.invoke(addExpectedFunctionException);

    client.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        try {
          FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function);
          fail("expected low memory exception was not thrown");
        } catch (FunctionException e) {
          if (!(e.getCause().getCause() instanceof LowMemoryException)) {
            Assert.fail("unexpected exception", e);
          }
          // expected
        }
        FunctionService.onRegion(getRootRegion().getSubregion(regionName)).execute(function2);
        return null;
      }
    });

    server1.invoke(removeExpectedFunctionException);
    server2.invoke(removeExpectedFunctionException);

    final DistributedMember server2Id =
        (DistributedMember) server2.invoke(new SerializableCallable() {
          @Override
          public Object call() throws Exception {
            return getCache().getMyId();
          }
        });

    // test function execution on healthy & sick members
    accessor.invoke(new SerializableCallable() {
      @Override
      public Object call() throws Exception {
        PartitionedRegion pr = (PartitionedRegion) getRootRegion().getSubregion(regionName);
        Object sickKey1 = null;
        Object sickKey2 = null;
        Object healthyKey = null;
        for (int i = 0; i < 20; i++) {
          Object key = i;
          DistributedMember m = pr.getMemberOwning(key);
          if (m.equals(server2Id)) {
            if (sickKey1 == null) {
              sickKey1 = key;
              // execute
              Set s = new HashSet();
              s.add(sickKey1);
              Execution e = FunctionService.onRegion(pr);
              try {
                getCache().getLogger().fine(addExpectedFunctionExString);
                e.withFilter(s).setArguments(s).execute(function);
                getCache().getLogger().fine(removeExpectedFunctionExString);
                fail("expected LowMemoryExcception was not thrown");
              } catch (LowMemoryException ex) {
                // expected
              }
            } else if (sickKey2 == null) {
              sickKey2 = key;
              // execute
              Set s = new HashSet();
              s.add(sickKey1);
              s.add(sickKey2);
              Execution e = FunctionService.onRegion(pr);
              try {
                e.withFilter(s).setArguments(s).execute(function);
                fail("expected LowMemoryExcception was not thrown");
              } catch (LowMemoryException ex) {
                // expected
              }
            }
          } else {
            healthyKey = key;
            // execute
            Set s = new HashSet();
            s.add(healthyKey);
            Execution e = FunctionService.onRegion(pr);
            e.withFilter(s).setArguments(s).execute(function);
          }
          if (sickKey1 != null && sickKey2 != null && healthyKey != null) {
            break;
          }
        }
        return null;
      }
    });
  }
Make sure appropriate events are delivered when moving between states.
geode-core/src/distributedTest/java/org/apache/geode/cache/management/MemoryThresholdsDUnitTest.java