private void uploadClusterConfigsAndVerify() throws Exception {
    List<PartitionId> writablePartitions = testPartitionLayout.getPartitionLayout().getWritablePartitions(null);
    Set<String> writableInPartitionLayout = new HashSet<>();
    writablePartitions.forEach(k -> writableInPartitionLayout.add(k.toPathString()));
    Utils.writeJsonObjectToFile(zkJson, zkLayoutPath);
    Utils.writeJsonObjectToFile(testHardwareLayout.getHardwareLayout().toJSONObject(), hardwareLayoutPath);
    Utils.writeJsonObjectToFile(testPartitionLayout.getPartitionLayout().toJSONObject(), partitionLayoutPath);
    HelixBootstrapUpgradeUtil.uploadOrDeleteAdminConfigs(hardwareLayoutPath, partitionLayoutPath, zkLayoutPath,
        CLUSTER_NAME_PREFIX, dcStr, false, new String[]{ClusterMapUtils.PARTITION_OVERRIDE_STR}, null);
    // Check writable partitions in each datacenter
    for (ZkInfo zkInfo : dcsToZkInfo.values()) {
      HelixPropertyStore<ZNRecord> propertyStore =
          CommonUtils.createHelixPropertyStore("localhost:" + zkInfo.getPort(), propertyStoreConfig,
              Collections.singletonList(propertyStoreConfig.rootPath));
      try {
        ZNRecord zNRecord =
            propertyStore.get(ClusterMapUtils.PARTITION_OVERRIDE_ZNODE_PATH, null, AccessOption.PERSISTENT);
        if (!activeDcSet.contains(zkInfo.getDcName())) {
          assertNull(zNRecord);
        } else {
          assertNotNull(zNRecord);
          Map<String, Map<String, String>> overridePartition = zNRecord.getMapFields();
          Set<String> writableInDC = new HashSet<>();
          for (Map.Entry<String, Map<String, String>> entry : overridePartition.entrySet()) {
            if (entry.getValue().get(ClusterMapUtils.PARTITION_STATE).equals(ClusterMapUtils.READ_WRITE_STR)) {
              writableInDC.add(entry.getKey());
            }
          }
          // Verify writable partitions in DC match writable partitions in Partition Layout
          assertEquals("Mismatch in writable partitions for partitionLayout and propertyStore",
              writableInPartitionLayout, writableInDC);
        }
      } finally {
        propertyStore.stop();
      }
    }
    // delete partition override config
    HelixBootstrapUpgradeUtil.uploadOrDeleteAdminConfigs(hardwareLayoutPath, partitionLayoutPath, zkLayoutPath,
        CLUSTER_NAME_PREFIX, dcStr, true, new String[]{ClusterMapUtils.PARTITION_OVERRIDE_STR}, null);
    // verify that the config is cleaned up
    for (ZkInfo zkInfo : dcsToZkInfo.values()) {
      HelixPropertyStore<ZNRecord> propertyStore =
          CommonUtils.createHelixPropertyStore("localhost:" + zkInfo.getPort(), propertyStoreConfig,
              Collections.singletonList(propertyStoreConfig.rootPath));
      try {
        ZNRecord zNRecord =
            propertyStore.get(ClusterMapUtils.PARTITION_OVERRIDE_ZNODE_PATH, null, AccessOption.PERSISTENT);
        assertNull("Partition override config should no longer exist", zNRecord);
      } finally {
        propertyStore.stop();
      }
    }
  }
Write the layout files out from the constructed in-memory hardware and partition layouts; use the upload cluster config
tool to upload the partition seal states onto Zookeeper; verify that the writable partitions are consistent between the two.
After verification is done, partition override config will be safely deleted.
@throws IOException if a file read error is encountered.
@throws JSONException if a JSON parse error is encountered.
ambry-tools/src/integration-test/java/com/github/ambry/clustermap/HelixBootstrapUpgradeToolTest.java