private void scanColSet(int[] colSet, int[] expectedResultCols) throws IOException {
    LOG.info("Scanning column set: " + Arrays.toString(colSet));
    Scan scan = new Scan().withStartRow(ROW_BYTES).withStopRow(ROW_BYTES, true);
    addColumnSetToScan(scan, colSet);
    RegionScannerImpl scanner = region.getScanner(scan);
    KeyValueHeap storeHeap = scanner.storeHeap;
    assertEquals(0, storeHeap.getHeap().size());
    StoreScanner storeScanner = (StoreScanner) storeHeap.getCurrentForTesting();
    @SuppressWarnings({ "unchecked", "rawtypes" })
    List<StoreFileScanner> scanners =
      (List<StoreFileScanner>) (List) storeScanner.getAllScannersForTesting();

    // Sort scanners by their HFile's modification time.
    Collections.sort(scanners, new Comparator<StoreFileScanner>() {
      @Override
      public int compare(StoreFileScanner s1, StoreFileScanner s2) {
        Path p1 = s1.getReader().getHFileReader().getPath();
        Path p2 = s2.getReader().getHFileReader().getPath();
        long t1, t2;
        try {
          t1 = fs.getFileStatus(p1).getModificationTime();
          t2 = fs.getFileStatus(p2).getModificationTime();
        } catch (IOException ex) {
          throw new RuntimeException(ex);
        }
        return t1 < t2 ? -1 : t1 == t2 ? 1 : 0;
      }
    });

    StoreFileReader lastStoreFileReader = null;
    for (StoreFileScanner sfScanner : scanners)
      lastStoreFileReader = sfScanner.getReader();

    new HFilePrettyPrinter(conf).run(
      new String[] { "-m", "-p", "-f", lastStoreFileReader.getHFileReader().getPath().toString() });

    // Disable Bloom filter for the last store file. The disabled Bloom filter
    // will always return "true".
    LOG.info("Disabling Bloom filter for: " + lastStoreFileReader.getHFileReader().getName());
    lastStoreFileReader.disableBloomFilterForTesting();

    List<Cell> allResults = new ArrayList<>();

    { // Limit the scope of results.
      List<Cell> results = new ArrayList<>();
      while (scanner.next(results) || results.size() > 0) {
        allResults.addAll(results);
        results.clear();
      }
    }

    List<Integer> actualIds = new ArrayList<>();
    for (Cell kv : allResults) {
      String qual = Bytes.toString(CellUtil.cloneQualifier(kv));
      assertTrue(qual.startsWith(QUALIFIER_PREFIX));
      actualIds.add(Integer.valueOf(qual.substring(QUALIFIER_PREFIX.length())));
    }
    List<Integer> expectedIds = new ArrayList<>();
    for (int expectedId : expectedResultCols)
      expectedIds.add(expectedId);

    LOG.info("Column ids returned: " + actualIds + ", expected: " + expectedIds);
    assertEquals(expectedIds.toString(), actualIds.toString());
  }
Test a multi-column scanner when there is a Bloom filter false-positive. This is needed for the
multi-column Bloom filter optimization.
hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanWithBloomError.java