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.io.encoding;
019
020import static org.junit.jupiter.api.Assertions.assertTrue;
021
022import java.io.IOException;
023import java.util.List;
024import org.apache.hadoop.hbase.HRegionLocation;
025import org.apache.hadoop.hbase.client.Admin;
026import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
027import org.apache.hadoop.hbase.client.RegionLocator;
028import org.apache.hadoop.hbase.client.Result;
029import org.apache.hadoop.hbase.client.ResultScanner;
030import org.apache.hadoop.hbase.client.Scan;
031import org.apache.hadoop.hbase.client.Table;
032import org.apache.hadoop.hbase.io.compress.Compression;
033import org.apache.hadoop.hbase.io.hfile.CacheConfig;
034import org.apache.hadoop.hbase.regionserver.HRegionServer;
035import org.apache.hadoop.hbase.testclassification.IOTests;
036import org.apache.hadoop.hbase.testclassification.LargeTests;
037import org.apache.hadoop.hbase.util.TestMiniClusterLoadSequential;
038import org.apache.hadoop.hbase.util.Threads;
039import org.junit.jupiter.api.Tag;
040import org.junit.jupiter.api.Test;
041
042/**
043 * Uses the load tester
044 */
045@Tag(IOTests.TAG)
046@Tag(LargeTests.TAG)
047public class TestLoadAndSwitchEncodeOnDisk extends TestMiniClusterLoadSequential {
048
049  /** We do not alternate the multi-put flag in this test. */
050  private static final boolean USE_MULTI_PUT = true;
051
052  public TestLoadAndSwitchEncodeOnDisk() {
053    super(USE_MULTI_PUT, DataBlockEncoding.PREFIX);
054    conf.setBoolean(CacheConfig.CACHE_BLOCKS_ON_WRITE_KEY, true);
055  }
056
057  @Override
058  protected int numKeys() {
059    return 3000;
060  }
061
062  @Override
063  @Test
064  public void loadTest() throws Exception {
065    Admin admin = TEST_UTIL.getAdmin();
066
067    compression = Compression.Algorithm.GZ; // used for table setup
068    super.loadTest();
069
070    ColumnFamilyDescriptor hcd = getColumnDesc(admin);
071    System.err.println("\nDisabling encode-on-disk. Old column descriptor: " + hcd + "\n");
072    Table t = TEST_UTIL.getConnection().getTable(TABLE);
073    assertAllOnLine(t);
074
075    admin.disableTable(TABLE);
076    admin.modifyColumnFamily(TABLE, hcd);
077
078    System.err.println("\nRe-enabling table\n");
079    admin.enableTable(TABLE);
080
081    System.err.println("\nNew column descriptor: " + getColumnDesc(admin) + "\n");
082
083    // The table may not have all regions on line yet. Assert online before
084    // moving to major compact.
085    assertAllOnLine(t);
086
087    System.err.println("\nCompacting the table\n");
088    admin.majorCompact(TABLE);
089    // Wait until compaction completes
090    Threads.sleepWithoutInterrupt(5000);
091    HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0);
092    while (rs.getCompactSplitThread().getCompactionQueueSize() > 0) {
093      Threads.sleep(50);
094    }
095
096    System.err.println("\nDone with the test, shutting down the cluster\n");
097  }
098
099  private void assertAllOnLine(final Table t) throws IOException {
100    List<HRegionLocation> regions;
101    try (RegionLocator rl = TEST_UTIL.getConnection().getRegionLocator(t.getName())) {
102      regions = rl.getAllRegionLocations();
103    }
104    for (HRegionLocation e : regions) {
105      byte[] startkey = e.getRegion().getStartKey();
106      Scan s = new Scan().withStartRow(startkey);
107      ResultScanner scanner = t.getScanner(s);
108      Result r = scanner.next();
109      assertTrue(r != null && r.size() > 0);
110      scanner.close();
111    }
112  }
113}