1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import org.apache.hadoop.conf.Configuration;
21 import org.apache.hadoop.hbase.HConstants;
22 import org.apache.hadoop.hbase.ServerName;
23 import org.apache.hadoop.hbase.client.backoff.ExponentialClientBackoffPolicy;
24 import org.apache.hadoop.hbase.client.backoff.ServerStatistics;
25 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
26 import org.apache.hadoop.hbase.testclassification.SmallTests;
27 import org.apache.hadoop.hbase.util.Bytes;
28 import org.junit.Test;
29 import org.junit.experimental.categories.Category;
30 import org.mockito.Mockito;
31
32 import static org.junit.Assert.assertEquals;
33 import static org.junit.Assert.assertTrue;
34
35 @Category(SmallTests.class)
36 public class TestClientExponentialBackoff {
37
38 ServerName server = Mockito.mock(ServerName.class);
39 byte[] regionname = Bytes.toBytes("region");
40
41 @Test
42 public void testNulls() {
43 Configuration conf = new Configuration(false);
44 ExponentialClientBackoffPolicy backoff = new ExponentialClientBackoffPolicy(conf);
45 assertEquals(0, backoff.getBackoffTime(null, null, null));
46
47
48 assertEquals(0, backoff.getBackoffTime(server, null, null));
49 assertEquals(0, backoff.getBackoffTime(server, regionname, null));
50
51
52 ServerStatistics stats = new ServerStatistics();
53 assertEquals(0, backoff.getBackoffTime(server, regionname, stats));
54 }
55
56 @Test
57 public void testMaxLoad() {
58 Configuration conf = new Configuration(false);
59 ExponentialClientBackoffPolicy backoff = new ExponentialClientBackoffPolicy(conf);
60
61 ServerStatistics stats = new ServerStatistics();
62 update(stats, 100);
63 assertEquals(ExponentialClientBackoffPolicy.DEFAULT_MAX_BACKOFF, backoff.getBackoffTime(server,
64 regionname, stats));
65
66
67 long max = 100;
68 conf.setLong(ExponentialClientBackoffPolicy.MAX_BACKOFF_KEY, max);
69 ExponentialClientBackoffPolicy backoffShortTimeout = new ExponentialClientBackoffPolicy(conf);
70 assertEquals(max, backoffShortTimeout.getBackoffTime(server, regionname, stats));
71
72
73 update(stats, 101);
74 assertEquals(ExponentialClientBackoffPolicy.DEFAULT_MAX_BACKOFF, backoff.getBackoffTime(server,
75 regionname, stats));
76 assertEquals(max, backoffShortTimeout.getBackoffTime(server, regionname, stats));
77
78
79 update(stats, 99);
80 assertTrue(backoff.getBackoffTime(server,
81 regionname, stats) < ExponentialClientBackoffPolicy.DEFAULT_MAX_BACKOFF);
82 assertTrue(backoffShortTimeout.getBackoffTime(server, regionname, stats) < max);
83 }
84
85
86
87
88
89 @Test
90 public void testResultOrdering() {
91 Configuration conf = new Configuration(false);
92
93 conf.setLong(ExponentialClientBackoffPolicy.MAX_BACKOFF_KEY, Integer.MAX_VALUE);
94 ExponentialClientBackoffPolicy backoff = new ExponentialClientBackoffPolicy(conf);
95
96 ServerStatistics stats = new ServerStatistics();
97 long previous = backoff.getBackoffTime(server, regionname, stats);
98 for (int i = 1; i <= 100; i++) {
99 update(stats, i);
100 long next = backoff.getBackoffTime(server, regionname, stats);
101 assertTrue(
102 "Previous backoff time" + previous + " >= " + next + ", the next backoff time for " +
103 "load " + i, previous < next);
104 previous = next;
105 }
106 }
107
108 @Test
109 public void testHeapOccupancyPolicy() {
110 Configuration conf = new Configuration(false);
111 ExponentialClientBackoffPolicy backoff = new ExponentialClientBackoffPolicy(conf);
112
113 ServerStatistics stats = new ServerStatistics();
114 long backoffTime;
115
116 update(stats, 0, 95, 0);
117 backoffTime = backoff.getBackoffTime(server, regionname, stats);
118 assertTrue("Heap occupancy at low watermark had no effect", backoffTime > 0);
119
120 long previous = backoffTime;
121 update(stats, 0, 96, 0);
122 backoffTime = backoff.getBackoffTime(server, regionname, stats);
123 assertTrue("Increase above low watermark should have increased backoff",
124 backoffTime > previous);
125
126 update(stats, 0, 98, 0);
127 backoffTime = backoff.getBackoffTime(server, regionname, stats);
128 assertEquals("We should be using max backoff when at high watermark", backoffTime,
129 ExponentialClientBackoffPolicy.DEFAULT_MAX_BACKOFF);
130 }
131
132 @Test
133 public void testCompactionPressurePolicy() {
134 Configuration conf = new Configuration(false);
135 ExponentialClientBackoffPolicy backoff = new ExponentialClientBackoffPolicy(conf);
136
137 ServerStatistics stats = new ServerStatistics();
138 long backoffTime;
139
140 update(stats, 0, 0, 0);
141 backoffTime = backoff.getBackoffTime(server, regionname, stats);
142 assertTrue("Compaction pressure has no effect", backoffTime == 0);
143
144 long previous = backoffTime;
145 update(stats, 0, 0, 50);
146 backoffTime = backoff.getBackoffTime(server, regionname, stats);
147 assertTrue("Compaction pressure should be bigger",
148 backoffTime > previous);
149
150 update(stats, 0, 0, 100);
151 backoffTime = backoff.getBackoffTime(server, regionname, stats);
152 assertEquals("under heavy compaction pressure", backoffTime,
153 ExponentialClientBackoffPolicy.DEFAULT_MAX_BACKOFF);
154 }
155
156 private void update(ServerStatistics stats, int load) {
157 ClientProtos.RegionLoadStats stat = ClientProtos.RegionLoadStats.newBuilder()
158 .setMemstoreLoad
159 (load).build();
160 stats.update(regionname, stat);
161 }
162
163 private void update(ServerStatistics stats, int memstoreLoad, int heapOccupancy,
164 int compactionPressure) {
165 ClientProtos.RegionLoadStats stat = ClientProtos.RegionLoadStats.newBuilder()
166 .setMemstoreLoad(memstoreLoad)
167 .setHeapOccupancy(heapOccupancy)
168 .setCompactionPressure(compactionPressure)
169 .build();
170 stats.update(regionname, stat);
171 }
172 }