1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.util.compaction;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Set;
25 import com.google.common.base.Optional;
26 import com.google.common.collect.Iterables;
27 import com.google.common.collect.Lists;
28 import com.google.common.collect.Sets;
29 import org.apache.commons.lang.RandomStringUtils;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.fs.FileStatus;
32 import org.apache.hadoop.fs.FileSystem;
33 import org.apache.hadoop.fs.Path;
34 import org.apache.hadoop.hbase.HBaseTestingUtility;
35 import org.apache.hadoop.hbase.HRegionInfo;
36 import org.apache.hadoop.hbase.HTableDescriptor;
37 import org.apache.hadoop.hbase.TableName;
38 import org.apache.hadoop.hbase.client.Connection;
39 import org.apache.hadoop.hbase.regionserver.HRegion;
40 import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
41 import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
42 import org.apache.hadoop.hbase.testclassification.SmallTests;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import static org.junit.Assert.assertEquals;
45 import static org.junit.Assert.assertFalse;
46 import static org.junit.Assert.assertTrue;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.experimental.categories.Category;
50 import static org.mockito.Matchers.any;
51 import static org.mockito.Matchers.anyString;
52 import static org.mockito.Matchers.eq;
53 import static org.mockito.Matchers.isA;
54 import static org.mockito.Mockito.doReturn;
55 import static org.mockito.Mockito.mock;
56 import static org.mockito.Mockito.spy;
57 import static org.mockito.Mockito.when;
58
59 @Category({SmallTests.class})
60 public class MajorCompactionRequestTest {
61
62 protected static final HBaseTestingUtility UTILITY = new HBaseTestingUtility();
63 protected static final String FAMILY = "a";
64 protected Path rootRegionDir;
65 protected Path regionStoreDir;
66
67 @Before public void setUp() throws Exception {
68 rootRegionDir = UTILITY.getDataTestDirOnTestFS("MajorCompactionRequestTest");
69 regionStoreDir = new Path(rootRegionDir, FAMILY);
70 }
71
72 @Test public void testStoresNeedingCompaction() throws Exception {
73
74 List<StoreFileInfo> storeFiles = mockStoreFiles(regionStoreDir, 5, 10);
75 MajorCompactionRequest request = makeMockRequest(storeFiles, false);
76 Optional<MajorCompactionRequest> result =
77 request.createRequest(mock(Configuration.class), Sets.newHashSet(FAMILY), 100);
78 assertTrue(result.isPresent());
79
80
81 storeFiles = mockStoreFiles(regionStoreDir, 5, 101);
82 request = makeMockRequest(storeFiles, false);
83 result = request.createRequest(mock(Configuration.class), Sets.newHashSet(FAMILY), 100);
84 assertFalse(result.isPresent());
85 }
86
87 @Test public void testIfWeHaveNewReferenceFilesButOldStoreFiles() throws Exception {
88
89
90 TableName table = TableName.valueOf("MajorCompactorTest");
91 HTableDescriptor htd = UTILITY.createTableDescriptor(table, Bytes.toBytes(FAMILY));
92 HRegionInfo hri = new HRegionInfo(htd.getTableName());
93 HRegion region =
94 HBaseTestingUtility.createRegionAndWAL(hri, rootRegionDir, UTILITY.getRandomDir(),
95 UTILITY.getConfiguration(), htd);
96
97 Configuration configuration = mock(Configuration.class);
98
99 List<StoreFileInfo> storeFiles = mockStoreFiles(regionStoreDir, 4, 101);
100 List<Path> paths = new ArrayList<>();
101 for (StoreFileInfo storeFile : storeFiles) {
102 Path path = storeFile.getPath();
103 paths.add(path);
104 }
105
106 HRegionFileSystem fileSystem =
107 mockFileSystem(region.getRegionInfo(), true, storeFiles, 50);
108 MajorCompactionRequest majorCompactionRequest = spy(new MajorCompactionRequest(configuration,
109 region.getRegionInfo()));
110 doReturn(mock(Connection.class)).when(majorCompactionRequest).getConnection(eq(configuration));
111 doReturn(paths).when(majorCompactionRequest).getReferenceFilePaths(any(FileSystem.class),
112 any(Path.class));
113 doReturn(fileSystem).when(majorCompactionRequest).getFileSystem(any(Connection.class));
114 Set<String> result = majorCompactionRequest
115 .getStoresRequiringCompaction(Sets.newHashSet("a"), 100);
116 assertEquals(FAMILY, Iterables.getOnlyElement(result));
117 }
118
119 private HRegionFileSystem mockFileSystem(HRegionInfo info, boolean hasReferenceFiles,
120 List<StoreFileInfo> storeFiles) throws IOException {
121 Optional<StoreFileInfo> found = Optional.absent();
122 for (StoreFileInfo storeFile : storeFiles) {
123 found = Optional.of(storeFile);
124 break;
125 }
126 long timestamp = found.get().getModificationTime();
127 return mockFileSystem(info, hasReferenceFiles, storeFiles, timestamp);
128 }
129
130 private HRegionFileSystem mockFileSystem(HRegionInfo info, boolean hasReferenceFiles,
131 List<StoreFileInfo> storeFiles, long referenceFileTimestamp) throws IOException {
132 FileSystem fileSystem = mock(FileSystem.class);
133 if (hasReferenceFiles) {
134 FileStatus fileStatus = mock(FileStatus.class);
135 doReturn(referenceFileTimestamp).when(fileStatus).getModificationTime();
136 doReturn(fileStatus).when(fileSystem).getFileLinkStatus(isA(Path.class));
137 }
138 HRegionFileSystem mockSystem = mock(HRegionFileSystem.class);
139 doReturn(info).when(mockSystem).getRegionInfo();
140 doReturn(regionStoreDir).when(mockSystem).getStoreDir(FAMILY);
141 doReturn(hasReferenceFiles).when(mockSystem).hasReferences(anyString());
142 doReturn(storeFiles).when(mockSystem).getStoreFiles(anyString());
143 doReturn(fileSystem).when(mockSystem).getFileSystem();
144 return mockSystem;
145 }
146
147 List<StoreFileInfo> mockStoreFiles(Path regionStoreDir, int howMany, long timestamp)
148 throws IOException {
149 List<StoreFileInfo> infos = Lists.newArrayList();
150 int i = 0;
151 while (i < howMany) {
152 StoreFileInfo storeFileInfo = mock(StoreFileInfo.class);
153 doReturn(timestamp).doReturn(timestamp).when(storeFileInfo).getModificationTime();
154 doReturn(new Path(regionStoreDir, RandomStringUtils.randomAlphabetic(10))).when(storeFileInfo)
155 .getPath();
156 infos.add(storeFileInfo);
157 i++;
158 }
159 return infos;
160 }
161
162 private MajorCompactionRequest makeMockRequest(List<StoreFileInfo> storeFiles,
163 boolean references) throws IOException {
164 Configuration configuration = mock(Configuration.class);
165 HRegionInfo regionInfo = mock(HRegionInfo.class);
166 when(regionInfo.getEncodedName()).thenReturn("HBase");
167 when(regionInfo.getTable()).thenReturn(TableName.valueOf("foo"));
168 MajorCompactionRequest request =
169 new MajorCompactionRequest(configuration, regionInfo, Sets.newHashSet("a"));
170 MajorCompactionRequest spy = spy(request);
171 HRegionFileSystem fileSystem = mockFileSystem(regionInfo, references, storeFiles);
172 doReturn(fileSystem).when(spy).getFileSystem(isA(Connection.class));
173 doReturn(mock(Connection.class)).when(spy).getConnection(eq(configuration));
174 return spy;
175 }
176 }