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.backoff; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.util.OptionalLong; 025import java.util.concurrent.TimeUnit; 026import org.apache.hadoop.hbase.HBaseClassTestRule; 027import org.apache.hadoop.hbase.HBaseServerException; 028import org.apache.hadoop.hbase.quotas.RpcThrottlingException; 029import org.apache.hadoop.hbase.testclassification.ClientTests; 030import org.apache.hadoop.hbase.testclassification.SmallTests; 031import org.junit.ClassRule; 032import org.junit.Test; 033import org.junit.experimental.categories.Category; 034 035@Category({ ClientTests.class, SmallTests.class }) 036public class TestHBaseServerExceptionPauseManager { 037 038 private static final long WAIT_INTERVAL_MILLIS = 1L; 039 private static final long WAIT_INTERVAL_NANOS = 040 TimeUnit.MILLISECONDS.toNanos(WAIT_INTERVAL_MILLIS); 041 private static final long PAUSE_NANOS_FOR_SERVER_OVERLOADED = WAIT_INTERVAL_NANOS * 3; 042 043 private static final long PAUSE_NANOS = WAIT_INTERVAL_NANOS * 2; 044 045 private final RpcThrottlingException RPC_THROTTLING_EXCEPTION = new RpcThrottlingException( 046 RpcThrottlingException.Type.NumRequestsExceeded, WAIT_INTERVAL_MILLIS, "doot"); 047 private final Throwable OTHER_EXCEPTION = new RuntimeException(""); 048 private final HBaseServerException SERVER_OVERLOADED_EXCEPTION = new HBaseServerException(true); 049 050 @ClassRule 051 public static final HBaseClassTestRule CLASS_RULE = 052 HBaseClassTestRule.forClass(TestHBaseServerExceptionPauseManager.class); 053 054 @Test 055 public void itSupportsRpcThrottlingNanosNoTimeout() { 056 HBaseServerExceptionPauseManager pauseManager = 057 new HBaseServerExceptionPauseManager(PAUSE_NANOS, PAUSE_NANOS_FOR_SERVER_OVERLOADED, 0); 058 059 OptionalLong pauseNanos = 060 pauseManager.getPauseNsFromException(RPC_THROTTLING_EXCEPTION, 1, System.nanoTime()); 061 062 assertTrue(pauseNanos.isPresent()); 063 assertEquals(pauseNanos.getAsLong(), WAIT_INTERVAL_NANOS); 064 } 065 066 @Test 067 public void itSupportsRpcThrottlingNanosLenientTimeout() { 068 HBaseServerExceptionPauseManager pauseManager = new HBaseServerExceptionPauseManager( 069 PAUSE_NANOS, PAUSE_NANOS_FOR_SERVER_OVERLOADED, System.nanoTime() * 2); 070 071 OptionalLong pauseNanos = 072 pauseManager.getPauseNsFromException(RPC_THROTTLING_EXCEPTION, 1, System.nanoTime()); 073 074 assertTrue(pauseNanos.isPresent()); 075 assertEquals(pauseNanos.getAsLong(), WAIT_INTERVAL_NANOS); 076 } 077 078 @Test 079 public void itSupportsServerOverloadedExceptionNanos() { 080 HBaseServerExceptionPauseManager pauseManager = 081 new HBaseServerExceptionPauseManager(PAUSE_NANOS, PAUSE_NANOS_FOR_SERVER_OVERLOADED, 0); 082 083 OptionalLong pauseNanos = 084 pauseManager.getPauseNsFromException(SERVER_OVERLOADED_EXCEPTION, 1, System.nanoTime()); 085 086 assertTrue(pauseNanos.isPresent()); 087 // account for 1% jitter in pause time 088 assertTrue(pauseNanos.getAsLong() >= PAUSE_NANOS_FOR_SERVER_OVERLOADED * 0.99); 089 assertTrue(pauseNanos.getAsLong() <= PAUSE_NANOS_FOR_SERVER_OVERLOADED * 1.01); 090 } 091 092 @Test 093 public void itSupportsOtherExceptionNanos() { 094 HBaseServerExceptionPauseManager pauseManager = 095 new HBaseServerExceptionPauseManager(PAUSE_NANOS, PAUSE_NANOS_FOR_SERVER_OVERLOADED, 0); 096 097 OptionalLong pauseNanos = 098 pauseManager.getPauseNsFromException(OTHER_EXCEPTION, 1, System.nanoTime()); 099 100 assertTrue(pauseNanos.isPresent()); 101 // account for 1% jitter in pause time 102 assertTrue(pauseNanos.getAsLong() >= PAUSE_NANOS * 0.99); 103 assertTrue(pauseNanos.getAsLong() <= PAUSE_NANOS * 1.01); 104 } 105 106 @Test 107 public void itTimesOutRpcThrottlingException() { 108 HBaseServerExceptionPauseManager pauseManager = 109 new HBaseServerExceptionPauseManager(PAUSE_NANOS, PAUSE_NANOS_FOR_SERVER_OVERLOADED, 1); 110 111 OptionalLong pauseNanos = 112 pauseManager.getPauseNsFromException(RPC_THROTTLING_EXCEPTION, 1, System.nanoTime()); 113 114 assertFalse(pauseNanos.isPresent()); 115 } 116 117 @Test 118 public void itTimesOutRpcOtherException() { 119 HBaseServerExceptionPauseManager pauseManager = 120 new HBaseServerExceptionPauseManager(PAUSE_NANOS, PAUSE_NANOS_FOR_SERVER_OVERLOADED, 1); 121 122 OptionalLong pauseNanos = 123 pauseManager.getPauseNsFromException(OTHER_EXCEPTION, 1, System.nanoTime()); 124 125 assertFalse(pauseNanos.isPresent()); 126 } 127 128 @Test 129 public void itDoesNotTimeOutIfDisabled() { 130 HBaseServerExceptionPauseManager pauseManager = 131 new HBaseServerExceptionPauseManager(PAUSE_NANOS, PAUSE_NANOS_FOR_SERVER_OVERLOADED, 0); 132 133 OptionalLong pauseNanos = 134 pauseManager.getPauseNsFromException(OTHER_EXCEPTION, 1, System.nanoTime()); 135 136 assertTrue(pauseNanos.isPresent()); 137 } 138 139}