001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.rsgroup;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertNotNull;
023import static org.junit.Assert.assertNull;
024import static org.junit.Assert.assertTrue;
025import static org.junit.Assert.fail;
026
027import java.io.IOException;
028import java.util.Iterator;
029import java.util.List;
030import java.util.Map;
031import java.util.Set;
032import java.util.SortedSet;
033
034import org.apache.hadoop.hbase.HBaseClassTestRule;
035import org.apache.hadoop.hbase.NamespaceDescriptor;
036import org.apache.hadoop.hbase.ServerName;
037import org.apache.hadoop.hbase.TableExistsException;
038import org.apache.hadoop.hbase.TableName;
039import org.apache.hadoop.hbase.TableNotFoundException;
040import org.apache.hadoop.hbase.Waiter;
041import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
042import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
043import org.apache.hadoop.hbase.client.TableDescriptor;
044import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
045import org.apache.hadoop.hbase.constraint.ConstraintException;
046import org.apache.hadoop.hbase.master.ServerManager;
047import org.apache.hadoop.hbase.master.TableNamespaceManager;
048import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
049import org.apache.hadoop.hbase.net.Address;
050import org.apache.hadoop.hbase.quotas.QuotaUtil;
051import org.apache.hadoop.hbase.testclassification.MediumTests;
052import org.apache.hadoop.hbase.util.Bytes;
053import org.junit.After;
054import org.junit.AfterClass;
055import org.junit.Assert;
056import org.junit.Before;
057import org.junit.BeforeClass;
058import org.junit.ClassRule;
059import org.junit.Test;
060import org.junit.experimental.categories.Category;
061import org.slf4j.Logger;
062import org.slf4j.LoggerFactory;
063
064import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
065
066@Category({ MediumTests.class })
067public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
068
069  @ClassRule
070  public static final HBaseClassTestRule CLASS_RULE =
071    HBaseClassTestRule.forClass(TestRSGroupsAdmin1.class);
072
073  protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsAdmin1.class);
074
075  @BeforeClass
076  public static void setUp() throws Exception {
077    setUpTestBeforeClass();
078  }
079
080  @AfterClass
081  public static void tearDown() throws Exception {
082    tearDownAfterClass();
083  }
084
085  @Before
086  public void beforeMethod() throws Exception {
087    setUpBeforeMethod();
088  }
089
090  @After
091  public void afterMethod() throws Exception {
092    tearDownAfterMethod();
093  }
094
095  @Test
096  public void testValidGroupNames() throws IOException {
097    String[] badNames = { "foo*", "foo@", "-" };
098    String[] goodNames = { "foo_123" };
099
100    for (String entry : badNames) {
101      try {
102        rsGroupAdmin.addRSGroup(entry);
103        fail("Expected a constraint exception for: " + entry);
104      } catch (ConstraintException ex) {
105        // expected
106      }
107    }
108
109    for (String entry : goodNames) {
110      rsGroupAdmin.addRSGroup(entry);
111    }
112  }
113
114  @Test
115  public void testBogusArgs() throws Exception {
116    assertNull(rsGroupAdmin.getRSGroupInfoOfTable(TableName.valueOf("nonexistent")));
117    assertNull(rsGroupAdmin.getRSGroupOfServer(Address.fromParts("bogus", 123)));
118    assertNull(rsGroupAdmin.getRSGroupInfo("bogus"));
119
120    try {
121      rsGroupAdmin.removeRSGroup("bogus");
122      fail("Expected removing bogus group to fail");
123    } catch (ConstraintException ex) {
124      // expected
125    }
126
127    try {
128      rsGroupAdmin.moveTables(Sets.newHashSet(TableName.valueOf("bogustable")), "bogus");
129      fail("Expected move with bogus group to fail");
130    } catch (ConstraintException | TableNotFoundException ex) {
131      // expected
132    }
133
134    try {
135      rsGroupAdmin.moveServers(Sets.newHashSet(Address.fromParts("bogus", 123)), "bogus");
136      fail("Expected move with bogus group to fail");
137    } catch (ConstraintException ex) {
138      // expected
139    }
140
141    try {
142      admin.balancerSwitch(true, true);
143      rsGroupAdmin.balanceRSGroup("bogus");
144      admin.balancerSwitch(false, true);
145      fail("Expected move with bogus group to fail");
146    } catch (ConstraintException ex) {
147      // expected
148    }
149  }
150
151  @Test
152  public void testNamespaceConstraint() throws Exception {
153    String nsName = tablePrefix + "_foo";
154    String groupName = tablePrefix + "_foo";
155    LOG.info("testNamespaceConstraint");
156    rsGroupAdmin.addRSGroup(groupName);
157    assertTrue(observer.preAddRSGroupCalled);
158    assertTrue(observer.postAddRSGroupCalled);
159
160    admin.createNamespace(NamespaceDescriptor.create(nsName)
161      .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, groupName).build());
162    // test removing a referenced group
163    try {
164      rsGroupAdmin.removeRSGroup(groupName);
165      fail("Expected a constraint exception");
166    } catch (IOException ex) {
167    }
168    // test modify group
169    // changing with the same name is fine
170    admin.modifyNamespace(NamespaceDescriptor.create(nsName)
171      .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, groupName).build());
172    String anotherGroup = tablePrefix + "_anotherGroup";
173    rsGroupAdmin.addRSGroup(anotherGroup);
174    // test add non-existent group
175    admin.deleteNamespace(nsName);
176    rsGroupAdmin.removeRSGroup(groupName);
177    assertTrue(observer.preRemoveRSGroupCalled);
178    assertTrue(observer.postRemoveRSGroupCalled);
179    try {
180      admin.createNamespace(NamespaceDescriptor.create(nsName)
181        .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, "foo").build());
182      fail("Expected a constraint exception");
183    } catch (IOException ex) {
184    }
185  }
186
187  @Test
188  public void testGroupInfoMultiAccessing() throws Exception {
189    RSGroupInfoManager manager = rsGroupAdminEndpoint.getGroupInfoManager();
190    RSGroupInfo defaultGroup = manager.getRSGroup("default");
191    // getRSGroup updates default group's server list
192    // this process must not affect other threads iterating the list
193    Iterator<Address> it = defaultGroup.getServers().iterator();
194    manager.getRSGroup("default");
195    it.next();
196  }
197
198  @Test
199  public void testFailRemoveGroup() throws IOException, InterruptedException {
200    int initNumGroups = rsGroupAdmin.listRSGroups().size();
201    addGroup("bar", 3);
202    TEST_UTIL.createTable(tableName, Bytes.toBytes("f"));
203    rsGroupAdmin.moveTables(Sets.newHashSet(tableName), "bar");
204    RSGroupInfo barGroup = rsGroupAdmin.getRSGroupInfo("bar");
205    // group is not empty therefore it should fail
206    try {
207      rsGroupAdmin.removeRSGroup(barGroup.getName());
208      fail("Expected remove group to fail");
209    } catch (IOException e) {
210    }
211    // group cannot lose all it's servers therefore it should fail
212    try {
213      rsGroupAdmin.moveServers(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
214      fail("Expected move servers to fail");
215    } catch (IOException e) {
216    }
217
218    rsGroupAdmin.moveTables(barGroup.getTables(), RSGroupInfo.DEFAULT_GROUP);
219    try {
220      rsGroupAdmin.removeRSGroup(barGroup.getName());
221      fail("Expected move servers to fail");
222    } catch (IOException e) {
223    }
224
225    rsGroupAdmin.moveServers(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
226    rsGroupAdmin.removeRSGroup(barGroup.getName());
227
228    Assert.assertEquals(initNumGroups, rsGroupAdmin.listRSGroups().size());
229  }
230
231  @Test
232  public void testMultiTableMove() throws Exception {
233    final TableName tableNameA = TableName.valueOf(tablePrefix + name.getMethodName() + "A");
234    final TableName tableNameB = TableName.valueOf(tablePrefix + name.getMethodName() + "B");
235    final byte[] familyNameBytes = Bytes.toBytes("f");
236    String newGroupName = getGroupName(name.getMethodName());
237    final RSGroupInfo newGroup = addGroup(newGroupName, 1);
238
239    TEST_UTIL.createTable(tableNameA, familyNameBytes);
240    TEST_UTIL.createTable(tableNameB, familyNameBytes);
241    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
242      @Override
243      public boolean evaluate() throws Exception {
244        List<String> regionsA = getTableRegionMap().get(tableNameA);
245        if (regionsA == null) {
246          return false;
247        }
248        List<String> regionsB = getTableRegionMap().get(tableNameB);
249        if (regionsB == null) {
250          return false;
251        }
252        return getTableRegionMap().get(tableNameA).size() >= 1 &&
253          getTableRegionMap().get(tableNameB).size() >= 1;
254      }
255    });
256
257    RSGroupInfo tableGrpA = rsGroupAdmin.getRSGroupInfoOfTable(tableNameA);
258    assertTrue(tableGrpA.getName().equals(RSGroupInfo.DEFAULT_GROUP));
259
260    RSGroupInfo tableGrpB = rsGroupAdmin.getRSGroupInfoOfTable(tableNameB);
261    assertTrue(tableGrpB.getName().equals(RSGroupInfo.DEFAULT_GROUP));
262    // change table's group
263    LOG.info("Moving table [" + tableNameA + "," + tableNameB + "] to " + newGroup.getName());
264    rsGroupAdmin.moveTables(Sets.newHashSet(tableNameA, tableNameB), newGroup.getName());
265
266    // verify group change
267    Assert.assertEquals(newGroup.getName(),
268      rsGroupAdmin.getRSGroupInfoOfTable(tableNameA).getName());
269
270    Assert.assertEquals(newGroup.getName(),
271      rsGroupAdmin.getRSGroupInfoOfTable(tableNameB).getName());
272
273    // verify tables' not exist in old group
274    Set<TableName> DefaultTables =
275      rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables();
276    assertFalse(DefaultTables.contains(tableNameA));
277    assertFalse(DefaultTables.contains(tableNameB));
278
279    // verify tables' exist in new group
280    Set<TableName> newGroupTables = rsGroupAdmin.getRSGroupInfo(newGroupName).getTables();
281    assertTrue(newGroupTables.contains(tableNameA));
282    assertTrue(newGroupTables.contains(tableNameB));
283  }
284
285  @Test
286  public void testTableMoveTruncateAndDrop() throws Exception {
287    final byte[] familyNameBytes = Bytes.toBytes("f");
288    String newGroupName = getGroupName(name.getMethodName());
289    final RSGroupInfo newGroup = addGroup(newGroupName, 2);
290
291    TEST_UTIL.createMultiRegionTable(tableName, familyNameBytes, 5);
292    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
293      @Override
294      public boolean evaluate() throws Exception {
295        List<String> regions = getTableRegionMap().get(tableName);
296        if (regions == null) {
297          return false;
298        }
299
300        return getTableRegionMap().get(tableName).size() >= 5;
301      }
302    });
303
304    RSGroupInfo tableGrp = rsGroupAdmin.getRSGroupInfoOfTable(tableName);
305    assertTrue(tableGrp.getName().equals(RSGroupInfo.DEFAULT_GROUP));
306
307    // change table's group
308    LOG.info("Moving table " + tableName + " to " + newGroup.getName());
309    rsGroupAdmin.moveTables(Sets.newHashSet(tableName), newGroup.getName());
310
311    // verify group change
312    Assert.assertEquals(newGroup.getName(),
313      rsGroupAdmin.getRSGroupInfoOfTable(tableName).getName());
314
315    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
316      @Override
317      public boolean evaluate() throws Exception {
318        Map<ServerName, List<String>> serverMap = getTableServerRegionMap().get(tableName);
319        int count = 0;
320        if (serverMap != null) {
321          for (ServerName rs : serverMap.keySet()) {
322            if (newGroup.containsServer(rs.getAddress())) {
323              count += serverMap.get(rs).size();
324            }
325          }
326        }
327        return count == 5;
328      }
329    });
330
331    // test truncate
332    admin.disableTable(tableName);
333    admin.truncateTable(tableName, true);
334    Assert.assertEquals(1, rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getTables().size());
335    Assert.assertEquals(tableName,
336      rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getTables().first());
337
338    // verify removed table is removed from group
339    TEST_UTIL.deleteTable(tableName);
340    Assert.assertEquals(0, rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getTables().size());
341
342    assertTrue(observer.preMoveTablesCalled);
343    assertTrue(observer.postMoveTablesCalled);
344  }
345
346  @Test
347  public void testDisabledTableMove() throws Exception {
348    final byte[] familyNameBytes = Bytes.toBytes("f");
349    String newGroupName = getGroupName(name.getMethodName());
350    final RSGroupInfo newGroup = addGroup(newGroupName, 2);
351
352    TEST_UTIL.createMultiRegionTable(tableName, familyNameBytes, 5);
353    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
354      @Override
355      public boolean evaluate() throws Exception {
356        List<String> regions = getTableRegionMap().get(tableName);
357        if (regions == null) {
358          return false;
359        }
360        return getTableRegionMap().get(tableName).size() >= 5;
361      }
362    });
363
364    RSGroupInfo tableGrp = rsGroupAdmin.getRSGroupInfoOfTable(tableName);
365    assertTrue(tableGrp.getName().equals(RSGroupInfo.DEFAULT_GROUP));
366
367    // test disable table
368    admin.disableTable(tableName);
369
370    // change table's group
371    LOG.info("Moving table " + tableName + " to " + newGroup.getName());
372    rsGroupAdmin.moveTables(Sets.newHashSet(tableName), newGroup.getName());
373
374    // verify group change
375    Assert.assertEquals(newGroup.getName(),
376      rsGroupAdmin.getRSGroupInfoOfTable(tableName).getName());
377  }
378
379  @Test
380  public void testNonExistentTableMove() throws Exception {
381    TableName tableName = TableName.valueOf(tablePrefix + name.getMethodName());
382
383    RSGroupInfo tableGrp = rsGroupAdmin.getRSGroupInfoOfTable(tableName);
384    assertNull(tableGrp);
385
386    // test if table exists already.
387    boolean exist = admin.tableExists(tableName);
388    assertFalse(exist);
389
390    LOG.info("Moving table " + tableName + " to " + RSGroupInfo.DEFAULT_GROUP);
391    try {
392      rsGroupAdmin.moveTables(Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
393      fail("Table " + tableName + " shouldn't have been successfully moved.");
394    } catch (IOException ex) {
395      assertTrue(ex instanceof TableNotFoundException);
396    }
397
398    try {
399      rsGroupAdmin.moveServersAndTables(Sets.newHashSet(Address.fromParts("bogus", 123)),
400        Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
401      fail("Table " + tableName + " shouldn't have been successfully moved.");
402    } catch (IOException ex) {
403      assertTrue(ex instanceof TableNotFoundException);
404    }
405    // verify group change
406    assertNull(rsGroupAdmin.getRSGroupInfoOfTable(tableName));
407  }
408
409  @Test
410  public void testRSGroupListDoesNotContainFailedTableCreation() throws Exception {
411    toggleQuotaCheckAndRestartMiniCluster(true);
412    String nsp = "np1";
413    NamespaceDescriptor nspDesc =
414      NamespaceDescriptor.create(nsp).addConfiguration(TableNamespaceManager.KEY_MAX_REGIONS, "5")
415        .addConfiguration(TableNamespaceManager.KEY_MAX_TABLES, "2").build();
416    admin.createNamespace(nspDesc);
417    assertEquals(3, admin.listNamespaceDescriptors().length);
418    ColumnFamilyDescriptor fam1 = ColumnFamilyDescriptorBuilder.of("fam1");
419    TableDescriptor tableDescOne = TableDescriptorBuilder
420      .newBuilder(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1"))
421      .setColumnFamily(fam1).build();
422    admin.createTable(tableDescOne);
423
424    TableDescriptor tableDescTwo = TableDescriptorBuilder
425      .newBuilder(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table2"))
426      .setColumnFamily(fam1).build();
427    boolean constraintViolated = false;
428
429    try {
430      admin.createTable(tableDescTwo, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 6);
431      Assert.fail("Creation table should fail because of quota violation.");
432    } catch (Exception exp) {
433      assertTrue(exp instanceof IOException);
434      constraintViolated = true;
435    } finally {
436      assertTrue("Constraint not violated for table " + tableDescTwo.getTableName(),
437        constraintViolated);
438    }
439    List<RSGroupInfo> rsGroupInfoList = rsGroupAdmin.listRSGroups();
440    boolean foundTable2 = false;
441    boolean foundTable1 = false;
442    for (int i = 0; i < rsGroupInfoList.size(); i++) {
443      if (rsGroupInfoList.get(i).getTables().contains(tableDescTwo.getTableName())) {
444        foundTable2 = true;
445      }
446      if (rsGroupInfoList.get(i).getTables().contains(tableDescOne.getTableName())) {
447        foundTable1 = true;
448      }
449    }
450    assertFalse("Found table2 in rsgroup list.", foundTable2);
451    assertTrue("Did not find table1 in rsgroup list", foundTable1);
452
453    TEST_UTIL.deleteTable(tableDescOne.getTableName());
454    admin.deleteNamespace(nspDesc.getName());
455    toggleQuotaCheckAndRestartMiniCluster(false);
456
457  }
458
459  @Test
460  public void testNotMoveTableToNullRSGroupWhenCreatingExistingTable()
461          throws Exception {
462    // Trigger
463    TableName tn1 = TableName.valueOf("t1");
464    TEST_UTIL.createTable(tn1, "cf1");
465    try {
466      // Create an existing table to trigger HBASE-21866
467      TEST_UTIL.createTable(tn1, "cf1");
468    } catch (TableExistsException teex) {
469      // Ignore
470    }
471
472    // Wait then verify
473    //   Could not verify until the rollback of CreateTableProcedure is done
474    //   (that is, the coprocessor finishes its work),
475    //   or the table is still in the "default" rsgroup even though HBASE-21866
476    //   is not fixed.
477    TEST_UTIL.waitFor(5000, new Waiter.Predicate<Exception>() {
478      @Override
479      public boolean evaluate() throws Exception {
480        return
481                (master.getMasterProcedureExecutor().getActiveExecutorCount() == 0);
482      }
483    });
484    SortedSet<TableName> tables
485            = rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables();
486    assertTrue("Table 't1' must be in 'default' rsgroup", tables.contains(tn1));
487
488    // Cleanup
489    TEST_UTIL.deleteTable(tn1);
490  }
491
492  private void toggleQuotaCheckAndRestartMiniCluster(boolean enable) throws Exception {
493    TEST_UTIL.shutdownMiniCluster();
494    TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, enable);
495    TEST_UTIL.startMiniCluster(NUM_SLAVES_BASE - 1);
496    TEST_UTIL.getConfiguration().setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART,
497      NUM_SLAVES_BASE - 1);
498    TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
499    initialize();
500  }
501
502  @Test
503  public void testRenameRSGroup() throws Exception {
504    // Add rsgroup, and assign 2 servers and a table to it.
505    RSGroupInfo oldgroup = addGroup("oldgroup", 2);
506    final TableName tb1 = TableName.valueOf("testRename");
507    TEST_UTIL.createTable(tb1, "tr");
508    rsGroupAdmin.moveTables(Sets.newHashSet(tb1), oldgroup.getName());
509    TEST_UTIL.waitFor(1000,
510      (Waiter.Predicate<Exception>) () ->
511        rsGroupAdmin.getRSGroupInfoOfTable(tb1).getServers().size() == 2);
512    oldgroup = rsGroupAdmin.getRSGroupInfo(oldgroup.getName());
513    assertEquals(2, oldgroup.getServers().size());
514    assertEquals(oldgroup.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb1).getName());
515    assertTrue(oldgroup.getTables().contains(tb1));
516
517    // Another rsgroup and table for verification
518    // that they are unchanged during we're renaming oldgroup.
519    RSGroupInfo normal = addGroup("normal", 1);
520    final TableName tb2 = TableName.valueOf("unmovedTable");
521    TEST_UTIL.createTable(tb2, "ut");
522    rsGroupAdmin.moveTables(Sets.newHashSet(tb2), normal.getName());
523    TEST_UTIL.waitFor(1000,
524      (Waiter.Predicate<Exception>) () ->
525        rsGroupAdmin.getRSGroupInfoOfTable(tb2).getServers().size() == 1);
526    normal = rsGroupAdmin.getRSGroupInfo(normal.getName());
527    assertEquals(1, normal.getServers().size());
528    assertEquals(normal.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb2).getName());
529    assertTrue(normal.containsTable(tb2));
530
531
532    // Rename rsgroup
533    rsGroupAdmin.renameRSGroup(oldgroup.getName(), "newgroup");
534    Set<Address> servers = oldgroup.getServers();
535    RSGroupInfo newgroup = rsGroupAdmin.getRSGroupInfo("newgroup");
536    assertEquals(servers.size(), newgroup.getServers().size());
537    for (Address server : servers) {
538      assertTrue(newgroup.containsServer(server));
539    }
540    assertEquals(newgroup.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb1).getName());
541    assertTrue(newgroup.containsTable(tb1));
542    assertEquals(normal.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb2).getName());
543  }
544
545  @Test
546  public void testRenameRSGroupConstraints() throws Exception {
547    // Add RSGroup, and assign 2 servers and a table to it.
548    String oldGroupName = "oldGroup";
549    RSGroupInfo oldGroup = addGroup(oldGroupName, 2);
550    oldGroup = rsGroupAdmin.getRSGroupInfo(oldGroup.getName());
551    assertNotNull(oldGroup);
552    assertEquals(2, oldGroup.getServers().size());
553
554    //Add another RSGroup
555    String anotherRSGroupName = "anotherRSGroup";
556    RSGroupInfo anotherGroup = addGroup(anotherRSGroupName, 1);
557    anotherGroup = rsGroupAdmin.getRSGroupInfo(anotherGroup.getName());
558    assertNotNull(anotherGroup);
559    assertEquals(1, anotherGroup.getServers().size());
560
561    //Rename a non existing RSGroup
562    try {
563      rsGroupAdmin.renameRSGroup("nonExistingRSGroup", "newRSGroup1");
564      fail("ConstraintException was expected.");
565    } catch (ConstraintException e) {
566      assertTrue(e.getMessage().contains("does not exist"));
567    }
568
569    //Rename to existing group
570    try {
571      rsGroupAdmin.renameRSGroup(oldGroup.getName(), anotherRSGroupName);
572      fail("ConstraintException was expected.");
573    } catch (ConstraintException e) {
574      assertTrue(e.getMessage().contains("Group already exists"));
575    }
576
577    //Rename default RSGroup
578    try {
579      rsGroupAdmin.renameRSGroup(RSGroupInfo.DEFAULT_GROUP, "newRSGroup2");
580      fail("ConstraintException was expected.");
581    } catch (ConstraintException e) {
582      //Do nothing
583    }
584
585    //Rename to default RSGroup
586    try {
587      rsGroupAdmin.renameRSGroup(oldGroup.getName(), RSGroupInfo.DEFAULT_GROUP);
588      fail("ConstraintException was expected.");
589    } catch (ConstraintException e) {
590      assertTrue(e.getMessage().contains("Group already exists"));
591    }
592  }
593}