@Test
  public void testFailedMoveServersTablesAndRepair() throws Exception {
    // This UT calls moveTablesAndServers() twice to test the idempotency of it.
    // The first time, movement fails because a region is made in SPLITTING state
    // which will not be moved.
    // The second time, the region state is OPEN and check if all
    // regions on target group servers after the call.
    final RSGroupInfo newGroup = addGroup(getGroupName(name.getMethodName()), 1);
    // create table
    final byte[] familyNameBytes = Bytes.toBytes("f");
    TableName table1 = TableName.valueOf(tableName.getNameAsString() + "_1");
    TableName table2 = TableName.valueOf(tableName.getNameAsString() + "_2");
    Random rand = ThreadLocalRandom.current();
    TEST_UTIL.createMultiRegionTable(table1, familyNameBytes, rand.nextInt(12) + 4);
    TEST_UTIL.createMultiRegionTable(table2, familyNameBytes, rand.nextInt(12) + 4);

    // randomly set a region state to SPLITTING to make move abort
    Pair<ServerName, RegionStateNode> gotPair =
      randomlySetRegionState(newGroup, RegionState.State.SPLITTING, table1, table2);
    RegionStateNode rsn = gotPair.getSecond();
    ServerName srcServer = rsn.getRegionLocation();

    // move server and table to newGroup and check regions
    try {
      ADMIN.moveServersToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
      ADMIN.setRSGroup(Sets.newHashSet(table2), newGroup.getName());
      fail("should get IOException when retry exhausted but there still exists failed moved "
        + "regions");
    } catch (Exception e) {
      assertTrue(
        e.getMessage().contains(gotPair.getSecond().getRegionInfo().getRegionNameAsString()));
    }
    for (RegionInfo regionInfo : MASTER.getAssignmentManager().getAssignedRegions()) {
      if (regionInfo.getTable().equals(table1) && regionInfo.equals(rsn.getRegionInfo())) {
        assertEquals(
          MASTER.getAssignmentManager().getRegionStates().getRegionServerOfRegion(regionInfo),
          srcServer);
      }
    }

    // retry moveServersAndTables to newGroup and check if all regions on srcServer belongs to
    // table2
    rsn.setState(RegionState.State.OPEN);
    ADMIN.moveServersToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
    ADMIN.setRSGroup(Sets.newHashSet(table2), newGroup.getName());
    for (RegionInfo regionsInfo : MASTER.getAssignmentManager().getRegionsOnServer(srcServer)) {
      assertEquals(regionsInfo.getTable(), table2);
    }
  }
Randomly choose a region to set state.
@param newGroup target group
@return source server of region, and region state
@throws IOException if methods called throw
hbase-server/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsAdmin2.java