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

    // Create the region in two VMs
    vm0.invoke(() -> createPartitionedRegion("region1", 1));
    vm1.invoke(() -> createPartitionedRegion("region1", 1));

    // Create some buckets
    vm0.invoke(() -> {
      Region<Number, String> region = getCache().getRegion("region1");
      for (int i = 0; i < 12; i++) {
        region.put(i, "A");
      }
    });

    // Create the region in one more VM.
    vm2.invoke(() -> createPartitionedRegion("region1", 1));

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

      assertThat(results.getTotalBucketCreatesCompleted()).isEqualTo(0);

      // We don't know how many primaries will move, it depends on
      // if the move bucket code moves the primary or a redundant bucket
      // assertIndexDetailsEquals(0, results.getTotalPrimaryTransfersCompleted());
      assertThat(results.getTotalBucketTransfersCompleted()).isEqualTo(8);
      assertThat(results.getTotalBucketTransferBytes()).isGreaterThan(0);

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

      PartitionRebalanceInfo details = detailSet.iterator().next();
      assertThat(details.getBucketCreatesCompleted()).isEqualTo(0);
      assertThat(details.getBucketTransferBytes()).isGreaterThan(0);
      assertThat(details.getBucketTransfersCompleted()).isEqualTo(8);

      long value = 0;
      Set<PartitionMemberInfo> beforeDetails = details.getPartitionMemberDetailsAfter();
      for (PartitionMemberInfo memberDetails : beforeDetails) {
        value += memberDetails.getSize();
      }

      long afterSize = 0;
      Set<PartitionMemberInfo> afterDetails = details.getPartitionMemberDetailsAfter();
      assertThat(afterDetails).hasSize(3);

      for (PartitionMemberInfo memberDetails : afterDetails) {
        assertThat(memberDetails.getBucketCount()).isEqualTo(8);
        assertThat(memberDetails.getPrimaryCount()).isEqualTo(4);
        afterSize += memberDetails.getSize();
      }

      assertThat(afterSize).isEqualTo(value);

      if (!simulate) {
        validateStatistics(manager, results);
      }

      return value;
    });

    if (!simulate) {
      for (VM vm : toArray(vm0, vm1, vm2)) {
        vm.invoke(() -> {
          Region region = getCache().getRegion("region1");

          PartitionRegionInfo details = PartitionRegionHelper.getPartitionRegionInfo(region);
          assertThat(details.getCreatedBucketCount()).isEqualTo(12);
          assertThat(details.getActualRedundantCopies()).isEqualTo(1);
          assertThat(details.getLowRedundancyBucketCount()).isEqualTo(0);

          long afterSize = 0;
          for (PartitionMemberInfo memberDetails : details.getPartitionMemberInfo()) {
            assertThat(memberDetails.getBucketCount()).isEqualTo(8);
            assertThat(memberDetails.getPrimaryCount()).isEqualTo(4);
            afterSize += memberDetails.getSize();
          }

          assertThat(afterSize).isEqualTo(totalSize);
        });
      }
    }
  }
Check to make sure that we balance buckets between two hosts with no redundancy.
geode-core/src/distributedTest/java/org/apache/geode/internal/cache/control/RebalanceOperationDistributedTest.java