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