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.mob;
019
020import static org.junit.jupiter.api.Assertions.assertArrayEquals;
021import static org.junit.jupiter.api.Assertions.assertEquals;
022
023import java.util.List;
024import java.util.stream.Stream;
025import org.apache.hadoop.hbase.Cell;
026import org.apache.hadoop.hbase.CellUtil;
027import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
028import org.apache.hadoop.hbase.HBaseTestingUtil;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
031import org.apache.hadoop.hbase.client.Put;
032import org.apache.hadoop.hbase.client.Result;
033import org.apache.hadoop.hbase.client.ResultScanner;
034import org.apache.hadoop.hbase.client.Scan;
035import org.apache.hadoop.hbase.client.Table;
036import org.apache.hadoop.hbase.client.TableDescriptor;
037import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
038import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory;
039import org.apache.hadoop.hbase.testclassification.LargeTests;
040import org.apache.hadoop.hbase.util.Bytes;
041import org.junit.jupiter.api.AfterEach;
042import org.junit.jupiter.api.BeforeEach;
043import org.junit.jupiter.api.Tag;
044import org.junit.jupiter.api.TestInfo;
045import org.junit.jupiter.api.TestTemplate;
046import org.junit.jupiter.params.provider.Arguments;
047
048@Tag(LargeTests.TAG)
049@HBaseParameterizedTestTemplate(name = "{index}: useFileBasedSFT={0}")
050public class TestDefaultMobStoreFlusher {
051
052  private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
053  private final static byte[] row1 = Bytes.toBytes("row1");
054  private final static byte[] row2 = Bytes.toBytes("row2");
055  private final static byte[] family = Bytes.toBytes("family");
056  private final static byte[] qf1 = Bytes.toBytes("qf1");
057  private final static byte[] qf2 = Bytes.toBytes("qf2");
058  private final static byte[] value1 = Bytes.toBytes("value1");
059  private final static byte[] value2 = Bytes.toBytes("value2");
060
061  private String testMethodName;
062
063  protected Boolean useFileBasedSFT;
064
065  public TestDefaultMobStoreFlusher(Boolean useFileBasedSFT) {
066    this.useFileBasedSFT = useFileBasedSFT;
067  }
068
069  public static Stream<Arguments> parameters() {
070    return Stream.of(false, true).map(Arguments::of);
071  }
072
073  @BeforeEach
074  public void setUpBefore(TestInfo testInfo) throws Exception {
075    testMethodName = testInfo.getTestMethod().get().getName()
076      + testInfo.getDisplayName().replaceAll("[:= ]", "_").replaceAll("_+", "_").trim();
077    if (useFileBasedSFT) {
078      TEST_UTIL.getConfiguration().set(StoreFileTrackerFactory.TRACKER_IMPL,
079        "org.apache.hadoop.hbase.regionserver.storefiletracker.FileBasedStoreFileTracker");
080    }
081    TEST_UTIL.startMiniCluster(1);
082  }
083
084  @AfterEach
085  public void tearDownAfter() throws Exception {
086    TEST_UTIL.shutdownMiniCluster();
087  }
088
089  @TestTemplate
090  public void testFlushNonMobFile() throws Exception {
091    final TableName tableName = TableName.valueOf(TestMobUtils.getTableName(testMethodName));
092    TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
093      .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(family).setMaxVersions(4).build())
094      .build();
095    testFlushFile(tableDescriptor);
096  }
097
098  @TestTemplate
099  public void testFlushMobFile() throws Exception {
100    final TableName tableName = TableName.valueOf(TestMobUtils.getTableName(testMethodName));
101    TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
102      .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(family).setMobEnabled(true)
103        .setMobThreshold(3L).setMaxVersions(4).build())
104      .build();
105    testFlushFile(tableDescriptor);
106  }
107
108  private void testFlushFile(TableDescriptor tableDescriptor) throws Exception {
109    Table table = null;
110    try {
111      table = TEST_UTIL.createTable(tableDescriptor, null);
112
113      // put data
114      Put put0 = new Put(row1);
115      put0.addColumn(family, qf1, 1, value1);
116      table.put(put0);
117
118      // put more data
119      Put put1 = new Put(row2);
120      put1.addColumn(family, qf2, 1, value2);
121      table.put(put1);
122
123      // flush
124      TEST_UTIL.flush(tableDescriptor.getTableName());
125
126      // Scan
127      Scan scan = new Scan();
128      scan.addColumn(family, qf1);
129      scan.readVersions(4);
130      ResultScanner scanner = table.getScanner(scan);
131
132      // Compare
133      int size = 0;
134      for (Result result : scanner) {
135        size++;
136        List<Cell> cells = result.getColumnCells(family, qf1);
137        // Verify the cell size
138        assertEquals(1, cells.size());
139        // Verify the value
140        assertArrayEquals(value1, CellUtil.cloneValue(cells.get(0)));
141      }
142      scanner.close();
143      assertEquals(1, size);
144    } finally {
145      table.close();
146    }
147  }
148}