@Test
  public void testOneHopNetWriteRemoteWriter() throws CacheException {
    final String name = getUniqueName() + "Region";
    final String objectName = "Object7";
    final Integer value = 483;
    final Integer updateValue = 484;

    vm0.invoke("Create replicate Region", () -> {
      try {
        RegionFactory<Object, Object> factory = getCache().createRegionFactory();
        factory.setScope(Scope.DISTRIBUTED_ACK);
        factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
        createRegion(name, factory);
      } catch (CacheException ex) {
        fail("While creating empty region", ex);
      }
    });

    vm1.invoke("Create empty Region", () -> {
      try {
        RegionFactory<Object, Object> factory = getCache().createRegionFactory();
        factory.setScope(Scope.DISTRIBUTED_ACK);
        factory.setDataPolicy(DataPolicy.EMPTY);
        createRegion(name, factory);
      } catch (CacheException ex) {
        fail("While creating empty region", ex);
      }
    });

    vm2.invoke("Create replicated region with cacheWriter", () -> {
      netWriteInvoked = false;
      operationWasCreate = false;
      originWasRemote = false;
      writerInvocationCount = 0;
      try {
        RegionFactory<Object, Object> factory = getCache().createRegionFactory();
        factory.setScope(Scope.DISTRIBUTED_ACK);
        factory.setDataPolicy(DataPolicy.EMPTY);
        factory.setCacheWriter(new CacheWriter<Object, Object>() {
          @Override
          public void beforeCreate(EntryEvent e) throws CacheWriterException {
            logger.info("cache writer beforeCreate invoked for " + e);
            netWriteInvoked = true;
            operationWasCreate = true;
            originWasRemote = e.isOriginRemote();
            writerInvocationCount++;
          }

          @Override
          public void beforeUpdate(EntryEvent e) throws CacheWriterException {
            logger.info("cache writer beforeUpdate invoked for " + e);
            netWriteInvoked = true;
            operationWasCreate = false;
            originWasRemote = e.isOriginRemote();
            writerInvocationCount++;
          }

          @Override
          public void beforeDestroy(EntryEvent e) throws CacheWriterException {}

          @Override
          public void beforeRegionDestroy(RegionEvent e) throws CacheWriterException {}

          @Override
          public void beforeRegionClear(RegionEvent e) throws CacheWriterException {}

          @Override
          public void close() {}
        });

        createRegion(name, factory);

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

    vm1.invoke("do a put that should be proxied in the other vm and invoke its cache writer",
        () -> {
          try {
            getRootRegion().getSubregion(name).put(objectName, value);
          } catch (CacheWriterException | TimeoutException ignored) {
          }
        });

    vm2.invoke("ensure that cache writer was invoked with correct settings in event",
        () -> {
          assertThat(netWriteInvoked).describedAs("expected cache writer to be invoked").isTrue();
          assertThat(originWasRemote).describedAs("expected originRemote to be true").isTrue();
          assertThat(operationWasCreate).describedAs("expected event to be create").isTrue();
          assertThat(writerInvocationCount)
              .describedAs("expected only one cache writer invocation").isEqualTo(1);
          // set flags for the next test - updating the same key
          netWriteInvoked = false;
          writerInvocationCount = 0;
        });

    vm1.invoke("do an update that should be proxied in the other vm and invoke its cache writer",
        () -> {
          try {
            getRootRegion().getSubregion(name).put(objectName, updateValue);
          } catch (CacheWriterException | TimeoutException ignored) {
          }
        });

    vm2.invoke("ensure that cache writer was invoked with correct settings in event",
        () -> {
          assertThat(netWriteInvoked).describedAs("expected cache writer to be invoked").isTrue();
          assertThat(originWasRemote).describedAs("expected originRemote to be true").isTrue();
          assertThat(operationWasCreate).describedAs("expected event to be create").isTrue();
          assertThat(writerInvocationCount)
              .describedAs("expected only one cache writer invocation").isEqualTo(1);
        });
  }
same as the previous test but the cache writer is in a third, non-replicated, vm
geode-core/src/distributedTest/java/org/apache/geode/cache30/SearchAndLoadDUnitTest.java