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