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