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;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertNotNull;
022import static org.junit.Assert.assertNull;
023
024import java.io.IOException;
025import org.apache.hadoop.hbase.client.RegionInfo;
026import org.apache.hadoop.hbase.regionserver.HRegionServer;
027import org.apache.hadoop.hbase.testclassification.MediumTests;
028import org.apache.hadoop.hbase.testclassification.MiscTests;
029import org.apache.hadoop.hbase.util.Bytes;
030import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
031import org.apache.hbase.thirdparty.com.google.common.collect.Iterables;
032import org.junit.After;
033import org.junit.Before;
034import org.junit.ClassRule;
035import org.junit.Rule;
036import org.junit.Test;
037import org.junit.experimental.categories.Category;
038import org.junit.rules.TestName;
039
040/**
041 * Test whether moved region cache is correct
042 */
043@Category({ MiscTests.class, MediumTests.class })
044public class TestMovedRegionCache {
045
046  @ClassRule
047  public static final HBaseClassTestRule CLASS_RULE =
048      HBaseClassTestRule.forClass(TestMovedRegionCache.class);
049
050  @Rule
051  public TestName name = new TestName();
052
053  private HBaseTestingUtility UTIL;
054  private MiniZooKeeperCluster zkCluster;
055  private HRegionServer source;
056  private HRegionServer dest;
057  private RegionInfo movedRegionInfo;
058
059  @Before
060  public void setup() throws Exception {
061    UTIL = new HBaseTestingUtility();
062    zkCluster = UTIL.startMiniZKCluster();
063    StartMiniClusterOption option = StartMiniClusterOption.builder().numRegionServers(2).build();
064    MiniHBaseCluster cluster = UTIL.startMiniHBaseCluster(option);
065    source = cluster.getRegionServer(0);
066    dest = cluster.getRegionServer(1);
067    assertEquals(2, cluster.getRegionServerThreads().size());
068    TableName tableName = TableName.valueOf(name.getMethodName());
069    UTIL.createTable(tableName, Bytes.toBytes("cf"));
070    UTIL.waitTableAvailable(tableName, 30_000);
071    movedRegionInfo = Iterables.getOnlyElement(cluster.getRegions(tableName)).getRegionInfo();
072    UTIL.getAdmin().move(movedRegionInfo.getEncodedNameAsBytes(), source.getServerName());
073    UTIL.waitFor(2000, new Waiter.Predicate<IOException>() {
074      @Override
075      public boolean evaluate() throws IOException {
076        return source.getOnlineRegion(movedRegionInfo.getRegionName()) != null;
077      }
078    });
079  }
080
081  @After
082  public void after() throws Exception {
083    UTIL.shutdownMiniCluster();
084    if (zkCluster != null) {
085      zkCluster.shutdown();
086    }
087  }
088
089  @Test
090  public void testMovedRegionsCache() throws IOException, InterruptedException {
091    UTIL.getAdmin().move(movedRegionInfo.getEncodedNameAsBytes(), dest.getServerName());
092    UTIL.waitFor(2000, new Waiter.Predicate<IOException>() {
093      @Override
094      public boolean evaluate() throws IOException {
095        return dest.getOnlineRegion(movedRegionInfo.getRegionName()) != null;
096      }
097    });
098    assertNotNull("Moved region NOT in the cache!", source.getMovedRegion(
099      movedRegionInfo.getEncodedName()));
100    Thread.sleep(source.movedRegionCacheExpiredTime());
101    assertNull("Expired moved region exist in the cache!", source.getMovedRegion(
102      movedRegionInfo.getEncodedName()));
103  }
104}