1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase;
19
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertTrue;
25
26 import java.io.IOException;
27 import java.util.Map;
28 import java.util.NavigableMap;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.HBaseTestCase.FlushCache;
34 import org.apache.hadoop.hbase.HBaseTestCase.HTableIncommon;
35 import org.apache.hadoop.hbase.HBaseTestCase.Incommon;
36 import org.apache.hadoop.hbase.client.Get;
37 import org.apache.hadoop.hbase.client.HBaseAdmin;
38 import org.apache.hadoop.hbase.client.HTable;
39 import org.apache.hadoop.hbase.client.Put;
40 import org.apache.hadoop.hbase.client.Result;
41 import org.apache.hadoop.hbase.client.ResultScanner;
42 import org.apache.hadoop.hbase.client.Scan;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.junit.After;
45 import org.junit.AfterClass;
46 import org.junit.Before;
47 import org.junit.BeforeClass;
48 import org.junit.Test;
49 import org.junit.experimental.categories.Category;
50
51
52
53
54
55 @Category(MediumTests.class)
56 public class TestMultiVersions {
57 private static final Log LOG = LogFactory.getLog(TestMultiVersions.class);
58 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
59 private HBaseAdmin admin;
60
61 @BeforeClass
62 public static void setUpBeforeClass() throws Exception {
63 UTIL.startMiniCluster();
64 }
65
66 @AfterClass
67 public static void tearDownAfterClass() throws Exception {
68 UTIL.shutdownMiniCluster();
69 }
70
71 @Before
72 public void before()
73 throws MasterNotRunningException, ZooKeeperConnectionException {
74 this.admin = new HBaseAdmin(UTIL.getConfiguration());
75 }
76
77 @After
78 public void after() throws IOException {
79 this.admin.close();
80 }
81
82
83
84
85
86
87
88
89
90
91 @Test
92 public void testTimestamps() throws Exception {
93 HTableDescriptor desc = new HTableDescriptor("testTimestamps");
94 desc.addFamily(new HColumnDescriptor(TimestampTestBase.FAMILY_NAME));
95 this.admin.createTable(desc);
96 HTable table = new HTable(UTIL.getConfiguration(), desc.getName());
97
98
99 Incommon incommon = new HTableIncommon(table);
100 TimestampTestBase.doTestDelete(incommon, new FlushCache() {
101 public void flushcache() throws IOException {
102 UTIL.getHBaseCluster().flushcache();
103 }
104 });
105
106
107
108 TimestampTestBase.doTestTimestampScanning(incommon, new FlushCache() {
109 public void flushcache() throws IOException {
110 UTIL.getMiniHBaseCluster().flushcache();
111 }
112 });
113
114 table.close();
115 }
116
117
118
119
120
121
122
123 @Test
124 public void testGetRowVersions() throws Exception {
125 final String tableName = "testGetRowVersions";
126 final byte [] contents = Bytes.toBytes("contents");
127 final byte [] row = Bytes.toBytes("row");
128 final byte [] value1 = Bytes.toBytes("value1");
129 final byte [] value2 = Bytes.toBytes("value2");
130 final long timestamp1 = 100L;
131 final long timestamp2 = 200L;
132 final HTableDescriptor desc = new HTableDescriptor(tableName);
133 desc.addFamily(new HColumnDescriptor(contents));
134 this.admin.createTable(desc);
135 Put put = new Put(row, timestamp1, null);
136 put.add(contents, contents, value1);
137 HTable table = new HTable(UTIL.getConfiguration(), tableName);
138 table.put(put);
139
140 table.close();
141 UTIL.shutdownMiniHBaseCluster();
142 LOG.debug("HBase cluster shut down -- restarting");
143 UTIL.startMiniHBaseCluster(1, 1);
144
145
146 table = new HTable(new Configuration(UTIL.getConfiguration()), tableName);
147
148 put = new Put(row, timestamp2, null);
149 put.add(contents, contents, value2);
150 table.put(put);
151
152 Get get = new Get(row);
153
154 Result r = table.get(get);
155 assertNotNull(r);
156 assertFalse(r.isEmpty());
157 assertTrue(r.size() == 1);
158 byte [] value = r.getValue(contents, contents);
159 assertTrue(value.length != 0);
160 assertTrue(Bytes.equals(value, value2));
161
162 get = new Get(row);
163 get.setMaxVersions();
164 r = table.get(get);
165 assertTrue(r.size() == 2);
166 value = r.getValue(contents, contents);
167 assertTrue(value.length != 0);
168 assertTrue(Bytes.equals(value, value2));
169 NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map =
170 r.getMap();
171 NavigableMap<byte[], NavigableMap<Long, byte[]>> familyMap =
172 map.get(contents);
173 NavigableMap<Long, byte[]> versionMap = familyMap.get(contents);
174 assertTrue(versionMap.size() == 2);
175 assertTrue(Bytes.equals(value1, versionMap.get(timestamp1)));
176 assertTrue(Bytes.equals(value2, versionMap.get(timestamp2)));
177 table.close();
178 }
179
180
181
182
183
184
185
186
187
188 @Test
189 public void testScanMultipleVersions() throws Exception {
190 final byte [] tableName = Bytes.toBytes("testScanMultipleVersions");
191 final HTableDescriptor desc = new HTableDescriptor(tableName);
192 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
193 final byte [][] rows = new byte[][] {
194 Bytes.toBytes("row_0200"),
195 Bytes.toBytes("row_0800")
196 };
197 final byte [][] splitRows = new byte[][] {Bytes.toBytes("row_0500")};
198 final long [] timestamp = new long[] {100L, 1000L};
199 this.admin.createTable(desc, splitRows);
200 HTable table = new HTable(UTIL.getConfiguration(), tableName);
201
202 NavigableMap<HRegionInfo, ServerName> locations = table.getRegionLocations();
203 assertEquals(2, locations.size());
204 int index = 0;
205 for (Map.Entry<HRegionInfo, ServerName> e: locations.entrySet()) {
206 HRegionInfo hri = e.getKey();
207 if (index == 0) {
208 assertTrue(Bytes.equals(HConstants.EMPTY_START_ROW, hri.getStartKey()));
209 assertTrue(Bytes.equals(hri.getEndKey(), splitRows[0]));
210 } else if (index == 1) {
211 assertTrue(Bytes.equals(splitRows[0], hri.getStartKey()));
212 assertTrue(Bytes.equals(hri.getEndKey(), HConstants.EMPTY_END_ROW));
213 }
214 index++;
215 }
216
217 for (int i = 0; i < locations.size(); i++) {
218 for (int j = 0; j < timestamp.length; j++) {
219 Put put = new Put(rows[i], timestamp[j], null);
220 put.add(HConstants.CATALOG_FAMILY, null, timestamp[j],
221 Bytes.toBytes(timestamp[j]));
222 table.put(put);
223 }
224 }
225
226 for (int i = 0; i < rows.length; i++) {
227 for (int j = 0; j < timestamp.length; j++) {
228 Get get = new Get(rows[i]);
229 get.addFamily(HConstants.CATALOG_FAMILY);
230 get.setTimeStamp(timestamp[j]);
231 Result result = table.get(get);
232 int cellCount = 0;
233 for(@SuppressWarnings("unused")KeyValue kv : result.list()) {
234 cellCount++;
235 }
236 assertTrue(cellCount == 1);
237 }
238 table.close();
239 }
240
241
242 int count = 0;
243 Scan scan = new Scan();
244 scan.addFamily(HConstants.CATALOG_FAMILY);
245 ResultScanner s = table.getScanner(scan);
246 try {
247 for (Result rr = null; (rr = s.next()) != null;) {
248 System.out.println(rr.toString());
249 count += 1;
250 }
251 assertEquals("Number of rows should be 2", 2, count);
252 } finally {
253 s.close();
254 }
255
256
257
258
259 count = 0;
260 scan = new Scan();
261 scan.setTimeRange(1000L, Long.MAX_VALUE);
262 scan.addFamily(HConstants.CATALOG_FAMILY);
263
264 s = table.getScanner(scan);
265 try {
266 while (s.next() != null) {
267 count += 1;
268 }
269 assertEquals("Number of rows should be 2", 2, count);
270 } finally {
271 s.close();
272 }
273
274
275
276
277 count = 0;
278 scan = new Scan();
279 scan.setTimeStamp(1000L);
280 scan.addFamily(HConstants.CATALOG_FAMILY);
281
282 s = table.getScanner(scan);
283 try {
284 while (s.next() != null) {
285 count += 1;
286 }
287 assertEquals("Number of rows should be 2", 2, count);
288 } finally {
289 s.close();
290 }
291
292
293
294
295 count = 0;
296 scan = new Scan();
297 scan.setTimeRange(100L, 1000L);
298 scan.addFamily(HConstants.CATALOG_FAMILY);
299
300 s = table.getScanner(scan);
301 try {
302 while (s.next() != null) {
303 count += 1;
304 }
305 assertEquals("Number of rows should be 2", 2, count);
306 } finally {
307 s.close();
308 }
309
310
311
312
313 count = 0;
314 scan = new Scan();
315 scan.setTimeStamp(100L);
316 scan.addFamily(HConstants.CATALOG_FAMILY);
317
318 s = table.getScanner(scan);
319 try {
320 while (s.next() != null) {
321 count += 1;
322 }
323 assertEquals("Number of rows should be 2", 2, count);
324 } finally {
325 s.close();
326 }
327 }
328
329 @org.junit.Rule
330 public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
331 new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
332 }
333