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.hc.client5.http.impl.classic;
28
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.TimeoutException;
32
33 import org.apache.hc.client5.http.HttpRoute;
34 import org.apache.hc.client5.http.config.RequestConfig;
35 import org.apache.hc.client5.http.io.ConnectionEndpoint;
36 import org.apache.hc.client5.http.io.HttpClientConnectionManager;
37 import org.apache.hc.client5.http.io.LeaseRequest;
38 import org.apache.hc.client5.http.protocol.HttpClientContext;
39 import org.apache.hc.core5.concurrent.Cancellable;
40 import org.apache.hc.core5.concurrent.CancellableDependency;
41 import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
42 import org.apache.hc.core5.http.HttpHost;
43 import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
44 import org.apache.hc.core5.io.CloseMode;
45 import org.apache.hc.core5.util.TimeValue;
46 import org.apache.hc.core5.util.Timeout;
47 import org.junit.Assert;
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.mockito.Mock;
51 import org.mockito.Mockito;
52 import org.mockito.MockitoAnnotations;
53 import org.slf4j.Logger;
54
55 @SuppressWarnings({"static-access"})
56 public class TestInternalExecRuntime {
57
58 @Mock
59 private Logger log;
60 @Mock
61 private HttpClientConnectionManager mgr;
62 @Mock
63 private LeaseRequest leaseRequest;
64 @Mock
65 private HttpRequestExecutor requestExecutor;
66 @Mock
67 private CancellableDependency cancellableDependency;
68 @Mock
69 private ConnectionEndpoint connectionEndpoint;
70
71 private HttpRoute route;
72 private InternalExecRuntime execRuntime;
73
74 @Before
75 public void setup() {
76 MockitoAnnotations.initMocks(this);
77 route = new HttpRoute(new HttpHost("host", 80));
78 execRuntime = new InternalExecRuntime(log, mgr, requestExecutor, cancellableDependency);
79 }
80
81 @Test
82 public void testAcquireEndpoint() throws Exception {
83 final HttpClientContext context = HttpClientContext.create();
84 final RequestConfig config = RequestConfig.custom()
85 .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS)
86 .setConnectTimeout(123, TimeUnit.MILLISECONDS)
87 .build();
88 context.setRequestConfig(config);
89 final HttpRoute route = new HttpRoute(new HttpHost("host", 80));
90
91 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
92 .thenReturn(leaseRequest);
93 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
94
95 execRuntime.acquireEndpoint("some-id", route, null, context);
96
97 Assert.assertTrue(execRuntime.isEndpointAcquired());
98 Assert.assertSame(connectionEndpoint, execRuntime.ensureValid());
99 Assert.assertFalse(execRuntime.isEndpointConnected());
100 Assert.assertFalse(execRuntime.isConnectionReusable());
101
102 Mockito.verify(leaseRequest).get(Timeout.ofMilliseconds(345));
103 Mockito.verify(cancellableDependency, Mockito.times(1)).setDependency(leaseRequest);
104 Mockito.verify(cancellableDependency, Mockito.times(1)).setDependency(execRuntime);
105 Mockito.verify(cancellableDependency, Mockito.times(2)).setDependency(Mockito.<Cancellable>any());
106 }
107
108 @Test(expected = IllegalStateException.class)
109 public void testAcquireEndpointAlreadyAcquired() throws Exception {
110 final HttpClientContext context = HttpClientContext.create();
111
112 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
113 .thenReturn(leaseRequest);
114 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
115
116 execRuntime.acquireEndpoint("some-id", route, null, context);
117
118 Assert.assertTrue(execRuntime.isEndpointAcquired());
119 Assert.assertSame(connectionEndpoint, execRuntime.ensureValid());
120
121 execRuntime.acquireEndpoint("some-id", route, null, context);
122 }
123
124 @Test(expected = ConnectionRequestTimeoutException.class)
125 public void testAcquireEndpointLeaseRequestTimeout() throws Exception {
126 final HttpClientContext context = HttpClientContext.create();
127
128 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
129 .thenReturn(leaseRequest);
130 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenThrow(new TimeoutException("timeout"));
131
132 execRuntime.acquireEndpoint("some-id", route, null, context);
133 }
134
135 @Test(expected = RequestFailedException.class)
136 public void testAcquireEndpointLeaseRequestFailure() throws Exception {
137 final HttpClientContext context = HttpClientContext.create();
138
139 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
140 .thenReturn(leaseRequest);
141 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenThrow(new ExecutionException(new IllegalStateException()));
142
143 execRuntime.acquireEndpoint("some-id", route, null, context);
144 }
145
146 @Test
147 public void testAbortEndpoint() throws Exception {
148 final HttpClientContext context = HttpClientContext.create();
149 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
150 .thenReturn(leaseRequest);
151 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
152
153 execRuntime.acquireEndpoint("some-id", new HttpRoute(new HttpHost("host", 80)), null, context);
154 Assert.assertTrue(execRuntime.isEndpointAcquired());
155 execRuntime.discardEndpoint();
156
157 Assert.assertFalse(execRuntime.isEndpointAcquired());
158
159 Mockito.verify(connectionEndpoint).close(CloseMode.IMMEDIATE);
160 Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS);
161
162 execRuntime.discardEndpoint();
163
164 Mockito.verify(connectionEndpoint, Mockito.times(1)).close(CloseMode.IMMEDIATE);
165 Mockito.verify(mgr, Mockito.times(1)).release(
166 Mockito.<ConnectionEndpoint>any(),
167 Mockito.any(),
168 Mockito.<TimeValue>any());
169 }
170
171 @Test
172 public void testCancell() throws Exception {
173 final HttpClientContext context = HttpClientContext.create();
174
175 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
176 .thenReturn(leaseRequest);
177 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
178
179 execRuntime.acquireEndpoint("some-id", route, null, context);
180 Assert.assertTrue(execRuntime.isEndpointAcquired());
181
182 Assert.assertTrue(execRuntime.cancel());
183
184 Assert.assertFalse(execRuntime.isEndpointAcquired());
185
186 Mockito.verify(connectionEndpoint).close(CloseMode.IMMEDIATE);
187 Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS);
188
189 Assert.assertFalse(execRuntime.cancel());
190
191 Mockito.verify(connectionEndpoint, Mockito.times(1)).close(CloseMode.IMMEDIATE);
192 Mockito.verify(mgr, Mockito.times(1)).release(
193 Mockito.<ConnectionEndpoint>any(),
194 Mockito.any(),
195 Mockito.<TimeValue>any());
196 }
197
198 @Test
199 public void testReleaseEndpointReusable() throws Exception {
200 final HttpClientContext context = HttpClientContext.create();
201
202 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
203 .thenReturn(leaseRequest);
204 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
205
206 execRuntime.acquireEndpoint("some-id", route, null, context);
207 Assert.assertTrue(execRuntime.isEndpointAcquired());
208
209 execRuntime.markConnectionReusable("some state", TimeValue.ofMilliseconds(100000));
210
211 execRuntime.releaseEndpoint();
212
213 Assert.assertFalse(execRuntime.isEndpointAcquired());
214
215 Mockito.verify(connectionEndpoint, Mockito.never()).close();
216 Mockito.verify(mgr).release(connectionEndpoint, "some state", TimeValue.ofMilliseconds(100000));
217
218 execRuntime.releaseEndpoint();
219
220 Mockito.verify(mgr, Mockito.times(1)).release(
221 Mockito.<ConnectionEndpoint>any(),
222 Mockito.any(),
223 Mockito.<TimeValue>any());
224 }
225
226 @Test
227 public void testReleaseEndpointNonReusable() throws Exception {
228 final HttpClientContext context = HttpClientContext.create();
229
230 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
231 .thenReturn(leaseRequest);
232 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
233
234 execRuntime.acquireEndpoint("some-id", route, null, context);
235 Assert.assertTrue(execRuntime.isEndpointAcquired());
236
237 execRuntime.markConnectionReusable("some state", TimeValue.ofMilliseconds(100000));
238 execRuntime.markConnectionNonReusable();
239
240 execRuntime.releaseEndpoint();
241
242 Assert.assertFalse(execRuntime.isEndpointAcquired());
243
244 Mockito.verify(connectionEndpoint, Mockito.times(1)).close(CloseMode.IMMEDIATE);
245 Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS);
246
247 execRuntime.releaseEndpoint();
248
249 Mockito.verify(mgr, Mockito.times(1)).release(
250 Mockito.<ConnectionEndpoint>any(),
251 Mockito.any(),
252 Mockito.<TimeValue>any());
253 }
254
255 @Test
256 public void testConnectEndpoint() throws Exception {
257 final HttpClientContext context = HttpClientContext.create();
258 final RequestConfig config = RequestConfig.custom()
259 .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS)
260 .setConnectTimeout(123, TimeUnit.MILLISECONDS)
261 .build();
262 context.setRequestConfig(config);
263
264 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
265 .thenReturn(leaseRequest);
266 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
267
268 execRuntime.acquireEndpoint("some-id", route, null, context);
269 Assert.assertTrue(execRuntime.isEndpointAcquired());
270
271 Mockito.when(connectionEndpoint.isConnected()).thenReturn(false);
272 Assert.assertFalse(execRuntime.isEndpointConnected());
273
274 execRuntime.connectEndpoint(context);
275
276 Mockito.verify(mgr).connect(connectionEndpoint, Timeout.ofMilliseconds(123), context);
277 }
278
279 @Test
280 public void testDisonnectEndpoint() throws Exception {
281 final HttpClientContext context = HttpClientContext.create();
282
283 Mockito.when(mgr.lease(Mockito.eq("some-id"), Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any()))
284 .thenReturn(leaseRequest);
285 Mockito.when(leaseRequest.get(Mockito.<Timeout>any())).thenReturn(connectionEndpoint);
286
287 execRuntime.acquireEndpoint("some-id", route, null, context);
288 Assert.assertTrue(execRuntime.isEndpointAcquired());
289
290 Mockito.when(connectionEndpoint.isConnected()).thenReturn(true);
291 Assert.assertTrue(execRuntime.isEndpointConnected());
292
293 execRuntime.connectEndpoint(context);
294
295 Mockito.verify(mgr, Mockito.never()).connect(
296 Mockito.same(connectionEndpoint), Mockito.<TimeValue>any(), Mockito.<HttpClientContext>any());
297
298 execRuntime.disconnectEndpoint();
299
300 Mockito.verify(connectionEndpoint).close();
301 }
302
303 }