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.regionserver;
019
020import static org.junit.Assert.assertEquals;
021
022import java.io.IOException;
023import java.util.Arrays;
024import java.util.List;
025import org.apache.hadoop.conf.Configuration;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.HBaseTestingUtil;
028import org.apache.hadoop.hbase.HConstants;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.TableNameTestRule;
031import org.apache.hadoop.hbase.client.TableDescriptor;
032import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
033import org.apache.hadoop.hbase.testclassification.MediumTests;
034import org.apache.hadoop.hbase.testclassification.RegionServerTests;
035import org.apache.hadoop.hbase.util.Bytes;
036import org.apache.hadoop.hbase.util.RegionSplitter;
037import org.junit.After;
038import org.junit.AfterClass;
039import org.junit.BeforeClass;
040import org.junit.ClassRule;
041import org.junit.Rule;
042import org.junit.Test;
043import org.junit.experimental.categories.Category;
044import org.junit.runner.RunWith;
045import org.junit.runners.Parameterized;
046import org.junit.runners.Parameterized.Parameter;
047import org.junit.runners.Parameterized.Parameters;
048
049@RunWith(Parameterized.class)
050@Category({ RegionServerTests.class, MediumTests.class })
051public class TestRegionReplicasWithModifyTable {
052
053  @ClassRule
054  public static final HBaseClassTestRule CLASS_RULE =
055    HBaseClassTestRule.forClass(TestRegionReplicasWithModifyTable.class);
056
057  private static final int NB_SERVERS = 3;
058
059  private static final HBaseTestingUtil HTU = new HBaseTestingUtil();
060  private static final byte[] f = HConstants.CATALOG_FAMILY;
061
062  @Parameter
063  public boolean disableBeforeModifying;
064
065  @Rule
066  public TableNameTestRule name = new TableNameTestRule();
067
068  @Parameters
069  public static List<Object[]> params() {
070    return Arrays.asList(new Object[] { true }, new Object[] { false });
071  }
072
073  @BeforeClass
074  public static void before() throws Exception {
075    HTU.startMiniCluster(NB_SERVERS);
076  }
077
078  private void enableReplicationByModification(boolean withReplica, int initialReplicaCount,
079    int enableReplicaCount, int splitCount) throws IOException, InterruptedException {
080    TableName tableName = name.getTableName();
081    TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName);
082    if (withReplica) {
083      builder.setRegionReplication(initialReplicaCount);
084    }
085    TableDescriptor htd = builder.build();
086    if (splitCount > 0) {
087      byte[][] splits = getSplits(splitCount);
088      HTU.createTable(htd, new byte[][] { f }, splits, new Configuration(HTU.getConfiguration()));
089    } else {
090      HTU.createTable(htd, new byte[][] { f }, (byte[][]) null,
091        new Configuration(HTU.getConfiguration()));
092    }
093    if (disableBeforeModifying) {
094      HTU.getAdmin().disableTable(tableName);
095    }
096    HBaseTestingUtil.setReplicas(HTU.getAdmin(), tableName, enableReplicaCount);
097    if (disableBeforeModifying) {
098      HTU.getAdmin().enableTable(tableName);
099    }
100    int expectedRegionCount;
101    if (splitCount > 0) {
102      expectedRegionCount = enableReplicaCount * splitCount;
103    } else {
104      expectedRegionCount = enableReplicaCount;
105    }
106    assertTotalRegions(expectedRegionCount);
107  }
108
109  private static byte[][] getSplits(int numRegions) {
110    RegionSplitter.UniformSplit split = new RegionSplitter.UniformSplit();
111    split.setFirstRow(Bytes.toBytes(0L));
112    split.setLastRow(Bytes.toBytes(Long.MAX_VALUE));
113    return split.split(numRegions);
114  }
115
116  @AfterClass
117  public static void afterClass() throws Exception {
118    HTU.shutdownMiniCluster();
119  }
120
121  @After
122  public void tearDown() throws IOException {
123    TableName tableName = name.getTableName();
124    HTU.getAdmin().disableTable(tableName);
125    HTU.getAdmin().deleteTable(tableName);
126  }
127
128  private void assertTotalRegions(int expected) {
129    int actual = HTU.getHBaseCluster().getRegions(name.getTableName()).size();
130    assertEquals(expected, actual);
131  }
132
133  @Test
134  public void testRegionReplicasUsingEnableTable() throws Exception {
135    enableReplicationByModification(false, 0, 3, 0);
136  }
137
138  @Test
139  public void testRegionReplicasUsingEnableTableForMultipleRegions() throws Exception {
140    enableReplicationByModification(false, 0, 3, 10);
141  }
142
143  @Test
144  public void testRegionReplicasByEnableTableWhenReplicaCountIsIncreased() throws Exception {
145    enableReplicationByModification(true, 2, 3, 0);
146  }
147
148  @Test
149  public void testRegionReplicasByEnableTableWhenReplicaCountIsDecreased() throws Exception {
150    enableReplicationByModification(true, 3, 2, 0);
151  }
152
153  @Test
154  public void testRegionReplicasByEnableTableWhenReplicaCountIsDecreasedWithMultipleRegions()
155    throws Exception {
156    enableReplicationByModification(true, 3, 2, 20);
157  }
158
159  @Test
160  public void testRegionReplicasByEnableTableWhenReplicaCountIsIncreasedWithMultipleRegions()
161    throws Exception {
162    enableReplicationByModification(true, 2, 3, 15);
163  }
164}