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.HBaseTestingUtil; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 029import org.apache.hadoop.hbase.client.Delete; 030import org.apache.hadoop.hbase.client.Get; 031import org.apache.hadoop.hbase.client.Put; 032import org.apache.hadoop.hbase.client.Result; 033import org.apache.hadoop.hbase.client.ResultScanner; 034import org.apache.hadoop.hbase.client.Scan; 035import org.apache.hadoop.hbase.client.Table; 036import org.apache.hadoop.hbase.client.TableDescriptor; 037import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 038import org.apache.hadoop.hbase.testclassification.MediumTests; 039import org.apache.hadoop.hbase.testclassification.RegionServerTests; 040import org.apache.hadoop.hbase.util.Bytes; 041import org.apache.hadoop.hbase.util.Threads; 042import org.junit.AfterClass; 043import org.junit.BeforeClass; 044import org.junit.ClassRule; 045import org.junit.Rule; 046import org.junit.Test; 047import org.junit.experimental.categories.Category; 048import org.junit.rules.TestName; 049 050@Category({ RegionServerTests.class, MediumTests.class }) 051public class TestNewVersionBehaviorFromClientSide { 052 053 @ClassRule 054 public static final HBaseClassTestRule CLASS_RULE = 055 HBaseClassTestRule.forClass(TestNewVersionBehaviorFromClientSide.class); 056 057 private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 058 059 private static final byte[] ROW = Bytes.toBytes("r1"); 060 private static final byte[] ROW2 = Bytes.toBytes("r2"); 061 private static final byte[] FAMILY = Bytes.toBytes("f"); 062 private static final byte[] value = Bytes.toBytes("value"); 063 private static final byte[] col1 = Bytes.toBytes("col1"); 064 private static final byte[] col2 = Bytes.toBytes("col2"); 065 private static final byte[] col3 = Bytes.toBytes("col3"); 066 067 @Rule 068 public TestName name = new TestName(); 069 070 @BeforeClass 071 public static void setUpBeforeClass() throws Exception { 072 TEST_UTIL.startMiniCluster(1); 073 } 074 075 @AfterClass 076 public static void setDownAfterClass() throws Exception { 077 TEST_UTIL.shutdownMiniCluster(); 078 } 079 080 private Table createTable() throws IOException { 081 TableName tableName = TableName.valueOf(name.getMethodName()); 082 TableDescriptor tableDescriptor = 083 TableDescriptorBuilder.newBuilder(tableName).setColumnFamily(ColumnFamilyDescriptorBuilder 084 .newBuilder(FAMILY).setNewVersionBehavior(true).setMaxVersions(3).build()).build(); 085 TEST_UTIL.getAdmin().createTable(tableDescriptor); 086 return TEST_UTIL.getConnection().getTable(tableName); 087 } 088 089 @Test 090 public void testPutAndDeleteVersions() throws IOException { 091 try (Table t = createTable()) { 092 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 093 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 094 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 095 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 096 t.delete(new Delete(ROW).addColumns(FAMILY, col1, 2000000)); 097 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000000, value)); 098 TEST_UTIL.getAdmin().flush(t.getName()); 099 Result r = t.get(new Get(ROW).readVersions(3)); 100 assertEquals(1, r.size()); 101 assertEquals(1000000, r.rawCells()[0].getTimestamp()); 102 } 103 } 104 105 @Test 106 public void testPutMasked() throws IOException { 107 try (Table t = createTable()) { 108 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 109 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 110 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 111 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 112 113 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 114 115 Result r = t.get(new Get(ROW).readVersions(3)); 116 assertEquals(2, r.size()); 117 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 118 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 119 TEST_UTIL.getAdmin().flush(t.getName()); 120 r = t.get(new Get(ROW).readVersions(3)); 121 assertEquals(2, r.size()); 122 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 123 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 124 } 125 } 126 127 @Test 128 public void testPutMasked2() throws IOException { 129 try (Table t = createTable()) { 130 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 131 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 132 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 133 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 134 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 135 136 Result r = t.get(new Get(ROW).readVersions(3)); 137 assertEquals(3, r.size()); 138 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 139 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 140 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 141 TEST_UTIL.getAdmin().flush(t.getName()); 142 r = t.get(new Get(ROW).readVersions(3)); 143 assertEquals(3, r.size()); 144 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 145 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 146 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 147 } 148 } 149 150 @Test 151 public void testPutMaskedAndUserMaxVersion() throws IOException { 152 try (Table t = createTable()) { 153 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 154 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 155 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 156 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 157 158 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000004)); 159 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 160 161 Result r = t.get(new Get(ROW).readVersions(1)); 162 assertEquals(1, r.size()); 163 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 164 TEST_UTIL.getAdmin().flush(t.getName()); 165 r = t.get(new Get(ROW).readVersions(1)); 166 assertEquals(1, r.size()); 167 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 168 } 169 } 170 171 @Test 172 public void testSameTs() throws IOException { 173 try (Table t = createTable()) { 174 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 175 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 176 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, 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, 1000004, value)); 180 181 Result r = t.get(new Get(ROW).readVersions(3)); 182 assertEquals(3, r.size()); 183 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 184 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 185 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 186 TEST_UTIL.getAdmin().flush(t.getName()); 187 r = t.get(new Get(ROW).readVersions(3)); 188 assertEquals(3, r.size()); 189 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 190 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 191 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 192 } 193 } 194 195 @Test 196 public void testSameTsAndDelete() throws IOException { 197 try (Table t = createTable()) { 198 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 199 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 200 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, 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 205 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 206 207 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 208 209 Result r = t.get(new Get(ROW).readVersions(3)); 210 assertEquals(3, r.size()); 211 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 212 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 213 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 214 TEST_UTIL.getAdmin().flush(t.getName()); 215 r = t.get(new Get(ROW).readVersions(3)); 216 assertEquals(3, r.size()); 217 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 218 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 219 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 220 } 221 } 222 223 @Test 224 public void testDeleteFamily() throws IOException { 225 try (Table t = createTable()) { 226 227 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 228 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 229 t.put(new Put(ROW).addColumn(FAMILY, col2, 1000002, value)); 230 t.put(new Put(ROW).addColumn(FAMILY, col3, 1000001, value)); 231 232 t.delete(new Delete(ROW).addFamily(FAMILY, 2000000)); 233 234 t.put(new Put(ROW).addColumn(FAMILY, col3, 1500002, value)); 235 t.put(new Put(ROW).addColumn(FAMILY, col2, 1500001, value)); 236 t.put(new Put(ROW).addColumn(FAMILY, col1, 1500001, value)); 237 t.put(new Put(ROW).addColumn(FAMILY, col1, 1500002, value)); 238 TEST_UTIL.getAdmin().flush(t.getName()); 239 Result r = t.get(new Get(ROW).readVersions(3)); 240 assertEquals(4, r.size()); 241 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 242 assertEquals(1500001, r.rawCells()[1].getTimestamp()); 243 assertEquals(1500001, r.rawCells()[2].getTimestamp()); 244 assertEquals(1500002, r.rawCells()[3].getTimestamp()); 245 246 t.delete(new Delete(ROW).addFamilyVersion(FAMILY, 1500001)); 247 248 r = t.get(new Get(ROW).readVersions(3)); 249 assertEquals(2, r.size()); 250 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 251 assertEquals(1500002, r.rawCells()[1].getTimestamp()); 252 253 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 254 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 255 t.put(new Put(ROW).addColumn(FAMILY, col2, 1000002, value)); 256 t.put(new Put(ROW).addColumn(FAMILY, col3, 1000001, value)); 257 TEST_UTIL.getAdmin().flush(t.getName()); 258 r = t.get(new Get(ROW).readVersions(3)); 259 assertEquals(6, r.size()); 260 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 261 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 262 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 263 assertEquals(1000002, r.rawCells()[3].getTimestamp()); 264 assertEquals(1500002, r.rawCells()[4].getTimestamp()); 265 assertEquals(1000001, r.rawCells()[5].getTimestamp()); 266 } 267 } 268 269 @Test 270 public void testTimeRange() throws IOException { 271 try (Table t = createTable()) { 272 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 273 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 274 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 275 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 276 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000005, value)); 277 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000006, value)); 278 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000007, value)); 279 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000008, value)); 280 Result r = t.get(new Get(ROW).readVersions(3).setTimeRange(0, 1000005)); 281 assertEquals(0, r.size()); 282 TEST_UTIL.getAdmin().flush(t.getName()); 283 r = t.get(new Get(ROW).readVersions(3).setTimeRange(0, 1000005)); 284 assertEquals(0, r.size()); 285 } 286 } 287 288 @Test 289 public void testExplicitColum() throws IOException { 290 try (Table t = createTable()) { 291 t.put(new Put(ROW).addColumn(FAMILY, col1, value)); 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, col2, 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, col3, 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 Result r = t.get(new Get(ROW).readVersions(3).addColumn(FAMILY, col2)); 304 assertEquals(3, r.size()); 305 TEST_UTIL.getAdmin().flush(t.getName()); 306 r = t.get(new Get(ROW).readVersions(3).addColumn(FAMILY, col2)); 307 assertEquals(3, r.size()); 308 TEST_UTIL.getAdmin().flush(t.getName()); 309 } 310 } 311 312 @Test 313 public void testGetColumnHint() throws IOException { 314 createTable(); 315 try (Table t = 316 TEST_UTIL.getConnection().getTableBuilder(TableName.valueOf(name.getMethodName()), null) 317 .setOperationTimeout(10000).setRpcTimeout(10000).build()) { 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).readAllVersions())) { 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).readAllVersions())) { 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).readAllVersions())) { 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}