001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNull; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import org.apache.hadoop.hbase.HBaseClassTestRule; 026import org.apache.hadoop.hbase.HBaseTestingUtility; 027import org.apache.hadoop.hbase.HColumnDescriptor; 028import org.apache.hadoop.hbase.HTableDescriptor; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.client.Delete; 031import org.apache.hadoop.hbase.client.Get; 032import org.apache.hadoop.hbase.client.Put; 033import org.apache.hadoop.hbase.client.Result; 034import org.apache.hadoop.hbase.client.ResultScanner; 035import org.apache.hadoop.hbase.client.Scan; 036import org.apache.hadoop.hbase.client.Table; 037import org.apache.hadoop.hbase.testclassification.MediumTests; 038import org.apache.hadoop.hbase.testclassification.RegionServerTests; 039import org.apache.hadoop.hbase.util.Bytes; 040import org.apache.hadoop.hbase.util.Threads; 041import org.junit.AfterClass; 042import org.junit.BeforeClass; 043import org.junit.ClassRule; 044import org.junit.Rule; 045import org.junit.Test; 046import org.junit.experimental.categories.Category; 047import org.junit.rules.TestName; 048 049@Category({ RegionServerTests.class, MediumTests.class }) 050public class TestNewVersionBehaviorFromClientSide { 051 052 @ClassRule 053 public static final HBaseClassTestRule CLASS_RULE = 054 HBaseClassTestRule.forClass(TestNewVersionBehaviorFromClientSide.class); 055 056 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 057 058 private static final byte[] ROW = Bytes.toBytes("r1"); 059 private static final byte[] ROW2 = Bytes.toBytes("r2"); 060 private static final byte[] FAMILY = Bytes.toBytes("f"); 061 private static final byte[] value = Bytes.toBytes("value"); 062 private static final byte[] col1 = Bytes.toBytes("col1"); 063 private static final byte[] col2 = Bytes.toBytes("col2"); 064 private static final byte[] col3 = Bytes.toBytes("col3"); 065 066 @Rule 067 public TestName name = new TestName(); 068 069 @BeforeClass 070 public static void setUpBeforeClass() throws Exception { 071 TEST_UTIL.startMiniCluster(1); 072 } 073 074 @AfterClass 075 public static void setDownAfterClass() throws Exception { 076 TEST_UTIL.shutdownMiniCluster(); 077 } 078 079 private Table createTable() throws IOException { 080 TableName tableName = TableName.valueOf(name.getMethodName()); 081 HTableDescriptor table = new HTableDescriptor(tableName); 082 HColumnDescriptor fam = new HColumnDescriptor(FAMILY); 083 fam.setNewVersionBehavior(true); 084 fam.setMaxVersions(3); 085 table.addFamily(fam); 086 TEST_UTIL.getHBaseAdmin().createTable(table); 087 return TEST_UTIL.getConnection().getTable(tableName); 088 } 089 090 @Test 091 public void testPutAndDeleteVersions() throws IOException { 092 try (Table t = createTable()) { 093 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 094 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 095 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 096 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 097 t.delete(new Delete(ROW).addColumns(FAMILY, col1, 2000000)); 098 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000000, value)); 099 TEST_UTIL.getAdmin().flush(t.getName()); 100 Result r = t.get(new Get(ROW).setMaxVersions(3)); 101 assertEquals(1, r.size()); 102 assertEquals(1000000, r.rawCells()[0].getTimestamp()); 103 } 104 } 105 106 @Test 107 public void testPutMasked() throws IOException { 108 try (Table t = createTable()) { 109 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 110 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 111 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 112 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 113 114 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 115 116 Result r = t.get(new Get(ROW).setMaxVersions(3)); 117 assertEquals(2, r.size()); 118 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 119 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 120 TEST_UTIL.getAdmin().flush(t.getName()); 121 r = t.get(new Get(ROW).setMaxVersions(3)); 122 assertEquals(2, r.size()); 123 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 124 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 125 } 126 } 127 128 @Test 129 public void testPutMasked2() throws IOException { 130 try (Table t = createTable()) { 131 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 132 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 133 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 134 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 135 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 136 137 Result r = t.get(new Get(ROW).setMaxVersions(3)); 138 assertEquals(3, r.size()); 139 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 140 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 141 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 142 TEST_UTIL.getAdmin().flush(t.getName()); 143 r = t.get(new Get(ROW).setMaxVersions(3)); 144 assertEquals(3, r.size()); 145 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 146 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 147 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 148 } 149 } 150 151 @Test 152 public void testPutMaskedAndUserMaxVersion() throws IOException { 153 try (Table t = createTable()) { 154 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 155 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 156 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 157 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 158 159 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000004)); 160 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 161 162 Result r = t.get(new Get(ROW).setMaxVersions(1)); 163 assertEquals(1, r.size()); 164 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 165 TEST_UTIL.getAdmin().flush(t.getName()); 166 r = t.get(new Get(ROW).setMaxVersions(1)); 167 assertEquals(1, r.size()); 168 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 169 } 170 } 171 172 @Test 173 public void testSameTs() throws IOException { 174 try (Table t = createTable()) { 175 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 176 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 177 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 178 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 179 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 180 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 181 182 Result r = t.get(new Get(ROW).setMaxVersions(3)); 183 assertEquals(3, r.size()); 184 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 185 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 186 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 187 TEST_UTIL.getAdmin().flush(t.getName()); 188 r = t.get(new Get(ROW).setMaxVersions(3)); 189 assertEquals(3, r.size()); 190 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 191 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 192 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 193 } 194 } 195 196 @Test 197 public void testSameTsAndDelete() throws IOException { 198 try (Table t = createTable()) { 199 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 200 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 201 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 202 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 203 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 204 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 205 206 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 207 208 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 209 210 Result r = t.get(new Get(ROW).setMaxVersions(3)); 211 assertEquals(3, r.size()); 212 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 213 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 214 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 215 TEST_UTIL.getAdmin().flush(t.getName()); 216 r = t.get(new Get(ROW).setMaxVersions(3)); 217 assertEquals(3, r.size()); 218 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 219 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 220 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 221 } 222 } 223 224 @Test 225 public void testDeleteFamily() throws IOException { 226 try (Table t = createTable()) { 227 228 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 229 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 230 t.put(new Put(ROW).addColumn(FAMILY, col2, 1000002, value)); 231 t.put(new Put(ROW).addColumn(FAMILY, col3, 1000001, value)); 232 233 t.delete(new Delete(ROW).addFamily(FAMILY, 2000000)); 234 235 t.put(new Put(ROW).addColumn(FAMILY, col3, 1500002, value)); 236 t.put(new Put(ROW).addColumn(FAMILY, col2, 1500001, value)); 237 t.put(new Put(ROW).addColumn(FAMILY, col1, 1500001, value)); 238 t.put(new Put(ROW).addColumn(FAMILY, col1, 1500002, value)); 239 TEST_UTIL.getAdmin().flush(t.getName()); 240 Result r = t.get(new Get(ROW).setMaxVersions(3)); 241 assertEquals(4, r.size()); 242 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 243 assertEquals(1500001, r.rawCells()[1].getTimestamp()); 244 assertEquals(1500001, r.rawCells()[2].getTimestamp()); 245 assertEquals(1500002, r.rawCells()[3].getTimestamp()); 246 247 t.delete(new Delete(ROW).addFamilyVersion(FAMILY, 1500001)); 248 249 r = t.get(new Get(ROW).setMaxVersions(3)); 250 assertEquals(2, r.size()); 251 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 252 assertEquals(1500002, r.rawCells()[1].getTimestamp()); 253 254 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 255 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 256 t.put(new Put(ROW).addColumn(FAMILY, col2, 1000002, value)); 257 t.put(new Put(ROW).addColumn(FAMILY, col3, 1000001, value)); 258 TEST_UTIL.getAdmin().flush(t.getName()); 259 r = t.get(new Get(ROW).setMaxVersions(3)); 260 assertEquals(6, r.size()); 261 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 262 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 263 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 264 assertEquals(1000002, r.rawCells()[3].getTimestamp()); 265 assertEquals(1500002, r.rawCells()[4].getTimestamp()); 266 assertEquals(1000001, r.rawCells()[5].getTimestamp()); 267 } 268 } 269 270 @Test 271 public void testTimeRange() throws IOException { 272 try (Table t = createTable()) { 273 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 274 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 275 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 276 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 277 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000005, value)); 278 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000006, value)); 279 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000007, value)); 280 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000008, value)); 281 Result r = t.get(new Get(ROW).setMaxVersions(3).setTimeRange(0, 1000005)); 282 assertEquals(0, r.size()); 283 TEST_UTIL.getAdmin().flush(t.getName()); 284 r = t.get(new Get(ROW).setMaxVersions(3).setTimeRange(0, 1000005)); 285 assertEquals(0, r.size()); 286 } 287 } 288 289 @Test 290 public void testExplicitColum() throws IOException { 291 try (Table t = createTable()) { 292 t.put(new Put(ROW).addColumn(FAMILY, col1, value)); 293 t.put(new Put(ROW).addColumn(FAMILY, col1, value)); 294 t.put(new Put(ROW).addColumn(FAMILY, col1, value)); 295 t.put(new Put(ROW).addColumn(FAMILY, col1, value)); 296 t.put(new Put(ROW).addColumn(FAMILY, col2, value)); 297 t.put(new Put(ROW).addColumn(FAMILY, col2, value)); 298 t.put(new Put(ROW).addColumn(FAMILY, col2, value)); 299 t.put(new Put(ROW).addColumn(FAMILY, col2, value)); 300 t.put(new Put(ROW).addColumn(FAMILY, col3, value)); 301 t.put(new Put(ROW).addColumn(FAMILY, col3, value)); 302 t.put(new Put(ROW).addColumn(FAMILY, col3, value)); 303 t.put(new Put(ROW).addColumn(FAMILY, col3, value)); 304 Result r = t.get(new Get(ROW).setMaxVersions(3).addColumn(FAMILY, col2)); 305 assertEquals(3, r.size()); 306 TEST_UTIL.getAdmin().flush(t.getName()); 307 r = t.get(new Get(ROW).setMaxVersions(3).addColumn(FAMILY, col2)); 308 assertEquals(3, r.size()); 309 TEST_UTIL.getAdmin().flush(t.getName()); 310 } 311 } 312 313 @Test 314 public void testgetColumnHint() throws IOException { 315 try (Table t = createTable()) { 316 t.setOperationTimeout(10000); 317 t.setRpcTimeout(10000); 318 t.put(new Put(ROW).addColumn(FAMILY, col1, 100, value)); 319 t.put(new Put(ROW).addColumn(FAMILY, col1, 101, value)); 320 t.put(new Put(ROW).addColumn(FAMILY, col1, 102, value)); 321 t.put(new Put(ROW).addColumn(FAMILY, col1, 103, value)); 322 t.put(new Put(ROW).addColumn(FAMILY, col1, 104, value)); 323 t.put(new Put(ROW2).addColumn(FAMILY, col1, 104, value)); 324 TEST_UTIL.getAdmin().flush(t.getName()); 325 t.delete(new Delete(ROW).addColumn(FAMILY, col1)); 326 } 327 } 328 329 @Test 330 public void testRawScanAndMajorCompaction() throws IOException { 331 try (Table t = createTable()) { 332 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 333 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 334 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 335 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 336 337 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000004)); 338 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 339 340 try (ResultScanner scannner = t.getScanner(new Scan().setRaw(true).setMaxVersions())) { 341 Result r = scannner.next(); 342 assertNull(scannner.next()); 343 assertEquals(6, r.size()); 344 } 345 TEST_UTIL.getAdmin().flush(t.getName()); 346 try (ResultScanner scannner = t.getScanner(new Scan().setRaw(true).setMaxVersions())) { 347 Result r = scannner.next(); 348 assertNull(scannner.next()); 349 assertEquals(6, r.size()); 350 } 351 TEST_UTIL.getAdmin().majorCompact(t.getName()); 352 Threads.sleep(5000); 353 try (ResultScanner scannner = t.getScanner(new Scan().setRaw(true).setMaxVersions())) { 354 Result r = scannner.next(); 355 assertNull(scannner.next()); 356 assertEquals(1, r.size()); 357 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 358 } 359 } 360 } 361 362 @Test 363 public void testNullColumnQualifier() throws IOException { 364 try (Table t = createTable()) { 365 Delete del = new Delete(ROW); 366 del.addColumn(FAMILY, null); 367 t.delete(del); 368 Result r = t.get(new Get(ROW)); // NPE 369 assertTrue(r.isEmpty()); 370 } 371 } 372}