diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestInvocationRecordFilter.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestInvocationRecordFilter.java new file mode 100644 index 00000000000..a92d9e42ef2 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestInvocationRecordFilter.java @@ -0,0 +1,182 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.filter; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HRegionInfo; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.SmallTests; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.regionserver.HRegion; +import org.apache.hadoop.hbase.regionserver.InternalScanner; +import org.apache.hadoop.hbase.regionserver.wal.HLog; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Test the invocation logic of the filters. A filter must be invoked only for + * the columns that are requested for. + */ +@Category(SmallTests.class) +public class TestInvocationRecordFilter { + + private static final byte[] TABLE_NAME_BYTES = Bytes + .toBytes("invocationrecord"); + private static final byte[] FAMILY_NAME_BYTES = Bytes.toBytes("cf"); + + private static final byte[] ROW_BYTES = Bytes.toBytes("row"); + private static final String QUALIFIER_PREFIX = "qualifier"; + private static final String VALUE_PREFIX = "value"; + + private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private HRegion region; + + @Before + public void setUp() throws Exception { + HTableDescriptor htd = new HTableDescriptor( + TableName.valueOf(TABLE_NAME_BYTES)); + htd.addFamily(new HColumnDescriptor(FAMILY_NAME_BYTES)); + HRegionInfo info = new HRegionInfo(htd.getTableName(), null, null, false); + this.region = HRegion.createHRegion(info, TEST_UTIL.getDataTestDir(), + TEST_UTIL.getConfiguration(), htd); + + Put put = new Put(ROW_BYTES); + for (int i = 0; i < 10; i += 2) { + // puts 0, 2, 4, 6 and 8 + put.add(FAMILY_NAME_BYTES, Bytes.toBytes(QUALIFIER_PREFIX + i), i, + Bytes.toBytes(VALUE_PREFIX + i)); + } + this.region.put(put); + this.region.flushcache(); + } + + @Test + public void testFilterInvocation() throws Exception { + List selectQualifiers = new ArrayList(); + List expectedQualifiers = new ArrayList(); + + selectQualifiers.add(-1); + verifyInvocationResults(selectQualifiers.toArray(new Integer[0]), + expectedQualifiers.toArray(new Integer[0])); + + selectQualifiers.clear(); + + selectQualifiers.add(0); + expectedQualifiers.add(0); + verifyInvocationResults(selectQualifiers.toArray(new Integer[0]), + expectedQualifiers.toArray(new Integer[0])); + + selectQualifiers.add(3); + verifyInvocationResults(selectQualifiers.toArray(new Integer[0]), + expectedQualifiers.toArray(new Integer[0])); + + selectQualifiers.add(4); + expectedQualifiers.add(4); + verifyInvocationResults(selectQualifiers.toArray(new Integer[0]), + expectedQualifiers.toArray(new Integer[0])); + + selectQualifiers.add(5); + verifyInvocationResults(selectQualifiers.toArray(new Integer[0]), + expectedQualifiers.toArray(new Integer[0])); + + selectQualifiers.add(8); + expectedQualifiers.add(8); + verifyInvocationResults(selectQualifiers.toArray(new Integer[0]), + expectedQualifiers.toArray(new Integer[0])); + } + + public void verifyInvocationResults(Integer[] selectQualifiers, + Integer[] expectedQualifiers) throws Exception { + Get get = new Get(ROW_BYTES); + for (int i = 0; i < selectQualifiers.length; i++) { + get.addColumn(FAMILY_NAME_BYTES, + Bytes.toBytes(QUALIFIER_PREFIX + selectQualifiers[i])); + } + + get.setFilter(new InvocationRecordFilter()); + + List expectedValues = new ArrayList(); + for (int i = 0; i < expectedQualifiers.length; i++) { + expectedValues.add(new KeyValue(ROW_BYTES, FAMILY_NAME_BYTES, Bytes + .toBytes(QUALIFIER_PREFIX + expectedQualifiers[i]), + expectedQualifiers[i], Bytes.toBytes(VALUE_PREFIX + + expectedQualifiers[i]))); + } + + Scan scan = new Scan(get); + List actualValues = new ArrayList(); + List temp = new ArrayList(); + InternalScanner scanner = this.region.getScanner(scan); + while (scanner.next(temp)) { + actualValues.addAll(temp); + temp.clear(); + } + actualValues.addAll(temp); + Assert.assertTrue("Actual values " + actualValues + + " differ from the expected values:" + expectedValues, + expectedValues.equals(actualValues)); + } + + @After + public void tearDown() throws Exception { + HLog hlog = region.getLog(); + region.close(); + hlog.closeAndDelete(); + } + + /** + * Filter which gives the list of keyvalues for which the filter is invoked. + */ + private static class InvocationRecordFilter extends FilterBase { + + private List visitedKeyValues = new ArrayList(); + + public void reset() { + visitedKeyValues.clear(); + } + + public ReturnCode filterKeyValue(Cell ignored) { + visitedKeyValues.add(ignored); + return ReturnCode.INCLUDE; + } + + public void filterRowCells(List kvs) { + kvs.clear(); + kvs.addAll(visitedKeyValues); + } + + public boolean hasFilterRow() { + return true; + } + } +} \ No newline at end of file