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