View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.regionserver;
20  
21  import static org.mockito.Mockito.verify;
22  
23  import java.io.IOException;
24  
25  import org.junit.Before;
26  import org.junit.BeforeClass;
27  import org.junit.Test;
28  import org.junit.experimental.categories.Category;
29  import org.mockito.Mockito;
30  
31  import com.google.protobuf.RpcController;
32  import com.google.protobuf.ServiceException;
33  
34  import org.apache.hadoop.conf.Configuration;
35  import org.apache.hadoop.hbase.HBaseTestingUtility;
36  import org.apache.hadoop.hbase.TableName;
37  import org.apache.hadoop.hbase.protobuf.RequestConverter;
38  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
39  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Action;
40  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiRequest;
41  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
42  import org.apache.hadoop.hbase.testclassification.MediumTests;
43  import org.apache.hadoop.hbase.util.Bytes;
44  
45  /**
46   * Tests logging of large batch commands via Multi. Tests are fast, but uses a mini-cluster (to test
47   * via "Multi" commands) so classified as MediumTests
48   */
49  @Category(MediumTests.class)
50  public class TestMultiLogThreshold {
51  
52    private static RSRpcServices SERVICES;
53  
54    private static HBaseTestingUtility TEST_UTIL;
55    private static Configuration CONF;
56    private static final byte[] TEST_FAM = Bytes.toBytes("fam");
57    private static RSRpcServices.LogDelegate LD;
58    private static HRegionServer RS;
59    private static int THRESHOLD;
60  
61    @BeforeClass
62    public static void setup() throws Exception {
63      final TableName tableName = TableName.valueOf("tableName");
64      TEST_UTIL = HBaseTestingUtility.createLocalHTU();
65      CONF = TEST_UTIL.getConfiguration();
66      THRESHOLD = CONF.getInt(RSRpcServices.BATCH_ROWS_THRESHOLD_NAME,
67        RSRpcServices.BATCH_ROWS_THRESHOLD_DEFAULT);
68      TEST_UTIL.startMiniCluster();
69      TEST_UTIL.createTable(tableName, TEST_FAM);
70      RS = TEST_UTIL.getRSForFirstRegionInTable(tableName);
71    }
72  
73    @Before
74    public void setupTest() throws Exception {
75      LD = Mockito.mock(RSRpcServices.LogDelegate.class);
76      SERVICES = new RSRpcServices(RS, LD);
77    }
78  
79    private enum ActionType {
80      REGION_ACTIONS, ACTIONS;
81    }
82  
83    /**
84     * Sends a multi request with a certain amount of rows, will populate Multi command with either
85     * "rows" number of RegionActions with one Action each or one RegionAction with "rows" number of
86     * Actions
87     */
88    private void sendMultiRequest(int rows, ActionType actionType) throws ServiceException {
89      RpcController rpcc = Mockito.mock(RpcController.class);
90      MultiRequest.Builder builder = MultiRequest.newBuilder();
91      int numRAs = 1;
92      int numAs = 1;
93      switch (actionType) {
94      case REGION_ACTIONS:
95        numRAs = rows;
96        break;
97      case ACTIONS:
98        numAs = rows;
99        break;
100     }
101     for (int i = 0; i < numRAs; i++) {
102       RegionAction.Builder rab = RegionAction.newBuilder();
103       rab.setRegion(RequestConverter.buildRegionSpecifier(
104         HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME,
105         new String("someStuff" + i).getBytes()));
106       for (int j = 0; j < numAs; j++) {
107         Action.Builder ab = Action.newBuilder();
108         rab.addAction(ab.build());
109       }
110       builder.addRegionAction(rab.build());
111     }
112     try {
113       SERVICES.multi(rpcc, builder.build());
114     } catch (ClassCastException e) {
115       // swallow expected exception due to mocked RpcController
116     }
117   }
118 
119   @Test
120   public void testMultiLogThresholdRegionActions() throws ServiceException, IOException {
121     sendMultiRequest(THRESHOLD + 1, ActionType.REGION_ACTIONS);
122     verify(LD, Mockito.times(1)).logBatchWarning(Mockito.anyString(), Mockito.anyInt(),
123       Mockito.anyInt());
124   }
125 
126   @Test
127   public void testMultiNoLogThresholdRegionActions() throws ServiceException, IOException {
128     sendMultiRequest(THRESHOLD, ActionType.REGION_ACTIONS);
129     verify(LD, Mockito.never()).logBatchWarning(Mockito.anyString(), Mockito.anyInt(),
130       Mockito.anyInt());
131   }
132 
133   @Test
134   public void testMultiLogThresholdActions() throws ServiceException, IOException {
135     sendMultiRequest(THRESHOLD + 1, ActionType.ACTIONS);
136     verify(LD, Mockito.times(1)).logBatchWarning(Mockito.anyString(), Mockito.anyInt(),
137       Mockito.anyInt());
138   }
139 
140   @Test
141   public void testMultiNoLogThresholdAction() throws ServiceException, IOException {
142     sendMultiRequest(THRESHOLD, ActionType.ACTIONS);
143     verify(LD, Mockito.never()).logBatchWarning(Mockito.anyString(), Mockito.anyInt(),
144       Mockito.anyInt());
145   }
146 
147 }