View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.ipc;
19  
20  import com.google.common.collect.ImmutableList;
21  import com.google.common.collect.ImmutableMap;
22  import com.google.common.collect.ImmutableSet;
23  import com.google.common.collect.Maps;
24  import com.google.protobuf.Message;
25  import org.apache.hadoop.conf.Configuration;
26  import org.apache.hadoop.hbase.HBaseConfiguration;
27  import org.apache.hadoop.hbase.HConstants;
28  import org.apache.hadoop.hbase.client.Put;
29  import org.apache.hadoop.hbase.monitoring.MonitoredRPCHandlerImpl;
30  import org.apache.hadoop.hbase.security.User;
31  import org.apache.hadoop.hbase.testclassification.SmallTests;
32  import org.apache.hadoop.hbase.client.Put;
33  import org.apache.hadoop.hbase.ipc.RpcServer.Call;
34  import org.apache.hadoop.hbase.protobuf.generated.RPCProtos;
35  import org.apache.hadoop.hbase.testclassification.SmallTests;
36  import org.junit.Before;
37  import org.junit.Test;
38  import org.junit.experimental.categories.Category;
39  import org.mockito.invocation.InvocationOnMock;
40  import org.mockito.stubbing.Answer;
41  
42  import java.io.IOException;
43  import java.net.InetSocketAddress;
44  import java.util.List;
45  import java.util.Map;
46  import java.util.concurrent.CountDownLatch;
47  
48  import static org.junit.Assert.assertEquals;
49  import static org.mockito.Matchers.anyObject;
50  import static org.mockito.Mockito.doAnswer;
51  import static org.mockito.Mockito.mock;
52  import static org.mockito.Mockito.timeout;
53  import static org.mockito.Mockito.verify;
54  import static org.mockito.Mockito.when;
55  
56  @Category(SmallTests.class)
57  public class TestSimpleRpcScheduler {
58  
59    private final RpcScheduler.Context CONTEXT = new RpcScheduler.Context() {
60      @Override
61      public InetSocketAddress getListenerAddress() {
62        return InetSocketAddress.createUnresolved("127.0.0.1", 1000);
63      }
64    };
65    private Configuration conf;
66  
67    @Before
68    public void setUp() {
69      conf = HBaseConfiguration.create();
70    }
71  
72    @Test
73    public void testBasic() throws IOException, InterruptedException {
74      PriorityFunction qosFunction = mock(PriorityFunction.class);
75      RpcScheduler scheduler = new SimpleRpcScheduler(
76        conf, 10, 0, 0, qosFunction, null, 0);
77      scheduler.init(CONTEXT);
78      scheduler.start();
79      CallRunner task = createMockTask();
80      task.setStatus(new MonitoredRPCHandlerImpl());
81      scheduler.dispatch(task);
82      verify(task, timeout(1000)).run();
83      scheduler.stop();
84    }
85  
86    @Test
87    public void testHandlerIsolation() throws IOException, InterruptedException {
88      CallRunner generalTask = createMockTask();
89      CallRunner priorityTask = createMockTask();
90      CallRunner replicationTask = createMockTask();
91      List<CallRunner> tasks = ImmutableList.of(
92          generalTask,
93          priorityTask,
94          replicationTask);
95      Map<CallRunner, Integer> qos = ImmutableMap.of(
96          generalTask, 0,
97          priorityTask, HConstants.HIGH_QOS + 1,
98          replicationTask, HConstants.REPLICATION_QOS);
99      PriorityFunction qosFunction = mock(PriorityFunction.class);
100     final Map<CallRunner, Thread> handlerThreads = Maps.newHashMap();
101     final CountDownLatch countDownLatch = new CountDownLatch(tasks.size());
102     Answer<Void> answerToRun = new Answer<Void>() {
103       @Override
104       public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
105         synchronized (handlerThreads) {
106           handlerThreads.put(
107               (CallRunner) invocationOnMock.getMock(),
108               Thread.currentThread());
109         }
110         countDownLatch.countDown();
111         return null;
112       }
113     };
114     for (CallRunner task : tasks) {
115       task.setStatus(new MonitoredRPCHandlerImpl());
116       doAnswer(answerToRun).when(task).run();
117     }
118 
119     RpcScheduler scheduler = new SimpleRpcScheduler(
120       conf, 1, 1 ,1, qosFunction, null, HConstants.HIGH_QOS);
121     scheduler.init(CONTEXT);
122     scheduler.start();
123     for (CallRunner task : tasks) {
124       when(qosFunction.getPriority((RPCProtos.RequestHeader) anyObject(), (Message) anyObject()))
125           .thenReturn(qos.get(task));
126       scheduler.dispatch(task);
127     }
128     for (CallRunner task : tasks) {
129       verify(task, timeout(1000)).run();
130     }
131     scheduler.stop();
132 
133     // Tests that these requests are handled by three distinct threads.
134     countDownLatch.await();
135     assertEquals(3, ImmutableSet.copyOf(handlerThreads.values()).size());
136   }
137 
138   private CallRunner createMockTask() {
139     Call call = mock(Call.class);
140     CallRunner task = mock(CallRunner.class);
141     when(task.getCall()).thenReturn(call);
142     return task;
143   }
144 
145 }