1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.impl.client;
28
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.assertTrue;
31
32 import java.util.Random;
33
34 import org.apache.http.HttpHost;
35 import org.apache.http.client.BackoffManager;
36 import org.apache.http.conn.routing.HttpRoute;
37 import org.junit.Before;
38 import org.junit.Test;
39
40 public class TestAIMDBackoffManager {
41
42 private AIMDBackoffManager impl;
43 private MockConnPoolControl connPerRoute;
44 private HttpRoute route;
45 private MockClock clock;
46
47 @Before
48 public void setUp() {
49 connPerRoute = new MockConnPoolControl();
50 route = new HttpRoute(new HttpHost("localhost", 80));
51 clock = new MockClock();
52 impl = new AIMDBackoffManager(connPerRoute, clock);
53 impl.setPerHostConnectionCap(10);
54 }
55
56 @Test
57 public void isABackoffManager() {
58 assertTrue(impl instanceof BackoffManager);
59 }
60
61 @Test
62 public void halvesConnectionsOnBackoff() {
63 connPerRoute.setMaxPerRoute(route, 4);
64 impl.backOff(route);
65 assertEquals(2, connPerRoute.getMaxPerRoute(route));
66 }
67
68 @Test
69 public void doesNotBackoffBelowOneConnection() {
70 connPerRoute.setMaxPerRoute(route, 1);
71 impl.backOff(route);
72 assertEquals(1, connPerRoute.getMaxPerRoute(route));
73 }
74
75 @Test
76 public void increasesByOneOnProbe() {
77 connPerRoute.setMaxPerRoute(route, 2);
78 impl.probe(route);
79 assertEquals(3, connPerRoute.getMaxPerRoute(route));
80 }
81
82 @Test
83 public void doesNotIncreaseBeyondPerHostMaxOnProbe() {
84 connPerRoute.setDefaultMaxPerRoute(5);
85 connPerRoute.setMaxPerRoute(route, 5);
86 impl.setPerHostConnectionCap(5);
87 impl.probe(route);
88 assertEquals(5, connPerRoute.getMaxPerRoute(route));
89 }
90
91 @Test
92 public void backoffDoesNotAdjustDuringCoolDownPeriod() {
93 connPerRoute.setMaxPerRoute(route, 4);
94 final long now = System.currentTimeMillis();
95 clock.setCurrentTime(now);
96 impl.backOff(route);
97 final long max = connPerRoute.getMaxPerRoute(route);
98 clock.setCurrentTime(now + 1);
99 impl.backOff(route);
100 assertEquals(max, connPerRoute.getMaxPerRoute(route));
101 }
102
103 @Test
104 public void backoffStillAdjustsAfterCoolDownPeriod() {
105 connPerRoute.setMaxPerRoute(route, 8);
106 final long now = System.currentTimeMillis();
107 clock.setCurrentTime(now);
108 impl.backOff(route);
109 final long max = connPerRoute.getMaxPerRoute(route);
110 clock.setCurrentTime(now + 10 * 1000L);
111 impl.backOff(route);
112 assertTrue(max == 1 || max > connPerRoute.getMaxPerRoute(route));
113 }
114
115 @Test
116 public void probeDoesNotAdjustDuringCooldownPeriod() {
117 connPerRoute.setMaxPerRoute(route, 4);
118 final long now = System.currentTimeMillis();
119 clock.setCurrentTime(now);
120 impl.probe(route);
121 final long max = connPerRoute.getMaxPerRoute(route);
122 clock.setCurrentTime(now + 1);
123 impl.probe(route);
124 assertEquals(max, connPerRoute.getMaxPerRoute(route));
125 }
126
127 @Test
128 public void probeStillAdjustsAfterCoolDownPeriod() {
129 connPerRoute.setMaxPerRoute(route, 8);
130 final long now = System.currentTimeMillis();
131 clock.setCurrentTime(now);
132 impl.probe(route);
133 final long max = connPerRoute.getMaxPerRoute(route);
134 clock.setCurrentTime(now + 10 * 1000L);
135 impl.probe(route);
136 assertTrue(max < connPerRoute.getMaxPerRoute(route));
137 }
138
139 @Test
140 public void willBackoffImmediatelyEvenAfterAProbe() {
141 connPerRoute.setMaxPerRoute(route, 8);
142 final long now = System.currentTimeMillis();
143 clock.setCurrentTime(now);
144 impl.probe(route);
145 final long max = connPerRoute.getMaxPerRoute(route);
146 clock.setCurrentTime(now + 1);
147 impl.backOff(route);
148 assertTrue(connPerRoute.getMaxPerRoute(route) < max);
149 }
150
151 @Test
152 public void backOffFactorIsConfigurable() {
153 connPerRoute.setMaxPerRoute(route, 10);
154 impl.setBackoffFactor(0.9);
155 impl.backOff(route);
156 assertEquals(9, connPerRoute.getMaxPerRoute(route));
157 }
158
159 @Test
160 public void coolDownPeriodIsConfigurable() {
161 long cd = new Random().nextLong() / 2;
162 if (cd < 0) {
163 cd *= -1;
164 }
165 if (cd < 1) {
166 cd++;
167 }
168 final long now = System.currentTimeMillis();
169 impl.setCooldownMillis(cd);
170 clock.setCurrentTime(now);
171 impl.probe(route);
172 final int max0 = connPerRoute.getMaxPerRoute(route);
173 clock.setCurrentTime(now);
174 impl.probe(route);
175 assertEquals(max0, connPerRoute.getMaxPerRoute(route));
176 clock.setCurrentTime(now + cd + 1);
177 impl.probe(route);
178 assertTrue(max0 < connPerRoute.getMaxPerRoute(route));
179 }
180 }