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.client; 019 020import static org.junit.Assert.assertTrue; 021import static org.junit.Assert.fail; 022 023import java.net.SocketTimeoutException; 024import org.apache.hadoop.conf.Configuration; 025import org.apache.hadoop.hbase.HBaseClassTestRule; 026import org.apache.hadoop.hbase.HConstants; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.ipc.HBaseRpcController; 029import org.apache.hadoop.hbase.ipc.RpcControllerFactory; 030import org.apache.hadoop.hbase.testclassification.ClientTests; 031import org.apache.hadoop.hbase.testclassification.MediumTests; 032import org.junit.Before; 033import org.junit.ClassRule; 034import org.junit.Test; 035import org.junit.experimental.categories.Category; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039@Category({ ClientTests.class, MediumTests.class }) 040public class TestCISleep extends AbstractTestCITimeout { 041 042 @ClassRule 043 public static final HBaseClassTestRule CLASS_RULE = 044 HBaseClassTestRule.forClass(TestCISleep.class); 045 046 private static Logger LOG = LoggerFactory.getLogger(TestCISleep.class); 047 048 private TableName tableName; 049 050 @Before 051 public void setUp() { 052 tableName = TableName.valueOf(name.getMethodName()); 053 } 054 055 /** 056 * Test starting from 0 index when RpcRetryingCaller calculate the backoff time. 057 */ 058 @Test 059 public void testRpcRetryingCallerSleep() throws Exception { 060 TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName) 061 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAM_NAM)) 062 .setCoprocessor(CoprocessorDescriptorBuilder.newBuilder(SleepAndFailFirstTime.class.getName()) 063 .setProperty(SleepAndFailFirstTime.SLEEP_TIME_CONF_KEY, String.valueOf(2000)).build()) 064 .build(); 065 TEST_UTIL.getAdmin().createTable(htd); 066 067 Configuration c = new Configuration(TEST_UTIL.getConfiguration()); 068 c.setInt(HConstants.HBASE_CLIENT_PAUSE, 3000); 069 c.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 4000); 070 071 try (Connection conn = ConnectionFactory.createConnection(c)) { 072 SleepAndFailFirstTime.ct.set(0); 073 try (Table table = conn.getTableBuilder(tableName, null).setOperationTimeout(8000).build()) { 074 // Check that it works. Because 2s + 3s * RETRY_BACKOFF[0] + 2s < 8s 075 table.get(new Get(FAM_NAM)); 076 } 077 SleepAndFailFirstTime.ct.set(0); 078 try (Table table = conn.getTableBuilder(tableName, null).setOperationTimeout(6000).build()) { 079 // Will fail this time. After sleep, there are not enough time for second retry 080 // Beacuse 2s + 3s + 2s > 6s 081 table.get(new Get(FAM_NAM)); 082 fail("We expect an exception here"); 083 } catch (SocketTimeoutException e) { 084 LOG.info("We received an exception, as expected ", e); 085 } 086 } 087 } 088 089 @Test 090 public void testCallableSleep() throws Exception { 091 long pauseTime; 092 long baseTime = 100; 093 final TableName tableName = TableName.valueOf(name.getMethodName()); 094 TEST_UTIL.createTable(tableName, FAM_NAM); 095 ClientServiceCallable<Object> regionServerCallable = 096 new ClientServiceCallable<Object>(TEST_UTIL.getConnection(), tableName, FAM_NAM, 097 new RpcControllerFactory(TEST_UTIL.getConfiguration()).newController(), 098 HConstants.PRIORITY_UNSET) { 099 @Override 100 protected Object rpcCall() throws Exception { 101 return null; 102 } 103 }; 104 105 regionServerCallable.prepare(false); 106 for (int i = 0; i < HConstants.RETRY_BACKOFF.length; i++) { 107 pauseTime = regionServerCallable.sleep(baseTime, i); 108 assertTrue(pauseTime >= (baseTime * HConstants.RETRY_BACKOFF[i])); 109 assertTrue(pauseTime <= (baseTime * HConstants.RETRY_BACKOFF[i] * 1.01f)); 110 } 111 112 RegionAdminServiceCallable<Object> regionAdminServiceCallable = 113 new RegionAdminServiceCallable<Object>((ClusterConnection) TEST_UTIL.getConnection(), 114 new RpcControllerFactory(TEST_UTIL.getConfiguration()), tableName, FAM_NAM) { 115 @Override 116 public Object call(HBaseRpcController controller) throws Exception { 117 return null; 118 } 119 }; 120 121 regionAdminServiceCallable.prepare(false); 122 for (int i = 0; i < HConstants.RETRY_BACKOFF.length; i++) { 123 pauseTime = regionAdminServiceCallable.sleep(baseTime, i); 124 assertTrue(pauseTime >= (baseTime * HConstants.RETRY_BACKOFF[i])); 125 assertTrue(pauseTime <= (baseTime * HConstants.RETRY_BACKOFF[i] * 1.01f)); 126 } 127 128 try ( 129 MasterCallable<Object> masterCallable = new MasterCallable<Object>(TEST_UTIL.getConnection(), 130 new RpcControllerFactory(TEST_UTIL.getConfiguration())) { 131 @Override 132 protected Object rpcCall() throws Exception { 133 return null; 134 } 135 }) { 136 for (int i = 0; i < HConstants.RETRY_BACKOFF.length; i++) { 137 pauseTime = masterCallable.sleep(baseTime, i); 138 assertTrue(pauseTime >= (baseTime * HConstants.RETRY_BACKOFF[i])); 139 assertTrue(pauseTime <= (baseTime * HConstants.RETRY_BACKOFF[i] * 1.01f)); 140 } 141 } 142 } 143}