@Test
  public void testNetLoad() throws CacheException {
    disconnectAllFromDS();
    final String name = getUniqueName() + "-ACK";
    final String objectName = "B";
    final Integer value = 43;
    loaderInvoked = false;
    remoteLoaderInvoked = false;
    vm0.invoke("Create ACK Region", () -> {
      try {
        loaderInvoked = false;
        RegionFactory<Object, Object> factory = getCache().createRegionFactory();
        factory.setScope(Scope.DISTRIBUTED_ACK);

        Region<Object, Object> region = createRegion(name, factory);
        region.create(objectName, null);

      } catch (CacheException ex) {
        fail("While creating ACK region", ex);
      }
    });

    vm1.invoke("Create ACK Region", () -> {
      try {
        RegionFactory<Object, Object> factory = getCache().createRegionFactory();
        factory.setScope(Scope.DISTRIBUTED_ACK);
        factory.setCacheLoader(new CacheLoader<Object, Object>() {
          @Override
          public Object load(LoaderHelper helper) {
            remoteLoaderInvoked = true;
            return value;
          }

          @Override
          public void close() {

          }
        });
        createRegion(name, factory);
      } catch (CacheException ex) {
        fail("While creating ACK region", ex);
      }
    });

    vm0.invoke("Get a value from remote loader", () -> {
      for (int i = 0; i < 1; i++) {
        try {
          Object result = getRootRegion().getSubregion(name).get(objectName);
          assertThat(value).isEqualTo(result);
          assertThat(loaderInvoked).isEqualTo(Boolean.FALSE);

        } catch (CacheLoaderException | TimeoutException cle) {
          fail("While getting value for ACK region", cle);

        }
      }
    });
  }
This test is for a bug in which a cache loader threw an exception that caused the wrong value
to be put in a Future in nonTxnFindObject. This in turn caused a concurrent search for the
object to not invoke the loader a second time.
<p>
VM0 is used to create a cache and a region having a loader that simulates the conditions that
caused the bug. One async thread then does a get() which invokes the loader. Another async
thread does a get() which reaches nonTxnFindObject and blocks waiting for the first thread's
load to complete. The loader then throws an exception that is sent back to the first thread.
The second thread should then cause the loader to be invoked again, and this time the loader
will return a value. Both threads then validate that they received the expected result.
geode-core/src/distributedTest/java/org/apache/geode/cache30/SearchAndLoadDUnitTest.java