HBASE-24033 Add ut for loading the corrupt recovered hfiles (#1322)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / wal / TestWALRootDir.java
blob6ea1daf47a6a05df2f44b2b7fbcc20128e7b8b0b
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.wal;
20 import static org.junit.Assert.assertEquals;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.fs.FileStatus;
28 import org.apache.hadoop.fs.FileSystem;
29 import org.apache.hadoop.fs.Path;
30 import org.apache.hadoop.hbase.HBaseClassTestRule;
31 import org.apache.hadoop.hbase.HBaseTestingUtility;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.KeyValue;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.client.RegionInfo;
36 import org.apache.hadoop.hbase.client.RegionInfoBuilder;
37 import org.apache.hadoop.hbase.regionserver.MultiVersionConcurrencyControl;
38 import org.apache.hadoop.hbase.testclassification.MediumTests;
39 import org.apache.hadoop.hbase.util.Bytes;
40 import org.apache.hadoop.hbase.util.FSUtils;
41 import org.junit.AfterClass;
42 import org.junit.Before;
43 import org.junit.BeforeClass;
44 import org.junit.ClassRule;
45 import org.junit.Test;
46 import org.junit.experimental.categories.Category;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 @Category(MediumTests.class)
51 public class TestWALRootDir {
53 @ClassRule
54 public static final HBaseClassTestRule CLASS_RULE =
55 HBaseClassTestRule.forClass(TestWALRootDir.class);
57 private static final Logger LOG = LoggerFactory.getLogger(TestWALRootDir.class);
58 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
59 private static Configuration conf;
60 private static FileSystem fs;
61 private static FileSystem walFs;
62 private static final TableName tableName = TableName.valueOf("TestWALWALDir");
63 private static final byte [] rowName = Bytes.toBytes("row");
64 private static final byte [] family = Bytes.toBytes("column");
65 private static Path walRootDir;
66 private static Path rootDir;
67 private static WALFactory wals;
69 @Before
70 public void setUp() throws Exception {
71 cleanup();
74 @BeforeClass
75 public static void setUpBeforeClass() throws Exception {
76 conf = TEST_UTIL.getConfiguration();
77 TEST_UTIL.startMiniDFSCluster(1);
78 rootDir = TEST_UTIL.createRootDir();
79 walRootDir = TEST_UTIL.createWALRootDir();
80 fs = FSUtils.getRootDirFileSystem(conf);
81 walFs = FSUtils.getWALFileSystem(conf);
84 @AfterClass
85 public static void tearDownAfterClass() throws Exception {
86 cleanup();
87 TEST_UTIL.shutdownMiniDFSCluster();
90 @Test
91 public void testWALRootDir() throws Exception {
92 RegionInfo regionInfo = RegionInfoBuilder.newBuilder(tableName).build();
93 wals = new WALFactory(conf, "testWALRootDir");
94 WAL log = wals.getWAL(regionInfo);
96 assertEquals(1, getWALFiles(walFs, walRootDir).size());
97 byte [] value = Bytes.toBytes("value");
98 WALEdit edit = new WALEdit();
99 edit.add(new KeyValue(rowName, family, Bytes.toBytes("1"),
100 System.currentTimeMillis(), value));
101 long txid =
102 log.appendData(regionInfo, getWalKey(System.currentTimeMillis(), regionInfo, 0), edit);
103 log.sync(txid);
104 assertEquals("Expect 1 log have been created", 1,
105 getWALFiles(walFs, walRootDir).size());
106 log.rollWriter();
107 //Create 1 more WAL
108 assertEquals(2, getWALFiles(walFs, new Path(walRootDir,
109 HConstants.HREGION_LOGDIR_NAME)).size());
110 edit.add(new KeyValue(rowName, family, Bytes.toBytes("2"),
111 System.currentTimeMillis(), value));
112 txid = log.appendData(regionInfo, getWalKey(System.currentTimeMillis(), regionInfo, 1), edit);
113 log.sync(txid);
114 log.rollWriter();
115 log.shutdown();
117 assertEquals("Expect 3 logs in WALs dir", 3, getWALFiles(walFs,
118 new Path(walRootDir, HConstants.HREGION_LOGDIR_NAME)).size());
121 private WALKeyImpl getWalKey(final long time, RegionInfo hri, final long startPoint) {
122 return new WALKeyImpl(hri.getEncodedNameAsBytes(), tableName, time,
123 new MultiVersionConcurrencyControl(startPoint));
126 private List<FileStatus> getWALFiles(FileSystem fs, Path dir)
127 throws IOException {
128 List<FileStatus> result = new ArrayList<FileStatus>();
129 LOG.debug("Scanning " + dir.toString() + " for WAL files");
131 FileStatus[] files = fs.listStatus(dir);
132 if (files == null) return Collections.emptyList();
133 for (FileStatus file : files) {
134 if (file.isDirectory()) {
135 // recurse into sub directories
136 result.addAll(getWALFiles(fs, file.getPath()));
137 } else {
138 String name = file.getPath().toString();
139 if (!name.startsWith(".")) {
140 result.add(file);
144 return result;
147 private static void cleanup() throws Exception{
148 walFs.delete(walRootDir, true);
149 fs.delete(rootDir, true);