1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.rsgroup;
21
22 import com.google.common.collect.Maps;
23 import com.google.common.collect.Sets;
24 import com.google.common.net.HostAndPort;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.ClusterStatus;
29 import org.apache.hadoop.hbase.HBaseCluster;
30 import org.apache.hadoop.hbase.HBaseTestingUtility;
31 import org.apache.hadoop.hbase.HColumnDescriptor;
32 import org.apache.hadoop.hbase.HRegionInfo;
33 import org.apache.hadoop.hbase.HTableDescriptor;
34 import org.apache.hadoop.hbase.NamespaceDescriptor;
35 import org.apache.hadoop.hbase.RegionLoad;
36 import org.apache.hadoop.hbase.ServerName;
37 import org.apache.hadoop.hbase.TableName;
38 import org.apache.hadoop.hbase.Waiter;
39 import org.apache.hadoop.hbase.client.HBaseAdmin;
40 import org.apache.hadoop.hbase.constraint.ConstraintException;
41 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
42 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.junit.Assert;
45 import org.junit.Test;
46
47 import java.io.IOException;
48 import java.security.SecureRandom;
49 import java.util.HashSet;
50 import java.util.LinkedList;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Set;
54 import java.util.TreeMap;
55 import static org.junit.Assert.assertEquals;
56 import static org.junit.Assert.assertFalse;
57 import static org.junit.Assert.assertNull;
58 import static org.junit.Assert.assertTrue;
59 import static org.junit.Assert.fail;
60
61 public abstract class TestRSGroupsBase {
62 protected static final Log LOG = LogFactory.getLog(TestRSGroupsBase.class);
63
64
65 protected final static String groupPrefix = "Group";
66 protected final static String tablePrefix = "Group";
67 protected final static SecureRandom rand = new SecureRandom();
68
69
70 protected static HBaseTestingUtility TEST_UTIL;
71 protected static HBaseAdmin admin;
72 protected static HBaseCluster cluster;
73 protected static RSGroupAdmin rsGroupAdmin;
74 protected static Configuration conf;
75
76 public final static String WAIT_TIMEOUT_KEY = "hbase.it.rsgroups.wait.timeout";
77 public final static long DEFAULT_WAIT_TIMEOUT = 60000*5;
78 public final static String NUM_SLAVES_BASE_KEY = "hbase.it.rsgroups.num.slaves.base";
79 public final static int DEFAULT_NUM_SLAVES_BASE = 4;
80
81
82
83 protected RSGroupInfo addGroup(RSGroupAdmin gAdmin, String groupName,
84 int serverCount) throws IOException, InterruptedException {
85 RSGroupInfo defaultInfo = gAdmin
86 .getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP);
87 assertTrue(defaultInfo != null);
88 assertTrue(defaultInfo.getServers().size() >= serverCount);
89 gAdmin.addRSGroup(groupName);
90
91 Set<HostAndPort> set = new HashSet<HostAndPort>();
92 for(HostAndPort server: defaultInfo.getServers()) {
93 if(set.size() == serverCount) {
94 break;
95 }
96 set.add(server);
97 }
98 gAdmin.moveServers(set, groupName);
99 RSGroupInfo result = gAdmin.getRSGroupInfo(groupName);
100 assertTrue(result.getServers().size() >= serverCount);
101 return result;
102 }
103
104 static void removeGroup(RSGroupAdminClient groupAdmin, String groupName) throws IOException {
105 RSGroupInfo RSGroupInfo = groupAdmin.getRSGroupInfo(groupName);
106 groupAdmin.moveTables(RSGroupInfo.getTables(), RSGroupInfo.DEFAULT_GROUP);
107 groupAdmin.moveServers(RSGroupInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
108 groupAdmin.removeRSGroup(groupName);
109 }
110
111 protected void deleteTableIfNecessary() throws IOException {
112 for (HTableDescriptor desc : TEST_UTIL.getHBaseAdmin().listTables(tablePrefix+".*")) {
113 TEST_UTIL.deleteTable(desc.getTableName());
114 }
115 }
116
117 protected void deleteNamespaceIfNecessary() throws IOException {
118 for (NamespaceDescriptor desc : TEST_UTIL.getHBaseAdmin().listNamespaceDescriptors()) {
119 if(desc.getName().startsWith(tablePrefix)) {
120 admin.deleteNamespace(desc.getName());
121 }
122 }
123 }
124
125 protected void deleteGroups() throws IOException {
126 RSGroupAdmin groupAdmin = rsGroupAdmin.newClient(TEST_UTIL.getConnection());
127 for(RSGroupInfo group: groupAdmin.listRSGroups()) {
128 if(!group.getName().equals(RSGroupInfo.DEFAULT_GROUP)) {
129 groupAdmin.moveTables(group.getTables(), RSGroupInfo.DEFAULT_GROUP);
130 groupAdmin.moveServers(group.getServers(), RSGroupInfo.DEFAULT_GROUP);
131 groupAdmin.removeRSGroup(group.getName());
132 }
133 }
134 }
135
136 public Map<TableName, List<String>> getTableRegionMap() throws IOException {
137 Map<TableName, List<String>> map = Maps.newTreeMap();
138 Map<TableName, Map<ServerName, List<String>>> tableServerRegionMap
139 = getTableServerRegionMap();
140 for(TableName tableName : tableServerRegionMap.keySet()) {
141 if(!map.containsKey(tableName)) {
142 map.put(tableName, new LinkedList<String>());
143 }
144 for(List<String> subset: tableServerRegionMap.get(tableName).values()) {
145 map.get(tableName).addAll(subset);
146 }
147 }
148 return map;
149 }
150
151 public Map<TableName, Map<ServerName, List<String>>> getTableServerRegionMap()
152 throws IOException {
153 Map<TableName, Map<ServerName, List<String>>> map = Maps.newTreeMap();
154 ClusterStatus status = TEST_UTIL.getHBaseClusterInterface().getClusterStatus();
155 for(ServerName serverName : status.getServers()) {
156 for(RegionLoad rl : status.getLoad(serverName).getRegionsLoad().values()) {
157 TableName tableName = HRegionInfo.getTable(rl.getName());
158 if(!map.containsKey(tableName)) {
159 map.put(tableName, new TreeMap<ServerName, List<String>>());
160 }
161 if(!map.get(tableName).containsKey(serverName)) {
162 map.get(tableName).put(serverName, new LinkedList<String>());
163 }
164 map.get(tableName).get(serverName).add(rl.getNameAsString());
165 }
166 }
167 return map;
168 }
169
170 @Test
171 public void testBogusArgs() throws Exception {
172 assertNull(rsGroupAdmin.getRSGroupInfoOfTable(TableName.valueOf("nonexistent")));
173 assertNull(rsGroupAdmin.getRSGroupOfServer(HostAndPort.fromParts("bogus",123)));
174 assertNull(rsGroupAdmin.getRSGroupInfo("bogus"));
175
176 try {
177 rsGroupAdmin.removeRSGroup("bogus");
178 fail("Expected removing bogus group to fail");
179 } catch(ConstraintException ex) {
180
181 }
182
183 try {
184 rsGroupAdmin.moveTables(Sets.newHashSet(TableName.valueOf("bogustable")), "bogus");
185 fail("Expected move with bogus group to fail");
186 } catch(ConstraintException ex) {
187
188 }
189
190 try {
191 rsGroupAdmin.moveServers(Sets.newHashSet(HostAndPort.fromParts("bogus",123)), "bogus");
192 fail("Expected move with bogus group to fail");
193 } catch(ConstraintException ex) {
194
195 }
196
197 try {
198 rsGroupAdmin.balanceRSGroup("bogus");
199 fail("Expected move with bogus group to fail");
200 } catch(ConstraintException ex) {
201
202 }
203 }
204
205 @Test
206 public void testCreateMultiRegion() throws IOException {
207 LOG.info("testCreateMultiRegion");
208 TableName tableName = TableName.valueOf(tablePrefix + "_testCreateMultiRegion");
209 byte[] end = {1,3,5,7,9};
210 byte[] start = {0,2,4,6,8};
211 byte[][] f = {Bytes.toBytes("f")};
212 TEST_UTIL.createTable(tableName, f,1,start,end,10);
213 }
214
215 @Test
216 public void testCreateAndDrop() throws Exception {
217 LOG.info("testCreateAndDrop");
218
219 final TableName tableName = TableName.valueOf(tablePrefix + "_testCreateAndDrop");
220 TEST_UTIL.createTable(tableName, Bytes.toBytes("cf"));
221
222 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
223 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
224 @Override
225 public boolean evaluate() throws Exception {
226 return getTableRegionMap().get(tableName) != null;
227 }
228 });
229 TEST_UTIL.deleteTable(tableName);
230 }
231
232
233 @Test
234 public void testSimpleRegionServerMove() throws IOException,
235 InterruptedException {
236 LOG.info("testSimpleRegionServerMove");
237
238 int initNumGroups = rsGroupAdmin.listRSGroups().size();
239 RSGroupInfo appInfo = addGroup(rsGroupAdmin, getGroupName("testSimpleRegionServerMove"), 1);
240 RSGroupInfo adminInfo = addGroup(rsGroupAdmin, getGroupName("testSimpleRegionServerMove"), 1);
241 RSGroupInfo dInfo = rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP);
242 Assert.assertEquals(initNumGroups + 2, rsGroupAdmin.listRSGroups().size());
243 assertEquals(1, adminInfo.getServers().size());
244 assertEquals(1, appInfo.getServers().size());
245 assertEquals(getNumServers() - 2, dInfo.getServers().size());
246 rsGroupAdmin.moveServers(appInfo.getServers(),
247 RSGroupInfo.DEFAULT_GROUP);
248 rsGroupAdmin.removeRSGroup(appInfo.getName());
249 rsGroupAdmin.moveServers(adminInfo.getServers(),
250 RSGroupInfo.DEFAULT_GROUP);
251 rsGroupAdmin.removeRSGroup(adminInfo.getName());
252 Assert.assertEquals(rsGroupAdmin.listRSGroups().size(), initNumGroups);
253 }
254
255
256 public int getNumServers() throws IOException {
257 ClusterStatus status = admin.getClusterStatus();
258 ServerName master = status.getMaster();
259 int count = 0;
260 for (ServerName sn : status.getServers()) {
261 if (!sn.equals(master)) {
262 count++;
263 }
264 }
265 return count;
266 }
267
268 @Test
269 public void testMoveServers() throws Exception {
270 LOG.info("testMoveServers");
271
272
273 addGroup(rsGroupAdmin, "bar", 3);
274 rsGroupAdmin.addRSGroup("foo");
275
276 RSGroupInfo barGroup = rsGroupAdmin.getRSGroupInfo("bar");
277 RSGroupInfo fooGroup = rsGroupAdmin.getRSGroupInfo("foo");
278 assertEquals(3, barGroup.getServers().size());
279 assertEquals(0, fooGroup.getServers().size());
280
281
282 try {
283 rsGroupAdmin.moveServers(Sets.newHashSet(HostAndPort.fromString("foo:9999")),"foo");
284 fail("Bogus servers shouldn't have been successfully moved.");
285 } catch(IOException ex) {
286 String exp = "Server foo:9999 does not have a group.";
287 String msg = "Expected '"+exp+"' in exception message: ";
288 assertTrue(msg+" "+ex.getMessage(), ex.getMessage().contains(exp));
289 }
290
291
292 LOG.info("moving servers "+barGroup.getServers()+" to group foo");
293 rsGroupAdmin.moveServers(barGroup.getServers(), fooGroup.getName());
294
295 barGroup = rsGroupAdmin.getRSGroupInfo("bar");
296 fooGroup = rsGroupAdmin.getRSGroupInfo("foo");
297 assertEquals(0,barGroup.getServers().size());
298 assertEquals(3,fooGroup.getServers().size());
299
300 LOG.info("moving servers "+fooGroup.getServers()+" to group default");
301 rsGroupAdmin.moveServers(fooGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
302
303 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
304 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
305 @Override
306 public boolean evaluate() throws Exception {
307 return getNumServers() ==
308 rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getServers().size();
309 }
310 });
311
312 fooGroup = rsGroupAdmin.getRSGroupInfo("foo");
313 assertEquals(0,fooGroup.getServers().size());
314
315
316 LOG.info("Remove group "+barGroup.getName());
317 rsGroupAdmin.removeRSGroup(barGroup.getName());
318 Assert.assertEquals(null, rsGroupAdmin.getRSGroupInfo(barGroup.getName()));
319 LOG.info("Remove group "+fooGroup.getName());
320 rsGroupAdmin.removeRSGroup(fooGroup.getName());
321 Assert.assertEquals(null, rsGroupAdmin.getRSGroupInfo(fooGroup.getName()));
322 }
323
324 @Test
325 public void testTableMoveTruncateAndDrop() throws Exception {
326 LOG.info("testTableMove");
327
328 final TableName tableName = TableName.valueOf(tablePrefix + "_testTableMoveAndDrop");
329 final byte[] familyNameBytes = Bytes.toBytes("f");
330 String newGroupName = getGroupName("testTableMove");
331 final RSGroupInfo newGroup = addGroup(rsGroupAdmin, newGroupName, 2);
332
333 TEST_UTIL.createMultiRegionTable(tableName, familyNameBytes, 5);
334 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
335 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
336 @Override
337 public boolean evaluate() throws Exception {
338 List<String> regions = getTableRegionMap().get(tableName);
339 if (regions == null)
340 return false;
341 return getTableRegionMap().get(tableName).size() >= 5;
342 }
343 });
344
345 RSGroupInfo tableGrp = rsGroupAdmin.getRSGroupInfoOfTable(tableName);
346 assertTrue(tableGrp.getName().equals(RSGroupInfo.DEFAULT_GROUP));
347
348
349 LOG.info("Moving table "+tableName+" to "+newGroup.getName());
350 rsGroupAdmin.moveTables(Sets.newHashSet(tableName), newGroup.getName());
351
352
353 Assert.assertEquals(newGroup.getName(),
354 rsGroupAdmin.getRSGroupInfoOfTable(tableName).getName());
355
356 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
357 @Override
358 public boolean evaluate() throws Exception {
359 Map<ServerName, List<String>> serverMap = getTableServerRegionMap().get(tableName);
360 int count = 0;
361 if (serverMap != null) {
362 for (ServerName rs : serverMap.keySet()) {
363 if (newGroup.containsServer(rs.getHostPort())) {
364 count += serverMap.get(rs).size();
365 }
366 }
367 }
368 return count == 5;
369 }
370 });
371
372
373 admin.disableTable(tableName);
374 admin.truncateTable(tableName, true);
375 Assert.assertEquals(1, rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getTables().size());
376 Assert.assertEquals(tableName, rsGroupAdmin.getRSGroupInfo(
377 newGroup.getName()).getTables().first());
378
379
380 TEST_UTIL.deleteTable(tableName);
381 Assert.assertEquals(0, rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getTables().size());
382 }
383
384 @Test
385 public void testGroupBalance() throws Exception {
386 LOG.info("testGroupBalance");
387 String newGroupName = getGroupName("testGroupBalance");
388 final RSGroupInfo newGroup = addGroup(rsGroupAdmin, newGroupName, 3);
389
390 final TableName tableName = TableName.valueOf(tablePrefix+"_ns", "testGroupBalance");
391 admin.createNamespace(
392 NamespaceDescriptor.create(tableName.getNamespaceAsString())
393 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, newGroupName).build());
394 final byte[] familyNameBytes = Bytes.toBytes("f");
395 final HTableDescriptor desc = new HTableDescriptor(tableName);
396 desc.addFamily(new HColumnDescriptor("f"));
397 byte [] startKey = Bytes.toBytes("aaaaa");
398 byte [] endKey = Bytes.toBytes("zzzzz");
399 admin.createTable(desc, startKey, endKey, 6);
400 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
401 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
402 @Override
403 public boolean evaluate() throws Exception {
404 List<String> regions = getTableRegionMap().get(tableName);
405 if (regions == null) {
406 return false;
407 }
408 return regions.size() >= 6;
409 }
410 });
411
412
413 Map<ServerName,List<String>> assignMap =
414 getTableServerRegionMap().get(tableName);
415 final ServerName first = assignMap.entrySet().iterator().next().getKey();
416 for(HRegionInfo region: admin.getTableRegions(tableName)) {
417 if(!assignMap.get(first).contains(region)) {
418 admin.move(region.getEncodedNameAsBytes(), Bytes.toBytes(first.getServerName()));
419 }
420 }
421 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
422 @Override
423 public boolean evaluate() throws Exception {
424 Map<ServerName, List<String>> map = getTableServerRegionMap().get(tableName);
425 if (map == null) {
426 return true;
427 }
428 List<String> regions = map.get(first);
429 if (regions == null) {
430 return true;
431 }
432 return regions.size() >= 6;
433 }
434 });
435
436
437 rsGroupAdmin.balanceRSGroup(RSGroupInfo.DEFAULT_GROUP);
438 assertEquals(6, getTableServerRegionMap().get(tableName).get(first).size());
439
440 rsGroupAdmin.balanceRSGroup(newGroupName);
441 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
442 @Override
443 public boolean evaluate() throws Exception {
444 for (List<String> regions : getTableServerRegionMap().get(tableName).values()) {
445 if (2 != regions.size()) {
446 return false;
447 }
448 }
449 return true;
450 }
451 });
452 }
453
454 @Test
455 public void testRegionMove() throws Exception {
456 LOG.info("testRegionMove");
457
458 final RSGroupInfo newGroup = addGroup(rsGroupAdmin, getGroupName("testRegionMove"), 1);
459 final TableName tableName = TableName.valueOf(tablePrefix + rand.nextInt());
460 final byte[] familyNameBytes = Bytes.toBytes("f");
461
462 TEST_UTIL.createMultiRegionTable(tableName, familyNameBytes, 6);
463 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
464 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
465 @Override
466 public boolean evaluate() throws Exception {
467 List<String> regions = getTableRegionMap().get(tableName);
468 if (regions == null)
469 return false;
470 return getTableRegionMap().get(tableName).size() >= 6;
471 }
472 });
473
474
475 Map<ServerName,List<String>> assignMap =
476 getTableServerRegionMap().get(tableName);
477 String targetRegion = null;
478 for(ServerName server : assignMap.keySet()) {
479 targetRegion = assignMap.get(server).size() > 0 ? assignMap.get(server).get(0) : null;
480 if(targetRegion != null) {
481 break;
482 }
483 }
484
485 ServerName targetServer = null;
486 for(ServerName server : admin.getClusterStatus().getServers()) {
487 if(!newGroup.containsServer(server.getHostPort())) {
488 targetServer = server;
489 break;
490 }
491 }
492
493 final AdminProtos.AdminService.BlockingInterface targetRS =
494 admin.getConnection().getAdmin(targetServer);
495
496
497 rsGroupAdmin.moveServers(Sets.newHashSet(targetServer.getHostPort()),
498 newGroup.getName());
499 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
500 @Override
501 public boolean evaluate() throws Exception {
502 return ProtobufUtil.getOnlineRegions(targetRS).size() <= 0;
503 }
504 });
505
506
507 TEST_UTIL.getHBaseAdmin().move(Bytes.toBytes(HRegionInfo.encodeRegionName(Bytes.toBytes(targetRegion))),
508 Bytes.toBytes(targetServer.getServerName()));
509 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
510 @Override
511 public boolean evaluate() throws Exception {
512 return
513 getTableRegionMap().get(tableName) != null &&
514 getTableRegionMap().get(tableName).size() == 6 &&
515 admin.getClusterStatus().getRegionsInTransition().size() < 1;
516 }
517 });
518
519
520 assertFalse(ProtobufUtil.getOnlineRegions(targetRS).contains(targetRegion));
521 }
522
523 @Test
524 public void testFailRemoveGroup() throws IOException, InterruptedException {
525 LOG.info("testFailRemoveGroup");
526
527 int initNumGroups = rsGroupAdmin.listRSGroups().size();
528 addGroup(rsGroupAdmin, "bar", 3);
529 TableName tableName = TableName.valueOf(tablePrefix+"_my_table");
530 TEST_UTIL.createTable(tableName, Bytes.toBytes("f"));
531 rsGroupAdmin.moveTables(Sets.newHashSet(tableName), "bar");
532 RSGroupInfo barGroup = rsGroupAdmin.getRSGroupInfo("bar");
533
534 try {
535 rsGroupAdmin.removeRSGroup(barGroup.getName());
536 fail("Expected remove group to fail");
537 } catch(IOException e) {
538 }
539
540 try {
541 rsGroupAdmin.moveServers(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
542 fail("Expected move servers to fail");
543 } catch(IOException e) {
544 }
545
546 rsGroupAdmin.moveTables(barGroup.getTables(), RSGroupInfo.DEFAULT_GROUP);
547 try {
548 rsGroupAdmin.removeRSGroup(barGroup.getName());
549 fail("Expected move servers to fail");
550 } catch(IOException e) {
551 }
552
553 rsGroupAdmin.moveServers(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
554 rsGroupAdmin.removeRSGroup(barGroup.getName());
555
556 Assert.assertEquals(initNumGroups, rsGroupAdmin.listRSGroups().size());
557 }
558
559
560 public void testKillRS() throws Exception {
561 LOG.info("testKillRS");
562 RSGroupInfo appInfo = addGroup(rsGroupAdmin, "appInfo", 1);
563
564
565 final TableName tableName = TableName.valueOf(tablePrefix+"_ns", "_testKillRS");
566 admin.createNamespace(
567 NamespaceDescriptor.create(tableName.getNamespaceAsString())
568 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, appInfo.getName()).build());
569 final HTableDescriptor desc = new HTableDescriptor(tableName);
570 desc.addFamily(new HColumnDescriptor("f"));
571 admin.createTable(desc);
572
573 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
574 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
575 @Override
576 public boolean evaluate() throws Exception {
577 return getTableRegionMap().get(desc.getTableName()) != null;
578 }
579 });
580
581 ServerName targetServer = ServerName.parseServerName(
582 appInfo.getServers().iterator().next().toString());
583 AdminProtos.AdminService.BlockingInterface targetRS =
584 admin.getConnection().getAdmin(targetServer);
585 HRegionInfo targetRegion = ProtobufUtil.getOnlineRegions(targetRS).get(0);
586 Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(targetRS).size());
587
588 try {
589
590
591 targetRS.stopServer(null,
592 AdminProtos.StopServerRequest.newBuilder().setReason("Die").build());
593 } catch(Exception e) {
594 }
595 assertFalse(cluster.getClusterStatus().getServers().contains(targetServer));
596
597
598 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
599 @Override
600 public boolean evaluate() throws Exception {
601 return cluster.getClusterStatus().getRegionsInTransition().size() == 0;
602 }
603 });
604 Set<HostAndPort> newServers = Sets.newHashSet();
605 newServers.add(
606 rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getServers().iterator().next());
607 rsGroupAdmin.moveServers(newServers, appInfo.getName());
608
609
610
611 admin.disableTable(tableName);
612 admin.enableTable(tableName);
613
614
615 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
616 @Override
617 public boolean evaluate() throws Exception {
618 return cluster.getClusterStatus().getRegionsInTransition().size() == 0;
619 }
620 });
621
622 targetServer = ServerName.parseServerName(
623 newServers.iterator().next().toString());
624 targetRS =
625 admin.getConnection().getAdmin(targetServer);
626 Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(targetRS).size());
627 Assert.assertEquals(tableName,
628 ProtobufUtil.getOnlineRegions(targetRS).get(0).getTable());
629 }
630
631 @Test
632 public void testValidGroupNames() throws IOException {
633 String[] badNames = {"foo*","foo@","-"};
634 String[] goodNames = {"foo_123"};
635
636 for(String entry: badNames) {
637 try {
638 rsGroupAdmin.addRSGroup(entry);
639 fail("Expected a constraint exception for: "+entry);
640 } catch(ConstraintException ex) {
641
642 }
643 }
644
645 for(String entry: goodNames) {
646 rsGroupAdmin.addRSGroup(entry);
647 }
648 }
649
650 private String getGroupName(String baseName) {
651 return groupPrefix+"_"+baseName+"_"+rand.nextInt(Integer.MAX_VALUE);
652 }
653
654 @Test
655 public void testMultiTableMove() throws Exception {
656 LOG.info("testMultiTableMove");
657
658 final TableName tableNameA = TableName.valueOf(tablePrefix + "_testMultiTableMoveA");
659 final TableName tableNameB = TableName.valueOf(tablePrefix + "_testMultiTableMoveB");
660 final byte[] familyNameBytes = Bytes.toBytes("f");
661 String newGroupName = getGroupName("testMultiTableMove");
662 final RSGroupInfo newGroup = addGroup(rsGroupAdmin, newGroupName, 1);
663
664 TEST_UTIL.createTable(tableNameA, familyNameBytes);
665 TEST_UTIL.createTable(tableNameB, familyNameBytes);
666 TEST_UTIL.waitFor(60000, new Waiter.Predicate<Exception>() {
667 @Override
668 public boolean evaluate() throws Exception {
669 List<String> regionsA = getTableRegionMap().get(tableNameA);
670 if (regionsA == null)
671 return false;
672 List<String> regionsB = getTableRegionMap().get(tableNameB);
673 if (regionsB == null)
674 return false;
675
676 return getTableRegionMap().get(tableNameA).size() >= 1
677 && getTableRegionMap().get(tableNameB).size() >= 1;
678 }
679 });
680
681 RSGroupInfo tableGrpA = rsGroupAdmin.getRSGroupInfoOfTable(tableNameA);
682 assertTrue(tableGrpA.getName().equals(RSGroupInfo.DEFAULT_GROUP));
683
684 RSGroupInfo tableGrpB = rsGroupAdmin.getRSGroupInfoOfTable(tableNameB);
685 assertTrue(tableGrpB.getName().equals(RSGroupInfo.DEFAULT_GROUP));
686
687 LOG.info("Moving table [" + tableNameA + "," + tableNameB + "] to " + newGroup.getName());
688 rsGroupAdmin.moveTables(Sets.newHashSet(tableNameA, tableNameB), newGroup.getName());
689
690
691 Assert.assertEquals(newGroup.getName(),
692 rsGroupAdmin.getRSGroupInfoOfTable(tableNameA).getName());
693
694 Assert.assertEquals(newGroup.getName(),
695 rsGroupAdmin.getRSGroupInfoOfTable(tableNameB).getName());
696
697
698 Set<TableName> DefaultTables = rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables();
699 assertFalse(DefaultTables.contains(tableNameA));
700 assertFalse(DefaultTables.contains(tableNameB));
701
702
703 Set<TableName> newGroupTables = rsGroupAdmin.getRSGroupInfo(newGroupName).getTables();
704 assertTrue(newGroupTables.contains(tableNameA));
705 assertTrue(newGroupTables.contains(tableNameB));
706 }
707 }