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.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertNull; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023 024import java.io.IOException; 025import org.apache.hadoop.hbase.HBaseTestingUtil; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 028import org.apache.hadoop.hbase.client.Delete; 029import org.apache.hadoop.hbase.client.Get; 030import org.apache.hadoop.hbase.client.Put; 031import org.apache.hadoop.hbase.client.Result; 032import org.apache.hadoop.hbase.client.ResultScanner; 033import org.apache.hadoop.hbase.client.Scan; 034import org.apache.hadoop.hbase.client.Table; 035import org.apache.hadoop.hbase.client.TableDescriptor; 036import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 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.jupiter.api.AfterAll; 042import org.junit.jupiter.api.BeforeAll; 043import org.junit.jupiter.api.BeforeEach; 044import org.junit.jupiter.api.Tag; 045import org.junit.jupiter.api.Test; 046import org.junit.jupiter.api.TestInfo; 047 048@Tag(RegionServerTests.TAG) 049@Tag(MediumTests.TAG) 050public class TestNewVersionBehaviorFromClientSide { 051 052 private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 053 054 private static final byte[] ROW = Bytes.toBytes("r1"); 055 private static final byte[] ROW2 = Bytes.toBytes("r2"); 056 private static final byte[] FAMILY = Bytes.toBytes("f"); 057 private static final byte[] value = Bytes.toBytes("value"); 058 private static final byte[] col1 = Bytes.toBytes("col1"); 059 private static final byte[] col2 = Bytes.toBytes("col2"); 060 private static final byte[] col3 = Bytes.toBytes("col3"); 061 private String name; 062 063 @BeforeAll 064 public static void setUpBeforeClass() throws Exception { 065 TEST_UTIL.startMiniCluster(1); 066 } 067 068 @AfterAll 069 public static void setDownAfterClass() throws Exception { 070 TEST_UTIL.shutdownMiniCluster(); 071 } 072 073 private Table createTable() throws IOException { 074 TableName tableName = TableName.valueOf(name); 075 TableDescriptor tableDescriptor = 076 TableDescriptorBuilder.newBuilder(tableName).setColumnFamily(ColumnFamilyDescriptorBuilder 077 .newBuilder(FAMILY).setNewVersionBehavior(true).setMaxVersions(3).build()).build(); 078 TEST_UTIL.getAdmin().createTable(tableDescriptor); 079 return TEST_UTIL.getConnection().getTable(tableName); 080 } 081 082 @BeforeEach 083 public void setTestName(TestInfo testInfo) { 084 this.name = testInfo.getTestMethod().get().getName(); 085 } 086 087 @Test 088 public void testPutAndDeleteVersions() throws IOException { 089 try (Table t = createTable()) { 090 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 091 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 092 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 093 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 094 t.delete(new Delete(ROW).addColumns(FAMILY, col1, 2000000)); 095 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000000, value)); 096 TEST_UTIL.getAdmin().flush(t.getName()); 097 Result r = t.get(new Get(ROW).readVersions(3)); 098 assertEquals(1, r.size()); 099 assertEquals(1000000, r.rawCells()[0].getTimestamp()); 100 } 101 } 102 103 @Test 104 public void testPutMasked() throws IOException { 105 try (Table t = createTable()) { 106 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 107 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 108 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 109 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 110 111 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 112 113 Result r = t.get(new Get(ROW).readVersions(3)); 114 assertEquals(2, r.size()); 115 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 116 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 117 TEST_UTIL.getAdmin().flush(t.getName()); 118 r = t.get(new Get(ROW).readVersions(3)); 119 assertEquals(2, r.size()); 120 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 121 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 122 } 123 } 124 125 @Test 126 public void testPutMasked2() throws IOException { 127 try (Table t = createTable()) { 128 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 129 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 130 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 131 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 132 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 133 134 Result r = t.get(new Get(ROW).readVersions(3)); 135 assertEquals(3, r.size()); 136 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 137 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 138 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 139 TEST_UTIL.getAdmin().flush(t.getName()); 140 r = t.get(new Get(ROW).readVersions(3)); 141 assertEquals(3, r.size()); 142 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 143 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 144 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 145 } 146 } 147 148 @Test 149 public void testPutMaskedAndUserMaxVersion() throws IOException { 150 try (Table t = createTable()) { 151 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 152 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 153 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 154 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 155 156 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000004)); 157 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 158 159 Result r = t.get(new Get(ROW).readVersions(1)); 160 assertEquals(1, r.size()); 161 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 162 TEST_UTIL.getAdmin().flush(t.getName()); 163 r = t.get(new Get(ROW).readVersions(1)); 164 assertEquals(1, r.size()); 165 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 166 } 167 } 168 169 @Test 170 public void testSameTs() throws IOException { 171 try (Table t = createTable()) { 172 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 173 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 174 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 175 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 176 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 177 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 178 179 Result r = t.get(new Get(ROW).readVersions(3)); 180 assertEquals(3, r.size()); 181 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 182 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 183 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 184 TEST_UTIL.getAdmin().flush(t.getName()); 185 r = t.get(new Get(ROW).readVersions(3)); 186 assertEquals(3, r.size()); 187 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 188 assertEquals(1000003, r.rawCells()[1].getTimestamp()); 189 assertEquals(1000002, r.rawCells()[2].getTimestamp()); 190 } 191 } 192 193 @Test 194 public void testSameTsAndDelete() throws IOException { 195 try (Table t = createTable()) { 196 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 197 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 198 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 199 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 200 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 201 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 202 203 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 204 205 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 206 207 Result r = t.get(new Get(ROW).readVersions(3)); 208 assertEquals(3, r.size()); 209 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 210 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 211 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 212 TEST_UTIL.getAdmin().flush(t.getName()); 213 r = t.get(new Get(ROW).readVersions(3)); 214 assertEquals(3, r.size()); 215 assertEquals(1000004, r.rawCells()[0].getTimestamp()); 216 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 217 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 218 } 219 } 220 221 @Test 222 public void testDeleteFamily() throws IOException { 223 try (Table t = createTable()) { 224 225 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 226 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 227 t.put(new Put(ROW).addColumn(FAMILY, col2, 1000002, value)); 228 t.put(new Put(ROW).addColumn(FAMILY, col3, 1000001, value)); 229 230 t.delete(new Delete(ROW).addFamily(FAMILY, 2000000)); 231 232 t.put(new Put(ROW).addColumn(FAMILY, col3, 1500002, value)); 233 t.put(new Put(ROW).addColumn(FAMILY, col2, 1500001, value)); 234 t.put(new Put(ROW).addColumn(FAMILY, col1, 1500001, value)); 235 t.put(new Put(ROW).addColumn(FAMILY, col1, 1500002, value)); 236 TEST_UTIL.getAdmin().flush(t.getName()); 237 Result r = t.get(new Get(ROW).readVersions(3)); 238 assertEquals(4, r.size()); 239 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 240 assertEquals(1500001, r.rawCells()[1].getTimestamp()); 241 assertEquals(1500001, r.rawCells()[2].getTimestamp()); 242 assertEquals(1500002, r.rawCells()[3].getTimestamp()); 243 244 t.delete(new Delete(ROW).addFamilyVersion(FAMILY, 1500001)); 245 246 r = t.get(new Get(ROW).readVersions(3)); 247 assertEquals(2, r.size()); 248 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 249 assertEquals(1500002, r.rawCells()[1].getTimestamp()); 250 251 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 252 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 253 t.put(new Put(ROW).addColumn(FAMILY, col2, 1000002, value)); 254 t.put(new Put(ROW).addColumn(FAMILY, col3, 1000001, value)); 255 TEST_UTIL.getAdmin().flush(t.getName()); 256 r = t.get(new Get(ROW).readVersions(3)); 257 assertEquals(6, r.size()); 258 assertEquals(1500002, r.rawCells()[0].getTimestamp()); 259 assertEquals(1000002, r.rawCells()[1].getTimestamp()); 260 assertEquals(1000001, r.rawCells()[2].getTimestamp()); 261 assertEquals(1000002, r.rawCells()[3].getTimestamp()); 262 assertEquals(1500002, r.rawCells()[4].getTimestamp()); 263 assertEquals(1000001, r.rawCells()[5].getTimestamp()); 264 } 265 } 266 267 @Test 268 public void testTimeRange() throws IOException { 269 try (Table t = createTable()) { 270 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 271 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 272 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 273 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 274 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000005, value)); 275 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000006, value)); 276 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000007, value)); 277 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000008, value)); 278 Result r = t.get(new Get(ROW).readVersions(3).setTimeRange(0, 1000005)); 279 assertEquals(0, r.size()); 280 TEST_UTIL.getAdmin().flush(t.getName()); 281 r = t.get(new Get(ROW).readVersions(3).setTimeRange(0, 1000005)); 282 assertEquals(0, r.size()); 283 } 284 } 285 286 @Test 287 public void testExplicitColum() throws IOException { 288 try (Table t = createTable()) { 289 t.put(new Put(ROW).addColumn(FAMILY, col1, value)); 290 t.put(new Put(ROW).addColumn(FAMILY, col1, value)); 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, col2, value)); 294 t.put(new Put(ROW).addColumn(FAMILY, col2, 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, col3, value)); 298 t.put(new Put(ROW).addColumn(FAMILY, col3, value)); 299 t.put(new Put(ROW).addColumn(FAMILY, col3, value)); 300 t.put(new Put(ROW).addColumn(FAMILY, col3, value)); 301 Result r = t.get(new Get(ROW).readVersions(3).addColumn(FAMILY, col2)); 302 assertEquals(3, r.size()); 303 TEST_UTIL.getAdmin().flush(t.getName()); 304 r = t.get(new Get(ROW).readVersions(3).addColumn(FAMILY, col2)); 305 assertEquals(3, r.size()); 306 TEST_UTIL.getAdmin().flush(t.getName()); 307 } 308 } 309 310 @Test 311 public void testGetColumnHint() throws IOException { 312 createTable(); 313 try (Table t = TEST_UTIL.getConnection().getTableBuilder(TableName.valueOf(name), null) 314 .setOperationTimeout(10000).setRpcTimeout(10000).build()) { 315 t.put(new Put(ROW).addColumn(FAMILY, col1, 100, value)); 316 t.put(new Put(ROW).addColumn(FAMILY, col1, 101, value)); 317 t.put(new Put(ROW).addColumn(FAMILY, col1, 102, value)); 318 t.put(new Put(ROW).addColumn(FAMILY, col1, 103, value)); 319 t.put(new Put(ROW).addColumn(FAMILY, col1, 104, value)); 320 t.put(new Put(ROW2).addColumn(FAMILY, col1, 104, value)); 321 TEST_UTIL.getAdmin().flush(t.getName()); 322 t.delete(new Delete(ROW).addColumn(FAMILY, col1)); 323 } 324 } 325 326 @Test 327 public void testRawScanAndMajorCompaction() throws IOException { 328 try (Table t = createTable()) { 329 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000001, value)); 330 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000002, value)); 331 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000003, value)); 332 t.put(new Put(ROW).addColumn(FAMILY, col1, 1000004, value)); 333 334 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000004)); 335 t.delete(new Delete(ROW).addColumn(FAMILY, col1, 1000003)); 336 337 try (ResultScanner scannner = t.getScanner(new Scan().setRaw(true).readAllVersions())) { 338 Result r = scannner.next(); 339 assertNull(scannner.next()); 340 assertEquals(6, r.size()); 341 } 342 TEST_UTIL.getAdmin().flush(t.getName()); 343 try (ResultScanner scannner = t.getScanner(new Scan().setRaw(true).readAllVersions())) { 344 Result r = scannner.next(); 345 assertNull(scannner.next()); 346 assertEquals(6, r.size()); 347 } 348 TEST_UTIL.getAdmin().majorCompact(t.getName()); 349 Threads.sleep(5000); 350 try (ResultScanner scannner = t.getScanner(new Scan().setRaw(true).readAllVersions())) { 351 Result r = scannner.next(); 352 assertNull(scannner.next()); 353 assertEquals(1, r.size()); 354 assertEquals(1000002, r.rawCells()[0].getTimestamp()); 355 } 356 } 357 } 358 359 @Test 360 public void testNullColumnQualifier() throws IOException { 361 try (Table t = createTable()) { 362 Delete del = new Delete(ROW); 363 del.addColumn(FAMILY, null); 364 t.delete(del); 365 Result r = t.get(new Get(ROW)); // NPE 366 assertTrue(r.isEmpty()); 367 } 368 } 369}