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.master;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.hadoop.hbase.HConstants;
25 import org.apache.hadoop.hbase.MiniHBaseCluster;
26 import org.apache.hadoop.hbase.HBaseTestingUtility;
27 import org.apache.hadoop.hbase.HRegionInfo;
28 import org.apache.hadoop.hbase.HServerAddress;
29 import org.apache.hadoop.hbase.catalog.MetaReader;
30 import org.apache.hadoop.hbase.client.HBaseAdmin;
31 import org.apache.hadoop.hbase.client.HTable;
32 import org.apache.hadoop.hbase.executor.EventHandler;
33 import org.apache.hadoop.hbase.executor.EventHandler.EventHandlerListener;
34 import org.apache.hadoop.hbase.executor.EventHandler.EventType;
35 import org.apache.hadoop.hbase.util.Bytes;
36 import org.apache.hadoop.hbase.util.Pair;
37
38 import java.io.IOException;
39 import java.util.List;
40 import java.util.concurrent.CountDownLatch;
41 import java.util.concurrent.TimeUnit;
42
43 import org.junit.AfterClass;
44 import org.junit.BeforeClass;
45 import org.junit.Test;
46
47 import com.google.common.base.Joiner;
48
49 import static org.junit.Assert.*;
50
51 public class TestMaster {
52 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
53 private static final Log LOG = LogFactory.getLog(TestMaster.class);
54 private static final byte[] TABLENAME = Bytes.toBytes("TestMaster");
55 private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
56
57 @BeforeClass
58 public static void beforeAllTests() throws Exception {
59
60 TEST_UTIL.startMiniCluster(1);
61 }
62
63 @AfterClass
64 public static void afterAllTests() throws IOException {
65 TEST_UTIL.shutdownMiniCluster();
66 }
67
68 @Test
69 public void testMasterOpsWhileSplitting() throws Exception {
70 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
71 HMaster m = cluster.getMaster();
72 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
73
74 TEST_UTIL.createTable(TABLENAME, FAMILYNAME);
75 TEST_UTIL.loadTable(new HTable(TEST_UTIL.getConfiguration(), TABLENAME),
76 FAMILYNAME);
77
78 List<Pair<HRegionInfo, HServerAddress>> tableRegions =
79 MetaReader.getTableRegionsAndLocations(m.getCatalogTracker(),
80 Bytes.toString(TABLENAME));
81 LOG.info("Regions after load: " + Joiner.on(',').join(tableRegions));
82 assertEquals(1, tableRegions.size());
83 assertArrayEquals(HConstants.EMPTY_START_ROW,
84 tableRegions.get(0).getFirst().getStartKey());
85 assertArrayEquals(HConstants.EMPTY_END_ROW,
86 tableRegions.get(0).getFirst().getEndKey());
87
88
89
90 CountDownLatch aboutToOpen = new CountDownLatch(1);
91 CountDownLatch proceed = new CountDownLatch(1);
92 RegionOpenListener list = new RegionOpenListener(aboutToOpen, proceed);
93 cluster.getMaster().executorService.
94 registerListener(EventType.RS_ZK_REGION_OPENED, list);
95
96 LOG.info("Splitting table");
97 admin.split(TABLENAME);
98 LOG.info("Waiting for split result to be about to open");
99 aboutToOpen.await(60, TimeUnit.SECONDS);
100 try {
101 LOG.info("Making sure we can call getTableRegions while opening");
102 tableRegions = MetaReader.getTableRegionsAndLocations(
103 m.getCatalogTracker(), Bytes.toString(TABLENAME));
104
105 LOG.info("Regions: " + Joiner.on(',').join(tableRegions));
106
107 assertEquals(3, tableRegions.size());
108 LOG.info("Making sure we can call getTableRegionClosest while opening");
109 Pair<HRegionInfo,HServerAddress> pair =
110 m.getTableRegionForRow(TABLENAME, Bytes.toBytes("cde"));
111 LOG.info("Result is: " + pair);
112 Pair<HRegionInfo, HServerAddress> tableRegionFromName =
113 MetaReader.getRegion(m.getCatalogTracker(),
114 pair.getFirst().getRegionName());
115 assertEquals(tableRegionFromName.getFirst(), pair.getFirst());
116 } finally {
117 proceed.countDown();
118 }
119 }
120
121 static class RegionOpenListener implements EventHandlerListener {
122 CountDownLatch aboutToOpen, proceed;
123
124 public RegionOpenListener(CountDownLatch aboutToOpen, CountDownLatch proceed)
125 {
126 this.aboutToOpen = aboutToOpen;
127 this.proceed = proceed;
128 }
129
130 @Override
131 public void afterProcess(EventHandler event) {
132 if (event.getEventType() != EventType.RS_ZK_REGION_OPENED) {
133 return;
134 }
135 try {
136 aboutToOpen.countDown();
137 proceed.await(60, TimeUnit.SECONDS);
138 } catch (InterruptedException ie) {
139 throw new RuntimeException(ie);
140 }
141 return;
142 }
143
144 @Override
145 public void beforeProcess(EventHandler event) {
146 }
147 }
148 }