@Test
  @Parameters({"true, true, true", "true, false, true", "false, false, true", "true, true, false",
      "true, false, false", "false, false, false"})
  public void testSuccessfulExecution(boolean isPartitionedRegion,
      boolean isParallelGatewaySender, boolean concurrencyChecksEnabled) throws Exception {
    List<VM> serversInA = Arrays.asList(vm5, vm6, vm7);
    List<VM> serversInB = Arrays.asList(vm9, vm3);
    VM serverInC = vm4;
    VM client = vm8;
    String senderIdInA = "B";
    String senderIdInB = "C";

    int senderLocatorPort = create3WanSitesAndClient(isPartitionedRegion, vm0,
        vm1, vm2, serversInA, serversInB, serverInC, client,
        senderIdInA, senderIdInB, concurrencyChecksEnabled);

    int wanCopyRegionBatchSize = 20;
    int entries = 100;
    String regionName = getRegionName(isPartitionedRegion);
    // Put entries
    client.invoke(() -> doPutsFrom(regionName, 0, entries + 1));
    // remove an entry to make sure that replication works well even when removes.
    client.invoke(() -> removeEntry(regionName, entries));

    // Check that entries are put in the region
    for (VM member : serversInA) {
      member.invoke(() -> validateRegionSize(regionName, entries));
    }

    // Check that entries are not copied to "B" nor "C"
    for (VM serverInB : serversInB) {
      serverInB.invoke(() -> validateRegionSize(regionName, 0));
    }
    serverInC.invoke(() -> validateRegionSize(regionName, 0));

    // Create senders and receivers with replication as follows: "A" -> "B" -> "C"
    createSender(isParallelGatewaySender, serversInA, senderIdInA, 2);
    createSender(isParallelGatewaySender, serversInB, senderIdInB, 3);
    createReceivers(serversInB, serverInC);

    // Check that entries are not copied to "B" nor "C"
    serversInB.get(0).invoke(() -> validateRegionSize(regionName, 0));
    serverInC.invoke(() -> validateRegionSize(regionName, 0));

    // Execute wan-copy region command
    gfsh.connectAndVerify(senderLocatorPort, GfshCommandRule.PortType.locator);
    String commandString = new CommandStringBuilder(WAN_COPY_REGION)
        .addOption(WAN_COPY_REGION__REGION, regionName)
        .addOption(WAN_COPY_REGION__SENDERID, senderIdInA)
        .addOption(WAN_COPY_REGION__BATCHSIZE, String.valueOf(wanCopyRegionBatchSize))
        .getCommandString();

    // Check command status and output
    CommandResultAssert command =
        verifyStatusIsOk(gfsh.executeAndAssertThat(commandString), serversInA.size());
    if (isPartitionedRegion && isParallelGatewaySender) {
      String msg1 = CliStrings.format(WAN_COPY_REGION__MSG__COPIED__ENTRIES, 33);
      String msg2 = CliStrings.format(WAN_COPY_REGION__MSG__COPIED__ENTRIES, 34);
      command
          .hasTableSection(ResultModel.MEMBER_STATUS_SECTION)
          .hasColumn("Message")
          .containsExactlyInAnyOrder(msg1, msg1, msg2);
    } else {
      String msg1 = CliStrings.format(WAN_COPY_REGION__MSG__COPIED__ENTRIES, entries);
      String msg2 = CliStrings
          .format(WAN_COPY_REGION__MSG__SENDER__SERIAL__AND__NOT__PRIMARY, senderIdInA);
      command
          .hasTableSection(ResultModel.MEMBER_STATUS_SECTION)
          .hasColumn("Message")
          .containsExactlyInAnyOrder(msg1, msg2, msg2);
    }

    // Check that entries are copied in "B"
    for (VM serverInB : serversInB) {
      serverInB.invoke(() -> validateRegionSize(regionName, entries));
    }

    // Check that no entries are left in the queue from B to C
    for (VM serverInB : serversInB) {
      serverInB.invoke(() -> getSenderStats(senderIdInB, 0));
    }

    // Check that the region's data is the same in sites "A" and "B"
    checkEqualRegionData(regionName, serversInA.get(0), serversInB.get(0),
        concurrencyChecksEnabled);

    // Check that wanCopyRegionBatchSize is correctly used by the command
    long receivedBatches = 0;
    for (VM serverInB : serversInB) {
      receivedBatches += serverInB.invoke(() -> getReceiverStats().get(2));
    }
    if (isPartitionedRegion && isParallelGatewaySender) {
      assertThat(receivedBatches).isEqualTo(6);
    } else {
      assertThat(receivedBatches).isEqualTo(5);
    }

    // Check that entries are not copied in "C" (generateCallbacks is false)
    serverInC.invoke(() -> validateRegionSize(regionName, 0));
  }
Scenario with 3 WAN sites: "A", "B" and "C".
Initially, no replication is configured between sites.
Several entries are put in WAN site "A".

The following gateway senders are created and started:
- In "A" site: to replicate region entries to "B" site. Sender called "B".
- In "B" site: to replicate region entries to "C" site. Sender called "C".
(Replication is as follows: A -> B -> C)

The "wan-copy region" command is run from "A" site passing sender "B".

It must be verified that the entries are copied to site "B".
It must also be verified that the entries are not transitively
copied to "C" even though replication is configured from "B" to "C"
because with this command generateCallbacks is set to false in the
events generated.
geode-wan/src/distributedTest/java/org/apache/geode/cache/wan/internal/cli/commands/WanCopyRegionCommandDistributedTest.java