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