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