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 junit.framework.TestCase.fail; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import java.util.List; 025import java.util.stream.Collectors; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.DoNotRetryIOException; 028import org.apache.hadoop.hbase.HBaseClassTestRule; 029import org.apache.hadoop.hbase.HBaseTestingUtility; 030import org.apache.hadoop.hbase.TableName; 031import org.apache.hadoop.hbase.client.Admin; 032import org.apache.hadoop.hbase.client.DoNotRetryRegionException; 033import org.apache.hadoop.hbase.client.Put; 034import org.apache.hadoop.hbase.client.RegionInfo; 035import org.apache.hadoop.hbase.client.Table; 036import org.apache.hadoop.hbase.testclassification.MediumTests; 037import org.apache.hadoop.hbase.util.Bytes; 038import org.junit.AfterClass; 039import org.junit.Before; 040import org.junit.BeforeClass; 041import org.junit.ClassRule; 042import org.junit.Rule; 043import org.junit.Test; 044import org.junit.experimental.categories.Category; 045import org.junit.rules.ExpectedException; 046import org.junit.rules.TestName; 047 048/** 049 * Test move fails when table disabled 050 */ 051@Category({ MediumTests.class }) 052public class TestRegionMove { 053 054 @ClassRule 055 public static final HBaseClassTestRule CLASS_RULE = 056 HBaseClassTestRule.forClass(TestRegionMove.class); 057 058 @Rule 059 public ExpectedException thrown = ExpectedException.none(); 060 061 @Rule 062 public TestName name = new TestName(); 063 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 064 public static Configuration CONF; 065 protected static final String F1 = "f1"; 066 067 // Test names 068 protected TableName tableName; 069 protected String method; 070 071 @BeforeClass 072 public static void startCluster() throws Exception { 073 TEST_UTIL.startMiniCluster(2); 074 } 075 076 @AfterClass 077 public static void stopCluster() throws Exception { 078 TEST_UTIL.shutdownMiniCluster(); 079 } 080 081 @Before 082 public void setup() throws IOException { 083 CONF = TEST_UTIL.getConfiguration(); 084 method = name.getMethodName(); 085 tableName = TableName.valueOf(method); 086 } 087 088 @Test 089 public void testDisableAndMove() throws Exception { 090 Admin admin = TEST_UTIL.getAdmin(); 091 092 // Create a table with more than one region 093 Table t = TEST_UTIL.createMultiRegionTable(tableName, Bytes.toBytes(F1), 10); 094 TEST_UTIL.waitUntilAllRegionsAssigned(tableName); 095 096 // Write an update to each region 097 for (RegionInfo regionInfo : admin.getRegions(tableName)) { 098 byte[] startKey = regionInfo.getStartKey(); 099 // The startKey of the first region is "empty", which would throw an error if we try to 100 // Put that. 101 byte[] rowKey = org.apache.hbase.thirdparty.com.google.common.primitives.Bytes 102 .concat(startKey, Bytes.toBytes("1")); 103 Put p = new Put(rowKey); 104 p.addColumn(Bytes.toBytes(F1), Bytes.toBytes("q1"), Bytes.toBytes("value")); 105 t.put(p); 106 } 107 108 // Get a Region which is on the first RS 109 HRegionServer rs1 = TEST_UTIL.getRSForFirstRegionInTable(tableName); 110 HRegionServer rs2 = TEST_UTIL.getOtherRegionServer(rs1); 111 List<RegionInfo> regionsOnRS1ForTable = admin.getRegions(rs1.getServerName()).stream() 112 .filter((regionInfo) -> regionInfo.getTable().equals(tableName)).collect(Collectors.toList()); 113 assertTrue("Expected to find at least one region for " + tableName + " on " 114 + rs1.getServerName() + ", but found none", !regionsOnRS1ForTable.isEmpty()); 115 final RegionInfo regionToMove = regionsOnRS1ForTable.get(0); 116 117 // Offline the region and then try to move it. Should fail. 118 admin.unassign(regionToMove.getRegionName(), true); 119 try { 120 admin.move(regionToMove.getEncodedNameAsBytes(), rs2.getServerName()); 121 fail(); 122 } catch (DoNotRetryRegionException e) { 123 // We got expected exception 124 } 125 // Reassign for next stage of test. 126 admin.assign(regionToMove.getRegionName()); 127 128 // Disable the table 129 admin.disableTable(tableName); 130 131 try { 132 // Move the region to the other RS -- should fail 133 admin.move(regionToMove.getEncodedNameAsBytes(), rs2.getServerName()); 134 fail(); 135 } catch (DoNotRetryIOException e) { 136 // We got expected exception 137 } 138 } 139}