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.apache.hadoop.hbase.HBaseTestingUtil.countRows; 021import static org.junit.jupiter.api.Assertions.assertEquals; 022import static org.junit.jupiter.api.Assertions.assertNull; 023import static org.junit.jupiter.api.Assertions.assertTrue; 024 025import java.io.IOException; 026import java.util.Arrays; 027import java.util.Iterator; 028import java.util.List; 029import java.util.stream.Stream; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.hbase.Cell; 032import org.apache.hadoop.hbase.CellUtil; 033import org.apache.hadoop.hbase.CompareOperator; 034import org.apache.hadoop.hbase.HBaseCommonTestingUtil; 035import org.apache.hadoop.hbase.HBaseTestingUtil; 036import org.apache.hadoop.hbase.HConstants; 037import org.apache.hadoop.hbase.HRegionLocation; 038import org.apache.hadoop.hbase.StartTestingClusterOption; 039import org.apache.hadoop.hbase.TableName; 040import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; 041import org.apache.hadoop.hbase.filter.BinaryComparator; 042import org.apache.hadoop.hbase.filter.Filter; 043import org.apache.hadoop.hbase.filter.FilterList; 044import org.apache.hadoop.hbase.filter.PrefixFilter; 045import org.apache.hadoop.hbase.filter.RowFilter; 046import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 047import org.apache.hadoop.hbase.filter.WhileMatchFilter; 048import org.apache.hadoop.hbase.util.Bytes; 049import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 050import org.apache.hadoop.hbase.util.NonRepeatedEnvironmentEdge; 051import org.apache.hadoop.hbase.util.TableDescriptorChecker; 052import org.junit.jupiter.api.AfterAll; 053import org.junit.jupiter.api.AfterEach; 054import org.junit.jupiter.api.BeforeEach; 055import org.junit.jupiter.api.TestInfo; 056import org.junit.jupiter.params.provider.Arguments; 057import org.slf4j.Logger; 058import org.slf4j.LoggerFactory; 059 060public class FromClientSideTestBase { 061 private static final Logger LOG = LoggerFactory.getLogger(FromClientSideTestBase.class); 062 protected static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 063 static byte[] ROW = Bytes.toBytes("testRow"); 064 static byte[] FAMILY = Bytes.toBytes("testFamily"); 065 static final byte[] INVALID_FAMILY = Bytes.toBytes("invalidTestFamily"); 066 static byte[] QUALIFIER = Bytes.toBytes("testQualifier"); 067 static byte[] VALUE = Bytes.toBytes("testValue"); 068 static int SLAVES = 1; 069 070 protected Class<? extends ConnectionRegistry> registryImpl; 071 protected int numHedgedReqs; 072 073 protected TableName tableName; 074 075 protected FromClientSideTestBase(Class<? extends ConnectionRegistry> registryImpl, 076 int numHedgedReqs) { 077 this.registryImpl = registryImpl; 078 this.numHedgedReqs = numHedgedReqs; 079 } 080 081 @BeforeEach 082 public void setUp(TestInfo testInfo) { 083 tableName = TableName.valueOf(testInfo.getTestMethod().get().getName() 084 + testInfo.getDisplayName().replaceAll("[^A-Za-z0-9_]", "_")); 085 } 086 087 @AfterEach 088 public void tearDown() throws Exception { 089 for (TableDescriptor htd : TEST_UTIL.getAdmin().listTableDescriptors()) { 090 LOG.info("Tear down, remove table=" + htd.getTableName()); 091 TEST_UTIL.deleteTable(htd.getTableName()); 092 } 093 } 094 095 @SuppressWarnings("deprecation") 096 public static Stream<Arguments> parameters() { 097 return Stream.of(Arguments.of(RpcConnectionRegistry.class, 1), 098 Arguments.of(RpcConnectionRegistry.class, 2), Arguments.of(MasterRegistry.class, 1), 099 Arguments.of(MasterRegistry.class, 2), Arguments.of(ZKConnectionRegistry.class, 1)); 100 } 101 102 protected static final void initialize(Class<?>... cps) throws Exception { 103 // Uncomment the following lines if more verbosity is needed for 104 // debugging (see HBASE-12285 for details). 105 // ((Log4JLogger)RpcServer.LOG).getLogger().setLevel(Level.ALL); 106 // ((Log4JLogger)RpcClient.LOG).getLogger().setLevel(Level.ALL); 107 // ((Log4JLogger)ScannerCallable.LOG).getLogger().setLevel(Level.ALL); 108 // make sure that we do not get the same ts twice, see HBASE-19731 for more details. 109 EnvironmentEdgeManager.injectEdge(new NonRepeatedEnvironmentEdge()); 110 Configuration conf = TEST_UTIL.getConfiguration(); 111 conf.setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, 112 Arrays.stream(cps).map(Class::getName).toArray(String[]::new)); 113 conf.setBoolean(TableDescriptorChecker.TABLE_SANITY_CHECKS, true); // enable for below tests 114 // Use multiple masters for support hedged reads in registry 115 TEST_UTIL.startMiniCluster( 116 StartTestingClusterOption.builder().numMasters(3).numRegionServers(SLAVES).build()); 117 } 118 119 @AfterAll 120 public static void tearDownAfterClass() throws Exception { 121 TEST_UTIL.shutdownMiniCluster(); 122 } 123 124 @SuppressWarnings("deprecation") 125 protected final Configuration getClientConf() { 126 Configuration conf = new Configuration(TEST_UTIL.getConfiguration()); 127 conf.setClass(HConstants.CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY, registryImpl, 128 ConnectionRegistry.class); 129 conf.setInt(RpcConnectionRegistry.HEDGED_REQS_FANOUT_KEY, numHedgedReqs); 130 conf.setInt(MasterRegistry.MASTER_REGISTRY_HEDGED_REQS_FANOUT_KEY, numHedgedReqs); 131 return conf; 132 } 133 134 protected final Connection getConnection() throws IOException { 135 return ConnectionFactory.createConnection(getClientConf()); 136 } 137 138 protected void deleteColumns(Table ht, String value, String keyPrefix) throws IOException { 139 ResultScanner scanner = buildScanner(keyPrefix, value, ht); 140 Iterator<Result> it = scanner.iterator(); 141 int count = 0; 142 while (it.hasNext()) { 143 Result result = it.next(); 144 Delete delete = new Delete(result.getRow()); 145 delete.addColumn(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2")); 146 ht.delete(delete); 147 count++; 148 } 149 assertEquals(3, count, "Did not perform correct number of deletes"); 150 } 151 152 protected int getNumberOfRows(String keyPrefix, String value, Table ht) throws Exception { 153 ResultScanner resultScanner = buildScanner(keyPrefix, value, ht); 154 Iterator<Result> scanner = resultScanner.iterator(); 155 int numberOfResults = 0; 156 while (scanner.hasNext()) { 157 Result result = scanner.next(); 158 LOG.info("Got back key: " + Bytes.toString(result.getRow())); 159 for (Cell kv : result.rawCells()) { 160 LOG.info("kv=" + kv.toString() + ", " + Bytes.toString(CellUtil.cloneValue(kv))); 161 } 162 numberOfResults++; 163 } 164 return numberOfResults; 165 } 166 167 protected ResultScanner buildScanner(String keyPrefix, String value, Table ht) 168 throws IOException { 169 // OurFilterList allFilters = new OurFilterList(); 170 FilterList allFilters = new FilterList(/* FilterList.Operator.MUST_PASS_ALL */); 171 allFilters.addFilter(new PrefixFilter(Bytes.toBytes(keyPrefix))); 172 SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("trans-tags"), 173 Bytes.toBytes("qual2"), CompareOperator.EQUAL, Bytes.toBytes(value)); 174 filter.setFilterIfMissing(true); 175 allFilters.addFilter(filter); 176 177 // allFilters.addFilter(new 178 // RowExcludingSingleColumnValueFilter(Bytes.toBytes("trans-tags"), 179 // Bytes.toBytes("qual2"), CompareOp.EQUAL, Bytes.toBytes(value))); 180 181 Scan scan = new Scan(); 182 scan.addFamily(Bytes.toBytes("trans-blob")); 183 scan.addFamily(Bytes.toBytes("trans-type")); 184 scan.addFamily(Bytes.toBytes("trans-date")); 185 scan.addFamily(Bytes.toBytes("trans-tags")); 186 scan.addFamily(Bytes.toBytes("trans-group")); 187 scan.setFilter(allFilters); 188 189 return ht.getScanner(scan); 190 } 191 192 protected void putRows(Table ht, int numRows, String value, String key) throws IOException { 193 for (int i = 0; i < numRows; i++) { 194 String row = key + "_" + HBaseCommonTestingUtil.getRandomUUID().toString(); 195 LOG.info(String.format("Saving row: %s, with value %s", row, value)); 196 Put put = new Put(Bytes.toBytes(row)); 197 put.setDurability(Durability.SKIP_WAL); 198 put.addColumn(Bytes.toBytes("trans-blob"), null, Bytes.toBytes("value for blob")); 199 put.addColumn(Bytes.toBytes("trans-type"), null, Bytes.toBytes("statement")); 200 put.addColumn(Bytes.toBytes("trans-date"), null, Bytes.toBytes("20090921010101999")); 201 put.addColumn(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2"), Bytes.toBytes(value)); 202 put.addColumn(Bytes.toBytes("trans-group"), null, Bytes.toBytes("adhocTransactionGroupId")); 203 ht.put(put); 204 } 205 } 206 207 protected void assertRowCount(final Table t, final int expected) throws IOException { 208 assertEquals(expected, countRows(t, new Scan())); 209 } 210 211 /* 212 * @return Scan with RowFilter that does LESS than passed key. 213 */ 214 protected Scan createScanWithRowFilter(final byte[] key) { 215 return createScanWithRowFilter(key, null, CompareOperator.LESS); 216 } 217 218 /* 219 * @return Scan with RowFilter that does CompareOp op on passed key. 220 */ 221 protected Scan createScanWithRowFilter(final byte[] key, final byte[] startRow, 222 CompareOperator op) { 223 // Make sure key is of some substance... non-null and > than first key. 224 assertTrue(key != null && key.length > 0 225 && Bytes.BYTES_COMPARATOR.compare(key, new byte[] { 'a', 'a', 'a' }) >= 0); 226 LOG.info("Key=" + Bytes.toString(key)); 227 Scan s = startRow == null ? new Scan() : new Scan().withStartRow(startRow); 228 Filter f = new RowFilter(op, new BinaryComparator(key)); 229 f = new WhileMatchFilter(f); 230 s.setFilter(f); 231 return s; 232 } 233 234 /** 235 * Split table into multiple regions. 236 * @param t Table to split. 237 * @return Map of regions to servers. 238 */ 239 protected List<HRegionLocation> splitTable(final Table t) throws IOException { 240 // Split this table in two. 241 Admin admin = TEST_UTIL.getAdmin(); 242 admin.split(t.getName()); 243 // Is it right closing this admin? 244 admin.close(); 245 List<HRegionLocation> regions = waitOnSplit(t); 246 assertTrue(regions.size() > 1); 247 return regions; 248 } 249 250 /* 251 * Wait on table split. May return because we waited long enough on the split and it didn't 252 * happen. Caller should check. 253 * @return Map of table regions; caller needs to check table actually split. 254 */ 255 private List<HRegionLocation> waitOnSplit(final Table t) throws IOException { 256 try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(t.getName())) { 257 List<HRegionLocation> regions = locator.getAllRegionLocations(); 258 int originalCount = regions.size(); 259 for (int i = 0; i < TEST_UTIL.getConfiguration().getInt("hbase.test.retries", 30); i++) { 260 try { 261 Thread.sleep(1000); 262 } catch (InterruptedException e) { 263 e.printStackTrace(); 264 } 265 regions = locator.getAllRegionLocations(); 266 if (regions.size() > originalCount) { 267 break; 268 } 269 } 270 return regions; 271 } 272 } 273 274 protected Result getSingleScanResult(Table ht, Scan scan) throws IOException { 275 try (ResultScanner scanner = ht.getScanner(scan)) { 276 return scanner.next(); 277 } 278 } 279 280 byte[][] makeNAscii(byte[] base, int n) { 281 if (n > 256) { 282 return makeNBig(base, n); 283 } 284 byte[][] ret = new byte[n][]; 285 for (int i = 0; i < n; i++) { 286 byte[] tail = Bytes.toBytes(Integer.toString(i)); 287 ret[i] = Bytes.add(base, tail); 288 } 289 return ret; 290 } 291 292 protected byte[][] makeN(byte[] base, int n) { 293 if (n > 256) { 294 return makeNBig(base, n); 295 } 296 byte[][] ret = new byte[n][]; 297 for (int i = 0; i < n; i++) { 298 ret[i] = Bytes.add(base, new byte[] { (byte) i }); 299 } 300 return ret; 301 } 302 303 protected byte[][] makeNBig(byte[] base, int n) { 304 byte[][] ret = new byte[n][]; 305 for (int i = 0; i < n; i++) { 306 int byteA = (i % 256); 307 int byteB = (i >> 8); 308 ret[i] = Bytes.add(base, new byte[] { (byte) byteB, (byte) byteA }); 309 } 310 return ret; 311 } 312 313 protected long[] makeStamps(int n) { 314 long[] stamps = new long[n]; 315 for (int i = 0; i < n; i++) { 316 stamps[i] = i + 1L; 317 } 318 return stamps; 319 } 320 321 protected static boolean equals(byte[] left, byte[] right) { 322 if (left == null && right == null) { 323 return true; 324 } 325 if (left == null && right.length == 0) { 326 return true; 327 } 328 if (right == null && left.length == 0) { 329 return true; 330 } 331 return Bytes.equals(left, right); 332 } 333 334 protected void assertKey(Cell key, byte[] row, byte[] family, byte[] qualifier, byte[] value) { 335 assertTrue(equals(row, CellUtil.cloneRow(key)), "Expected row [" + Bytes.toString(row) + "] " 336 + "Got row [" + Bytes.toString(CellUtil.cloneRow(key)) + "]"); 337 assertTrue(equals(family, CellUtil.cloneFamily(key)), 338 "Expected family [" + Bytes.toString(family) + "] " + "Got family [" 339 + Bytes.toString(CellUtil.cloneFamily(key)) + "]"); 340 assertTrue(equals(qualifier, CellUtil.cloneQualifier(key)), 341 "Expected qualifier [" + Bytes.toString(qualifier) + "] " + "Got qualifier [" 342 + Bytes.toString(CellUtil.cloneQualifier(key)) + "]"); 343 assertTrue(equals(value, CellUtil.cloneValue(key)), "Expected value [" + Bytes.toString(value) 344 + "] " + "Got value [" + Bytes.toString(CellUtil.cloneValue(key)) + "]"); 345 } 346 347 static void assertIncrementKey(Cell key, byte[] row, byte[] family, byte[] qualifier, 348 long value) { 349 assertTrue(equals(row, CellUtil.cloneRow(key)), "Expected row [" + Bytes.toString(row) + "] " 350 + "Got row [" + Bytes.toString(CellUtil.cloneRow(key)) + "]"); 351 assertTrue(equals(family, CellUtil.cloneFamily(key)), 352 "Expected family [" + Bytes.toString(family) + "] " + "Got family [" 353 + Bytes.toString(CellUtil.cloneFamily(key)) + "]"); 354 assertTrue(equals(qualifier, CellUtil.cloneQualifier(key)), 355 "Expected qualifier [" + Bytes.toString(qualifier) + "] " + "Got qualifier [" 356 + Bytes.toString(CellUtil.cloneQualifier(key)) + "]"); 357 assertEquals(Bytes.toLong(CellUtil.cloneValue(key)), value, "Expected value [" + value + "] " 358 + "Got value [" + Bytes.toLong(CellUtil.cloneValue(key)) + "]"); 359 } 360 361 protected void assertNumKeys(Result result, int n) throws Exception { 362 assertEquals(result.size(), n, "Expected " + n + " keys but got " + result.size()); 363 } 364 365 protected void assertNResult(Result result, byte[] row, byte[][] families, byte[][] qualifiers, 366 byte[][] values, int[][] idxs) { 367 assertTrue(equals(row, result.getRow()), "Expected row [" + Bytes.toString(row) + "] " 368 + "Got row [" + Bytes.toString(result.getRow()) + "]"); 369 assertEquals(result.size(), idxs.length, 370 "Expected " + idxs.length + " keys but result contains " + result.size()); 371 372 Cell[] keys = result.rawCells(); 373 374 for (int i = 0; i < keys.length; i++) { 375 byte[] family = families[idxs[i][0]]; 376 byte[] qualifier = qualifiers[idxs[i][1]]; 377 byte[] value = values[idxs[i][2]]; 378 Cell key = keys[i]; 379 380 byte[] famb = CellUtil.cloneFamily(key); 381 byte[] qualb = CellUtil.cloneQualifier(key); 382 byte[] valb = CellUtil.cloneValue(key); 383 assertTrue(equals(family, famb), "(" + i + ") Expected family [" + Bytes.toString(family) 384 + "] " + "Got family [" + Bytes.toString(famb) + "]"); 385 assertTrue(equals(qualifier, qualb), "(" + i + ") Expected qualifier [" 386 + Bytes.toString(qualifier) + "] " + "Got qualifier [" + Bytes.toString(qualb) + "]"); 387 assertTrue(equals(value, valb), "(" + i + ") Expected value [" + Bytes.toString(value) + "] " 388 + "Got value [" + Bytes.toString(valb) + "]"); 389 } 390 } 391 392 protected void assertNResult(Result result, byte[] row, byte[] family, byte[] qualifier, 393 long[] stamps, byte[][] values, int start, int end) { 394 assertTrue(equals(row, result.getRow()), "Expected row [" + Bytes.toString(row) + "] " 395 + "Got row [" + Bytes.toString(result.getRow()) + "]"); 396 int expectedResults = end - start + 1; 397 assertEquals(expectedResults, result.size()); 398 399 Cell[] keys = result.rawCells(); 400 401 for (int i = 0; i < keys.length; i++) { 402 byte[] value = values[end - i]; 403 long ts = stamps[end - i]; 404 Cell key = keys[i]; 405 406 assertTrue(CellUtil.matchingFamily(key, family), 407 "(" + i + ") Expected family [" + Bytes.toString(family) + "] " + "Got family [" 408 + Bytes.toString(CellUtil.cloneFamily(key)) + "]"); 409 assertTrue(CellUtil.matchingQualifier(key, qualifier), 410 "(" + i + ") Expected qualifier [" + Bytes.toString(qualifier) + "] " + "Got qualifier [" 411 + Bytes.toString(CellUtil.cloneQualifier(key)) + "]"); 412 assertEquals(ts, key.getTimestamp(), 413 "Expected ts [" + ts + "] " + "Got ts [" + key.getTimestamp() + "]"); 414 assertTrue(CellUtil.matchingValue(key, value), 415 "(" + i + ") Expected value [" + Bytes.toString(value) + "] " + "Got value [" 416 + Bytes.toString(CellUtil.cloneValue(key)) + "]"); 417 } 418 } 419 420 /** 421 * Validate that result contains two specified keys, exactly. It is assumed key A sorts before key 422 * B. 423 */ 424 protected void assertDoubleResult(Result result, byte[] row, byte[] familyA, byte[] qualifierA, 425 byte[] valueA, byte[] familyB, byte[] qualifierB, byte[] valueB) { 426 assertTrue(equals(row, result.getRow()), "Expected row [" + Bytes.toString(row) + "] " 427 + "Got row [" + Bytes.toString(result.getRow()) + "]"); 428 assertEquals(2, result.size(), "Expected two keys but result contains " + result.size()); 429 Cell[] kv = result.rawCells(); 430 Cell kvA = kv[0]; 431 assertTrue(equals(familyA, CellUtil.cloneFamily(kvA)), 432 "(A) Expected family [" + Bytes.toString(familyA) + "] " + "Got family [" 433 + Bytes.toString(CellUtil.cloneFamily(kvA)) + "]"); 434 assertTrue(equals(qualifierA, CellUtil.cloneQualifier(kvA)), 435 "(A) Expected qualifier [" + Bytes.toString(qualifierA) + "] " + "Got qualifier [" 436 + Bytes.toString(CellUtil.cloneQualifier(kvA)) + "]"); 437 assertTrue(equals(valueA, CellUtil.cloneValue(kvA)), 438 "(A) Expected value [" + Bytes.toString(valueA) + "] " + "Got value [" 439 + Bytes.toString(CellUtil.cloneValue(kvA)) + "]"); 440 Cell kvB = kv[1]; 441 assertTrue(equals(familyB, CellUtil.cloneFamily(kvB)), 442 "(B) Expected family [" + Bytes.toString(familyB) + "] " + "Got family [" 443 + Bytes.toString(CellUtil.cloneFamily(kvB)) + "]"); 444 assertTrue(equals(qualifierB, CellUtil.cloneQualifier(kvB)), 445 "(B) Expected qualifier [" + Bytes.toString(qualifierB) + "] " + "Got qualifier [" 446 + Bytes.toString(CellUtil.cloneQualifier(kvB)) + "]"); 447 assertTrue(equals(valueB, CellUtil.cloneValue(kvB)), 448 "(B) Expected value [" + Bytes.toString(valueB) + "] " + "Got value [" 449 + Bytes.toString(CellUtil.cloneValue(kvB)) + "]"); 450 } 451 452 protected void assertSingleResult(Result result, byte[] row, byte[] family, byte[] qualifier, 453 byte[] value) { 454 assertTrue(equals(row, result.getRow()), "Expected row [" + Bytes.toString(row) + "] " 455 + "Got row [" + Bytes.toString(result.getRow()) + "]"); 456 assertEquals(1, result.size(), "Expected a single key but result contains " + result.size()); 457 Cell kv = result.rawCells()[0]; 458 assertTrue(equals(family, CellUtil.cloneFamily(kv)), 459 "Expected family [" + Bytes.toString(family) + "] " + "Got family [" 460 + Bytes.toString(CellUtil.cloneFamily(kv)) + "]"); 461 assertTrue(equals(qualifier, CellUtil.cloneQualifier(kv)), 462 "Expected qualifier [" + Bytes.toString(qualifier) + "] " + "Got qualifier [" 463 + Bytes.toString(CellUtil.cloneQualifier(kv)) + "]"); 464 assertTrue(equals(value, CellUtil.cloneValue(kv)), "Expected value [" + Bytes.toString(value) 465 + "] " + "Got value [" + Bytes.toString(CellUtil.cloneValue(kv)) + "]"); 466 } 467 468 protected void assertSingleResult(Result result, byte[] row, byte[] family, byte[] qualifier, 469 long value) { 470 assertTrue(equals(row, result.getRow()), "Expected row [" + Bytes.toString(row) + "] " 471 + "Got row [" + Bytes.toString(result.getRow()) + "]"); 472 assertEquals(1, result.size(), "Expected a single key but result contains " + result.size()); 473 Cell kv = result.rawCells()[0]; 474 assertTrue(equals(family, CellUtil.cloneFamily(kv)), 475 "Expected family [" + Bytes.toString(family) + "] " + "Got family [" 476 + Bytes.toString(CellUtil.cloneFamily(kv)) + "]"); 477 assertTrue(equals(qualifier, CellUtil.cloneQualifier(kv)), 478 "Expected qualifier [" + Bytes.toString(qualifier) + "] " + "Got qualifier [" 479 + Bytes.toString(CellUtil.cloneQualifier(kv)) + "]"); 480 assertEquals(value, Bytes.toLong(CellUtil.cloneValue(kv)), "Expected value [" + value + "] " 481 + "Got value [" + Bytes.toLong(CellUtil.cloneValue(kv)) + "]"); 482 } 483 484 protected void assertSingleResult(Result result, byte[] row, byte[] family, byte[] qualifier, 485 long ts, byte[] value) { 486 assertTrue(equals(row, result.getRow()), "Expected row [" + Bytes.toString(row) + "] " 487 + "Got row [" + Bytes.toString(result.getRow()) + "]"); 488 assertEquals(1, result.size(), "Expected a single key but result contains " + result.size()); 489 Cell kv = result.rawCells()[0]; 490 assertTrue(equals(family, CellUtil.cloneFamily(kv)), 491 "Expected family [" + Bytes.toString(family) + "] " + "Got family [" 492 + Bytes.toString(CellUtil.cloneFamily(kv)) + "]"); 493 assertTrue(equals(qualifier, CellUtil.cloneQualifier(kv)), 494 "Expected qualifier [" + Bytes.toString(qualifier) + "] " + "Got qualifier [" 495 + Bytes.toString(CellUtil.cloneQualifier(kv)) + "]"); 496 assertEquals(ts, kv.getTimestamp(), 497 "Expected ts [" + ts + "] " + "Got ts [" + kv.getTimestamp() + "]"); 498 assertTrue(equals(value, CellUtil.cloneValue(kv)), "Expected value [" + Bytes.toString(value) 499 + "] " + "Got value [" + Bytes.toString(CellUtil.cloneValue(kv)) + "]"); 500 } 501 502 protected void assertEmptyResult(Result result) throws Exception { 503 assertTrue(result.isEmpty(), 504 "expected an empty result but result contains " + result.size() + " keys"); 505 } 506 507 protected void assertNullResult(Result result) throws Exception { 508 assertNull(result, "expected null result but received a non-null result"); 509 } 510 511 protected void getVersionRangeAndVerifyGreaterThan(Table ht, byte[] row, byte[] family, 512 byte[] qualifier, long[] stamps, byte[][] values, int start, int end) throws IOException { 513 Get get = new Get(row); 514 get.addColumn(family, qualifier); 515 get.readVersions(Integer.MAX_VALUE); 516 get.setTimeRange(stamps[start + 1], Long.MAX_VALUE); 517 Result result = ht.get(get); 518 assertNResult(result, row, family, qualifier, stamps, values, start + 1, end); 519 } 520 521 protected void getVersionRangeAndVerify(Table ht, byte[] row, byte[] family, byte[] qualifier, 522 long[] stamps, byte[][] values, int start, int end) throws IOException { 523 Get get = new Get(row); 524 get.addColumn(family, qualifier); 525 get.readVersions(Integer.MAX_VALUE); 526 get.setTimeRange(stamps[start], stamps[end] + 1); 527 Result result = ht.get(get); 528 assertNResult(result, row, family, qualifier, stamps, values, start, end); 529 } 530 531 protected void getAllVersionsAndVerify(Table ht, byte[] row, byte[] family, byte[] qualifier, 532 long[] stamps, byte[][] values, int start, int end) throws IOException { 533 Get get = new Get(row); 534 get.addColumn(family, qualifier); 535 get.readVersions(Integer.MAX_VALUE); 536 Result result = ht.get(get); 537 assertNResult(result, row, family, qualifier, stamps, values, start, end); 538 } 539 540 protected void scanVersionRangeAndVerifyGreaterThan(Table ht, byte[] row, byte[] family, 541 byte[] qualifier, long[] stamps, byte[][] values, int start, int end) throws IOException { 542 Scan scan = new Scan().withStartRow(row); 543 scan.addColumn(family, qualifier); 544 scan.readVersions(Integer.MAX_VALUE); 545 scan.setTimeRange(stamps[start + 1], Long.MAX_VALUE); 546 Result result = getSingleScanResult(ht, scan); 547 assertNResult(result, row, family, qualifier, stamps, values, start + 1, end); 548 } 549 550 protected void scanVersionRangeAndVerify(Table ht, byte[] row, byte[] family, byte[] qualifier, 551 long[] stamps, byte[][] values, int start, int end) throws IOException { 552 Scan scan = new Scan().withStartRow(row); 553 scan.addColumn(family, qualifier); 554 scan.readVersions(Integer.MAX_VALUE); 555 scan.setTimeRange(stamps[start], stamps[end] + 1); 556 Result result = getSingleScanResult(ht, scan); 557 assertNResult(result, row, family, qualifier, stamps, values, start, end); 558 } 559 560 protected void scanAllVersionsAndVerify(Table ht, byte[] row, byte[] family, byte[] qualifier, 561 long[] stamps, byte[][] values, int start, int end) throws IOException { 562 Scan scan = new Scan().withStartRow(row); 563 scan.addColumn(family, qualifier); 564 scan.readVersions(Integer.MAX_VALUE); 565 Result result = getSingleScanResult(ht, scan); 566 assertNResult(result, row, family, qualifier, stamps, values, start, end); 567 } 568 569 protected void getVersionAndVerify(Table ht, byte[] row, byte[] family, byte[] qualifier, 570 long stamp, byte[] value) throws Exception { 571 Get get = new Get(row); 572 get.addColumn(family, qualifier); 573 get.setTimestamp(stamp); 574 get.readVersions(Integer.MAX_VALUE); 575 Result result = ht.get(get); 576 assertSingleResult(result, row, family, qualifier, stamp, value); 577 } 578 579 protected void getVersionAndVerifyMissing(Table ht, byte[] row, byte[] family, byte[] qualifier, 580 long stamp) throws Exception { 581 Get get = new Get(row); 582 get.addColumn(family, qualifier); 583 get.setTimestamp(stamp); 584 get.readVersions(Integer.MAX_VALUE); 585 Result result = ht.get(get); 586 assertEmptyResult(result); 587 } 588 589 protected void scanVersionAndVerify(Table ht, byte[] row, byte[] family, byte[] qualifier, 590 long stamp, byte[] value) throws Exception { 591 Scan scan = new Scan().withStartRow(row); 592 scan.addColumn(family, qualifier); 593 scan.setTimestamp(stamp); 594 scan.readVersions(Integer.MAX_VALUE); 595 Result result = getSingleScanResult(ht, scan); 596 assertSingleResult(result, row, family, qualifier, stamp, value); 597 } 598 599 protected void scanVersionAndVerifyMissing(Table ht, byte[] row, byte[] family, byte[] qualifier, 600 long stamp) throws Exception { 601 Scan scan = new Scan().withStartRow(row); 602 scan.addColumn(family, qualifier); 603 scan.setTimestamp(stamp); 604 scan.readVersions(Integer.MAX_VALUE); 605 Result result = getSingleScanResult(ht, scan); 606 assertNullResult(result); 607 } 608 609 protected void getTestNull(Table ht, byte[] row, byte[] family, byte[] value) throws Exception { 610 Get get = new Get(row); 611 get.addColumn(family, null); 612 Result result = ht.get(get); 613 assertSingleResult(result, row, family, null, value); 614 615 get = new Get(row); 616 get.addColumn(family, HConstants.EMPTY_BYTE_ARRAY); 617 result = ht.get(get); 618 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 619 620 get = new Get(row); 621 get.addFamily(family); 622 result = ht.get(get); 623 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 624 625 get = new Get(row); 626 result = ht.get(get); 627 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 628 629 } 630 631 protected void getTestNull(Table ht, byte[] row, byte[] family, long value) throws Exception { 632 Get get = new Get(row); 633 get.addColumn(family, null); 634 Result result = ht.get(get); 635 assertSingleResult(result, row, family, null, value); 636 637 get = new Get(row); 638 get.addColumn(family, HConstants.EMPTY_BYTE_ARRAY); 639 result = ht.get(get); 640 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 641 642 get = new Get(row); 643 get.addFamily(family); 644 result = ht.get(get); 645 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 646 647 get = new Get(row); 648 result = ht.get(get); 649 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 650 } 651 652 protected void scanTestNull(Table ht, byte[] row, byte[] family, byte[] value) throws Exception { 653 scanTestNull(ht, row, family, value, false); 654 } 655 656 protected void scanTestNull(Table ht, byte[] row, byte[] family, byte[] value, 657 boolean isReversedScan) throws Exception { 658 659 Scan scan = new Scan(); 660 scan.setReversed(isReversedScan); 661 scan.addColumn(family, null); 662 Result result = getSingleScanResult(ht, scan); 663 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 664 665 scan = new Scan(); 666 scan.setReversed(isReversedScan); 667 scan.addColumn(family, HConstants.EMPTY_BYTE_ARRAY); 668 result = getSingleScanResult(ht, scan); 669 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 670 671 scan = new Scan(); 672 scan.setReversed(isReversedScan); 673 scan.addFamily(family); 674 result = getSingleScanResult(ht, scan); 675 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 676 677 scan = new Scan(); 678 scan.setReversed(isReversedScan); 679 result = getSingleScanResult(ht, scan); 680 assertSingleResult(result, row, family, HConstants.EMPTY_BYTE_ARRAY, value); 681 682 } 683 684 protected void singleRowGetTest(Table ht, byte[][] ROWS, byte[][] FAMILIES, byte[][] QUALIFIERS, 685 byte[][] VALUES) throws Exception { 686 // Single column from memstore 687 Get get = new Get(ROWS[0]); 688 get.addColumn(FAMILIES[4], QUALIFIERS[0]); 689 Result result = ht.get(get); 690 assertSingleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0]); 691 692 // Single column from storefile 693 get = new Get(ROWS[0]); 694 get.addColumn(FAMILIES[2], QUALIFIERS[2]); 695 result = ht.get(get); 696 assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]); 697 698 // Single column from storefile, family match 699 get = new Get(ROWS[0]); 700 get.addFamily(FAMILIES[7]); 701 result = ht.get(get); 702 assertSingleResult(result, ROWS[0], FAMILIES[7], QUALIFIERS[7], VALUES[7]); 703 704 // Two columns, one from memstore one from storefile, same family, 705 // wildcard match 706 get = new Get(ROWS[0]); 707 get.addFamily(FAMILIES[4]); 708 result = ht.get(get); 709 assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0], FAMILIES[4], 710 QUALIFIERS[4], VALUES[4]); 711 712 // Two columns, one from memstore one from storefile, same family, 713 // explicit match 714 get = new Get(ROWS[0]); 715 get.addColumn(FAMILIES[4], QUALIFIERS[0]); 716 get.addColumn(FAMILIES[4], QUALIFIERS[4]); 717 result = ht.get(get); 718 assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0], FAMILIES[4], 719 QUALIFIERS[4], VALUES[4]); 720 721 // Three column, one from memstore two from storefile, different families, 722 // wildcard match 723 get = new Get(ROWS[0]); 724 get.addFamily(FAMILIES[4]); 725 get.addFamily(FAMILIES[7]); 726 result = ht.get(get); 727 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, 728 new int[][] { { 4, 0, 0 }, { 4, 4, 4 }, { 7, 7, 7 } }); 729 730 // Multiple columns from everywhere storefile, many family, wildcard 731 get = new Get(ROWS[0]); 732 get.addFamily(FAMILIES[2]); 733 get.addFamily(FAMILIES[4]); 734 get.addFamily(FAMILIES[6]); 735 get.addFamily(FAMILIES[7]); 736 result = ht.get(get); 737 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, new int[][] { { 2, 2, 2 }, 738 { 2, 4, 4 }, { 4, 0, 0 }, { 4, 4, 4 }, { 6, 6, 6 }, { 6, 7, 7 }, { 7, 7, 7 } }); 739 740 // Multiple columns from everywhere storefile, many family, wildcard 741 get = new Get(ROWS[0]); 742 get.addColumn(FAMILIES[2], QUALIFIERS[2]); 743 get.addColumn(FAMILIES[2], QUALIFIERS[4]); 744 get.addColumn(FAMILIES[4], QUALIFIERS[0]); 745 get.addColumn(FAMILIES[4], QUALIFIERS[4]); 746 get.addColumn(FAMILIES[6], QUALIFIERS[6]); 747 get.addColumn(FAMILIES[6], QUALIFIERS[7]); 748 get.addColumn(FAMILIES[7], QUALIFIERS[7]); 749 get.addColumn(FAMILIES[7], QUALIFIERS[8]); 750 result = ht.get(get); 751 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, new int[][] { { 2, 2, 2 }, 752 { 2, 4, 4 }, { 4, 0, 0 }, { 4, 4, 4 }, { 6, 6, 6 }, { 6, 7, 7 }, { 7, 7, 7 } }); 753 754 // Everything 755 get = new Get(ROWS[0]); 756 result = ht.get(get); 757 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, new int[][] { { 2, 2, 2 }, 758 { 2, 4, 4 }, { 4, 0, 0 }, { 4, 4, 4 }, { 6, 6, 6 }, { 6, 7, 7 }, { 7, 7, 7 }, { 9, 0, 0 } }); 759 760 // Get around inserted columns 761 762 get = new Get(ROWS[1]); 763 result = ht.get(get); 764 assertEmptyResult(result); 765 766 get = new Get(ROWS[0]); 767 get.addColumn(FAMILIES[4], QUALIFIERS[3]); 768 get.addColumn(FAMILIES[2], QUALIFIERS[3]); 769 result = ht.get(get); 770 assertEmptyResult(result); 771 772 } 773 774 protected void singleRowScanTest(Table ht, byte[][] ROWS, byte[][] FAMILIES, byte[][] QUALIFIERS, 775 byte[][] VALUES) throws Exception { 776 // Single column from memstore 777 Scan scan = new Scan(); 778 scan.addColumn(FAMILIES[4], QUALIFIERS[0]); 779 Result result = getSingleScanResult(ht, scan); 780 assertSingleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0]); 781 782 // Single column from storefile 783 scan = new Scan(); 784 scan.addColumn(FAMILIES[2], QUALIFIERS[2]); 785 result = getSingleScanResult(ht, scan); 786 assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]); 787 788 // Single column from storefile, family match 789 scan = new Scan(); 790 scan.addFamily(FAMILIES[7]); 791 result = getSingleScanResult(ht, scan); 792 assertSingleResult(result, ROWS[0], FAMILIES[7], QUALIFIERS[7], VALUES[7]); 793 794 // Two columns, one from memstore one from storefile, same family, 795 // wildcard match 796 scan = new Scan(); 797 scan.addFamily(FAMILIES[4]); 798 result = getSingleScanResult(ht, scan); 799 assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0], FAMILIES[4], 800 QUALIFIERS[4], VALUES[4]); 801 802 // Two columns, one from memstore one from storefile, same family, 803 // explicit match 804 scan = new Scan(); 805 scan.addColumn(FAMILIES[4], QUALIFIERS[0]); 806 scan.addColumn(FAMILIES[4], QUALIFIERS[4]); 807 result = getSingleScanResult(ht, scan); 808 assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0], FAMILIES[4], 809 QUALIFIERS[4], VALUES[4]); 810 811 // Three column, one from memstore two from storefile, different families, 812 // wildcard match 813 scan = new Scan(); 814 scan.addFamily(FAMILIES[4]); 815 scan.addFamily(FAMILIES[7]); 816 result = getSingleScanResult(ht, scan); 817 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, 818 new int[][] { { 4, 0, 0 }, { 4, 4, 4 }, { 7, 7, 7 } }); 819 820 // Multiple columns from everywhere storefile, many family, wildcard 821 scan = new Scan(); 822 scan.addFamily(FAMILIES[2]); 823 scan.addFamily(FAMILIES[4]); 824 scan.addFamily(FAMILIES[6]); 825 scan.addFamily(FAMILIES[7]); 826 result = getSingleScanResult(ht, scan); 827 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, new int[][] { { 2, 2, 2 }, 828 { 2, 4, 4 }, { 4, 0, 0 }, { 4, 4, 4 }, { 6, 6, 6 }, { 6, 7, 7 }, { 7, 7, 7 } }); 829 830 // Multiple columns from everywhere storefile, many family, wildcard 831 scan = new Scan(); 832 scan.addColumn(FAMILIES[2], QUALIFIERS[2]); 833 scan.addColumn(FAMILIES[2], QUALIFIERS[4]); 834 scan.addColumn(FAMILIES[4], QUALIFIERS[0]); 835 scan.addColumn(FAMILIES[4], QUALIFIERS[4]); 836 scan.addColumn(FAMILIES[6], QUALIFIERS[6]); 837 scan.addColumn(FAMILIES[6], QUALIFIERS[7]); 838 scan.addColumn(FAMILIES[7], QUALIFIERS[7]); 839 scan.addColumn(FAMILIES[7], QUALIFIERS[8]); 840 result = getSingleScanResult(ht, scan); 841 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, new int[][] { { 2, 2, 2 }, 842 { 2, 4, 4 }, { 4, 0, 0 }, { 4, 4, 4 }, { 6, 6, 6 }, { 6, 7, 7 }, { 7, 7, 7 } }); 843 844 // Everything 845 scan = new Scan(); 846 result = getSingleScanResult(ht, scan); 847 assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES, new int[][] { { 2, 2, 2 }, 848 { 2, 4, 4 }, { 4, 0, 0 }, { 4, 4, 4 }, { 6, 6, 6 }, { 6, 7, 7 }, { 7, 7, 7 }, { 9, 0, 0 } }); 849 850 // Scan around inserted columns 851 852 scan = new Scan().withStartRow(ROWS[1]); 853 result = getSingleScanResult(ht, scan); 854 assertNullResult(result); 855 856 scan = new Scan(); 857 scan.addColumn(FAMILIES[4], QUALIFIERS[3]); 858 scan.addColumn(FAMILIES[2], QUALIFIERS[3]); 859 result = getSingleScanResult(ht, scan); 860 assertNullResult(result); 861 } 862 863 /** 864 * Verify a single column using gets. Expects family and qualifier arrays to be valid for at least 865 * the range: idx-2 < idx < idx+2 866 */ 867 protected void getVerifySingleColumn(Table ht, byte[][] ROWS, int ROWIDX, byte[][] FAMILIES, 868 int FAMILYIDX, byte[][] QUALIFIERS, int QUALIFIERIDX, byte[][] VALUES, int VALUEIDX) 869 throws Exception { 870 Get get = new Get(ROWS[ROWIDX]); 871 Result result = ht.get(get); 872 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 873 VALUES[VALUEIDX]); 874 875 get = new Get(ROWS[ROWIDX]); 876 get.addFamily(FAMILIES[FAMILYIDX]); 877 result = ht.get(get); 878 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 879 VALUES[VALUEIDX]); 880 881 get = new Get(ROWS[ROWIDX]); 882 get.addFamily(FAMILIES[FAMILYIDX - 2]); 883 get.addFamily(FAMILIES[FAMILYIDX]); 884 get.addFamily(FAMILIES[FAMILYIDX + 2]); 885 result = ht.get(get); 886 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 887 VALUES[VALUEIDX]); 888 889 get = new Get(ROWS[ROWIDX]); 890 get.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[0]); 891 result = ht.get(get); 892 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 893 VALUES[VALUEIDX]); 894 895 get = new Get(ROWS[ROWIDX]); 896 get.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[1]); 897 get.addFamily(FAMILIES[FAMILYIDX]); 898 result = ht.get(get); 899 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 900 VALUES[VALUEIDX]); 901 902 get = new Get(ROWS[ROWIDX]); 903 get.addFamily(FAMILIES[FAMILYIDX]); 904 get.addColumn(FAMILIES[FAMILYIDX + 1], QUALIFIERS[1]); 905 get.addColumn(FAMILIES[FAMILYIDX - 2], QUALIFIERS[1]); 906 get.addFamily(FAMILIES[FAMILYIDX - 1]); 907 get.addFamily(FAMILIES[FAMILYIDX + 2]); 908 result = ht.get(get); 909 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 910 VALUES[VALUEIDX]); 911 912 } 913 914 /** 915 * Verify a single column using scanners. Expects family and qualifier arrays to be valid for at 916 * least the range: idx-2 to idx+2 Expects row array to be valid for at least idx to idx+2 917 */ 918 protected void scanVerifySingleColumn(Table ht, byte[][] ROWS, int ROWIDX, byte[][] FAMILIES, 919 int FAMILYIDX, byte[][] QUALIFIERS, int QUALIFIERIDX, byte[][] VALUES, int VALUEIDX) 920 throws Exception { 921 Scan scan = new Scan(); 922 Result result = getSingleScanResult(ht, scan); 923 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 924 VALUES[VALUEIDX]); 925 926 scan = new Scan().withStartRow(ROWS[ROWIDX]); 927 result = getSingleScanResult(ht, scan); 928 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 929 VALUES[VALUEIDX]); 930 931 scan = new Scan().withStartRow(ROWS[ROWIDX]).withStopRow(ROWS[ROWIDX + 1], true); 932 result = getSingleScanResult(ht, scan); 933 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 934 VALUES[VALUEIDX]); 935 936 scan = new Scan().withStartRow(HConstants.EMPTY_START_ROW).withStopRow(ROWS[ROWIDX + 1], true); 937 result = getSingleScanResult(ht, scan); 938 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 939 VALUES[VALUEIDX]); 940 941 scan = new Scan(); 942 scan.addFamily(FAMILIES[FAMILYIDX]); 943 result = getSingleScanResult(ht, scan); 944 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 945 VALUES[VALUEIDX]); 946 947 scan = new Scan(); 948 scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX]); 949 result = getSingleScanResult(ht, scan); 950 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 951 VALUES[VALUEIDX]); 952 953 scan = new Scan(); 954 scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX + 1]); 955 scan.addFamily(FAMILIES[FAMILYIDX]); 956 result = getSingleScanResult(ht, scan); 957 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 958 VALUES[VALUEIDX]); 959 960 scan = new Scan(); 961 scan.addColumn(FAMILIES[FAMILYIDX - 1], QUALIFIERS[QUALIFIERIDX + 1]); 962 scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX]); 963 scan.addFamily(FAMILIES[FAMILYIDX + 1]); 964 result = getSingleScanResult(ht, scan); 965 assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX], 966 VALUES[VALUEIDX]); 967 968 } 969 970 /** 971 * Verify we do not read any values by accident around a single column Same requirements as 972 * getVerifySingleColumn 973 */ 974 protected void getVerifySingleEmpty(Table ht, byte[][] ROWS, int ROWIDX, byte[][] FAMILIES, 975 int FAMILYIDX, byte[][] QUALIFIERS, int QUALIFIERIDX) throws Exception { 976 Get get = new Get(ROWS[ROWIDX]); 977 get.addFamily(FAMILIES[4]); 978 get.addColumn(FAMILIES[4], QUALIFIERS[1]); 979 Result result = ht.get(get); 980 assertEmptyResult(result); 981 982 get = new Get(ROWS[ROWIDX]); 983 get.addFamily(FAMILIES[4]); 984 get.addColumn(FAMILIES[4], QUALIFIERS[2]); 985 result = ht.get(get); 986 assertEmptyResult(result); 987 988 get = new Get(ROWS[ROWIDX]); 989 get.addFamily(FAMILIES[3]); 990 get.addColumn(FAMILIES[4], QUALIFIERS[2]); 991 get.addFamily(FAMILIES[5]); 992 result = ht.get(get); 993 assertEmptyResult(result); 994 995 get = new Get(ROWS[ROWIDX + 1]); 996 result = ht.get(get); 997 assertEmptyResult(result); 998 999 } 1000 1001 protected void scanVerifySingleEmpty(Table ht, byte[][] ROWS, int ROWIDX, byte[][] FAMILIES, 1002 int FAMILYIDX, byte[][] QUALIFIERS, int QUALIFIERIDX) throws Exception { 1003 Scan scan = new Scan().withStartRow(ROWS[ROWIDX + 1]); 1004 Result result = getSingleScanResult(ht, scan); 1005 assertNullResult(result); 1006 1007 scan = new Scan().withStartRow(ROWS[ROWIDX + 1]).withStopRow(ROWS[ROWIDX + 2], true); 1008 result = getSingleScanResult(ht, scan); 1009 assertNullResult(result); 1010 1011 scan = new Scan().withStartRow(HConstants.EMPTY_START_ROW).withStopRow(ROWS[ROWIDX]); 1012 result = getSingleScanResult(ht, scan); 1013 assertNullResult(result); 1014 1015 scan = new Scan(); 1016 scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX + 1]); 1017 scan.addFamily(FAMILIES[FAMILYIDX - 1]); 1018 result = getSingleScanResult(ht, scan); 1019 assertNullResult(result); 1020 1021 } 1022}