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.client; 019 020import static org.hamcrest.CoreMatchers.instanceOf; 021import static org.hamcrest.MatcherAssert.assertThat; 022import static org.junit.Assert.assertEquals; 023import static org.junit.Assert.assertFalse; 024import static org.junit.Assert.assertNotNull; 025import static org.junit.Assert.assertTrue; 026import static org.junit.Assert.fail; 027 028import java.io.IOException; 029import java.util.ArrayList; 030import java.util.Arrays; 031import java.util.Collection; 032import java.util.EnumSet; 033import java.util.HashSet; 034import java.util.List; 035import java.util.NavigableMap; 036import org.apache.hadoop.conf.Configuration; 037import org.apache.hadoop.hbase.Cell; 038import org.apache.hadoop.hbase.CellUtil; 039import org.apache.hadoop.hbase.ClusterMetrics.Option; 040import org.apache.hadoop.hbase.HBaseClassTestRule; 041import org.apache.hadoop.hbase.HColumnDescriptor; 042import org.apache.hadoop.hbase.HConstants; 043import org.apache.hadoop.hbase.HTableDescriptor; 044import org.apache.hadoop.hbase.KeyValue; 045import org.apache.hadoop.hbase.MiniHBaseCluster; 046import org.apache.hadoop.hbase.TableName; 047import org.apache.hadoop.hbase.TableNameTestRule; 048import org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint; 049import org.apache.hadoop.hbase.master.LoadBalancer; 050import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException; 051import org.apache.hadoop.hbase.testclassification.ClientTests; 052import org.apache.hadoop.hbase.testclassification.LargeTests; 053import org.apache.hadoop.hbase.util.Bytes; 054import org.junit.AfterClass; 055import org.junit.Assume; 056import org.junit.ClassRule; 057import org.junit.Rule; 058import org.junit.Test; 059import org.junit.experimental.categories.Category; 060import org.junit.runner.RunWith; 061import org.junit.runners.Parameterized; 062import org.slf4j.Logger; 063import org.slf4j.LoggerFactory; 064 065import org.apache.hbase.thirdparty.com.google.common.collect.Iterables; 066 067/** 068 * Run tests that use the HBase clients; {@link Table}. Sets up the HBase mini cluster once at start 069 * and runs through all client tests. Each creates a table named for the method and does its stuff 070 * against that. Parameterized to run with different registry implementations. 071 */ 072@Category({ LargeTests.class, ClientTests.class }) 073@SuppressWarnings("deprecation") 074@RunWith(Parameterized.class) 075public class TestFromClientSide4 extends FromClientSideBase { 076 private static final Logger LOG = LoggerFactory.getLogger(TestFromClientSide4.class); 077 @ClassRule 078 public static final HBaseClassTestRule CLASS_RULE = 079 HBaseClassTestRule.forClass(TestFromClientSide4.class); 080 @Rule 081 public TableNameTestRule name = new TableNameTestRule(); 082 083 // To keep the child classes happy. 084 TestFromClientSide4() { 085 } 086 087 public TestFromClientSide4(Class registry, int numHedgedReqs) throws Exception { 088 initialize(registry, numHedgedReqs, MultiRowMutationEndpoint.class); 089 } 090 091 @Parameterized.Parameters 092 public static Collection parameters() { 093 return Arrays.asList(new Object[][] { { MasterRegistry.class, 1 }, { MasterRegistry.class, 2 }, 094 { ZKConnectionRegistry.class, 1 } }); 095 } 096 097 @AfterClass 098 public static void tearDownAfterClass() throws Exception { 099 afterClass(); 100 } 101 102 /** 103 * Test batch operations with combination of valid and invalid args 104 */ 105 @Test 106 public void testBatchOperationsWithErrors() throws Exception { 107 final TableName tableName = name.getTableName(); 108 try (Table foo = TEST_UTIL.createTable(tableName, new byte[][] { FAMILY }, 10)) { 109 110 int NUM_OPS = 100; 111 112 // 1.1 Put with no column families (local validation, runtime exception) 113 List<Put> puts = new ArrayList<>(NUM_OPS); 114 for (int i = 0; i != NUM_OPS; i++) { 115 Put put = new Put(Bytes.toBytes(i)); 116 puts.add(put); 117 } 118 119 try { 120 foo.put(puts); 121 fail(); 122 } catch (IllegalArgumentException e) { 123 // expected 124 assertEquals(NUM_OPS, puts.size()); 125 } 126 127 // 1.2 Put with invalid column family 128 puts.clear(); 129 for (int i = 0; i < NUM_OPS; i++) { 130 Put put = new Put(Bytes.toBytes(i)); 131 put.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY, Bytes.toBytes(i)); 132 puts.add(put); 133 } 134 135 try { 136 foo.put(puts); 137 fail(); 138 } catch (RetriesExhaustedException e) { 139 if (e instanceof RetriesExhaustedWithDetailsException) { 140 assertThat(((RetriesExhaustedWithDetailsException) e).exceptions.get(0), 141 instanceOf(NoSuchColumnFamilyException.class)); 142 } else { 143 assertThat(e.getCause(), instanceOf(NoSuchColumnFamilyException.class)); 144 } 145 } 146 147 // 2.1 Get non-existent rows 148 List<Get> gets = new ArrayList<>(NUM_OPS); 149 for (int i = 0; i < NUM_OPS; i++) { 150 Get get = new Get(Bytes.toBytes(i)); 151 gets.add(get); 152 } 153 Result[] getsResult = foo.get(gets); 154 assertNotNull(getsResult); 155 assertEquals(NUM_OPS, getsResult.length); 156 for (int i = 0; i < NUM_OPS; i++) { 157 Result getResult = getsResult[i]; 158 if (i % 2 == 0) { 159 assertFalse(getResult.isEmpty()); 160 } else { 161 assertTrue(getResult.isEmpty()); 162 } 163 } 164 165 // 2.2 Get with invalid column family 166 gets.clear(); 167 for (int i = 0; i < NUM_OPS; i++) { 168 Get get = new Get(Bytes.toBytes(i)); 169 get.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY); 170 gets.add(get); 171 } 172 try { 173 foo.get(gets); 174 fail(); 175 } catch (RetriesExhaustedException e) { 176 if (e instanceof RetriesExhaustedWithDetailsException) { 177 assertThat(((RetriesExhaustedWithDetailsException) e).exceptions.get(0), 178 instanceOf(NoSuchColumnFamilyException.class)); 179 } else { 180 assertThat(e.getCause(), instanceOf(NoSuchColumnFamilyException.class)); 181 } 182 } 183 184 // 3.1 Delete with invalid column family 185 List<Delete> deletes = new ArrayList<>(NUM_OPS); 186 for (int i = 0; i < NUM_OPS; i++) { 187 Delete delete = new Delete(Bytes.toBytes(i)); 188 delete.addColumn((i % 2) == 0 ? FAMILY : INVALID_FAMILY, FAMILY); 189 deletes.add(delete); 190 } 191 try { 192 foo.delete(deletes); 193 fail(); 194 } catch (RetriesExhaustedException e) { 195 if (e instanceof RetriesExhaustedWithDetailsException) { 196 assertThat(((RetriesExhaustedWithDetailsException) e).exceptions.get(0), 197 instanceOf(NoSuchColumnFamilyException.class)); 198 } else { 199 assertThat(e.getCause(), instanceOf(NoSuchColumnFamilyException.class)); 200 } 201 } 202 203 // all valid rows should have been deleted 204 gets.clear(); 205 for (int i = 0; i < NUM_OPS; i++) { 206 Get get = new Get(Bytes.toBytes(i)); 207 gets.add(get); 208 } 209 getsResult = foo.get(gets); 210 assertNotNull(getsResult); 211 assertEquals(NUM_OPS, getsResult.length); 212 for (Result getResult : getsResult) { 213 assertTrue(getResult.isEmpty()); 214 } 215 216 // 3.2 Delete non-existent rows 217 deletes.clear(); 218 for (int i = 0; i < NUM_OPS; i++) { 219 Delete delete = new Delete(Bytes.toBytes(i)); 220 deletes.add(delete); 221 } 222 foo.delete(deletes); 223 } 224 } 225 226 // 227 // JIRA Testers 228 // 229 230 /** 231 * HBASE-867 If millions of columns in a column family, hbase scanner won't come up Test will 232 * create numRows rows, each with numColsPerRow columns (1 version each), and attempt to scan them 233 * all. To test at scale, up numColsPerRow to the millions (have not gotten that to work running 234 * as junit though) 235 */ 236 @Test 237 public void testJiraTest867() throws Exception { 238 int numRows = 10; 239 int numColsPerRow = 2000; 240 241 final TableName tableName = name.getTableName(); 242 243 byte[][] ROWS = makeN(ROW, numRows); 244 byte[][] QUALIFIERS = makeN(QUALIFIER, numColsPerRow); 245 246 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY)) { 247 248 // Insert rows 249 250 for (int i = 0; i < numRows; i++) { 251 Put put = new Put(ROWS[i]); 252 put.setDurability(Durability.SKIP_WAL); 253 for (int j = 0; j < numColsPerRow; j++) { 254 put.addColumn(FAMILY, QUALIFIERS[j], QUALIFIERS[j]); 255 } 256 assertEquals("Put expected to contain " + numColsPerRow + " columns but " + "only contains " 257 + put.size(), put.size(), numColsPerRow); 258 ht.put(put); 259 } 260 261 // Get a row 262 Get get = new Get(ROWS[numRows - 1]); 263 Result result = ht.get(get); 264 assertNumKeys(result, numColsPerRow); 265 Cell[] keys = result.rawCells(); 266 for (int i = 0; i < result.size(); i++) { 267 assertKey(keys[i], ROWS[numRows - 1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]); 268 } 269 270 // Scan the rows 271 Scan scan = new Scan(); 272 try (ResultScanner scanner = ht.getScanner(scan)) { 273 int rowCount = 0; 274 while ((result = scanner.next()) != null) { 275 assertNumKeys(result, numColsPerRow); 276 Cell[] kvs = result.rawCells(); 277 for (int i = 0; i < numColsPerRow; i++) { 278 assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]); 279 } 280 rowCount++; 281 } 282 assertEquals( 283 "Expected to scan " + numRows + " rows but actually scanned " + rowCount + " rows", 284 rowCount, numRows); 285 } 286 287 // flush and try again 288 289 TEST_UTIL.flush(); 290 291 // Get a row 292 get = new Get(ROWS[numRows - 1]); 293 result = ht.get(get); 294 assertNumKeys(result, numColsPerRow); 295 keys = result.rawCells(); 296 for (int i = 0; i < result.size(); i++) { 297 assertKey(keys[i], ROWS[numRows - 1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]); 298 } 299 300 // Scan the rows 301 scan = new Scan(); 302 try (ResultScanner scanner = ht.getScanner(scan)) { 303 int rowCount = 0; 304 while ((result = scanner.next()) != null) { 305 assertNumKeys(result, numColsPerRow); 306 Cell[] kvs = result.rawCells(); 307 for (int i = 0; i < numColsPerRow; i++) { 308 assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]); 309 } 310 rowCount++; 311 } 312 assertEquals( 313 "Expected to scan " + numRows + " rows but actually scanned " + rowCount + " rows", 314 rowCount, numRows); 315 } 316 } 317 } 318 319 /** 320 * HBASE-861 get with timestamp will return a value if there is a version with an earlier 321 * timestamp 322 */ 323 @Test 324 public void testJiraTest861() throws Exception { 325 final TableName tableName = name.getTableName(); 326 byte[][] VALUES = makeNAscii(VALUE, 7); 327 long[] STAMPS = makeStamps(7); 328 329 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 330 331 // Insert three versions 332 333 Put put = new Put(ROW); 334 put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 335 put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 336 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 337 ht.put(put); 338 339 // Get the middle value 340 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 341 342 // Try to get one version before (expect fail) 343 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]); 344 345 // Try to get one version after (expect fail) 346 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]); 347 348 // Try same from storefile 349 TEST_UTIL.flush(); 350 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 351 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]); 352 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]); 353 354 // Insert two more versions surrounding others, into memstore 355 put = new Put(ROW); 356 put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]); 357 put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]); 358 ht.put(put); 359 360 // Check we can get everything we should and can't get what we shouldn't 361 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]); 362 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]); 363 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 364 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 365 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 366 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]); 367 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]); 368 369 // Try same from two storefiles 370 TEST_UTIL.flush(); 371 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]); 372 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]); 373 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 374 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 375 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 376 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]); 377 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]); 378 } 379 } 380 381 /** 382 * HBASE-33 Add a HTable get/obtainScanner method that retrieves all versions of a particular 383 * column and row between two timestamps 384 */ 385 @Test 386 public void testJiraTest33() throws Exception { 387 final TableName tableName = name.getTableName(); 388 byte[][] VALUES = makeNAscii(VALUE, 7); 389 long[] STAMPS = makeStamps(7); 390 391 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 392 393 // Insert lots versions 394 395 Put put = new Put(ROW); 396 put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]); 397 put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 398 put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 399 put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 400 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 401 put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 402 ht.put(put); 403 404 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 405 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2); 406 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 407 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3); 408 409 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 410 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2); 411 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 412 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3); 413 414 // Try same from storefile 415 TEST_UTIL.flush(); 416 417 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 418 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2); 419 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 420 getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3); 421 422 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 423 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2); 424 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 425 scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3); 426 } 427 } 428 429 /** 430 * HBASE-1014 commit(BatchUpdate) method should return timestamp 431 */ 432 @Test 433 public void testJiraTest1014() throws Exception { 434 final TableName tableName = name.getTableName(); 435 436 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 437 438 long manualStamp = 12345; 439 440 // Insert lots versions 441 442 Put put = new Put(ROW); 443 put.addColumn(FAMILY, QUALIFIER, manualStamp, VALUE); 444 ht.put(put); 445 446 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, manualStamp, VALUE); 447 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp - 1); 448 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp + 1); 449 } 450 } 451 452 /** 453 * HBASE-1182 Scan for columns > some timestamp 454 */ 455 @Test 456 public void testJiraTest1182() throws Exception { 457 final TableName tableName = name.getTableName(); 458 byte[][] VALUES = makeNAscii(VALUE, 7); 459 long[] STAMPS = makeStamps(7); 460 461 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 462 463 // Insert lots versions 464 465 Put put = new Put(ROW); 466 put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]); 467 put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 468 put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 469 put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 470 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 471 put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 472 ht.put(put); 473 474 getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 475 getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5); 476 getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 477 478 scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 479 scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5); 480 scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 481 482 // Try same from storefile 483 TEST_UTIL.flush(); 484 485 getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 486 getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5); 487 getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 488 489 scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 490 scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5); 491 scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5); 492 } 493 } 494 495 /** 496 * HBASE-52 Add a means of scanning over all versions 497 */ 498 @Test 499 public void testJiraTest52() throws Exception { 500 final TableName tableName = name.getTableName(); 501 byte[][] VALUES = makeNAscii(VALUE, 7); 502 long[] STAMPS = makeStamps(7); 503 504 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 505 506 // Insert lots versions 507 508 Put put = new Put(ROW); 509 put.addColumn(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]); 510 put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 511 put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 512 put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 513 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 514 put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 515 ht.put(put); 516 517 getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 518 519 scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 520 521 // Try same from storefile 522 TEST_UTIL.flush(); 523 524 getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 525 526 scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5); 527 } 528 } 529 530 @Test 531 @SuppressWarnings("checkstyle:MethodLength") 532 public void testDuplicateVersions() throws Exception { 533 final TableName tableName = name.getTableName(); 534 535 long[] STAMPS = makeStamps(20); 536 byte[][] VALUES = makeNAscii(VALUE, 20); 537 538 try (Table ht = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 539 540 // Insert 4 versions of same column 541 Put put = new Put(ROW); 542 put.addColumn(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 543 put.addColumn(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 544 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 545 put.addColumn(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 546 ht.put(put); 547 548 // Verify we can get each one properly 549 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 550 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 551 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 552 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 553 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 554 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 555 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 556 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 557 558 // Verify we don't accidentally get others 559 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 560 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 561 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 562 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 563 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 564 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 565 566 // Ensure maxVersions in query is respected 567 Get get = new Get(ROW); 568 get.addColumn(FAMILY, QUALIFIER); 569 get.readVersions(2); 570 Result result = ht.get(get); 571 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 572 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 573 574 Scan scan = new Scan(ROW); 575 scan.addColumn(FAMILY, QUALIFIER); 576 scan.setMaxVersions(2); 577 result = getSingleScanResult(ht, scan); 578 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 579 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 580 581 // Flush and redo 582 583 TEST_UTIL.flush(); 584 585 // Verify we can get each one properly 586 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 587 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 588 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 589 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 590 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 591 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 592 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]); 593 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]); 594 595 // Verify we don't accidentally get others 596 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 597 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 598 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 599 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 600 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]); 601 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]); 602 603 // Ensure maxVersions in query is respected 604 get = new Get(ROW); 605 get.addColumn(FAMILY, QUALIFIER); 606 get.readVersions(2); 607 result = ht.get(get); 608 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 609 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 610 611 scan = new Scan(ROW); 612 scan.addColumn(FAMILY, QUALIFIER); 613 scan.setMaxVersions(2); 614 result = getSingleScanResult(ht, scan); 615 assertNResult(result, ROW, FAMILY, QUALIFIER, new long[] { STAMPS[4], STAMPS[5] }, 616 new byte[][] { VALUES[4], VALUES[5] }, 0, 1); 617 618 // Add some memstore and retest 619 620 // Insert 4 more versions of same column and a dupe 621 put = new Put(ROW); 622 put.addColumn(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]); 623 put.addColumn(FAMILY, QUALIFIER, STAMPS[4], VALUES[14]); 624 put.addColumn(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]); 625 put.addColumn(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 626 put.addColumn(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]); 627 ht.put(put); 628 629 // Ensure maxVersions in query is respected 630 get = new Get(ROW); 631 get.addColumn(FAMILY, QUALIFIER); 632 get.readVersions(7); 633 result = ht.get(get); 634 assertNResult(result, ROW, FAMILY, QUALIFIER, 635 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8] }, 636 new byte[][] { VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], 637 VALUES[8] }, 638 0, 6); 639 640 scan = new Scan(ROW); 641 scan.addColumn(FAMILY, QUALIFIER); 642 scan.setMaxVersions(7); 643 result = getSingleScanResult(ht, scan); 644 assertNResult(result, ROW, FAMILY, QUALIFIER, 645 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8] }, 646 new byte[][] { VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], 647 VALUES[8] }, 648 0, 6); 649 650 get = new Get(ROW); 651 get.readVersions(7); 652 result = ht.get(get); 653 assertNResult(result, ROW, FAMILY, QUALIFIER, 654 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8] }, 655 new byte[][] { VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], 656 VALUES[8] }, 657 0, 6); 658 659 scan = new Scan(ROW); 660 scan.setMaxVersions(7); 661 result = getSingleScanResult(ht, scan); 662 assertNResult(result, ROW, FAMILY, QUALIFIER, 663 new long[] { STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8] }, 664 new byte[][] { VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], 665 VALUES[8] }, 666 0, 6); 667 668 // Verify we can get each one properly 669 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 670 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 671 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]); 672 getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 673 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]); 674 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]); 675 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]); 676 scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]); 677 678 // Verify we don't accidentally get others 679 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 680 getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]); 681 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]); 682 scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]); 683 684 // Ensure maxVersions of table is respected 685 686 TEST_UTIL.flush(); 687 688 // Insert 4 more versions of same column and a dupe 689 put = new Put(ROW); 690 put.addColumn(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]); 691 put.addColumn(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]); 692 put.addColumn(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]); 693 put.addColumn(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]); 694 ht.put(put); 695 696 get = new Get(ROW); 697 get.addColumn(FAMILY, QUALIFIER); 698 get.readVersions(Integer.MAX_VALUE); 699 result = ht.get(get); 700 assertNResult(result, ROW, FAMILY, QUALIFIER, 701 new long[] { STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], 702 STAMPS[11], STAMPS[13], STAMPS[15] }, 703 new byte[][] { VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], 704 VALUES[11], VALUES[13], VALUES[15] }, 705 0, 9); 706 707 scan = new Scan(ROW); 708 scan.addColumn(FAMILY, QUALIFIER); 709 scan.setMaxVersions(Integer.MAX_VALUE); 710 result = getSingleScanResult(ht, scan); 711 assertNResult(result, ROW, FAMILY, QUALIFIER, 712 new long[] { STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], 713 STAMPS[11], STAMPS[13], STAMPS[15] }, 714 new byte[][] { VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], 715 VALUES[11], VALUES[13], VALUES[15] }, 716 0, 9); 717 718 // Delete a version in the memstore and a version in a storefile 719 Delete delete = new Delete(ROW); 720 delete.addColumn(FAMILY, QUALIFIER, STAMPS[11]); 721 delete.addColumn(FAMILY, QUALIFIER, STAMPS[7]); 722 ht.delete(delete); 723 724 // Test that it's gone 725 get = new Get(ROW); 726 get.addColumn(FAMILY, QUALIFIER); 727 get.readVersions(Integer.MAX_VALUE); 728 result = ht.get(get); 729 assertNResult(result, ROW, FAMILY, QUALIFIER, 730 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], 731 STAMPS[9], STAMPS[13], STAMPS[15] }, 732 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[8], 733 VALUES[9], VALUES[13], VALUES[15] }, 734 0, 9); 735 736 scan = new Scan(ROW); 737 scan.addColumn(FAMILY, QUALIFIER); 738 scan.setMaxVersions(Integer.MAX_VALUE); 739 result = getSingleScanResult(ht, scan); 740 assertNResult(result, ROW, FAMILY, QUALIFIER, 741 new long[] { STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], 742 STAMPS[9], STAMPS[13], STAMPS[15] }, 743 new byte[][] { VALUES[1], VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[8], 744 VALUES[9], VALUES[13], VALUES[15] }, 745 0, 9); 746 } 747 } 748 749 @Test 750 public void testUpdates() throws Exception { 751 final TableName tableName = name.getTableName(); 752 try (Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10)) { 753 754 // Write a column with values at timestamp 1, 2 and 3 755 byte[] row = Bytes.toBytes("row1"); 756 byte[] qualifier = Bytes.toBytes("myCol"); 757 Put put = new Put(row); 758 put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA")); 759 hTable.put(put); 760 761 put = new Put(row); 762 put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB")); 763 hTable.put(put); 764 765 put = new Put(row); 766 put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE")); 767 hTable.put(put); 768 769 Get get = new Get(row); 770 get.addColumn(FAMILY, qualifier); 771 get.readAllVersions(); 772 773 // Check that the column indeed has the right values at timestamps 1 and 774 // 2 775 Result result = hTable.get(get); 776 NavigableMap<Long, byte[]> navigableMap = result.getMap().get(FAMILY).get(qualifier); 777 assertEquals("AAA", Bytes.toString(navigableMap.get(1L))); 778 assertEquals("BBB", Bytes.toString(navigableMap.get(2L))); 779 780 // Update the value at timestamp 1 781 put = new Put(row); 782 put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC")); 783 hTable.put(put); 784 785 // Update the value at timestamp 2 786 put = new Put(row); 787 put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD")); 788 hTable.put(put); 789 790 // Check that the values at timestamp 2 and 1 got updated 791 result = hTable.get(get); 792 navigableMap = result.getMap().get(FAMILY).get(qualifier); 793 assertEquals("CCC", Bytes.toString(navigableMap.get(1L))); 794 assertEquals("DDD", Bytes.toString(navigableMap.get(2L))); 795 } 796 } 797 798 @Test 799 public void testUpdatesWithMajorCompaction() throws Exception { 800 final TableName tableName = name.getTableName(); 801 try (Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10); 802 Admin admin = TEST_UTIL.getAdmin()) { 803 804 // Write a column with values at timestamp 1, 2 and 3 805 byte[] row = Bytes.toBytes("row2"); 806 byte[] qualifier = Bytes.toBytes("myCol"); 807 Put put = new Put(row); 808 put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA")); 809 hTable.put(put); 810 811 put = new Put(row); 812 put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB")); 813 hTable.put(put); 814 815 put = new Put(row); 816 put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE")); 817 hTable.put(put); 818 819 Get get = new Get(row); 820 get.addColumn(FAMILY, qualifier); 821 get.readAllVersions(); 822 823 // Check that the column indeed has the right values at timestamps 1 and 824 // 2 825 Result result = hTable.get(get); 826 NavigableMap<Long, byte[]> navigableMap = result.getMap().get(FAMILY).get(qualifier); 827 assertEquals("AAA", Bytes.toString(navigableMap.get(1L))); 828 assertEquals("BBB", Bytes.toString(navigableMap.get(2L))); 829 830 // Trigger a major compaction 831 admin.flush(tableName); 832 admin.majorCompact(tableName); 833 Thread.sleep(6000); 834 835 // Update the value at timestamp 1 836 put = new Put(row); 837 put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC")); 838 hTable.put(put); 839 840 // Update the value at timestamp 2 841 put = new Put(row); 842 put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD")); 843 hTable.put(put); 844 845 // Trigger a major compaction 846 admin.flush(tableName); 847 admin.majorCompact(tableName); 848 Thread.sleep(6000); 849 850 // Check that the values at timestamp 2 and 1 got updated 851 result = hTable.get(get); 852 navigableMap = result.getMap().get(FAMILY).get(qualifier); 853 assertEquals("CCC", Bytes.toString(navigableMap.get(1L))); 854 assertEquals("DDD", Bytes.toString(navigableMap.get(2L))); 855 } 856 } 857 858 @Test 859 public void testMajorCompactionBetweenTwoUpdates() throws Exception { 860 final TableName tableName = name.getTableName(); 861 try (Table hTable = TEST_UTIL.createTable(tableName, FAMILY, 10); 862 Admin admin = TEST_UTIL.getAdmin()) { 863 864 // Write a column with values at timestamp 1, 2 and 3 865 byte[] row = Bytes.toBytes("row3"); 866 byte[] qualifier = Bytes.toBytes("myCol"); 867 Put put = new Put(row); 868 put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("AAA")); 869 hTable.put(put); 870 871 put = new Put(row); 872 put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("BBB")); 873 hTable.put(put); 874 875 put = new Put(row); 876 put.addColumn(FAMILY, qualifier, 3L, Bytes.toBytes("EEE")); 877 hTable.put(put); 878 879 Get get = new Get(row); 880 get.addColumn(FAMILY, qualifier); 881 get.readAllVersions(); 882 883 // Check that the column indeed has the right values at timestamps 1 and 884 // 2 885 Result result = hTable.get(get); 886 NavigableMap<Long, byte[]> navigableMap = result.getMap().get(FAMILY).get(qualifier); 887 assertEquals("AAA", Bytes.toString(navigableMap.get(1L))); 888 assertEquals("BBB", Bytes.toString(navigableMap.get(2L))); 889 890 // Trigger a major compaction 891 admin.flush(tableName); 892 admin.majorCompact(tableName); 893 Thread.sleep(6000); 894 895 // Update the value at timestamp 1 896 put = new Put(row); 897 put.addColumn(FAMILY, qualifier, 1L, Bytes.toBytes("CCC")); 898 hTable.put(put); 899 900 // Trigger a major compaction 901 admin.flush(tableName); 902 admin.majorCompact(tableName); 903 Thread.sleep(6000); 904 905 // Update the value at timestamp 2 906 put = new Put(row); 907 put.addColumn(FAMILY, qualifier, 2L, Bytes.toBytes("DDD")); 908 hTable.put(put); 909 910 // Trigger a major compaction 911 admin.flush(tableName); 912 admin.majorCompact(tableName); 913 Thread.sleep(6000); 914 915 // Check that the values at timestamp 2 and 1 got updated 916 result = hTable.get(get); 917 navigableMap = result.getMap().get(FAMILY).get(qualifier); 918 919 assertEquals("CCC", Bytes.toString(navigableMap.get(1L))); 920 assertEquals("DDD", Bytes.toString(navigableMap.get(2L))); 921 } 922 } 923 924 @Test 925 public void testGet_EmptyTable() throws IOException { 926 try (Table table = TEST_UTIL.createTable(name.getTableName(), FAMILY)) { 927 Get get = new Get(ROW); 928 get.addFamily(FAMILY); 929 Result r = table.get(get); 930 assertTrue(r.isEmpty()); 931 } 932 } 933 934 @Test 935 public void testGet_NullQualifier() throws IOException { 936 try (Table table = TEST_UTIL.createTable(name.getTableName(), FAMILY)) { 937 Put put = new Put(ROW); 938 put.addColumn(FAMILY, QUALIFIER, VALUE); 939 table.put(put); 940 941 put = new Put(ROW); 942 put.addColumn(FAMILY, null, VALUE); 943 table.put(put); 944 LOG.info("Row put"); 945 946 Get get = new Get(ROW); 947 get.addColumn(FAMILY, null); 948 Result r = table.get(get); 949 assertEquals(1, r.size()); 950 951 get = new Get(ROW); 952 get.addFamily(FAMILY); 953 r = table.get(get); 954 assertEquals(2, r.size()); 955 } 956 } 957 958 @Test 959 public void testGet_NonExistentRow() throws IOException { 960 try (Table table = TEST_UTIL.createTable(name.getTableName(), FAMILY)) { 961 Put put = new Put(ROW); 962 put.addColumn(FAMILY, QUALIFIER, VALUE); 963 table.put(put); 964 LOG.info("Row put"); 965 966 Get get = new Get(ROW); 967 get.addFamily(FAMILY); 968 Result r = table.get(get); 969 assertFalse(r.isEmpty()); 970 System.out.println("Row retrieved successfully"); 971 972 byte[] missingrow = Bytes.toBytes("missingrow"); 973 get = new Get(missingrow); 974 get.addFamily(FAMILY); 975 r = table.get(get); 976 assertTrue(r.isEmpty()); 977 LOG.info("Row missing as it should be"); 978 } 979 } 980 981 @Test 982 public void testPut() throws IOException { 983 final byte[] CONTENTS_FAMILY = Bytes.toBytes("contents"); 984 final byte[] SMALL_FAMILY = Bytes.toBytes("smallfam"); 985 final byte[] row1 = Bytes.toBytes("row1"); 986 final byte[] row2 = Bytes.toBytes("row2"); 987 final byte[] value = Bytes.toBytes("abcd"); 988 try (Table table = 989 TEST_UTIL.createTable(name.getTableName(), new byte[][] { CONTENTS_FAMILY, SMALL_FAMILY })) { 990 Put put = new Put(row1); 991 put.addColumn(CONTENTS_FAMILY, null, value); 992 table.put(put); 993 994 put = new Put(row2); 995 put.addColumn(CONTENTS_FAMILY, null, value); 996 997 assertEquals(1, put.size()); 998 assertEquals(1, put.getFamilyCellMap().get(CONTENTS_FAMILY).size()); 999 1000 // KeyValue v1 expectation. Cast for now until we go all Cell all the time. TODO 1001 KeyValue kv = (KeyValue) put.getFamilyCellMap().get(CONTENTS_FAMILY).get(0); 1002 1003 assertTrue(Bytes.equals(CellUtil.cloneFamily(kv), CONTENTS_FAMILY)); 1004 // will it return null or an empty byte array? 1005 assertTrue(Bytes.equals(CellUtil.cloneQualifier(kv), new byte[0])); 1006 1007 assertTrue(Bytes.equals(CellUtil.cloneValue(kv), value)); 1008 1009 table.put(put); 1010 1011 Scan scan = new Scan(); 1012 scan.addColumn(CONTENTS_FAMILY, null); 1013 try (ResultScanner scanner = table.getScanner(scan)) { 1014 for (Result r : scanner) { 1015 for (Cell key : r.rawCells()) { 1016 System.out.println(Bytes.toString(r.getRow()) + ": " + key.toString()); 1017 } 1018 } 1019 } 1020 } 1021 } 1022 1023 @Test 1024 public void testPutNoCF() throws IOException { 1025 final byte[] BAD_FAM = Bytes.toBytes("BAD_CF"); 1026 final byte[] VAL = Bytes.toBytes(100); 1027 try (Table table = TEST_UTIL.createTable(name.getTableName(), FAMILY)) { 1028 boolean caughtNSCFE = false; 1029 1030 try { 1031 Put p = new Put(ROW); 1032 p.addColumn(BAD_FAM, QUALIFIER, VAL); 1033 table.put(p); 1034 } catch (Exception e) { 1035 caughtNSCFE = e instanceof NoSuchColumnFamilyException; 1036 } 1037 assertTrue("Should throw NoSuchColumnFamilyException", caughtNSCFE); 1038 } 1039 } 1040 1041 @Test 1042 public void testRowsPut() throws IOException { 1043 final byte[] CONTENTS_FAMILY = Bytes.toBytes("contents"); 1044 final byte[] SMALL_FAMILY = Bytes.toBytes("smallfam"); 1045 final int NB_BATCH_ROWS = 10; 1046 final byte[] value = Bytes.toBytes("abcd"); 1047 try (Table table = 1048 TEST_UTIL.createTable(name.getTableName(), new byte[][] { CONTENTS_FAMILY, SMALL_FAMILY })) { 1049 ArrayList<Put> rowsUpdate = new ArrayList<>(); 1050 for (int i = 0; i < NB_BATCH_ROWS; i++) { 1051 byte[] row = Bytes.toBytes("row" + i); 1052 Put put = new Put(row); 1053 put.setDurability(Durability.SKIP_WAL); 1054 put.addColumn(CONTENTS_FAMILY, null, value); 1055 rowsUpdate.add(put); 1056 } 1057 table.put(rowsUpdate); 1058 Scan scan = new Scan(); 1059 scan.addFamily(CONTENTS_FAMILY); 1060 try (ResultScanner scanner = table.getScanner(scan)) { 1061 int nbRows = Iterables.size(scanner); 1062 assertEquals(NB_BATCH_ROWS, nbRows); 1063 } 1064 } 1065 } 1066 1067 @Test 1068 public void testRowsPutBufferedManyManyFlushes() throws IOException { 1069 final byte[] CONTENTS_FAMILY = Bytes.toBytes("contents"); 1070 final byte[] SMALL_FAMILY = Bytes.toBytes("smallfam"); 1071 final byte[] value = Bytes.toBytes("abcd"); 1072 final int NB_BATCH_ROWS = 10; 1073 try (Table table = 1074 TEST_UTIL.createTable(name.getTableName(), new byte[][] { CONTENTS_FAMILY, SMALL_FAMILY })) { 1075 ArrayList<Put> rowsUpdate = new ArrayList<>(); 1076 for (int i = 0; i < NB_BATCH_ROWS * 10; i++) { 1077 byte[] row = Bytes.toBytes("row" + i); 1078 Put put = new Put(row); 1079 put.setDurability(Durability.SKIP_WAL); 1080 put.addColumn(CONTENTS_FAMILY, null, value); 1081 rowsUpdate.add(put); 1082 } 1083 table.put(rowsUpdate); 1084 1085 Scan scan = new Scan(); 1086 scan.addFamily(CONTENTS_FAMILY); 1087 try (ResultScanner scanner = table.getScanner(scan)) { 1088 int nbRows = Iterables.size(scanner); 1089 assertEquals(NB_BATCH_ROWS * 10, nbRows); 1090 } 1091 } 1092 } 1093 1094 @Test 1095 public void testAddKeyValue() { 1096 final byte[] CONTENTS_FAMILY = Bytes.toBytes("contents"); 1097 final byte[] value = Bytes.toBytes("abcd"); 1098 final byte[] row1 = Bytes.toBytes("row1"); 1099 final byte[] row2 = Bytes.toBytes("row2"); 1100 byte[] qualifier = Bytes.toBytes("qf1"); 1101 Put put = new Put(row1); 1102 1103 // Adding KeyValue with the same row 1104 KeyValue kv = new KeyValue(row1, CONTENTS_FAMILY, qualifier, value); 1105 boolean ok = true; 1106 try { 1107 put.add(kv); 1108 } catch (IOException e) { 1109 ok = false; 1110 } 1111 assertTrue(ok); 1112 1113 // Adding KeyValue with the different row 1114 kv = new KeyValue(row2, CONTENTS_FAMILY, qualifier, value); 1115 ok = false; 1116 try { 1117 put.add(kv); 1118 } catch (IOException e) { 1119 ok = true; 1120 } 1121 assertTrue(ok); 1122 } 1123 1124 /** 1125 * test for HBASE-737 1126 */ 1127 @Test 1128 public void testHBase737() throws IOException { 1129 final byte[] FAM1 = Bytes.toBytes("fam1"); 1130 final byte[] FAM2 = Bytes.toBytes("fam2"); 1131 // Open table 1132 try (Table table = TEST_UTIL.createTable(name.getTableName(), new byte[][] { FAM1, FAM2 })) { 1133 // Insert some values 1134 Put put = new Put(ROW); 1135 put.addColumn(FAM1, Bytes.toBytes("letters"), Bytes.toBytes("abcdefg")); 1136 table.put(put); 1137 try { 1138 Thread.sleep(1000); 1139 } catch (InterruptedException i) { 1140 // ignore 1141 } 1142 1143 put = new Put(ROW); 1144 put.addColumn(FAM1, Bytes.toBytes("numbers"), Bytes.toBytes("123456")); 1145 table.put(put); 1146 1147 try { 1148 Thread.sleep(1000); 1149 } catch (InterruptedException i) { 1150 // ignore 1151 } 1152 1153 put = new Put(ROW); 1154 put.addColumn(FAM2, Bytes.toBytes("letters"), Bytes.toBytes("hijklmnop")); 1155 table.put(put); 1156 1157 long[] times = new long[3]; 1158 1159 // First scan the memstore 1160 1161 Scan scan = new Scan(); 1162 scan.addFamily(FAM1); 1163 scan.addFamily(FAM2); 1164 try (ResultScanner s = table.getScanner(scan)) { 1165 int index = 0; 1166 Result r; 1167 while ((r = s.next()) != null) { 1168 for (Cell key : r.rawCells()) { 1169 times[index++] = key.getTimestamp(); 1170 } 1171 } 1172 } 1173 for (int i = 0; i < times.length - 1; i++) { 1174 for (int j = i + 1; j < times.length; j++) { 1175 assertTrue(times[j] > times[i]); 1176 } 1177 } 1178 1179 // Flush data to disk and try again 1180 TEST_UTIL.flush(); 1181 1182 // Reset times 1183 Arrays.fill(times, 0); 1184 1185 try { 1186 Thread.sleep(1000); 1187 } catch (InterruptedException i) { 1188 // ignore 1189 } 1190 scan = new Scan(); 1191 scan.addFamily(FAM1); 1192 scan.addFamily(FAM2); 1193 try (ResultScanner s = table.getScanner(scan)) { 1194 int index = 0; 1195 Result r = null; 1196 while ((r = s.next()) != null) { 1197 for (Cell key : r.rawCells()) { 1198 times[index++] = key.getTimestamp(); 1199 } 1200 } 1201 for (int i = 0; i < times.length - 1; i++) { 1202 for (int j = i + 1; j < times.length; j++) { 1203 assertTrue(times[j] > times[i]); 1204 } 1205 } 1206 } 1207 } 1208 } 1209 1210 @Test 1211 public void testListTables() throws IOException { 1212 final String testTableName = name.getTableName().toString(); 1213 final TableName tableName1 = TableName.valueOf(testTableName + "1"); 1214 final TableName tableName2 = TableName.valueOf(testTableName + "2"); 1215 final TableName tableName3 = TableName.valueOf(testTableName + "3"); 1216 TableName[] tables = new TableName[] { tableName1, tableName2, tableName3 }; 1217 for (TableName table : tables) { 1218 TEST_UTIL.createTable(table, FAMILY); 1219 } 1220 try (Admin admin = TEST_UTIL.getAdmin()) { 1221 List<TableDescriptor> ts = admin.listTableDescriptors(); 1222 HashSet<TableDescriptor> result = new HashSet<>(ts); 1223 int size = result.size(); 1224 assertTrue(size >= tables.length); 1225 for (TableName table : tables) { 1226 boolean found = false; 1227 for (TableDescriptor t : ts) { 1228 if (t.getTableName().equals(table)) { 1229 found = true; 1230 break; 1231 } 1232 } 1233 assertTrue("Not found: " + table, found); 1234 } 1235 } 1236 } 1237 1238 /** 1239 * simple test that just executes parts of the client API that accept a pre-created Connection 1240 * instance 1241 */ 1242 @Test 1243 public void testUnmanagedHConnection() throws IOException { 1244 final TableName tableName = name.getTableName(); 1245 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY); 1246 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); 1247 Table t = conn.getTable(tableName); Admin admin = conn.getAdmin()) { 1248 assertTrue(admin.tableExists(tableName)); 1249 assertTrue(t.get(new Get(ROW)).isEmpty()); 1250 } 1251 } 1252 1253 /** 1254 * test of that unmanaged HConnections are able to reconnect properly (see HBASE-5058) 1255 */ 1256 @Test 1257 public void testUnmanagedHConnectionReconnect() throws Exception { 1258 Configuration conf = TEST_UTIL.getConfiguration(); 1259 Class registryImpl = conf.getClass(HConstants.CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY, 1260 ZKConnectionRegistry.class); 1261 // This test does not make sense for MasterRegistry since it stops the only master in the 1262 // cluster and starts a new master without populating the underlying config for the connection. 1263 Assume.assumeFalse(registryImpl.equals(MasterRegistry.class)); 1264 final TableName tableName = name.getTableName(); 1265 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY); 1266 try (Connection conn = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) { 1267 try (Table t = conn.getTable(tableName); Admin admin = conn.getAdmin()) { 1268 assertTrue(admin.tableExists(tableName)); 1269 assertTrue(t.get(new Get(ROW)).isEmpty()); 1270 } 1271 1272 // stop the master 1273 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); 1274 cluster.stopMaster(0, false); 1275 cluster.waitOnMaster(0); 1276 1277 // start up a new master 1278 cluster.startMaster(); 1279 assertTrue(cluster.waitForActiveAndReadyMaster()); 1280 1281 // test that the same unmanaged connection works with a new 1282 // Admin and can connect to the new master; 1283 boolean tablesOnMaster = LoadBalancer.isTablesOnMaster(TEST_UTIL.getConfiguration()); 1284 try (Admin admin = conn.getAdmin()) { 1285 assertTrue(admin.tableExists(tableName)); 1286 assertEquals( 1287 admin.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS)).getLiveServerMetrics().size(), 1288 SLAVES + (tablesOnMaster ? 1 : 0)); 1289 } 1290 } 1291 } 1292 1293 @Test 1294 public void testMiscHTableStuff() throws IOException { 1295 final String testTableName = name.getTableName().toString(); 1296 final TableName tableAname = TableName.valueOf(testTableName + "A"); 1297 final TableName tableBname = TableName.valueOf(testTableName + "B"); 1298 final byte[] attrName = Bytes.toBytes("TESTATTR"); 1299 final byte[] attrValue = Bytes.toBytes("somevalue"); 1300 byte[] value = Bytes.toBytes("value"); 1301 1302 try (Table a = TEST_UTIL.createTable(tableAname, HConstants.CATALOG_FAMILY); 1303 Table b = TEST_UTIL.createTable(tableBname, HConstants.CATALOG_FAMILY)) { 1304 Put put = new Put(ROW); 1305 put.addColumn(HConstants.CATALOG_FAMILY, null, value); 1306 a.put(put); 1307 1308 // open a new connection to A and a connection to b 1309 try (Table newA = TEST_UTIL.getConnection().getTable(tableAname)) { 1310 1311 // copy data from A to B 1312 Scan scan = new Scan(); 1313 scan.addFamily(HConstants.CATALOG_FAMILY); 1314 try (ResultScanner s = newA.getScanner(scan)) { 1315 for (Result r : s) { 1316 put = new Put(r.getRow()); 1317 put.setDurability(Durability.SKIP_WAL); 1318 for (Cell kv : r.rawCells()) { 1319 put.add(kv); 1320 } 1321 b.put(put); 1322 } 1323 } 1324 } 1325 1326 // Opening a new connection to A will cause the tables to be reloaded 1327 try (Table anotherA = TEST_UTIL.getConnection().getTable(tableAname)) { 1328 Get get = new Get(ROW); 1329 get.addFamily(HConstants.CATALOG_FAMILY); 1330 anotherA.get(get); 1331 } 1332 1333 // We can still access A through newA because it has the table information 1334 // cached. And if it needs to recalibrate, that will cause the information 1335 // to be reloaded. 1336 1337 // Test user metadata 1338 Admin admin = TEST_UTIL.getAdmin(); 1339 // make a modifiable descriptor 1340 HTableDescriptor desc = new HTableDescriptor(a.getDescriptor()); 1341 // offline the table 1342 admin.disableTable(tableAname); 1343 // add a user attribute to HTD 1344 desc.setValue(attrName, attrValue); 1345 // add a user attribute to HCD 1346 for (HColumnDescriptor c : desc.getFamilies()) { 1347 c.setValue(attrName, attrValue); 1348 } 1349 // update metadata for all regions of this table 1350 admin.modifyTable(desc); 1351 // enable the table 1352 admin.enableTable(tableAname); 1353 1354 // Test that attribute changes were applied 1355 desc = new HTableDescriptor(a.getDescriptor()); 1356 assertEquals("wrong table descriptor returned", desc.getTableName(), tableAname); 1357 // check HTD attribute 1358 value = desc.getValue(attrName); 1359 assertNotNull("missing HTD attribute value", value); 1360 assertFalse("HTD attribute value is incorrect", Bytes.compareTo(value, attrValue) != 0); 1361 // check HCD attribute 1362 for (HColumnDescriptor c : desc.getFamilies()) { 1363 value = c.getValue(attrName); 1364 assertNotNull("missing HCD attribute value", value); 1365 assertFalse("HCD attribute value is incorrect", Bytes.compareTo(value, attrValue) != 0); 1366 } 1367 } 1368 } 1369}