View Javadoc

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  
23  import org.apache.hadoop.hbase.testclassification.LargeTests;
24  import org.apache.hadoop.hbase.testclassification.VerySlowMapReduceTests;
25  import org.junit.Test;
26  import org.junit.experimental.categories.Category;
27  
28  /**
29   * TestTableInputFormatScan part 1.
30   * @see TestTableInputFormatScanBase
31   */
32  @Category({VerySlowMapReduceTests.class, LargeTests.class})
33  public class TestTableInputFormatScan1 extends TestTableInputFormatScanBase {
34  
35    /**
36     * Tests a MR scan using specific start and stop rows.
37     *
38     * @throws IOException
39     * @throws ClassNotFoundException
40     * @throws InterruptedException
41     */
42    @Test
43    public void testScanEmptyToEmpty()
44    throws IOException, InterruptedException, ClassNotFoundException {
45      testScan(null, null, null);
46    }
47  
48    /**
49     * Tests a MR scan using specific start and stop rows.
50     *
51     * @throws IOException
52     * @throws ClassNotFoundException
53     * @throws InterruptedException
54     */
55    @Test
56    public void testScanEmptyToAPP()
57    throws IOException, InterruptedException, ClassNotFoundException {
58      testScan(null, "app", "apo");
59    }
60  
61    /**
62     * Tests a MR scan using specific start and stop rows.
63     *
64     * @throws IOException
65     * @throws ClassNotFoundException
66     * @throws InterruptedException
67     */
68    @Test
69    public void testScanEmptyToBBA()
70    throws IOException, InterruptedException, ClassNotFoundException {
71      testScan(null, "bba", "baz");
72    }
73  
74    /**
75     * Tests a MR scan using specific start and stop rows.
76     *
77     * @throws IOException
78     * @throws ClassNotFoundException
79     * @throws InterruptedException
80     */
81    @Test
82    public void testScanEmptyToBBB()
83    throws IOException, InterruptedException, ClassNotFoundException {
84      testScan(null, "bbb", "bba");
85    }
86  
87    /**
88     * Tests a MR scan using specific start and stop rows.
89     *
90     * @throws IOException
91     * @throws ClassNotFoundException
92     * @throws InterruptedException
93     */
94    @Test
95    public void testScanEmptyToOPP()
96    throws IOException, InterruptedException, ClassNotFoundException {
97      testScan(null, "opp", "opo");
98    }
99  
100   /**
101    * Tests a MR scan using specific number of mappers. The test table has 25 regions,
102    * and all region sizes are set as 0 as default. The average region size is 1 (the smallest
103    * positive). When we set hbase.mapreduce.input.ratio as -1, all regions will be cut into two
104    * MapRedcue input splits, the number of MR input splits should be 50; when we set hbase
105    * .mapreduce.input.ratio as 100, the sum of all region sizes is less then the average region
106    * size, all regions will be combined into 1 MapRedcue input split.
107    *
108    * @throws IOException
109    * @throws ClassNotFoundException
110    * @throws InterruptedException
111    */
112   @Test
113   public void testGetSplits() throws IOException, InterruptedException, ClassNotFoundException {
114     testNumOfSplits("-1", 52);
115     testNumOfSplits("100", 1);
116   }
117 
118   /**
119    * Tests the getSplitKey() method in TableInputFormatBase.java
120    *
121    * @throws IOException
122    * @throws ClassNotFoundException
123    * @throws InterruptedException
124    */
125   @Test
126   public void testGetSplitsPoint() throws IOException, InterruptedException,
127           ClassNotFoundException {
128     // Test Case 1: "aaabcdef" and "aaaff", split point is "aaad".
129     byte[] start1 = { 'a', 'a', 'a', 'b', 'c', 'd', 'e', 'f' };
130     byte[] end1 = { 'a', 'a', 'a', 'f', 'f' };
131     byte[] splitPoint1 = { 'a', 'a', 'a', 'd' };
132     testGetSplitKey(start1, end1, splitPoint1, true);
133 
134     // Test Case 2: "111000" and "1125790", split point is "111b".
135     byte[] start2 = { '1', '1', '1', '0', '0', '0' };
136     byte[] end2 = { '1', '1', '2', '5', '7', '9', '0' };
137     byte[] splitPoint2 = { '1', '1', '1', 'b' };
138     testGetSplitKey(start2, end2, splitPoint2, true);
139 
140     // Test Case 3: "aaaaaa" and "aab", split point is "aaap".
141     byte[] start3 = { 'a', 'a', 'a', 'a', 'a', 'a' };
142     byte[] end3 = { 'a', 'a', 'b' };
143     byte[] splitPoint3 = { 'a', 'a', 'a', 'p' };
144     testGetSplitKey(start3, end3, splitPoint3, true);
145 
146     // Test Case 4: "aaa" and "aaaz", split point is "aaaM".
147     byte[] start4 = { 'a', 'a', 'a' };
148     byte[] end4 = { 'a', 'a', 'a', 'z' };
149     byte[] splitPoint4 = { 'a', 'a', 'a', 'M' };
150     testGetSplitKey(start4, end4, splitPoint4, true);
151 
152     // Test Case 5: "aaa" and "aaba", split point is "aaap".
153     byte[] start5 = { 'a', 'a', 'a' };
154     byte[] end5 = { 'a', 'a', 'b', 'a' };
155     byte[] splitPoint5 = { 'a', 'a', 'a', 'p' };
156     testGetSplitKey(start5, end5, splitPoint5, true);
157 
158     // Test Case 6: empty key and "hhhqqqwww", split point is "h"
159     byte[] start6 = {};
160     byte[] end6 = { 'h', 'h', 'h', 'q', 'q', 'q', 'w', 'w' };
161     byte[] splitPoint6 = { 'h' };
162     testGetSplitKey(start6, end6, splitPoint6, true);
163 
164     // Test Case 7: "ffffaaa" and empty key, split point depends on the mode we choose(text key or
165     // binary key).
166     byte[] start7 = { 'f', 'f', 'f', 'f', 'a', 'a', 'a' };
167     byte[] end7 = {};
168     byte[] splitPointText7 = { 'f', '~', '~', '~', '~', '~', '~'  };
169     byte[] splitPointBinary7 = { 'f', 127, 127, 127, 127, 127, 127  };
170     testGetSplitKey(start7, end7, splitPointText7, true);
171     testGetSplitKey(start7, end7, splitPointBinary7, false);
172 
173     // Test Case 8: both start key and end key are empty. Split point depends on the mode we
174     // choose (text key or binary key).
175     byte[] start8 = {};
176     byte[] end8 = {};
177     byte[] splitPointText8 = { 'O' };
178     byte[] splitPointBinary8 = { 0 };
179     testGetSplitKey(start8, end8, splitPointText8, true);
180     testGetSplitKey(start8, end8, splitPointBinary8, false);
181 
182     // Test Case 9: Binary Key example
183     byte[] start9 = { 13, -19, 126, 127 };
184     byte[] end9 = { 13, -19, 127, 0 };
185     byte[] splitPoint9 = { 13, -19, 127, -64 };
186     testGetSplitKey(start9, end9, splitPoint9, false);
187   }
188 
189 }