@Test
  @Parameters({"true", "false"})
  @TestCaseName("{method}(simulate={0})")
  public void testEnforceZone(boolean simulate) {
    VM vm0 = getVM(0);
    VM vm1 = getVM(1);
    VM vm2 = getVM(2);

    vm0.invoke(() -> setRedundancyZone("A"));
    vm1.invoke(() -> setRedundancyZone("A"));

    DistributedMember zoneBMember = vm2.invoke(() -> {
      setRedundancyZone("B");
      return getCache().getDistributedSystem().getDistributedMember();
    });

    // Create the region in only 1 VM
    vm0.invoke(() -> createPartitionedRegion("region1", 1));

    // Create some buckets
    vm0.invoke(() -> {
      Region<Number, String> region = getCache().getRegion("region1");
      region.put(1, "A");
      region.put(2, "A");
      region.put(3, "A");
      region.put(4, "A");
      region.put(5, "A");
      region.put(6, "A");
    });

    // make sure we can tell that the buckets have low redundancy
    vm0.invoke(() -> validateRedundancy("region1", 6, 0, 6));

    // Create the region in the other VMs (should have no effect)
    vm1.invoke(() -> createPartitionedRegion("region1", 1));
    vm2.invoke(() -> createPartitionedRegion("region1", 1));

    // Make sure we still have low redundancy
    vm0.invoke(() -> validateRedundancy("region1", 6, 0, 6));

    // Now simulate a rebalance
    vm0.invoke(() -> {
      InternalResourceManager manager = getCache().getInternalResourceManager();
      RebalanceResults results = doRebalance(simulate, manager);

      // We expect to satisfy redundancy with the zone B member
      assertThat(results.getTotalBucketCreatesCompleted()).isEqualTo(6);

      // 2 primaries will go to vm2, leaving vm0 and vm1 with 2 primaries each
      assertThat(results.getTotalPrimaryTransfersCompleted()).isEqualTo(2);

      // We actually *will* transfer 3 buckets to the other member in zone A, because that
      // improves
      // the balance
      assertThat(results.getTotalBucketTransfersCompleted()).isEqualTo(3);

      Set<PartitionRebalanceInfo> detailSet = results.getPartitionRebalanceDetails();
      assertThat(detailSet).hasSize(1);

      PartitionRebalanceInfo details = detailSet.iterator().next();
      assertThat(details.getBucketCreatesCompleted()).isEqualTo(6);
      assertThat(details.getPrimaryTransfersCompleted()).isEqualTo(2);
      assertThat(details.getBucketTransfersCompleted()).isEqualTo(3);

      Set<PartitionMemberInfo> afterDetails = details.getPartitionMemberDetailsAfter();
      for (PartitionMemberInfo info : afterDetails) {
        if (info.getDistributedMember().equals(zoneBMember)) {
          assertThat(info.getBucketCount()).isEqualTo(6);
        } else {
          assertThat(info.getBucketCount()).isEqualTo(3);
        }
        assertThat(info.getPrimaryCount()).isEqualTo(2);
      }

      // assertIndexDetailsEquals(0, details.getBucketTransferBytes());
      if (!simulate) {
        validateStatistics(manager, results);
      }
    });

    if (!simulate) {
      vm0.invoke(() -> validateBucketCount("region1", 3));
      vm1.invoke(() -> validateBucketCount("region1", 3));
      vm2.invoke(() -> validateBucketCount("region1", 6));
    }
  }
Test that we correctly use the redundancy-zone property to determine where to place redundant
copies of a buckets.
geode-core/src/distributedTest/java/org/apache/geode/internal/cache/control/RebalanceOperationDistributedTest.java