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)) 064 .build()) 065 .build(); 066 TEST_UTIL.getAdmin().createTable(htd); 067 068 Configuration c = new Configuration(TEST_UTIL.getConfiguration()); 069 c.setInt(HConstants.HBASE_CLIENT_PAUSE, 3000); 070 c.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 4000); 071 072 try (Connection conn = ConnectionFactory.createConnection(c)) { 073 SleepAndFailFirstTime.ct.set(0); 074 try (Table table = conn.getTableBuilder(tableName, null).setOperationTimeout(8000).build()) { 075 // Check that it works. Because 2s + 3s * RETRY_BACKOFF[0] + 2s < 8s 076 table.get(new Get(FAM_NAM)); 077 } 078 SleepAndFailFirstTime.ct.set(0); 079 try (Table table = conn.getTableBuilder(tableName, null).setOperationTimeout(6000).build()) { 080 // Will fail this time. After sleep, there are not enough time for second retry 081 // Beacuse 2s + 3s + 2s > 6s 082 table.get(new Get(FAM_NAM)); 083 fail("We expect an exception here"); 084 } catch (SocketTimeoutException e) { 085 LOG.info("We received an exception, as expected ", e); 086 } 087 } 088 } 089 090 @Test 091 public void testCallableSleep() throws Exception { 092 long pauseTime; 093 long baseTime = 100; 094 final TableName tableName = TableName.valueOf(name.getMethodName()); 095 TEST_UTIL.createTable(tableName, FAM_NAM); 096 ClientServiceCallable<Object> regionServerCallable = 097 new ClientServiceCallable<Object>(TEST_UTIL.getConnection(), tableName, FAM_NAM, 098 new RpcControllerFactory(TEST_UTIL.getConfiguration()).newController(), 099 HConstants.PRIORITY_UNSET) { 100 @Override 101 protected Object rpcCall() throws Exception { 102 return null; 103 } 104 }; 105 106 regionServerCallable.prepare(false); 107 for (int i = 0; i < HConstants.RETRY_BACKOFF.length; i++) { 108 pauseTime = regionServerCallable.sleep(baseTime, i); 109 assertTrue(pauseTime >= (baseTime * HConstants.RETRY_BACKOFF[i])); 110 assertTrue(pauseTime <= (baseTime * HConstants.RETRY_BACKOFF[i] * 1.01f)); 111 } 112 113 RegionAdminServiceCallable<Object> regionAdminServiceCallable = 114 new RegionAdminServiceCallable<Object>((ClusterConnection) TEST_UTIL.getConnection(), 115 new RpcControllerFactory(TEST_UTIL.getConfiguration()), tableName, FAM_NAM) { 116 @Override 117 public Object call(HBaseRpcController controller) throws Exception { 118 return null; 119 } 120 }; 121 122 regionAdminServiceCallable.prepare(false); 123 for (int i = 0; i < HConstants.RETRY_BACKOFF.length; i++) { 124 pauseTime = regionAdminServiceCallable.sleep(baseTime, i); 125 assertTrue(pauseTime >= (baseTime * HConstants.RETRY_BACKOFF[i])); 126 assertTrue(pauseTime <= (baseTime * HConstants.RETRY_BACKOFF[i] * 1.01f)); 127 } 128 129 try ( 130 MasterCallable<Object> masterCallable = new MasterCallable<Object>(TEST_UTIL.getConnection(), 131 new RpcControllerFactory(TEST_UTIL.getConfiguration())) { 132 @Override 133 protected Object rpcCall() throws Exception { 134 return null; 135 } 136 }) { 137 for (int i = 0; i < HConstants.RETRY_BACKOFF.length; i++) { 138 pauseTime = masterCallable.sleep(baseTime, i); 139 assertTrue(pauseTime >= (baseTime * HConstants.RETRY_BACKOFF[i])); 140 assertTrue(pauseTime <= (baseTime * HConstants.RETRY_BACKOFF[i] * 1.01f)); 141 } 142 } 143 } 144}