@Test
  public void testAddNewPartitionsAndDataNodesBeingFullAutoCompatibleWithDifferentNumberOfReplicas() throws Exception {
    assumeTrue(fullAutoCompatible);
    int basePort = 18088;
    int basePartitionId = 0;
    int dataNode = 6;
    int numPartition = 100;
    // Test 1: Add 100 partitions that have 3 replicas, and 100 partitions that have only one replica, per dc.
    testHardwareLayout = constructInitialHardwareLayoutJSON(CLUSTER_NAME_IN_STATIC_CLUSTER_MAP, dataNode, basePort);
    testPartitionLayout = constructInitialPartitionLayoutJSON(testHardwareLayout, numPartition, null);
    for (int i = 0; i < numPartition; i++) {
      testPartitionLayout.addNewPartition(testHardwareLayout, testHardwareLayout.getIndependentDataNodes(1),
          "SPECIAL_CLASS");
    }
    writeBootstrapOrUpgrade(2, false, dataNode);
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER, 3,
        generateSetOfIntegers(0, numPartition));
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER + 1, 1,
        generateSetOfIntegers(numPartition, numPartition * 2));
    verifyDataNodeConfigs();

    // Test 2: Add a new group of partitions and instances.
    basePort += dataNode * 2; // it has two datacenter
    basePartitionId += 2 * numPartition;
    TestHardwareLayout secondTestHardwareLayout =
        constructInitialHardwareLayoutJSON(CLUSTER_NAME_IN_STATIC_CLUSTER_MAP, dataNode, basePort);
    TestPartitionLayout secondTestPartitionLayout =
        constructInitialPartitionLayoutJSON(secondTestHardwareLayout, numPartition, null, basePartitionId);
    for (int i = 0; i < numPartition; i++) {
      secondTestPartitionLayout.addNewPartition(secondTestHardwareLayout,
          secondTestHardwareLayout.getIndependentDataNodes(1), "SPECIAL_CLASS");
    }
    testPartitionLayout.merge(secondTestPartitionLayout);
    writeBootstrapOrUpgrade(4, false, dataNode);
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER + 2, 3,
        generateSetOfIntegers(basePartitionId, basePartitionId + numPartition));
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER + 3, 1,
        generateSetOfIntegers(basePartitionId + numPartition, basePartitionId + 2 * numPartition));
    verifyDataNodeConfigs();

    // Test 3: Add a new partition with 3 replicas to second partition layout
    List<DataNode> dataNodeIdsForNewPartition = secondTestHardwareLayout.getIndependentDataNodes(3);
    testPartitionLayout.addNewPartition(testHardwareLayout, dataNodeIdsForNewPartition, DEFAULT_PARTITION_CLASS);
    writeBootstrapOrUpgrade(4, false, dataNode);
    Set<Integer> expectedPartitionIds = generateSetOfIntegers(basePartitionId, basePartitionId + numPartition);
    expectedPartitionIds.add(testPartitionLayout.getPartitionCount() - 1);
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER + 2, 3, expectedPartitionIds);
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER + 3, 1,
        generateSetOfIntegers(basePartitionId + numPartition, basePartitionId + 2 * numPartition));
    verifyDataNodeConfigs();

    // Test 4: Add a new partition with 1 replica to second partition layout
    dataNodeIdsForNewPartition = secondTestHardwareLayout.getIndependentDataNodes(1);
    testPartitionLayout.addNewPartition(testHardwareLayout, dataNodeIdsForNewPartition, DEFAULT_PARTITION_CLASS);
    writeBootstrapOrUpgrade(4, false, dataNode);
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER + 2, 3, expectedPartitionIds);
    expectedPartitionIds = generateSetOfIntegers(basePartitionId + numPartition, basePartitionId + 2 * numPartition);
    expectedPartitionIds.add(testPartitionLayout.getPartitionCount() - 1);
    verifyResourcePartitionRange(FULL_AUTO_COMPATIBLE_RESOURCE_NAME_START_NUMBER + 3, 1, expectedPartitionIds);
    verifyDataNodeConfigs();

    // Test 5: Replace a data node with a new one
    String dcName = activeDcSet.iterator().next();
    DataNode randomDataNode = testHardwareLayout.getRandomDataNodeFromDc(dcName);
    DataNode newDataNode = testPartitionLayout.replaceDataNodeWithNewOne(randomDataNode);
    writeBootstrapOrUpgrade(4, false, dataNode);
    System.out.println(
        "Replace data node " + randomDataNode.getPort() + " with new data node " + newDataNode.getPort());
    verifyDataNodeConfigs();
  }
Test adding new partitions and data nodes to full auto compatible resources, but partitions can have
different number of replicas.
@throws Exception
ambry-tools/src/integration-test/java/com/github/ambry/clustermap/HelixBootstrapUpgradeToolTest.java