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.catalog;
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26
27 import java.io.IOException;
28 import java.util.List;
29 import java.util.concurrent.atomic.AtomicBoolean;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.Abortable;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.HConstants;
37 import org.apache.hadoop.hbase.HRegionInfo;
38 import org.apache.hadoop.hbase.ServerName;
39 import org.apache.hadoop.hbase.client.HBaseAdmin;
40 import org.apache.hadoop.hbase.client.HTable;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.apache.hadoop.hbase.util.Pair;
43 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
44 import org.junit.AfterClass;
45 import org.junit.Before;
46 import org.junit.BeforeClass;
47 import org.junit.Test;
48
49
50
51
52 public class TestMetaReaderEditor {
53 private static final Log LOG = LogFactory.getLog(TestMetaReaderEditor.class);
54 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
55 private ZooKeeperWatcher zkw;
56 private CatalogTracker ct;
57 private final static Abortable ABORTABLE = new Abortable() {
58 private final AtomicBoolean abort = new AtomicBoolean(false);
59
60 @Override
61 public void abort(String why, Throwable e) {
62 LOG.info(why, e);
63 abort.set(true);
64 }
65
66 @Override
67 public boolean isAborted() {
68 return abort.get();
69 }
70
71 };
72
73 @BeforeClass public static void beforeClass() throws Exception {
74 UTIL.startMiniCluster(3);
75 }
76
77 @Before public void setup() throws IOException, InterruptedException {
78 Configuration c = new Configuration(UTIL.getConfiguration());
79
80
81 c.setLong("hbase.client.pause", 1000);
82 c.setInt("hbase.client.retries.number", 10);
83 zkw = new ZooKeeperWatcher(c, "TestMetaReaderEditor", ABORTABLE);
84 ct = new CatalogTracker(zkw, c, ABORTABLE);
85 ct.start();
86 }
87
88 @AfterClass public static void afterClass() throws Exception {
89 UTIL.shutdownMiniCluster();
90 }
91
92
93
94
95
96
97
98
99 @Test (timeout = 180000) public void testRetrying()
100 throws IOException, InterruptedException {
101 final String name = "testRetrying";
102 LOG.info("Started " + name);
103 final byte [] nameBytes = Bytes.toBytes(name);
104 HTable t = UTIL.createTable(nameBytes, HConstants.CATALOG_FAMILY);
105 int regionCount = UTIL.createMultiRegions(t, HConstants.CATALOG_FAMILY);
106
107 final List<HRegionInfo> regions =
108 testGettingTableRegions(this.ct, nameBytes, regionCount);
109 MetaTask reader = new MetaTask(this.ct, "reader") {
110 @Override
111 void metaTask() throws Throwable {
112 testGetRegion(this.ct, regions.get(0));
113 LOG.info("Read " + regions.get(0).getEncodedName());
114 }
115 };
116 MetaTask writer = new MetaTask(this.ct, "writer") {
117 @Override
118 void metaTask() throws Throwable {
119 MetaEditor.addRegionToMeta(this.ct, regions.get(0));
120 LOG.info("Wrote " + regions.get(0).getEncodedName());
121 }
122 };
123 reader.start();
124 writer.start();
125
126 assertTrue(reader.isProgressing());
127 assertTrue(writer.isProgressing());
128
129
130 for (int i = 0; i < 2; i++) {
131 LOG.info("Restart=" + i);
132 UTIL.ensureSomeRegionServersAvailable(2);
133 int index = -1;
134 do {
135 index = UTIL.getMiniHBaseCluster().getServerWithMeta();
136 } while (index == -1);
137 UTIL.getMiniHBaseCluster().abortRegionServer(index);
138 UTIL.getMiniHBaseCluster().waitOnRegionServer(index);
139 }
140 assertTrue(reader.toString(), reader.isProgressing());
141 assertTrue(writer.toString(), writer.isProgressing());
142 reader.stop = true;
143 writer.stop = true;
144 reader.join();
145 writer.join();
146 }
147
148
149
150
151 abstract static class MetaTask extends Thread {
152 boolean stop = false;
153 int count = 0;
154 Throwable t = null;
155 final CatalogTracker ct;
156
157 MetaTask(final CatalogTracker ct, final String name) {
158 super(name);
159 this.ct = ct;
160 }
161
162 @Override
163 public void run() {
164 try {
165 while(!this.stop) {
166 LOG.info("Before " + this.getName()+ ", count=" + this.count);
167 metaTask();
168 this.count += 1;
169 LOG.info("After " + this.getName() + ", count=" + this.count);
170 Thread.sleep(100);
171 }
172 } catch (Throwable t) {
173 LOG.info(this.getName() + " failed", t);
174 this.t = t;
175 }
176 }
177
178 boolean isProgressing() throws InterruptedException {
179 int currentCount = this.count;
180 while(currentCount == this.count) {
181 if (!isAlive()) return false;
182 if (this.t != null) return false;
183 Thread.sleep(10);
184 }
185 return true;
186 }
187
188 @Override
189 public String toString() {
190 return "count=" + this.count + ", t=" +
191 (this.t == null? "null": this.t.toString());
192 }
193
194 abstract void metaTask() throws Throwable;
195 }
196
197 @Test public void testGetRegionsCatalogTables()
198 throws IOException, InterruptedException {
199 List<HRegionInfo> regions =
200 MetaReader.getTableRegions(ct, HConstants.META_TABLE_NAME);
201 assertTrue(regions.size() >= 1);
202 assertTrue(MetaReader.getTableRegionsAndLocations(ct,
203 Bytes.toString(HConstants.META_TABLE_NAME)).size() >= 1);
204 assertTrue(MetaReader.getTableRegionsAndLocations(ct,
205 Bytes.toString(HConstants.ROOT_TABLE_NAME)).size() == 1);
206 }
207
208 @Test public void testTableExists() throws IOException {
209 final String name = "testTableExists";
210 final byte [] nameBytes = Bytes.toBytes(name);
211 assertFalse(MetaReader.tableExists(ct, name));
212 UTIL.createTable(nameBytes, HConstants.CATALOG_FAMILY);
213 assertTrue(MetaReader.tableExists(ct, name));
214 HBaseAdmin admin = UTIL.getHBaseAdmin();
215 admin.disableTable(name);
216 admin.deleteTable(name);
217 assertFalse(MetaReader.tableExists(ct, name));
218 assertTrue(MetaReader.tableExists(ct,
219 Bytes.toString(HConstants.META_TABLE_NAME)));
220 assertTrue(MetaReader.tableExists(ct,
221 Bytes.toString(HConstants.ROOT_TABLE_NAME)));
222 }
223
224 @Test public void testGetRegion() throws IOException, InterruptedException {
225 final String name = "testGetRegion";
226 LOG.info("Started " + name);
227
228 Pair<HRegionInfo, ServerName> pair =
229 MetaReader.getRegion(ct, Bytes.toBytes("nonexistent-region"));
230 assertNull(pair);
231
232 pair =
233 MetaReader.getRegion(ct, HRegionInfo.FIRST_META_REGIONINFO.getRegionName());
234 assertEquals(HRegionInfo.FIRST_META_REGIONINFO.getEncodedName(),
235 pair.getFirst().getEncodedName());
236 LOG.info("Finished " + name);
237 }
238
239
240 @Test public void testScanMetaForTable()
241 throws IOException, InterruptedException {
242 final String name = "testScanMetaForTable";
243 LOG.info("Started " + name);
244
245
246
247
248
249
250
251
252
253 UTIL.createTable(Bytes.toBytes(name), HConstants.CATALOG_FAMILY);
254 for (int i = 3; i < 3; i ++) {
255 UTIL.createTable(Bytes.toBytes(name+i), HConstants.CATALOG_FAMILY);
256 }
257
258 byte[] greaterName = Bytes.toBytes("testScanMetaForTablf");
259 UTIL.createTable(greaterName, HConstants.CATALOG_FAMILY);
260
261
262
263 assertEquals(1, MetaReader.getTableRegions(ct, Bytes.toBytes(name)).size());
264 for (int i = 3; i < 3; i ++) {
265 assertEquals(1, MetaReader.getTableRegions(ct, Bytes.toBytes(name+i)).size());
266 }
267 assertEquals(1, MetaReader.getTableRegions(ct, greaterName).size());
268 }
269
270 private static List<HRegionInfo> testGettingTableRegions(final CatalogTracker ct,
271 final byte [] nameBytes, final int regionCount)
272 throws IOException, InterruptedException {
273 List<HRegionInfo> regions = MetaReader.getTableRegions(ct, nameBytes);
274 assertEquals(regionCount, regions.size());
275 Pair<HRegionInfo, ServerName> pair =
276 MetaReader.getRegion(ct, regions.get(0).getRegionName());
277 assertEquals(regions.get(0).getEncodedName(),
278 pair.getFirst().getEncodedName());
279 return regions;
280 }
281
282 private static void testGetRegion(final CatalogTracker ct,
283 final HRegionInfo region)
284 throws IOException, InterruptedException {
285 Pair<HRegionInfo, ServerName> pair =
286 MetaReader.getRegion(ct, region.getRegionName());
287 assertEquals(region.getEncodedName(),
288 pair.getFirst().getEncodedName());
289 }
290 }