HBASE-26416 Implement a new method for region replication instead of using replay...
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / util / HFileArchiveTestingUtil.java
blob4835d2f12b06901e3a4dfebad486cea1b2de2cef
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.util;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNull;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.fs.FileStatus;
30 import org.apache.hadoop.fs.FileSystem;
31 import org.apache.hadoop.fs.Path;
32 import org.apache.hadoop.hbase.HBaseTestingUtil;
33 import org.apache.hadoop.hbase.regionserver.HRegion;
34 import org.apache.hadoop.hbase.regionserver.Store;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 /**
39 * Test helper for testing archiving of HFiles
41 public class HFileArchiveTestingUtil {
43 private static final Logger LOG = LoggerFactory.getLogger(HFileArchiveTestingUtil.class);
45 private HFileArchiveTestingUtil() {
46 // NOOP private ctor since this is just a utility class
49 public static boolean compareArchiveToOriginal(FileStatus[] previous, FileStatus[] archived,
50 FileSystem fs, boolean hasTimedBackup) {
52 List<List<String>> lists = getFileLists(previous, archived);
53 List<String> original = lists.get(0);
54 Collections.sort(original);
56 List<String> currentFiles = lists.get(1);
57 Collections.sort(currentFiles);
59 List<String> backedup = lists.get(2);
60 Collections.sort(backedup);
62 // check the backed up files versus the current (should match up, less the
63 // backup time in the name)
64 if (!hasTimedBackup == (backedup.size() > 0)) {
65 LOG.debug("backedup files doesn't match expected.");
66 return false;
68 String msg = null;
69 if (hasTimedBackup) {
70 msg = assertArchiveEquality(original, backedup);
71 if (msg != null) {
72 LOG.debug(msg);
73 return false;
76 msg = assertArchiveEquality(original, currentFiles);
77 if (msg != null) {
78 LOG.debug(msg);
79 return false;
81 return true;
84 /**
85 * Compare the archived files to the files in the original directory
86 * @param expected original files that should have been archived
87 * @param actual files that were archived
88 * @param fs filessystem on which the archiving took place
89 * @throws IOException
91 public static void assertArchiveEqualToOriginal(FileStatus[] expected, FileStatus[] actual,
92 FileSystem fs) throws IOException {
93 assertArchiveEqualToOriginal(expected, actual, fs, false);
96 /**
97 * Compare the archived files to the files in the original directory
98 * @param expected original files that should have been archived
99 * @param actual files that were archived
100 * @param fs {@link FileSystem} on which the archiving took place
101 * @param hasTimedBackup <tt>true</tt> if we expect to find an archive backup directory with a
102 * copy of the files in the archive directory (and the original files).
103 * @throws IOException
105 public static void assertArchiveEqualToOriginal(FileStatus[] expected, FileStatus[] actual,
106 FileSystem fs, boolean hasTimedBackup) throws IOException {
108 List<List<String>> lists = getFileLists(expected, actual);
109 List<String> original = lists.get(0);
110 Collections.sort(original);
112 List<String> currentFiles = lists.get(1);
113 Collections.sort(currentFiles);
115 List<String> backedup = lists.get(2);
116 Collections.sort(backedup);
118 // check the backed up files versus the current (should match up, less the
119 // backup time in the name)
120 assertEquals("Didn't expect any backup files, but got: " + backedup, hasTimedBackup,
121 backedup.size() > 0);
122 String msg = null;
123 if (hasTimedBackup) {
124 assertArchiveEquality(original, backedup);
125 assertNull(msg, msg);
128 // do the rest of the comparison
129 msg = assertArchiveEquality(original, currentFiles);
130 assertNull(msg, msg);
133 private static String assertArchiveEquality(List<String> expected, List<String> archived) {
134 String compare = compareFileLists(expected, archived);
135 if (!(expected.size() == archived.size())) return "Not the same number of current files\n"
136 + compare;
137 if (!expected.equals(archived)) return "Different backup files, but same amount\n" + compare;
138 return null;
142 * @return &lt;expected, gotten, backup&gt;, where each is sorted
144 private static List<List<String>> getFileLists(FileStatus[] previous, FileStatus[] archived) {
145 List<List<String>> files = new ArrayList<>(3);
147 // copy over the original files
148 List<String> originalFileNames = convertToString(previous);
149 files.add(originalFileNames);
151 List<String> currentFiles = new ArrayList<>(previous.length);
152 List<FileStatus> backedupFiles = new ArrayList<>(previous.length);
153 for (FileStatus f : archived) {
154 String name = f.getPath().getName();
155 // if the file has been backed up
156 if (name.contains(".")) {
157 Path parent = f.getPath().getParent();
158 String shortName = name.split("[.]")[0];
159 Path modPath = new Path(parent, shortName);
160 FileStatus file = new FileStatus(f.getLen(), f.isDirectory(), f.getReplication(),
161 f.getBlockSize(), f.getModificationTime(), modPath);
162 backedupFiles.add(file);
163 } else {
164 // otherwise, add it to the list to compare to the original store files
165 currentFiles.add(name);
169 files.add(currentFiles);
170 files.add(convertToString(backedupFiles));
171 return files;
174 private static List<String> convertToString(FileStatus[] files) {
175 return convertToString(Arrays.asList(files));
178 private static List<String> convertToString(List<FileStatus> files) {
179 List<String> originalFileNames = new ArrayList<>(files.size());
180 for (FileStatus f : files) {
181 originalFileNames.add(f.getPath().getName());
183 return originalFileNames;
186 /* Get a pretty representation of the differences */
187 private static String compareFileLists(List<String> expected, List<String> gotten) {
188 StringBuilder sb = new StringBuilder("Expected (" + expected.size() + "): \t\t Gotten ("
189 + gotten.size() + "):\n");
190 List<String> notFound = new ArrayList<>();
191 for (String s : expected) {
192 if (gotten.contains(s)) sb.append(s + "\t\t" + s + "\n");
193 else notFound.add(s);
195 sb.append("Not Found:\n");
196 for (String s : notFound) {
197 sb.append(s + "\n");
199 sb.append("\nExtra:\n");
200 for (String s : gotten) {
201 if (!expected.contains(s)) sb.append(s + "\n");
203 return sb.toString();
207 * Helper method to get the archive directory for the specified region
208 * @param conf {@link Configuration} to check for the name of the archive directory
209 * @param region region that is being archived
210 * @return {@link Path} to the archive directory for the given region
212 public static Path getRegionArchiveDir(Configuration conf, HRegion region) throws IOException {
213 return HFileArchiveUtil.getRegionArchiveDir(CommonFSUtils.getRootDir(conf),
214 region.getTableDescriptor().getTableName(), region.getRegionInfo().getEncodedName());
218 * Helper method to get the store archive directory for the specified region
219 * @param conf {@link Configuration} to check for the name of the archive directory
220 * @param region region that is being archived
221 * @param store store that is archiving files
222 * @return {@link Path} to the store archive directory for the given region
224 public static Path getStoreArchivePath(Configuration conf, HRegion region, Store store)
225 throws IOException {
226 return HFileArchiveUtil.getStoreArchivePath(conf, region.getRegionInfo(),
227 region.getRegionFileSystem().getTableDir(), store.getColumnFamilyDescriptor().getName());
230 public static Path getStoreArchivePath(HBaseTestingUtil util, String tableName,
231 byte[] storeName) throws IOException {
232 byte[] table = Bytes.toBytes(tableName);
233 // get the RS and region serving our table
234 List<HRegion> servingRegions = util.getHBaseCluster().getRegions(table);
235 HRegion region = servingRegions.get(0);
237 // check that we actually have some store files that were archived
238 Store store = region.getStore(storeName);
239 return HFileArchiveTestingUtil.getStoreArchivePath(util.getConfiguration(), region, store);