@Test
  public void testPutAllEventSequenceOnSerialGatewaySenderWithPR() {

    // create two distributed systems with each having a cache containing
    // a Replicated Region with one entry and concurrency checks enabled.

    // Site 1
    Integer lnPort = vm0.invoke(() -> WANTestBase.createFirstLocatorWithDSId(1));
    createCacheInVMs(lnPort, vm1);
    Integer lnRecPort = vm1.invoke(WANTestBase::createReceiver);

    // Site 2
    Integer nyPort = vm2.invoke(() -> WANTestBase.createFirstRemoteLocator(2, lnPort));
    createCacheInVMs(nyPort, vm3);
    Integer nyRecPort = vm3.invoke(WANTestBase::createReceiver);

    LogWriterUtils.getLogWriter().info("Created locators and receivers in 2 distributed systems");

    // Site 1
    vm1.invoke(() -> WANTestBase.createSender("ln1", 2, false, 10, 1, false, false, null, true));

    vm1.invoke(() -> WANTestBase.createPartitionedRegion("repRegion", "ln1", 0, 1, isOffHeap()));
    vm1.invoke(() -> WANTestBase.startSender("ln1"));
    vm1.invoke(() -> WANTestBase.waitForSenderRunningState("ln1"));

    // Site 2
    vm3.invoke(() -> WANTestBase.createSender("ny1", 1, false, 10, 1, false, false, null, true));

    vm3.invoke(() -> WANTestBase.createPartitionedRegion("repRegion", "ny1", 0, 1, isOffHeap()));
    vm3.invoke(() -> WANTestBase.startSender("ny1"));
    vm3.invoke(() -> WANTestBase.waitForSenderRunningState("ny1"));

    Wait.pause(2000);

    // Perform a put in vm1
    AsyncInvocation<Void> asynch1 =
        vm1.invokeAsync(new CacheSerializableRunnable("Putting an entry in ds1") {

          @Override
          public void run2() throws CacheException {
            assertNotNull(cache);
            // Test hook to make put wait after RE lock is released but before Gateway events are
            // sent.
            DistributedCacheOperation.SLOW_DISTRIBUTION_MS = 2000;

            Region region = cache.getRegion(SEPARATOR + "repRegion");
            Map testMap = new HashMap();
            testMap.put("testKey", "testValue1");
            region.putAll(testMap);

            assertEquals(1, region.size());
            assertEquals("testValue2", region.get("testKey"));
          }
        });

    // wait for vm1 to propagate put to vm3
    Wait.pause(1000);

    AsyncInvocation<Void> asynch2 =
        vm1.invokeAsync(new CacheSerializableRunnable("Putting an entry in ds1") {

          @Override
          public void run2() throws CacheException {
            assertNotNull(cache);
            Region region = cache.getRegion(SEPARATOR + "repRegion");

            while (!region.containsKey("testKey")) {
              Wait.pause(10);
            }
            // Test hook to make put wait after RE lock is released but before Gateway events are
            // sent.
            DistributedCacheOperation.SLOW_DISTRIBUTION_MS = 0;

            region.put("testKey", "testValue2");

            assertEquals(1, region.size());
            assertEquals("testValue2", region.get("testKey"));
          }
        });

    try {
      asynch1.join(5000);
      asynch2.join(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      vm1.invoke(new CacheSerializableRunnable("Reset Test Hook") {

        @Override
        public void run2() throws CacheException {
          DistributedCacheOperation.SLOW_DISTRIBUTION_MS = 0;
        }
      });
    }

    // Wait for all Gateway events be received by vm3.
    Wait.pause(1000);

    long putAllTimeStampVm1 = vm1
        .invoke(NewWANConcurrencyCheckForDestroyDUnitTest::getVersionTimestampAfterPutAllOp);

    long putAllTimeStampVm3 = vm3
        .invoke(NewWANConcurrencyCheckForDestroyDUnitTest::getVersionTimestampAfterPutAllOp);

    assertEquals(putAllTimeStampVm1, putAllTimeStampVm3);
  }
This is similar to above test but for PartitionedRegion.
geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/misc/NewWANConcurrencyCheckForDestroyDUnitTest.java