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.List;
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.hbase.HBaseClassTestRule;
026import org.apache.hadoop.hbase.HBaseTestingUtility;
027import org.apache.hadoop.hbase.HConstants;
028import org.apache.hadoop.hbase.HTableDescriptor;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.client.Table;
031import org.apache.hadoop.hbase.testclassification.MediumTests;
032import org.apache.hadoop.hbase.testclassification.RegionServerTests;
033import org.apache.hadoop.hbase.util.Bytes;
034import org.apache.hadoop.hbase.util.RegionSplitter;
035import org.junit.AfterClass;
036import org.junit.BeforeClass;
037import org.junit.ClassRule;
038import org.junit.Rule;
039import org.junit.Test;
040import org.junit.experimental.categories.Category;
041import org.junit.rules.TestName;
042
043@Category({ RegionServerTests.class, MediumTests.class })
044public class TestRegionReplicasWithModifyTable {
045
046  @ClassRule
047  public static final HBaseClassTestRule CLASS_RULE =
048      HBaseClassTestRule.forClass(TestRegionReplicasWithModifyTable.class);
049
050  private static final int NB_SERVERS = 3;
051  private static Table table;
052  private static final byte[] row = "TestRegionReplicasWithModifyTable".getBytes();
053
054  private static final HBaseTestingUtility HTU = new HBaseTestingUtility();
055  private static final byte[] f = HConstants.CATALOG_FAMILY;
056
057  @Rule
058  public TestName name = new TestName();
059
060  @BeforeClass
061  public static void before() throws Exception {
062    HTU.startMiniCluster(NB_SERVERS);
063  }
064
065  private static void enableReplicationByModification(final TableName tableName,
066      boolean withReplica, int initialReplicaCount, int enableReplicaCount, int splitCount)
067      throws IOException, InterruptedException {
068    HTableDescriptor htd = new HTableDescriptor(tableName);
069    if (withReplica) {
070      htd.setRegionReplication(initialReplicaCount);
071    }
072    if (splitCount > 0) {
073      byte[][] splits = getSplits(splitCount);
074      table = HTU.createTable(htd, new byte[][] { f }, splits,
075        new Configuration(HTU.getConfiguration()));
076
077    } else {
078      table = HTU.createTable(htd, new byte[][] { f }, (byte[][]) null,
079        new Configuration(HTU.getConfiguration()));
080    }
081    HBaseTestingUtility.setReplicas(HTU.getAdmin(), table.getName(), enableReplicaCount);
082  }
083
084  private static byte[][] getSplits(int numRegions) {
085    RegionSplitter.UniformSplit split = new RegionSplitter.UniformSplit();
086    split.setFirstRow(Bytes.toBytes(0L));
087    split.setLastRow(Bytes.toBytes(Long.MAX_VALUE));
088    return split.split(numRegions);
089  }
090
091  @AfterClass
092  public static void afterClass() throws Exception {
093    HRegionServer.TEST_SKIP_REPORTING_TRANSITION = false;
094    table.close();
095    HTU.shutdownMiniCluster();
096  }
097
098  private HRegionServer getRS() {
099    return HTU.getMiniHBaseCluster().getRegionServer(0);
100  }
101
102  private HRegionServer getSecondaryRS() {
103    return HTU.getMiniHBaseCluster().getRegionServer(1);
104  }
105
106  private HRegionServer getTertiaryRS() {
107    return HTU.getMiniHBaseCluster().getRegionServer(2);
108  }
109
110  @Test
111  public void testRegionReplicasUsingEnableTable() throws Exception {
112    TableName tableName = null;
113    try {
114      tableName = TableName.valueOf(name.getMethodName());
115      enableReplicationByModification(tableName, false, 0, 3, 0);
116      List<HRegion> onlineRegions = getRS().getRegions(tableName);
117      List<HRegion> onlineRegions2 = getSecondaryRS().getRegions(tableName);
118      List<HRegion> onlineRegions3 = getTertiaryRS().getRegions(tableName);
119      int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size();
120      assertEquals("the number of regions should be more than 1", 3, totalRegions);
121    } finally {
122      disableAndDeleteTable(tableName);
123    }
124  }
125
126  private void disableAndDeleteTable(TableName tableName) throws IOException {
127    HTU.getAdmin().disableTable(tableName);
128    HTU.getAdmin().deleteTable(tableName);
129  }
130
131  @Test
132  public void testRegionReplicasUsingEnableTableForMultipleRegions() throws Exception {
133    TableName tableName = null;
134    try {
135      tableName = TableName.valueOf(name.getMethodName());
136      enableReplicationByModification(tableName, false, 0, 3, 10);
137      List<HRegion> onlineRegions = getRS().getRegions(tableName);
138      List<HRegion> onlineRegions2 = getSecondaryRS().getRegions(tableName);
139      List<HRegion> onlineRegions3 = getTertiaryRS().getRegions(tableName);
140      int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size();
141      assertEquals("the number of regions should be equal to 30", 30, totalRegions);
142    } finally {
143      disableAndDeleteTable(tableName);
144    }
145  }
146
147  @Test
148  public void testRegionReplicasByEnableTableWhenReplicaCountIsIncreased() throws Exception {
149    TableName tableName = null;
150    try {
151      tableName = TableName.valueOf(name.getMethodName());
152      enableReplicationByModification(tableName, true, 2, 3, 0);
153      List<HRegion> onlineRegions = getRS().getRegions(tableName);
154      List<HRegion> onlineRegions2 = getSecondaryRS().getRegions(tableName);
155      List<HRegion> onlineRegions3 = getTertiaryRS().getRegions(tableName);
156      int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size();
157      assertEquals("the number of regions should be 3", 3, totalRegions);
158    } finally {
159      disableAndDeleteTable(tableName);
160    }
161  }
162
163  @Test
164  public void testRegionReplicasByEnableTableWhenReplicaCountIsDecreased() throws Exception {
165    TableName tableName = null;
166    try {
167      tableName = TableName.valueOf(name.getMethodName());
168      enableReplicationByModification(tableName, true, 3, 2, 0);
169      List<HRegion> onlineRegions = getRS().getRegions(tableName);
170      List<HRegion> onlineRegions2 = getSecondaryRS().getRegions(tableName);
171      List<HRegion> onlineRegions3 = getTertiaryRS().getRegions(tableName);
172      int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size();
173      assertEquals("the number of regions should be reduced to 2", 2, totalRegions);
174    } finally {
175      disableAndDeleteTable(tableName);
176    }
177  }
178
179  @Test
180  public void testRegionReplicasByEnableTableWhenReplicaCountIsDecreasedWithMultipleRegions()
181      throws Exception {
182    TableName tableName = null;
183    try {
184      tableName = TableName.valueOf(name.getMethodName());
185      enableReplicationByModification(tableName, true, 3, 2, 20);
186      List<HRegion> onlineRegions = getRS().getRegions(tableName);
187      List<HRegion> onlineRegions2 = getSecondaryRS().getRegions(tableName);
188      List<HRegion> onlineRegions3 = getTertiaryRS().getRegions(tableName);
189      int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size();
190      assertEquals("the number of regions should be reduced to 40", 40, totalRegions);
191    } finally {
192      disableAndDeleteTable(tableName);
193    }
194  }
195
196  @Test
197  public void testRegionReplicasByEnableTableWhenReplicaCountIsIncreasedWithmultipleRegions()
198      throws Exception {
199    TableName tableName = null;
200    try {
201      tableName = TableName.valueOf(name.getMethodName());
202      enableReplicationByModification(tableName, true, 2, 3, 15);
203      List<HRegion> onlineRegions = getRS().getRegions(tableName);
204      List<HRegion> onlineRegions2 = getSecondaryRS().getRegions(tableName);
205      List<HRegion> onlineRegions3 = getTertiaryRS().getRegions(tableName);
206      int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size();
207      assertEquals("the number of regions should be equal to 45", 3 * 15, totalRegions);
208    } finally {
209      disableAndDeleteTable(tableName);
210    }
211  }
212}