1 /** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 package org.apache.hadoop.hbase.mapreduce; 20 21 import java.io.IOException; 22 import java.util.List; 23 24 import org.apache.hadoop.hbase.HRegionLocation; 25 import org.apache.hadoop.hbase.client.HTable; 26 import org.apache.hadoop.hbase.testclassification.LargeTests; 27 import org.junit.Test; 28 import org.junit.experimental.categories.Category; 29 30 /** 31 * TestTableInputFormatScan part 1. 32 * @see TestTableInputFormatScanBase 33 */ 34 @Category(LargeTests.class) 35 public class TestTableInputFormatScan1 extends TestTableInputFormatScanBase { 36 37 /** 38 * Tests a MR scan using specific start and stop rows. 39 * 40 * @throws IOException 41 * @throws ClassNotFoundException 42 * @throws InterruptedException 43 */ 44 @Test testScanEmptyToEmpty()45 public void testScanEmptyToEmpty() 46 throws IOException, InterruptedException, ClassNotFoundException { 47 testScan(null, null, null); 48 } 49 50 /** 51 * Tests a MR scan using specific start and stop rows. 52 * 53 * @throws IOException 54 * @throws ClassNotFoundException 55 * @throws InterruptedException 56 */ 57 @Test testScanEmptyToAPP()58 public void testScanEmptyToAPP() 59 throws IOException, InterruptedException, ClassNotFoundException { 60 testScan(null, "app", "apo"); 61 } 62 63 /** 64 * Tests a MR scan using specific start and stop rows. 65 * 66 * @throws IOException 67 * @throws ClassNotFoundException 68 * @throws InterruptedException 69 */ 70 @Test testScanEmptyToBBA()71 public void testScanEmptyToBBA() 72 throws IOException, InterruptedException, ClassNotFoundException { 73 testScan(null, "bba", "baz"); 74 } 75 76 /** 77 * Tests a MR scan using specific start and stop rows. 78 * 79 * @throws IOException 80 * @throws ClassNotFoundException 81 * @throws InterruptedException 82 */ 83 @Test testScanEmptyToBBB()84 public void testScanEmptyToBBB() 85 throws IOException, InterruptedException, ClassNotFoundException { 86 testScan(null, "bbb", "bba"); 87 } 88 89 /** 90 * Tests a MR scan using specific start and stop rows. 91 * 92 * @throws IOException 93 * @throws ClassNotFoundException 94 * @throws InterruptedException 95 */ 96 @Test testScanEmptyToOPP()97 public void testScanEmptyToOPP() 98 throws IOException, InterruptedException, ClassNotFoundException { 99 testScan(null, "opp", "opo"); 100 } 101 102 /** 103 * Tests a MR scan using specific number of mappers. The test table has 25 regions, 104 * and all region sizes are set as 0 as default. The average region size is 1 (the smallest 105 * positive). When we set hbase.mapreduce.input.ratio as -1, all regions will be cut into two 106 * MapRedcue input splits, the number of MR input splits should be 50; when we set hbase 107 * .mapreduce.input.ratio as 100, the sum of all region sizes is less then the average region 108 * size, all regions will be combined into 1 MapRedcue input split. 109 * 110 * @throws IOException 111 * @throws ClassNotFoundException 112 * @throws InterruptedException 113 */ 114 @Test testGetSplits()115 public void testGetSplits() throws IOException, InterruptedException, ClassNotFoundException { 116 HTable table = new HTable(TEST_UTIL.getConfiguration(), TABLE_NAME); 117 List<HRegionLocation> locs = table.getRegionLocator().getAllRegionLocations(); 118 119 testNumOfSplits("-1", locs.size()*2); 120 table.close(); 121 testNumOfSplits("100", 1); 122 } 123 124 /** 125 * Tests the getSplitKey() method in TableInputFormatBase.java 126 * 127 * @throws IOException 128 * @throws ClassNotFoundException 129 * @throws InterruptedException 130 */ 131 @Test testGetSplitsPoint()132 public void testGetSplitsPoint() throws IOException, InterruptedException, 133 ClassNotFoundException { 134 // Test Case 1: "aaabcdef" and "aaaff", split point is "aaad". 135 byte[] start1 = { 'a', 'a', 'a', 'b', 'c', 'd', 'e', 'f' }; 136 byte[] end1 = { 'a', 'a', 'a', 'f', 'f' }; 137 byte[] splitPoint1 = { 'a', 'a', 'a', 'd' }; 138 testGetSplitKey(start1, end1, splitPoint1, true); 139 140 // Test Case 2: "111000" and "1125790", split point is "111b". 141 byte[] start2 = { '1', '1', '1', '0', '0', '0' }; 142 byte[] end2 = { '1', '1', '2', '5', '7', '9', '0' }; 143 byte[] splitPoint2 = { '1', '1', '1', 'b' }; 144 testGetSplitKey(start2, end2, splitPoint2, true); 145 146 // Test Case 3: "aaaaaa" and "aab", split point is "aaap". 147 byte[] start3 = { 'a', 'a', 'a', 'a', 'a', 'a' }; 148 byte[] end3 = { 'a', 'a', 'b' }; 149 byte[] splitPoint3 = { 'a', 'a', 'a', 'p' }; 150 testGetSplitKey(start3, end3, splitPoint3, true); 151 152 // Test Case 4: "aaa" and "aaaz", split point is "aaaM". 153 byte[] start4 = { 'a', 'a', 'a' }; 154 byte[] end4 = { 'a', 'a', 'a', 'z' }; 155 byte[] splitPoint4 = { 'a', 'a', 'a', 'M' }; 156 testGetSplitKey(start4, end4, splitPoint4, true); 157 158 // Test Case 5: "aaa" and "aaba", split point is "aaap". 159 byte[] start5 = { 'a', 'a', 'a' }; 160 byte[] end5 = { 'a', 'a', 'b', 'a' }; 161 byte[] splitPoint5 = { 'a', 'a', 'a', 'p' }; 162 testGetSplitKey(start5, end5, splitPoint5, true); 163 164 // Test Case 6: empty key and "hhhqqqwww", split point is "h" 165 byte[] start6 = {}; 166 byte[] end6 = { 'h', 'h', 'h', 'q', 'q', 'q', 'w', 'w' }; 167 byte[] splitPoint6 = { 'h' }; 168 testGetSplitKey(start6, end6, splitPoint6, true); 169 170 // Test Case 7: "ffffaaa" and empty key, split point depends on the mode we choose(text key or 171 // binary key). 172 byte[] start7 = { 'f', 'f', 'f', 'f', 'a', 'a', 'a' }; 173 byte[] end7 = {}; 174 byte[] splitPointText7 = { 'f', '~', '~', '~', '~', '~', '~' }; 175 byte[] splitPointBinary7 = { 'f', 127, 127, 127, 127, 127, 127 }; 176 testGetSplitKey(start7, end7, splitPointText7, true); 177 testGetSplitKey(start7, end7, splitPointBinary7, false); 178 179 // Test Case 8: both start key and end key are empty. Split point depends on the mode we 180 // choose (text key or binary key). 181 byte[] start8 = {}; 182 byte[] end8 = {}; 183 byte[] splitPointText8 = { 'O' }; 184 byte[] splitPointBinary8 = { 0 }; 185 testGetSplitKey(start8, end8, splitPointText8, true); 186 testGetSplitKey(start8, end8, splitPointBinary8, false); 187 188 // Test Case 9: Binary Key example 189 byte[] start9 = { 13, -19, 126, 127 }; 190 byte[] end9 = { 13, -19, 127, 0 }; 191 byte[] splitPoint9 = { 13, -19, 127, -64 }; 192 testGetSplitKey(start9, end9, splitPoint9, false); 193 } 194 } 195