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
28
29
30
31 package com.jcabi.http;
32
33 import com.jcabi.http.request.BaseRequest;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.net.URI;
37 import java.util.Collection;
38 import java.util.Map;
39 import java.util.concurrent.Callable;
40 import java.util.function.Supplier;
41 import org.hamcrest.MatcherAssert;
42 import org.hamcrest.Matchers;
43 import org.junit.jupiter.api.Test;
44 import org.junit.jupiter.params.ParameterizedTest;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.ArgumentMatchers;
47 import org.mockito.Mockito;
48
49
50
51
52
53 @SuppressWarnings("PMD.TooManyMethods")
54 final class RequestTimeoutLossTest extends RequestTestTemplate {
55
56
57
58 private static final String LOCALHOST_URL = "http://localhost";
59
60
61
62
63 private static final String CONTENT_TYPE = "Content-Type";
64
65
66
67
68 private static final int CONNECT_TIMEOUT = 1234;
69
70
71
72
73 private static final int READ_TIMEOUT = 2345;
74
75
76
77
78
79
80
81
82 @ParameterizedTest
83 @Values
84 void testTimeoutOrderDoesntMatterBeforeBody(
85 final Class<? extends Request> type
86 )
87 throws Exception {
88 final Callable<Response> execution = new Callable<Response>() {
89 @Override
90 public Response call() throws Exception {
91 return RequestTimeoutLossTest.request(type)
92 .through(MockWire.class)
93 .method(Request.GET)
94 .timeout(
95 RequestTimeoutLossTest.CONNECT_TIMEOUT,
96 RequestTimeoutLossTest.READ_TIMEOUT
97 )
98 .body()
99 .back()
100 .fetch();
101 }
102 };
103 this.testTimeoutOrderDoesntMatter(execution);
104 }
105
106
107
108
109
110
111
112
113 @ParameterizedTest
114 @Values
115 void testTimeoutOrderDoesntMatterBeforeFetch(
116 final Class<? extends Request> type
117 )
118 throws Exception {
119 final Callable<Response> execution = new Callable<Response>() {
120 @Override
121 public Response call() throws Exception {
122 return RequestTimeoutLossTest.request(type)
123 .through(MockWire.class)
124 .method(Request.GET)
125 .timeout(
126 RequestTimeoutLossTest.CONNECT_TIMEOUT,
127 RequestTimeoutLossTest.READ_TIMEOUT
128 )
129 .fetch();
130 }
131 };
132 this.testTimeoutOrderDoesntMatter(execution);
133 }
134
135
136
137
138
139
140
141
142 @ParameterizedTest
143 @Values
144 void testTimeoutOrderDoesntMatterBeforeHeader(
145 final Class<? extends Request> type
146 )
147 throws Exception {
148 final Callable<Response> execution = new Callable<Response>() {
149 @Override
150 public Response call() throws Exception {
151 return RequestTimeoutLossTest.request(type)
152 .through(MockWire.class)
153 .method(Request.GET)
154 .timeout(
155 RequestTimeoutLossTest.CONNECT_TIMEOUT,
156 RequestTimeoutLossTest.READ_TIMEOUT
157 )
158 .header(
159 RequestTimeoutLossTest.CONTENT_TYPE,
160 "text/plain"
161 )
162 .fetch();
163 }
164 };
165 this.testTimeoutOrderDoesntMatter(execution);
166 }
167
168
169
170
171
172
173
174
175 @ParameterizedTest
176 @Values
177 void testTimeoutOrderDoesntMatterBeforeMethod(
178 final Class<? extends Request> type
179 )
180 throws Exception {
181 final Callable<Response> execution = new Callable<Response>() {
182 @Override
183 public Response call() throws Exception {
184 return RequestTimeoutLossTest.request(type)
185 .through(MockWire.class)
186 .timeout(
187 RequestTimeoutLossTest.CONNECT_TIMEOUT,
188 RequestTimeoutLossTest.READ_TIMEOUT
189 )
190 .method(Request.GET)
191 .fetch();
192 }
193 };
194 this.testTimeoutOrderDoesntMatter(execution);
195 }
196
197
198
199
200
201
202
203
204 @ParameterizedTest
205 @Values
206 void testTimeoutOrderDoesntMatterBeforeMultipartBody(
207 final Class<? extends Request> type
208 )
209 throws Exception {
210 final Callable<Response> execution = new Callable<Response>() {
211 @Override
212 public Response call() throws Exception {
213 return RequestTimeoutLossTest.request(type)
214 .through(MockWire.class)
215 .method(Request.GET)
216 .timeout(
217 RequestTimeoutLossTest.CONNECT_TIMEOUT,
218 RequestTimeoutLossTest.READ_TIMEOUT
219 )
220 .multipartBody()
221 .back()
222 .fetch();
223 }
224 };
225 this.testTimeoutOrderDoesntMatter(execution);
226 }
227
228
229
230
231
232
233
234
235 @ParameterizedTest
236 @Values
237 void testTimeoutOrderDoesntMatterBeforeReset(
238 final Class<? extends Request> type
239 )
240 throws Exception {
241 final Callable<Response> execution = new Callable<Response>() {
242 @Override
243 public Response call() throws Exception {
244 return RequestTimeoutLossTest.request(type)
245 .through(MockWire.class)
246 .method(Request.GET)
247 .timeout(
248 RequestTimeoutLossTest.CONNECT_TIMEOUT,
249 RequestTimeoutLossTest.READ_TIMEOUT
250 )
251 .reset(RequestTimeoutLossTest.CONTENT_TYPE)
252 .fetch();
253 }
254 };
255 this.testTimeoutOrderDoesntMatter(execution);
256 }
257
258
259
260
261
262
263
264
265 @ParameterizedTest
266 @Values
267 void testTimeoutOrderDoesntMatterBeforeUriBack(
268 final Class<? extends Request> type
269 )
270 throws Exception {
271 this.testTimeoutOrderDoesntMatter(
272 new Callable<Response>() {
273 @Override
274 public Response call() throws Exception {
275 return RequestTimeoutLossTest.request(type)
276 .through(MockWire.class)
277 .method(Request.GET)
278 .timeout(
279 RequestTimeoutLossTest.CONNECT_TIMEOUT,
280 RequestTimeoutLossTest.READ_TIMEOUT
281 )
282 .uri()
283 .path("/api")
284 .back()
285 .fetch();
286 }
287 }
288 );
289 }
290
291
292
293
294
295
296 @Test
297 void passesThroughWire() throws IOException {
298 final Wire original = Mockito.mock(Wire.class);
299 final Wire wire = Mockito.mock(Wire.class);
300 final Response response = Mockito.mock(Response.class);
301 final Supplier<Collection<Map.Entry<String, String>>> hdrs =
302 new Supplier<Collection<Map.Entry<String, String>>>() {
303 @Override
304 public Collection<Map.Entry<String, String>> get() {
305 return ArgumentMatchers.anyCollection();
306 }
307 };
308 final String url = "fake-url";
309 Mockito.when(
310 wire.send(
311 ArgumentMatchers.any(Request.class),
312 ArgumentMatchers.eq(url),
313 ArgumentMatchers.anyString(),
314 hdrs.get(),
315 ArgumentMatchers.any(InputStream.class),
316 ArgumentMatchers.anyInt(),
317 ArgumentMatchers.anyInt()
318 )
319 ).thenReturn(response);
320 new BaseRequest(original, url).through(wire).fetch();
321 Mockito.verify(original, Mockito.never()).send(
322 ArgumentMatchers.any(Request.class),
323 ArgumentMatchers.anyString(),
324 ArgumentMatchers.anyString(),
325 hdrs.get(),
326 ArgumentMatchers.any(InputStream.class),
327 ArgumentMatchers.anyInt(),
328 ArgumentMatchers.anyInt()
329 );
330 Mockito.verify(wire).send(
331 ArgumentMatchers.any(Request.class),
332 ArgumentMatchers.anyString(),
333 ArgumentMatchers.anyString(),
334 hdrs.get(),
335 ArgumentMatchers.any(InputStream.class),
336 ArgumentMatchers.anyInt(),
337 ArgumentMatchers.anyInt()
338 );
339 }
340
341
342
343
344
345
346
347
348 @SuppressWarnings("unchecked")
349 private void testTimeoutOrderDoesntMatter(final Callable<Response> exec)
350 throws Exception {
351 synchronized (MockWire.class) {
352 final Wire wire = Mockito.mock(Wire.class);
353 final ArgumentCaptor<Integer> cnc = ArgumentCaptor
354 .forClass(Integer.class);
355 final ArgumentCaptor<Integer> rdc = ArgumentCaptor
356 .forClass(Integer.class);
357 MockWire.setMockDelegate(wire);
358 final Response response = Mockito.mock(Response.class);
359 Mockito.when(
360 wire.send(
361 Mockito.any(Request.class),
362 Mockito.anyString(),
363 Mockito.anyString(),
364 Mockito.<Map.Entry<String, String>>anyCollection(),
365 Mockito.any(InputStream.class),
366 Mockito.anyInt(),
367 Mockito.anyInt()
368 )
369 ).thenReturn(response);
370 exec.call();
371 Mockito.verify(wire).send(
372 Mockito.any(Request.class),
373 Mockito.anyString(),
374 Mockito.anyString(),
375 Mockito.<Map.Entry<String, String>>anyCollection(),
376 Mockito.any(InputStream.class),
377 cnc.capture(),
378 rdc.capture()
379 );
380 MatcherAssert.assertThat(
381 cnc.getValue().intValue(),
382 Matchers.is(RequestTimeoutLossTest.CONNECT_TIMEOUT)
383 );
384 MatcherAssert.assertThat(
385 rdc.getValue().intValue(),
386 Matchers.is(RequestTimeoutLossTest.READ_TIMEOUT)
387 );
388 }
389 }
390
391
392
393
394
395
396
397 private static Request request(final Class<? extends Request> type)
398 throws Exception {
399 return RequestTestTemplate.request(
400 new URI(RequestTimeoutLossTest.LOCALHOST_URL),
401 type
402 );
403 }
404
405 }