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 java.io.IOException; 021import java.util.Arrays; 022import java.util.List; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.hbase.HBaseClassTestRule; 025import org.apache.hadoop.hbase.HBaseTestingUtility; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.ipc.HBaseRpcController; 028import org.apache.hadoop.hbase.testclassification.LargeTests; 029import org.apache.hadoop.hbase.util.Bytes; 030import org.junit.After; 031import org.junit.Assert; 032import org.junit.Before; 033import org.junit.ClassRule; 034import org.junit.Test; 035import org.junit.experimental.categories.Category; 036import org.junit.runner.RunWith; 037import org.junit.runners.Parameterized; 038import org.mockito.Mockito; 039 040import org.apache.hbase.thirdparty.com.google.protobuf.RpcController; 041import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException; 042 043import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter; 044import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.Action; 045import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MultiRequest; 046import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.RegionAction; 047import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 048 049/** 050 * Tests logging of large batch commands via Multi. Tests are fast, but uses a mini-cluster (to test 051 * via "Multi" commands) so classified as MediumTests 052 */ 053@RunWith(Parameterized.class) 054@Category(LargeTests.class) 055public class TestMultiLogThreshold { 056 057 @ClassRule 058 public static final HBaseClassTestRule CLASS_RULE = 059 HBaseClassTestRule.forClass(TestMultiLogThreshold.class); 060 061 private static RSRpcServices SERVICES; 062 063 private static HBaseTestingUtility TEST_UTIL; 064 private static Configuration CONF; 065 private static final byte[] TEST_FAM = Bytes.toBytes("fam"); 066 private static RSRpcServices.LogDelegate LD; 067 private static HRegionServer RS; 068 private static int THRESHOLD; 069 070 @Parameterized.Parameter 071 public static boolean rejectLargeBatchOp; 072 073 @Parameterized.Parameters 074 public static List<Object[]> params() { 075 return Arrays.asList(new Object[] { false }, new Object[] { true }); 076 } 077 078 @Before 079 public void setupTest() throws Exception { 080 final TableName tableName = TableName.valueOf("tableName"); 081 TEST_UTIL = HBaseTestingUtility.createLocalHTU(); 082 CONF = TEST_UTIL.getConfiguration(); 083 THRESHOLD = CONF.getInt(RSRpcServices.BATCH_ROWS_THRESHOLD_NAME, 084 RSRpcServices.BATCH_ROWS_THRESHOLD_DEFAULT); 085 CONF.setBoolean("hbase.rpc.rows.size.threshold.reject", rejectLargeBatchOp); 086 TEST_UTIL.startMiniCluster(); 087 TEST_UTIL.createTable(tableName, TEST_FAM); 088 RS = TEST_UTIL.getRSForFirstRegionInTable(tableName); 089 } 090 091 @After 092 public void tearDown() throws Exception { 093 TEST_UTIL.shutdownMiniCluster(); 094 } 095 096 private enum ActionType { 097 REGION_ACTIONS, ACTIONS; 098 } 099 100 /** 101 * Sends a multi request with a certain amount of rows, will populate Multi command with either 102 * "rows" number of RegionActions with one Action each or one RegionAction with "rows" number of 103 * Actions 104 */ 105 private void sendMultiRequest(int rows, ActionType actionType) 106 throws ServiceException, IOException { 107 RpcController rpcc = Mockito.mock(HBaseRpcController.class); 108 MultiRequest.Builder builder = MultiRequest.newBuilder(); 109 int numRAs = 1; 110 int numAs = 1; 111 switch (actionType) { 112 case REGION_ACTIONS: 113 numRAs = rows; 114 break; 115 case ACTIONS: 116 numAs = rows; 117 break; 118 } 119 for (int i = 0; i < numRAs; i++) { 120 RegionAction.Builder rab = RegionAction.newBuilder(); 121 rab.setRegion(RequestConverter.buildRegionSpecifier( 122 HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME, 123 new String("someStuff" + i).getBytes())); 124 for (int j = 0; j < numAs; j++) { 125 Action.Builder ab = Action.newBuilder(); 126 rab.addAction(ab.build()); 127 } 128 builder.addRegionAction(rab.build()); 129 } 130 LD = Mockito.mock(RSRpcServices.LogDelegate.class); 131 SERVICES = new RSRpcServices(RS, LD); 132 SERVICES.multi(rpcc, builder.build()); 133 } 134 135 @Test 136 public void testMultiLogThresholdRegionActions() throws ServiceException, IOException { 137 try { 138 sendMultiRequest(THRESHOLD + 1, ActionType.REGION_ACTIONS); 139 Assert.assertFalse(rejectLargeBatchOp); 140 } catch (ServiceException e) { 141 Assert.assertTrue(rejectLargeBatchOp); 142 } 143 Mockito.verify(LD, Mockito.times(1)) 144 .logBatchWarning(Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); 145 146 sendMultiRequest(THRESHOLD, ActionType.REGION_ACTIONS); 147 Mockito.verify(LD, Mockito.never()) 148 .logBatchWarning(Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); 149 150 try { 151 sendMultiRequest(THRESHOLD + 1, ActionType.ACTIONS); 152 Assert.assertFalse(rejectLargeBatchOp); 153 } catch (ServiceException e) { 154 Assert.assertTrue(rejectLargeBatchOp); 155 } 156 Mockito.verify(LD, Mockito.times(1)) 157 .logBatchWarning(Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); 158 159 sendMultiRequest(THRESHOLD, ActionType.ACTIONS); 160 Mockito.verify(LD, Mockito.never()) 161 .logBatchWarning(Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); 162 } 163 164}