View Javadoc

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
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
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.
17   */
18  
19  package org.apache.hadoop.hbase.util.compaction;
20  
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertTrue;
23  
24  import static org.mockito.Matchers.anyString;
25  import static org.mockito.Matchers.eq;
26  import static org.mockito.Matchers.isA;
27  import static org.mockito.Mockito.doReturn;
28  import static org.mockito.Mockito.mock;
29  import static org.mockito.Mockito.spy;
30  import static org.mockito.Mockito.when;
31  
32  import com.google.common.base.Optional;
33  import com.google.common.collect.Lists;
34  import com.google.common.collect.Sets;
35  
36  import java.io.IOException;
37  import java.util.List;
38  
39  import org.apache.commons.lang.RandomStringUtils;
40  import org.apache.hadoop.conf.Configuration;
41  import org.apache.hadoop.fs.FileStatus;
42  import org.apache.hadoop.fs.FileSystem;
43  import org.apache.hadoop.fs.Path;
44  import org.apache.hadoop.hbase.HBaseTestingUtility;
45  import org.apache.hadoop.hbase.HRegionInfo;
46  import org.apache.hadoop.hbase.TableName;
47  import org.apache.hadoop.hbase.client.Connection;
48  import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
49  import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
50  import org.apache.hadoop.hbase.testclassification.SmallTests;
51  import org.junit.Before;
52  import org.junit.Test;
53  import org.junit.experimental.categories.Category;
54  
55  @Category({SmallTests.class})
56  public class TestMajorCompactionTTLRequest {
57  
58    private static final HBaseTestingUtility UTILITY = new HBaseTestingUtility();
59    private static final String FAMILY = "a";
60    private Path regionStoreDir;
61  
62    @Before
63    public void setUp() throws Exception {
64      Path rootRegionDir = UTILITY.getDataTestDirOnTestFS("TestMajorCompactionTTLRequest");
65      regionStoreDir = new Path(rootRegionDir, FAMILY);
66    }
67  
68    @Test
69    public void testStoresNeedingCompaction() throws Exception {
70      // store files older than timestamp 10
71      List<StoreFileInfo> storeFiles1 = mockStoreFiles(regionStoreDir, 5, 10);
72      // store files older than timestamp 100
73      List<StoreFileInfo> storeFiles2 = mockStoreFiles(regionStoreDir, 5, 100);
74      List<StoreFileInfo> storeFiles = Lists.newArrayList(storeFiles1);
75      storeFiles.addAll(storeFiles2);
76  
77      MajorCompactionTTLRequest request = makeMockRequest(storeFiles);
78      // All files are <= 100, so region should not be compacted.
79      Optional<MajorCompactionRequest> result =
80          request.createRequest(mock(Configuration.class), Sets.newHashSet(FAMILY), 10);
81      assertFalse(result.isPresent());
82  
83      // All files are <= 100, so region should not be compacted yet.
84      result = request.createRequest(mock(Configuration.class), Sets.newHashSet(FAMILY), 100);
85      assertFalse(result.isPresent());
86  
87      // All files are <= 100, so they should be considered for compaction
88      result = request.createRequest(mock(Configuration.class), Sets.newHashSet(FAMILY), 101);
89      assertTrue(result.isPresent());
90    }
91  
92    private MajorCompactionTTLRequest makeMockRequest(List<StoreFileInfo> storeFiles)
93        throws IOException {
94      Configuration configuration = mock(Configuration.class);
95      HRegionInfo regionInfo = mock(HRegionInfo.class);
96      when(regionInfo.getEncodedName()).thenReturn("HBase");
97      when(regionInfo.getTable()).thenReturn(TableName.valueOf("foo"));
98      MajorCompactionTTLRequest request = new MajorCompactionTTLRequest(configuration, regionInfo);
99      MajorCompactionTTLRequest spy = spy(request);
100     HRegionFileSystem fileSystem = mockFileSystem(regionInfo, false, storeFiles);
101     doReturn(fileSystem).when(spy).getFileSystem(isA(Connection.class));
102     doReturn(mock(Connection.class)).when(spy).getConnection(eq(configuration));
103     return spy;
104   }
105 
106   private HRegionFileSystem mockFileSystem(HRegionInfo info, boolean hasReferenceFiles,
107       List<StoreFileInfo> storeFiles) throws IOException {
108     Optional<StoreFileInfo> found = Optional.absent();
109     for (StoreFileInfo storeFile : storeFiles) {
110       found = Optional.of(storeFile);
111       break;
112     }
113     long timestamp = found.get().getModificationTime();
114     return mockFileSystem(info, hasReferenceFiles, storeFiles, timestamp);
115   }
116 
117   private List<StoreFileInfo> mockStoreFiles(Path regionStoreDir, int howMany, long timestamp)
118       throws IOException {
119     List<StoreFileInfo> infos = Lists.newArrayList();
120     int i = 0;
121     while (i < howMany) {
122       StoreFileInfo storeFileInfo = mock(StoreFileInfo.class);
123       doReturn(timestamp).doReturn(timestamp).when(storeFileInfo).getModificationTime();
124       doReturn(new Path(regionStoreDir, RandomStringUtils.randomAlphabetic(10))).when(storeFileInfo)
125           .getPath();
126       infos.add(storeFileInfo);
127       i++;
128     }
129     return infos;
130   }
131 
132   private HRegionFileSystem mockFileSystem(HRegionInfo info, boolean hasReferenceFiles,
133       List<StoreFileInfo> storeFiles, long referenceFileTimestamp) throws IOException {
134     FileSystem fileSystem = mock(FileSystem.class);
135     if (hasReferenceFiles) {
136       FileStatus fileStatus = mock(FileStatus.class);
137       doReturn(referenceFileTimestamp).when(fileStatus).getModificationTime();
138       doReturn(fileStatus).when(fileSystem).getFileLinkStatus(isA(Path.class));
139     }
140     HRegionFileSystem mockSystem = mock(HRegionFileSystem.class);
141     doReturn(info).when(mockSystem).getRegionInfo();
142     doReturn(regionStoreDir).when(mockSystem).getStoreDir(FAMILY);
143     doReturn(hasReferenceFiles).when(mockSystem).hasReferences(anyString());
144     doReturn(storeFiles).when(mockSystem).getStoreFiles(anyString());
145     doReturn(fileSystem).when(mockSystem).getFileSystem();
146     return mockSystem;
147   }
148 }