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 com.google.protobuf.BlockingRpcChannel;
26 import com.google.protobuf.Descriptors.MethodDescriptor;
27 import com.google.protobuf.Message;
28 import com.google.protobuf.RpcController;
29 import com.google.protobuf.ServiceException;
30
31 import java.net.SocketAddress;
32 import java.net.SocketTimeoutException;
33 import java.util.Random;
34 import java.util.concurrent.atomic.AtomicInteger;
35
36 import org.apache.hadoop.conf.Configuration;
37 import org.apache.hadoop.hbase.HBaseConfiguration;
38 import org.apache.hadoop.hbase.HBaseTestingUtility;
39 import org.apache.hadoop.hbase.HConstants;
40 import org.apache.hadoop.hbase.MasterNotRunningException;
41 import org.apache.hadoop.hbase.ServerName;
42 import org.apache.hadoop.hbase.ipc.AbstractRpcClient;
43 import org.apache.hadoop.hbase.ipc.BlockingRpcClient;
44 import org.apache.hadoop.hbase.ipc.RpcClientFactory;
45 import org.apache.hadoop.hbase.net.Address;
46 import org.apache.hadoop.hbase.security.User;
47 import org.apache.hadoop.hbase.testclassification.ClientTests;
48 import org.apache.hadoop.hbase.testclassification.MediumTests;
49 import org.junit.AfterClass;
50 import org.junit.BeforeClass;
51 import org.junit.Test;
52 import org.junit.experimental.categories.Category;
53
54 @Category({MediumTests.class, ClientTests.class})
55 public class TestClientTimeouts {
56 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
57 protected static int SLAVES = 1;
58
59
60
61
62 @BeforeClass
63 public static void setUpBeforeClass() throws Exception {
64 TEST_UTIL.startMiniCluster(SLAVES);
65
66 TEST_UTIL.getConfiguration().set(
67 RpcClientFactory.CUSTOM_RPC_CLIENT_IMPL_CONF_KEY,
68 RandomTimeoutRpcClient.class.getName());
69 }
70
71
72
73
74 @AfterClass
75 public static void tearDownAfterClass() throws Exception {
76 TEST_UTIL.shutdownMiniCluster();
77 }
78
79
80
81
82
83
84 @Test
85 public void testAdminTimeout() throws Exception {
86 boolean lastFailed = false;
87 int initialInvocations = RandomTimeoutBlockingRpcChannel.invokations.get();
88 RandomTimeoutRpcClient rpcClient = (RandomTimeoutRpcClient) RpcClientFactory
89 .createClient(TEST_UTIL.getConfiguration(), TEST_UTIL.getClusterKey());
90
91 try {
92 for (int i = 0; i < 5 || (lastFailed && i < 100); ++i) {
93 lastFailed = false;
94
95 Configuration conf = HBaseConfiguration.create(TEST_UTIL.getConfiguration());
96 conf.set(HConstants.HBASE_CLIENT_INSTANCE_ID, String.valueOf(-1));
97 Admin admin = null;
98 Connection connection = null;
99 try {
100 connection = ConnectionFactory.createConnection(conf);
101 admin = connection.getAdmin();
102
103 HBaseAdmin.checkHBaseAvailable(conf);
104 admin.setBalancerRunning(false, false);
105 } catch (MasterNotRunningException ex) {
106
107
108 lastFailed = true;
109 } finally {
110 if(admin != null) {
111 admin.close();
112 if (admin.getConnection().isClosed()) {
113 rpcClient = (RandomTimeoutRpcClient) RpcClientFactory
114 .createClient(TEST_UTIL.getConfiguration(), TEST_UTIL.getClusterKey());
115 }
116 }
117 if(connection != null) {
118 connection.close();
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 BlockingRpcClient {
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, User ticket, int rpcTimeout) {
142 return new RandomTimeoutBlockingRpcChannel(this, sn, ticket, rpcTimeout);
143 }
144 }
145
146
147
148
149 static class RandomTimeoutBlockingRpcChannel
150 extends AbstractRpcClient.BlockingRpcChannelImplementation {
151 private static final Random RANDOM = new Random(System.currentTimeMillis());
152 public static final double CHANCE_OF_TIMEOUT = 0.3;
153 private static AtomicInteger invokations = new AtomicInteger();
154
155 RandomTimeoutBlockingRpcChannel(final BlockingRpcClient rpcClient, final ServerName sn,
156 final User ticket, final int rpcTimeout) {
157 super(rpcClient, Address.fromParts(sn.getHostname(), sn.getPort()), ticket, rpcTimeout);
158 }
159
160 @Override
161 public Message callBlockingMethod(MethodDescriptor md,
162 RpcController controller, Message param, Message returnType)
163 throws ServiceException {
164 invokations.getAndIncrement();
165 if (RANDOM.nextFloat() < CHANCE_OF_TIMEOUT) {
166
167
168
169 throw new ServiceException(new SocketTimeoutException("fake timeout"));
170 }
171 return super.callBlockingMethod(md, controller, param, returnType);
172 }
173 }
174 }