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 java.io.IOException;
021import java.util.stream.Stream;
022import org.apache.hadoop.hbase.HBaseTestingUtil;
023import org.apache.hadoop.hbase.HConstants;
024import org.apache.hadoop.hbase.TableName;
025import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
026import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
027import org.apache.hadoop.hbase.util.Bytes;
028import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
029import org.junit.jupiter.api.AfterAll;
030import org.junit.jupiter.api.AfterEach;
031import org.junit.jupiter.api.BeforeEach;
032import org.junit.jupiter.api.TestInfo;
033import org.junit.jupiter.params.provider.Arguments;
034
035/**
036 * Base class for testing clone snapsot
037 */
038public class CloneSnapshotFromClientTestBase {
039
040  protected final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
041
042  protected final byte[] FAMILY = Bytes.toBytes("cf");
043
044  protected String emptySnapshot;
045  protected String snapshotName0;
046  protected String snapshotName1;
047  protected String snapshotName2;
048  protected TableName tableName;
049  protected int snapshot0Rows;
050  protected int snapshot1Rows;
051  protected Admin admin;
052
053  protected int numReplicas;
054
055  private String testName;
056
057  protected CloneSnapshotFromClientTestBase(int numReplicas) {
058    this.numReplicas = numReplicas;
059  }
060
061  public static Stream<Arguments> parameters() {
062    return Stream.of(Arguments.of(1), Arguments.of(3));
063  }
064
065  protected static void setupConfiguration() {
066    TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
067    TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
068    TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
069    TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
070    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
071    TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
072    TEST_UTIL.getConfiguration().setBoolean("hbase.regionserver.compaction.enabled", false);
073  }
074
075  @AfterAll
076  public static void tearDownAfterClass() throws Exception {
077    TEST_UTIL.shutdownMiniCluster();
078  }
079
080  protected final String getValidMethodName() {
081    return testName;
082  }
083
084  /**
085   * Initialize the tests with a table filled with some data and two snapshots (snapshotName0,
086   * snapshotName1) of different states. The tableName, snapshotNames and the number of rows in the
087   * snapshot are initialized.
088   */
089  @BeforeEach
090  public void setUp(TestInfo testInfo) throws Exception {
091    this.admin = TEST_UTIL.getAdmin();
092    long tid = EnvironmentEdgeManager.currentTime();
093    testName = testInfo.getTestMethod().get().getName()
094      + testInfo.getDisplayName().replaceAll("[^0-9A-Za-z_]", "_");
095    tableName = TableName.valueOf(getValidMethodName() + tid);
096    emptySnapshot = "emptySnaptb-" + tid;
097    snapshotName0 = "snaptb0-" + tid;
098    snapshotName1 = "snaptb1-" + tid;
099    snapshotName2 = "snaptb2-" + tid;
100
101    createTableAndSnapshots();
102  }
103
104  protected void createTable() throws IOException, InterruptedException {
105    SnapshotTestingUtils.createTable(TEST_UTIL, tableName, numReplicas, FAMILY);
106  }
107
108  protected int numRowsToLoad() {
109    return 500;
110  }
111
112  protected int countRows(Table table) throws IOException {
113    return HBaseTestingUtil.countRows(table);
114  }
115
116  private void createTableAndSnapshots() throws Exception {
117    // create Table and disable it
118    createTable();
119    admin.disableTable(tableName);
120
121    // take an empty snapshot
122    admin.snapshot(emptySnapshot, tableName);
123
124    // enable table and insert data
125    admin.enableTable(tableName);
126    SnapshotTestingUtils.loadData(TEST_UTIL, tableName, numRowsToLoad(), FAMILY);
127    try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
128      snapshot0Rows = countRows(table);
129    }
130    admin.disableTable(tableName);
131
132    // take a snapshot
133    admin.snapshot(snapshotName0, tableName);
134
135    // enable table and insert more data
136    admin.enableTable(tableName);
137    SnapshotTestingUtils.loadData(TEST_UTIL, tableName, numRowsToLoad(), FAMILY);
138    try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
139      snapshot1Rows = countRows(table);
140    }
141    admin.disableTable(tableName);
142
143    // take a snapshot of the updated table
144    admin.snapshot(snapshotName1, tableName);
145
146    // re-enable table
147    admin.enableTable(tableName);
148  }
149
150  protected void verifyRowCount(final HBaseTestingUtil util, final TableName tableName,
151    long expectedRows) throws IOException {
152    SnapshotTestingUtils.verifyRowCount(util, tableName, expectedRows);
153  }
154
155  @AfterEach
156  public void tearDown() throws Exception {
157    if (admin.tableExists(tableName)) {
158      TEST_UTIL.deleteTable(tableName);
159    }
160    SnapshotTestingUtils.deleteAllSnapshots(admin);
161    SnapshotTestingUtils.deleteArchiveDirectory(TEST_UTIL);
162  }
163}