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