1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.client;
21
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24
25 import java.net.SocketAddress;
26 import java.net.SocketTimeoutException;
27 import java.net.UnknownHostException;
28 import java.util.Random;
29 import java.util.concurrent.atomic.AtomicInteger;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.HBaseConfiguration;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.HConstants;
37 import org.apache.hadoop.hbase.MasterNotRunningException;
38 import org.apache.hadoop.hbase.testclassification.MediumTests;
39 import org.apache.hadoop.hbase.ServerName;
40 import org.apache.hadoop.hbase.ipc.AbstractRpcClient;
41 import org.apache.hadoop.hbase.ipc.RpcClient;
42 import org.apache.hadoop.hbase.ipc.RpcClientFactory;
43 import org.apache.hadoop.hbase.ipc.RpcClientImpl;
44 import org.apache.hadoop.hbase.security.User;
45 import org.junit.AfterClass;
46 import org.junit.BeforeClass;
47 import org.junit.Test;
48 import org.junit.experimental.categories.Category;
49
50 import com.google.protobuf.BlockingRpcChannel;
51 import com.google.protobuf.Descriptors.MethodDescriptor;
52 import com.google.protobuf.Message;
53 import com.google.protobuf.RpcController;
54 import com.google.protobuf.ServiceException;
55
56 @Category(MediumTests.class)
57 public class TestClientTimeouts {
58 private static final Log LOG = LogFactory.getLog(TestClientTimeouts.class);
59 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
60 protected static int SLAVES = 1;
61
62
63
64
65 @BeforeClass
66 public static void setUpBeforeClass() throws Exception {
67 TEST_UTIL.startMiniCluster(SLAVES);
68
69 TEST_UTIL.getConfiguration().set(
70 RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY,
71 RandomTimeoutRpcClient.class.getName());
72 }
73
74
75
76
77 @AfterClass
78 public static void tearDownAfterClass() throws Exception {
79 TEST_UTIL.shutdownMiniCluster();
80 }
81
82
83
84
85
86
87 @Test
88 public void testAdminTimeout() throws Exception {
89 Connection lastConnection = null;
90 boolean lastFailed = false;
91 int initialInvocations = RandomTimeoutBlockingRpcChannel.invokations.get();
92 RandomTimeoutRpcClient rpcClient = (RandomTimeoutRpcClient) RpcClientFactory
93 .createClient(TEST_UTIL.getConfiguration(), TEST_UTIL.getClusterKey());
94
95 try {
96 for (int i = 0; i < 5 || (lastFailed && i < 100); ++i) {
97 lastFailed = false;
98
99 Configuration conf = HBaseConfiguration.create(TEST_UTIL.getConfiguration());
100 conf.set(HConstants.HBASE_CLIENT_INSTANCE_ID, String.valueOf(-1));
101 HBaseAdmin admin = null;
102 try {
103 admin = new HBaseAdmin(conf);
104 Connection connection = admin.getConnection();
105 assertFalse(connection == lastConnection);
106 lastConnection = connection;
107
108 HBaseAdmin.checkHBaseAvailable(conf);
109 admin.setBalancerRunning(false, false);
110 } catch (MasterNotRunningException ex) {
111
112
113 lastFailed = true;
114 } finally {
115 admin.close();
116 if (admin.getConnection().isClosed()) {
117 rpcClient = (RandomTimeoutRpcClient) RpcClientFactory
118 .createClient(TEST_UTIL.getConfiguration(), TEST_UTIL.getClusterKey());
119 }
120 }
121 }
122
123 assertFalse(lastFailed);
124 assertTrue(RandomTimeoutBlockingRpcChannel.invokations.get() > initialInvocations);
125 } finally {
126 rpcClient.close();
127 }
128 }
129
130
131
132
133 public static class RandomTimeoutRpcClient extends RpcClientImpl {
134 public RandomTimeoutRpcClient(Configuration conf, String clusterId, SocketAddress localAddr,
135 MetricsConnection metrics) {
136 super(conf, clusterId, localAddr, metrics);
137 }
138
139
140 @Override
141 public BlockingRpcChannel createBlockingRpcChannel(ServerName sn,
142 User ticket, int rpcTimeout) throws UnknownHostException {
143 return new RandomTimeoutBlockingRpcChannel(this, sn, ticket, rpcTimeout);
144 }
145 }
146
147
148
149
150 static class RandomTimeoutBlockingRpcChannel
151 extends AbstractRpcClient.BlockingRpcChannelImplementation {
152 private static final Random RANDOM = new Random(System.currentTimeMillis());
153 public static final double CHANCE_OF_TIMEOUT = 0.3;
154 private static AtomicInteger invokations = new AtomicInteger();
155
156 RandomTimeoutBlockingRpcChannel(final RpcClientImpl rpcClient, final ServerName sn,
157 final User ticket, final int rpcTimeout) throws UnknownHostException {
158 super(rpcClient, sn, ticket, rpcTimeout);
159 }
160
161 @Override
162 public Message callBlockingMethod(MethodDescriptor md,
163 RpcController controller, Message param, Message returnType)
164 throws ServiceException {
165 invokations.getAndIncrement();
166 if (RANDOM.nextFloat() < CHANCE_OF_TIMEOUT) {
167
168
169
170 throw new ServiceException(new SocketTimeoutException("fake timeout"));
171 }
172 return super.callBlockingMethod(md, controller, param, returnType);
173 }
174 }
175 }