2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.client
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertTrue
;
23 import org
.apache
.hadoop
.conf
.Configuration
;
24 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
25 import org
.apache
.hadoop
.hbase
.ServerName
;
26 import org
.apache
.hadoop
.hbase
.client
.backoff
.ExponentialClientBackoffPolicy
;
27 import org
.apache
.hadoop
.hbase
.client
.backoff
.ServerStatistics
;
28 import org
.apache
.hadoop
.hbase
.testclassification
.ClientTests
;
29 import org
.apache
.hadoop
.hbase
.testclassification
.SmallTests
;
30 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
31 import org
.junit
.ClassRule
;
32 import org
.junit
.Test
;
33 import org
.junit
.experimental
.categories
.Category
;
34 import org
.mockito
.Mockito
;
36 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.ProtobufUtil
;
37 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.ClientProtos
;
39 @Category({ClientTests
.class, SmallTests
.class})
40 public class TestClientExponentialBackoff
{
42 public static final HBaseClassTestRule CLASS_RULE
=
43 HBaseClassTestRule
.forClass(TestClientExponentialBackoff
.class);
45 ServerName server
= Mockito
.mock(ServerName
.class);
46 byte[] regionname
= Bytes
.toBytes("region");
49 public void testNulls() {
50 Configuration conf
= new Configuration(false);
51 ExponentialClientBackoffPolicy backoff
= new ExponentialClientBackoffPolicy(conf
);
52 assertEquals(0, backoff
.getBackoffTime(null, null, null));
54 // server name doesn't matter to calculation, but check it now anyways
55 assertEquals(0, backoff
.getBackoffTime(server
, null, null));
56 assertEquals(0, backoff
.getBackoffTime(server
, regionname
, null));
58 // check when no stats for the region yet
59 ServerStatistics stats
= new ServerStatistics();
60 assertEquals(0, backoff
.getBackoffTime(server
, regionname
, stats
));
64 public void testMaxLoad() {
65 Configuration conf
= new Configuration(false);
66 ExponentialClientBackoffPolicy backoff
= new ExponentialClientBackoffPolicy(conf
);
68 ServerStatistics stats
= new ServerStatistics();
70 assertEquals(ExponentialClientBackoffPolicy
.DEFAULT_MAX_BACKOFF
, backoff
.getBackoffTime(server
,
73 // another policy with a different max timeout
75 conf
.setLong(ExponentialClientBackoffPolicy
.MAX_BACKOFF_KEY
, max
);
76 ExponentialClientBackoffPolicy backoffShortTimeout
= new ExponentialClientBackoffPolicy(conf
);
77 assertEquals(max
, backoffShortTimeout
.getBackoffTime(server
, regionname
, stats
));
79 // test beyond 100 still doesn't exceed the max
81 assertEquals(ExponentialClientBackoffPolicy
.DEFAULT_MAX_BACKOFF
, backoff
.getBackoffTime(server
,
83 assertEquals(max
, backoffShortTimeout
.getBackoffTime(server
, regionname
, stats
));
85 // and that when we are below 100, its less than the max timeout
87 assertTrue(backoff
.getBackoffTime(server
,
88 regionname
, stats
) < ExponentialClientBackoffPolicy
.DEFAULT_MAX_BACKOFF
);
89 assertTrue(backoffShortTimeout
.getBackoffTime(server
, regionname
, stats
) < max
);
93 * Make sure that we get results in the order that we expect - backoff for a load of 1 should
94 * less than backoff for 10, which should be less than that for 50.
97 public void testResultOrdering() {
98 Configuration conf
= new Configuration(false);
99 // make the max timeout really high so we get differentiation between load factors
100 conf
.setLong(ExponentialClientBackoffPolicy
.MAX_BACKOFF_KEY
, Integer
.MAX_VALUE
);
101 ExponentialClientBackoffPolicy backoff
= new ExponentialClientBackoffPolicy(conf
);
103 ServerStatistics stats
= new ServerStatistics();
104 long previous
= backoff
.getBackoffTime(server
, regionname
, stats
);
105 for (int i
= 1; i
<= 100; i
++) {
107 long next
= backoff
.getBackoffTime(server
, regionname
, stats
);
109 "Previous backoff time" + previous
+ " >= " + next
+ ", the next backoff time for " +
110 "load " + i
, previous
< next
);
116 public void testHeapOccupancyPolicy() {
117 Configuration conf
= new Configuration(false);
118 ExponentialClientBackoffPolicy backoff
= new ExponentialClientBackoffPolicy(conf
);
120 ServerStatistics stats
= new ServerStatistics();
123 update(stats
, 0, 95, 0);
124 backoffTime
= backoff
.getBackoffTime(server
, regionname
, stats
);
125 assertTrue("Heap occupancy at low watermark had no effect", backoffTime
> 0);
127 long previous
= backoffTime
;
128 update(stats
, 0, 96, 0);
129 backoffTime
= backoff
.getBackoffTime(server
, regionname
, stats
);
130 assertTrue("Increase above low watermark should have increased backoff",
131 backoffTime
> previous
);
133 update(stats
, 0, 98, 0);
134 backoffTime
= backoff
.getBackoffTime(server
, regionname
, stats
);
135 assertEquals("We should be using max backoff when at high watermark",
136 ExponentialClientBackoffPolicy
.DEFAULT_MAX_BACKOFF
, backoffTime
);
140 public void testCompactionPressurePolicy() {
141 Configuration conf
= new Configuration(false);
142 ExponentialClientBackoffPolicy backoff
= new ExponentialClientBackoffPolicy(conf
);
144 ServerStatistics stats
= new ServerStatistics();
147 update(stats
, 0, 0, 0);
148 backoffTime
= backoff
.getBackoffTime(server
, regionname
, stats
);
149 assertTrue("Compaction pressure has no effect", backoffTime
== 0);
151 long previous
= backoffTime
;
152 update(stats
, 0, 0, 50);
153 backoffTime
= backoff
.getBackoffTime(server
, regionname
, stats
);
154 assertTrue("Compaction pressure should be bigger",
155 backoffTime
> previous
);
157 update(stats
, 0, 0, 100);
158 backoffTime
= backoff
.getBackoffTime(server
, regionname
, stats
);
159 assertEquals("under heavy compaction pressure",
160 ExponentialClientBackoffPolicy
.DEFAULT_MAX_BACKOFF
, backoffTime
);
163 private void update(ServerStatistics stats
, int load
) {
164 ClientProtos
.RegionLoadStats stat
= ClientProtos
.RegionLoadStats
.newBuilder()
165 .setMemStoreLoad(load
).build();
166 stats
.update(regionname
, ProtobufUtil
.createRegionLoadStats(stat
));
169 private void update(ServerStatistics stats
, int memstoreLoad
, int heapOccupancy
,
170 int compactionPressure
) {
171 ClientProtos
.RegionLoadStats stat
= ClientProtos
.RegionLoadStats
.newBuilder()
172 .setMemStoreLoad(memstoreLoad
)
173 .setHeapOccupancy(heapOccupancy
)
174 .setCompactionPressure(compactionPressure
)
176 stats
.update(regionname
, ProtobufUtil
.createRegionLoadStats(stat
));