1 package de.juplo.httpresources;
2
3
4 import mockit.Expectations;
5 import mockit.Injectable;
6 import mockit.Verifications;
7 import org.apache.http.Header;
8 import org.apache.http.HttpHeaders;
9 import org.apache.http.client.methods.CloseableHttpResponse;
10 import org.apache.http.client.methods.HttpUriRequest;
11 import org.apache.http.conn.HttpHostConnectException;
12 import org.apache.http.impl.client.CloseableHttpClient;
13 import org.apache.http.protocol.HttpContext;
14 import org.junit.jupiter.api.DisplayName;
15 import org.junit.jupiter.api.Test;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18 import org.springframework.cache.Cache;
19 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
20
21 import java.net.InetAddress;
22 import java.net.URI;
23 import java.time.Clock;
24 import java.time.ZoneId;
25
26 import static de.juplo.httpresources.HttpData.NOT_FETCHED;
27 import static de.juplo.httpresources.HttpResourceFetcher.DEFAULT_TTL;
28 import static de.juplo.httpresources.TestUtil.*;
29 import static org.junit.Assert.*;
30
31
32
33
34
35
36 public class HttpResourceFetcherTest
37 {
38 private final static Logger LOG =
39 LoggerFactory.getLogger(HttpResourceFetcherTest.class);
40
41 final static String ADDRESS = "http://foo/bar";
42 final static URI ADDRESS_URI = URI.create(ADDRESS);
43
44 final static HttpData WHATEVER = DATA_EXPIRED_DUMMY;
45 final static HttpData SAME_AS_CACHED = DATA_NOT_EXPIRED_DUMMY;
46
47 @Injectable
48 CloseableHttpClient client;
49 @Injectable
50 CloseableHttpResponse response;
51 @Injectable
52 Cache cache;
53
54 Clock clock;
55 HttpResourceFetcher fetcher;
56 HttpResources resources;
57
58 public void withServeStaleFalse()
59 {
60 Clock clock = Clock.fixed(NOW.toInstant(), ZoneId.of("GMT"));
61 fetcher = new HttpResourceFetcher(
62 new HttpComponentsClientHttpRequestFactory(client),
63 cache,
64 clock,
65 DEFAULT_TTL,
66 0,
67 false);
68 resources = new HttpResources(
69 fetcher,
70 clock);
71 }
72
73 public void withServeStaleFalseAndMinTTL()
74 {
75 clock = Clock.fixed(NOW.toInstant(), ZoneId.of("GMT"));
76 fetcher = new HttpResourceFetcher(
77 new HttpComponentsClientHttpRequestFactory(client),
78 cache,
79 clock,
80 DEFAULT_TTL,
81 MIN_TTL,
82 false);
83 resources = new HttpResources(
84 fetcher,
85 clock);
86 }
87
88 public void withServeStaleTrue()
89 {
90 Clock clock = Clock.fixed(NOW.toInstant(), ZoneId.of("GMT"));
91 fetcher = new HttpResourceFetcher(
92 new HttpComponentsClientHttpRequestFactory(client),
93 cache,
94 clock);
95 resources = new HttpResources(
96 fetcher,
97 clock);
98 }
99
100
101 @Test
102 @DisplayName("first request -- cached - valid")
103 public void test_Fetch_Cached_Valid() throws Exception
104 {
105 LOG.info("<-- start of test-case");
106 withServeStaleFalse();
107 new Expectations()
108 {{
109 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = DATA_NOT_EXPIRED;
110
111 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
112 response.getStatusLine(); result = OK; minTimes = 0;
113 response.getAllHeaders(); result = new Header[0]; minTimes = 0;
114 response.getEntity(); result = null; minTimes = 0;
115 response.close(); minTimes = 0;
116 }};
117
118 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
119
120 new Verifications()
121 {{
122 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); times = 0;
123 }};
124
125 assertEquals(data, DATA_NOT_EXPIRED);
126 }
127
128
129 @Test
130 @DisplayName("first request -- cached - expired")
131 public void test_Fetch_Cached_Expired() throws Exception
132 {
133 LOG.info("<-- start of test-case");
134 withServeStaleFalse();
135 new Expectations()
136 {{
137 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = DATA_EXPIRED;
138 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
139 response.getStatusLine(); result = OK;
140 response.getAllHeaders(); result = new Header[0];
141 response.getEntity(); result = null;
142 response.close();
143 }};
144
145 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
146
147 new Verifications()
148 {{
149 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); times = 1;
150 cache.put(ADDRESS_URI, data);
151 }};
152
153 assertNull(data.headers.getContentType());
154 assertNotNull(data.content);
155 assertEquals("", new String(data.content, UTF8));
156 assertEquals(LONG_NOW + DEFAULT_TTL, data.expires);
157 assertFalse(data.revalidate);
158 assertNull(data.eTag);
159 assertEquals(0l, data.lastModified);
160 }
161
162
163 @Test
164 @DisplayName("first request -- cached - not found")
165 public void test_Fetch_Cached_NotFound() throws Exception
166 {
167 LOG.info("<-- start of test-case");
168 withServeStaleFalse();
169 new Expectations()
170 {{
171 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = HttpData.NOT_FOUND;
172 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
173 response.getStatusLine(); result = OK;
174 response.getAllHeaders(); result = new Header[0];
175 response.getEntity(); result = null;
176 response.close();
177 }};
178
179 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
180
181 new Verifications()
182 {{
183 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); times = 1;
184 cache.put(ADDRESS_URI, data);
185 }};
186
187 assertNull(data.headers.getContentType());
188 assertNotNull(data.content);
189 assertEquals("", new String(data.content, UTF8));
190 assertEquals(LONG_NOW + DEFAULT_TTL, data.expires);
191 assertFalse(data.revalidate);
192 assertNull(data.eTag);
193 assertEquals(0l, data.lastModified);
194 }
195
196
197 @Test
198 @DisplayName("first request -- cached - server error")
199 public void test_Fetch_Cached_ServerError() throws Exception
200 {
201 LOG.info("<-- start of test-case");
202 withServeStaleFalse();
203 new Expectations()
204 {{
205 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = HttpData.SERVER_ERROR;
206 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
207 response.getStatusLine(); result = OK;
208 response.getAllHeaders(); result = new Header[0];
209 response.getEntity(); result = null;
210 response.close();
211 }};
212
213 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
214
215 new Verifications()
216 {{
217 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); times = 1;
218 cache.put(ADDRESS_URI, data);
219 }};
220
221 assertNull(data.headers.getContentType());
222 assertNotNull(data.content);
223 assertEquals("", new String(data.content, UTF8));
224 assertEquals(LONG_NOW + DEFAULT_TTL, data.expires);
225 assertFalse(data.revalidate);
226 assertNull(data.eTag);
227 assertEquals(0l, data.lastModified);
228 }
229
230
231 @Test
232 @DisplayName("first request -- 200 - no headers / no body")
233 public void test_Fetch_200_NoHeaders_NoBody() throws Exception
234 {
235 LOG.info("<-- start of test-case");
236 withServeStaleFalse();
237 new Expectations()
238 {{
239 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
240 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
241 response.getStatusLine(); result = OK;
242 response.getAllHeaders(); result = new Header[0];
243 response.getEntity(); result = null;
244 response.close();
245 }};
246
247 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
248
249 new Verifications()
250 {{
251 HttpUriRequest request;
252 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
253 assertEquals(ADDRESS_URI, request.getURI());
254 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
255 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
256 cache.put(ADDRESS_URI, data);
257 }};
258
259 assertNull(data.headers.getContentType());
260 assertNotNull(data.content);
261 assertEquals("", new String(data.content, UTF8));
262 assertEquals(LONG_NOW + DEFAULT_TTL, data.expires);
263 assertFalse(data.revalidate);
264 assertNull(data.eTag);
265 assertEquals(0l, data.lastModified);
266 }
267
268
269 @Test
270 @DisplayName("first request -- 200 - no headers")
271 public void test_Fetch_200_NoHeaders() throws Exception
272 {
273 LOG.info("<-- start of test-case");
274 withServeStaleFalse();
275 new Expectations()
276 {{
277 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
278 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
279 response.getStatusLine(); result = OK;
280 response.getAllHeaders(); result = new Header[0];
281 response.getEntity(); result = BODY;
282 response.close();
283 }};
284
285 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
286
287 new Verifications()
288 {{
289 HttpUriRequest request;
290 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
291 assertEquals(ADDRESS_URI, request.getURI());
292 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
293 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
294 cache.put(ADDRESS_URI, data);
295 }};
296
297 assertNull(data.headers.getContentType());
298 assertNotNull(data.content);
299 assertEquals(STR_CONTENT, new String(data.content, UTF8));
300 assertEquals(LONG_NOW + DEFAULT_TTL, data.expires);
301 assertFalse(data.revalidate);
302 assertNull(data.eTag);
303 assertEquals(0l, data.lastModified);
304 }
305
306
307 @Test
308 @DisplayName("first request -- 200 - HTTP/1.1")
309 public void test_Fetch_200_HTTP11() throws Exception
310 {
311 LOG.info("<-- start of test-case");
312 withServeStaleFalse();
313 new Expectations()
314 {{
315 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
316 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
317 response.getStatusLine(); result = OK;
318 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE };
319 response.getEntity(); result = BODY;
320 response.close();
321 }};
322
323 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
324
325 new Verifications()
326 {{
327 HttpUriRequest request;
328 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
329 assertEquals(ADDRESS_URI, request.getURI());
330 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
331 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
332 cache.put(ADDRESS_URI, data);
333 }};
334
335 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
336 assertNotNull(data.content);
337 assertEquals(STR_CONTENT, new String(data.content, UTF8));
338 assertEquals(LONG_SEND + (MAX_AGE - 1) * 1000, data.expires);
339 assertFalse(data.revalidate);
340 assertEquals(STR_ETAG, data.eTag);
341 assertEquals(LONG_THEN, data.lastModified);
342 }
343
344 @Test
345 @DisplayName("first request + min-TTL -- 200 - HTTP/1.1")
346 public void test_Fetch_200_HTTP11_MinTTL() throws Exception
347 {
348 LOG.info("<-- start of test-case");
349 withServeStaleFalseAndMinTTL();
350 new Expectations()
351 {{
352 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
353 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
354 response.getStatusLine(); result = OK;
355 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE };
356 response.getEntity(); result = BODY;
357 response.close();
358 }};
359
360 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
361
362 new Verifications()
363 {{
364 HttpUriRequest request;
365 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
366 assertEquals(ADDRESS_URI, request.getURI());
367 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
368 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
369 cache.put(ADDRESS_URI, data);
370 }};
371
372 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
373 assertNotNull(data.content);
374 assertEquals(STR_CONTENT, new String(data.content, UTF8));
375 assertEquals(LONG_SEND + MIN_TTL - 1000, data.expires);
376 assertFalse(data.revalidate);
377 assertEquals(STR_ETAG, data.eTag);
378 assertEquals(LONG_THEN, data.lastModified);
379 }
380
381
382 @Test
383 @DisplayName("first request -- 200 - HTTP/1.1 / Date-Header is missing")
384 public void test_Fetch_200_HTTP11_DateMissing_() throws Exception
385 {
386 LOG.info("<-- start of test-case");
387 withServeStaleFalse();
388 new Expectations()
389 {{
390 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
391 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
392 response.getStatusLine(); result = OK;
393 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE };
394 response.getEntity(); result = BODY;
395 response.close();
396 }};
397
398 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
399
400 new Verifications()
401 {{
402 HttpUriRequest request;
403 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
404 assertEquals(ADDRESS_URI, request.getURI());
405 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
406 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
407 cache.put(ADDRESS_URI, data);
408 }};
409
410 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
411 assertNotNull(data.content);
412 assertEquals(STR_CONTENT, new String(data.content, UTF8));
413 assertEquals(LONG_NOW + MAX_AGE * 1000, data.expires);
414 assertFalse(data.revalidate);
415 assertEquals(STR_ETAG, data.eTag);
416 assertEquals(LONG_THEN, data.lastModified);
417 }
418
419
420 @Test
421 @DisplayName("first request -- 200 - HTTP/1.1 / Cache-Control: public, max-age=0")
422 public void test_Fetch_200_HTTP11_MaxAge0() throws Exception
423 {
424 LOG.info("<-- start of test-case");
425 withServeStaleFalse();
426 new Expectations()
427 {{
428 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
429 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
430 response.getStatusLine(); result = OK;
431 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE_0 };
432 response.getEntity(); result = BODY;
433 response.close();
434 }};
435
436 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
437
438 new Verifications()
439 {{
440 HttpUriRequest request;
441 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
442 assertEquals(ADDRESS_URI, request.getURI());
443 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
444 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
445 cache.put(ADDRESS_URI, data);
446 }};
447
448 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
449 assertNotNull(data.content);
450 assertEquals(LONG_SEND - 1000, data.expires);
451 assertFalse(data.revalidate);
452 assertEquals(STR_ETAG, data.eTag);
453 assertEquals(LONG_THEN, data.lastModified);
454 }
455 @Test
456 @DisplayName("first request -- 200 - HTTP/1.1 / Cache-Control: no-cache")
457 public void test_Fetch_200_HTTP11_NoCache() throws Exception
458 {
459 LOG.info("<-- start of test-case");
460 withServeStaleFalse();
461 new Expectations()
462 {{
463 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
464 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
465 response.getStatusLine(); result = OK;
466 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_NO_CACHE };
467 response.getEntity(); result = BODY;
468 response.close();
469 }};
470
471 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
472
473 new Verifications()
474 {{
475 HttpUriRequest request;
476 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
477 assertEquals(ADDRESS_URI, request.getURI());
478 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
479 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
480 cache.put(ADDRESS_URI, data);
481 }};
482
483 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
484 assertNotNull(data.content);
485 assertEquals(LONG_SEND, data.expires);
486 assertFalse(data.revalidate);
487 assertEquals(STR_ETAG, data.eTag);
488 assertEquals(LONG_THEN, data.lastModified);
489 }
490
491
492 @Test
493 @DisplayName("first request -- 200 - HTTP/1.1 / Cache-Control: no-cache=\"Cookie\"")
494 public void test_Fetch_200_HTTP11_NoCacheQualified() throws Exception
495 {
496 LOG.info("<-- start of test-case");
497 withServeStaleFalse();
498 new Expectations()
499 {{
500 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
501 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
502 response.getStatusLine(); result = OK;
503 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_NO_CACHE_QUALIFIED };
504 response.getEntity(); result = BODY;
505 response.close();
506 }};
507
508 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
509
510 new Verifications()
511 {{
512 HttpUriRequest request;
513 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
514 assertEquals(ADDRESS_URI, request.getURI());
515 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
516 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
517 cache.put(ADDRESS_URI, data);
518 }};
519
520 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
521 assertNotNull(data.content);
522 assertEquals(STR_CONTENT, new String(data.content, UTF8));
523 assertEquals(LONG_SEND + (MAX_AGE - 1) * 1000, data.expires);
524 assertFalse(data.revalidate);
525 assertEquals(STR_ETAG, data.eTag);
526 assertEquals(LONG_THEN, data.lastModified);
527 }
528
529
530 @Test
531 @DisplayName("first request -- 200 - HTTP/1.0")
532 public void test_Fetch_200_HTTP10() throws Exception
533 {
534 LOG.info("<-- start of test-case");
535 withServeStaleFalse();
536 new Expectations()
537 {{
538 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
539 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
540 response.getStatusLine(); result = OK;
541 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, EXPIRES_VALID };
542 response.getEntity(); result = BODY;
543 response.close();
544 }};
545
546 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
547
548 new Verifications()
549 {{
550 HttpUriRequest request;
551 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
552 assertEquals(ADDRESS_URI, request.getURI());
553 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
554 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
555 cache.put(ADDRESS_URI, data);
556 }};
557
558 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
559 assertNotNull(data.content);
560 assertEquals(STR_CONTENT, new String(data.content, UTF8));
561 assertEquals(LONG_FEATURE, data.expires);
562 assertFalse(data.revalidate);
563 assertNull(data.eTag);
564 assertEquals(LONG_THEN, data.lastModified);
565 }
566
567
568 @Test
569 @DisplayName("first request -- 200 - HTTP/1.0 / invalid Expires-Header")
570 public void test_Fetch_200_HTTP10_InvalidExpires() throws Exception
571 {
572 LOG.info("<-- start of test-case");
573 withServeStaleFalse();
574 new Expectations()
575 {{
576 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
577 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
578 response.getStatusLine(); result = OK;
579 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, EXPIRES_INVALID };
580 response.getEntity(); result = BODY;
581 response.close();
582 }};
583
584 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
585
586 new Verifications()
587 {{
588 HttpUriRequest request;
589 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
590 assertEquals(ADDRESS_URI, request.getURI());
591 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
592 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
593 cache.put(ADDRESS_URI, data);
594 }};
595
596 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
597 assertNotNull(data.content);
598 assertEquals(0l, data.expires);
599 assertFalse(data.revalidate);
600 assertNull(data.eTag);
601 assertEquals(LONG_THEN, data.lastModified);
602 }
603
604
605 @Test
606 @DisplayName("first request -- 200 - HTTP/mixed: Expires + Cache-Control: private")
607 public void test_Fetch_200_Mixed() throws Exception
608 {
609 LOG.info("<-- start of test-case");
610 withServeStaleFalse();
611 new Expectations()
612 {{
613 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
614 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
615 response.getStatusLine(); result = OK;
616 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, EXPIRES_VALID, CACHE_CONTROL_PRIVATE };
617 response.getEntity(); result = BODY;
618 response.close();
619 }};
620
621 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
622
623 new Verifications()
624 {{
625 HttpUriRequest request;
626 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
627 assertEquals(ADDRESS_URI, request.getURI());
628 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
629 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
630 cache.put(ADDRESS_URI, data);
631 }};
632
633 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
634 assertNotNull(data.content);
635 assertEquals(STR_CONTENT, new String(data.content, UTF8));
636 assertEquals(LONG_FEATURE, data.expires);
637 assertFalse(data.revalidate);
638 assertEquals(STR_ETAG, data.eTag);
639 assertEquals(LONG_THEN, data.lastModified);
640 }
641
642
643 @Test
644 @DisplayName("first request -- 200 - HTTP/mixed: Expires + Cache-Control: max-age")
645 public void test_Fetch_200_Mixed_ExpiresOverwritten() throws Exception
646 {
647 LOG.info("<-- start of test-case");
648 withServeStaleFalse();
649 new Expectations()
650 {{
651 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
652 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
653 response.getStatusLine(); result = OK;
654 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE };
655 response.getEntity(); result = BODY;
656 response.close();
657 }};
658
659 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
660
661 new Verifications()
662 {{
663 HttpUriRequest request;
664 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
665 assertEquals(ADDRESS_URI, request.getURI());
666 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
667 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
668 cache.put(ADDRESS_URI, data);
669 }};
670
671 assertEquals(DATA_NOT_EXPIRED, data);
672 }
673
674
675 @Test
676 @DisplayName("first request -- 200 - HTTP/1.1 + Content-Encoding: gzip")
677 public void test_Fetch_200_HTTP11_Encoding() throws Exception
678 {
679 LOG.info("<-- start of test-case");
680 withServeStaleFalse();
681 new Expectations()
682 {{
683 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
684 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
685 response.getStatusLine(); result = OK;
686 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, CONTENT_ENCODING, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE };
687 response.getEntity(); result = BODY_GZIPPED;
688 response.close();
689 }};
690
691 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
692
693 new Verifications()
694 {{
695 HttpUriRequest request;
696 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
697 assertEquals(ADDRESS_URI, request.getURI());
698 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
699 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
700 cache.put(ADDRESS_URI, data);
701 }};
702
703 assertEquals(MIME_TYPE_CONTENT_TYPE_HTML, data.headers.getContentType());
704 assertNotNull(data.content);
705 assertEquals(new String(CONTENT_GZIPPED), new String(data.content, UTF8));
706 assertEquals(LONG_SEND + (MAX_AGE - 1) * 1000, data.expires);
707 assertFalse(data.revalidate);
708 assertEquals(STR_ETAG, data.eTag);
709 assertEquals(LONG_THEN, data.lastModified);
710 }
711
712 @Test
713 @DisplayName("first request -- 200 - HTTP/1.1 + Cache-Control: must-revalidate")
714 public void test_Fetch_200_HTTP11_MustRevalidate() throws Exception
715 {
716 LOG.info("<-- start of test-case");
717 withServeStaleFalse();
718 new Expectations()
719 {{
720 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
721 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
722 response.getStatusLine(); result = OK;
723 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_REVALIDATE };
724 response.getEntity(); result = BODY;
725 response.close();
726 }};
727
728 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
729
730 new Verifications()
731 {{
732 HttpUriRequest request;
733 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
734 assertEquals(ADDRESS_URI, request.getURI());
735 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
736 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
737 cache.put(ADDRESS_URI, data);
738 }};
739
740 assertEquals(DATA_NOT_EXPIRED_REVALIDATION_REQUIRED, data);
741 }
742
743
744 @Test
745 @DisplayName("first request -- 400 - HTTP/1.1")
746 public void test_Fetch_404_HTTP11() throws Exception
747 {
748 LOG.info("<-- start of test-case");
749 withServeStaleFalse();
750 new Expectations()
751 {{
752 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
753 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
754 response.getStatusLine(); result = NOT_FOUND;
755 response.getAllHeaders(); result = new Header[] { DATE };
756 response.close();
757 }};
758
759 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
760
761 new Verifications()
762 {{
763 HttpUriRequest request;
764 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
765 assertEquals(ADDRESS_URI, request.getURI());
766 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
767 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
768 cache.put(ADDRESS_URI, data);
769 }};
770
771 assertNull(data.headers.getContentType());
772 assertNull(data.content);
773 assertEquals(LONG_SEND - 1000, data.expires);
774 assertFalse(data.revalidate);
775 assertNull(data.eTag);
776 assertEquals(0, data.lastModified);
777 }
778
779
780 @Test
781 @DisplayName("first request -- 404 - HTTP/1.1 + Cache-Control: max-age")
782 public void test_Fetch_404_HTTP11_Cacheable() throws Exception
783 {
784 LOG.info("<-- start of test-case");
785 withServeStaleFalse();
786 new Expectations()
787 {{
788 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
789 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response;
790 response.getStatusLine(); result = NOT_FOUND;
791 response.getAllHeaders(); result = new Header[] { DATE };
792 response.close();
793 }};
794
795 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
796
797 new Verifications()
798 {{
799 HttpUriRequest request;
800 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
801 assertEquals(ADDRESS_URI, request.getURI());
802 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
803 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
804 cache.put(ADDRESS_URI, data);
805 }};
806
807 assertEquals(DATA_NOT_FOUND, data);
808 }
809
810
811 @Test
812 @DisplayName("first request -- 500 - HTTP/1.1")
813 public void test_Fetch_500_HTTP11() throws Exception
814 {
815 LOG.info("<-- start of test-case");
816 withServeStaleFalse();
817 new Expectations()
818 {{
819 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
820 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; times = 1;
821 response.getStatusLine(); result = SERVER_ERROR;
822 response.close();
823 }};
824
825 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
826
827 new Verifications()
828 {{
829 HttpUriRequest request;
830 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
831 assertEquals(ADDRESS_URI, request.getURI());
832 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
833 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
834 cache.put(ADDRESS_URI, data);
835 }};
836
837 assertEquals(HttpData.SERVER_ERROR, data);
838 }
839
840
841 @Test
842 @DisplayName("first request -- server is down")
843 public void test_Fetch_ServerDown() throws Exception
844 {
845 LOG.info("<-- start of test-case");
846 withServeStaleFalse();
847 new Expectations()
848 {{
849 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
850 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = new HttpHostConnectException(null, null, (InetAddress)null);
851 }};
852
853 HttpData data = fetcher.fetch(ADDRESS_URI, NOT_FETCHED);
854
855 new Verifications()
856 {{
857 HttpUriRequest request;
858 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
859 assertEquals(ADDRESS_URI, request.getURI());
860 assertNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
861 assertNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
862 cache.put(ADDRESS_URI, data);
863 }};
864
865 assertEquals(HttpData.SERVER_ERROR, data);
866 }
867
868
869 @Test
870 @DisplayName("update request -- cached - same -> request is executed")
871 public void test_Update_Cached_Same_RequestIsExecuted() throws Exception
872 {
873 LOG.info("<-- start of test-case");
874 withServeStaleFalse();
875 new Expectations()
876 {{
877 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = SAME_AS_CACHED;
878 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
879 response.getStatusLine(); result = NOT_MODIFIED; minTimes = 0;
880 response.getAllHeaders(); result = new Header[] { DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE }; minTimes = 0;
881 response.close(); minTimes = 0;
882 }};
883
884 HttpData data = fetcher.fetch(ADDRESS_URI, SAME_AS_CACHED);
885
886 new Verifications()
887 {{
888 HttpUriRequest request;
889 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
890 times = 1;
891 assertEquals(ADDRESS_URI, request.getURI());
892 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
893 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
894 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
895 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
896 cache.put(ADDRESS_URI, data);
897 }};
898
899 assertEquals(DATA_NOT_EXPIRED, data);
900 }
901
902
903 @Test
904 @DisplayName("update request -- cached - valid")
905 public void test_Update_Cached_Valid() throws Exception
906 {
907 LOG.info("<-- start of test-case");
908 withServeStaleFalse();
909 new Expectations()
910 {{
911 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = DATA_NOT_EXPIRED;
912 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
913 response.getStatusLine(); result = NOT_MODIFIED; minTimes = 0;
914 response.getAllHeaders(); result = new Header[] { DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE }; minTimes = 0;
915 response.close(); minTimes = 0;
916 }};
917
918 HttpData data = fetcher.fetch(ADDRESS_URI, WHATEVER);
919
920 new Verifications()
921 {{
922 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); times = 0;
923 }};
924
925 assertEquals(data, DATA_NOT_EXPIRED);
926 }
927
928
929 @Test
930 @DisplayName("update request -- cached - expired -> request is executed")
931 public void test_Update_Cached_Expired_RequestIsExecuted() throws Exception
932 {
933 LOG.info("<-- start of test-case");
934 withServeStaleFalse();
935 new Expectations()
936 {{
937 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = DATA_EXPIRED;
938 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
939 response.getStatusLine(); result = NOT_MODIFIED; minTimes = 0;
940 response.getAllHeaders(); result = new Header[] { DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE }; minTimes = 0;
941 response.close(); minTimes = 0;
942 }};
943
944 HttpData data = fetcher.fetch(ADDRESS_URI, WHATEVER);
945
946 new Verifications()
947 {{
948 HttpUriRequest request;
949 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
950 times = 1;
951 assertEquals(ADDRESS_URI, request.getURI());
952 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
953 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
954 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
955 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
956 cache.put(ADDRESS_URI, data);
957 }};
958
959 assertEquals(DATA_NOT_EXPIRED, data);
960 }
961
962
963 @Test
964 @DisplayName("update request -- 304: not modified")
965 public void test_Update_304() throws Exception
966 {
967 LOG.info("<-- start of test-case");
968 withServeStaleFalse();
969 new Expectations()
970 {{
971 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
972 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
973 response.getStatusLine(); result = NOT_MODIFIED; minTimes = 0;
974 response.getAllHeaders(); result = new Header[] { DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE }; minTimes = 0;
975 response.close(); minTimes = 0;
976 }};
977
978 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_EXPIRED);
979
980 new Verifications()
981 {{
982 HttpUriRequest request;
983 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
984 times = 1;
985 assertEquals(ADDRESS_URI, request.getURI());
986 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
987 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
988 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
989 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
990 cache.put(ADDRESS_URI, data);
991 }};
992
993 assertEquals(DATA_NOT_EXPIRED, data);
994 }
995
996
997 @Test
998 @DisplayName("update request -- 200: modified")
999 public void test_Update_200() throws Exception
1000 {
1001 LOG.info("<-- start of test-case");
1002 withServeStaleFalse();
1003 new Expectations()
1004 {{
1005 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1006 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
1007 response.getStatusLine(); result = OK; minTimes = 0;
1008 response.getAllHeaders(); result = new Header[] { CONTENT_TYPE_HTML, DATE_MODIFIED, LAST_MODIFIED_MODIFIED, ETAG_MODIFIED, CACHE_CONTROL_MAX_AGE }; minTimes = 0;
1009 response.getEntity(); result = BODY_MODIFIED; minTimes = 0;
1010 response.close(); minTimes = 0;
1011 }};
1012
1013 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_EXPIRED);
1014
1015 new Verifications()
1016 {{
1017 HttpUriRequest request;
1018 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
1019 times = 1;
1020 assertEquals(ADDRESS_URI, request.getURI());
1021 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1022 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1023 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1024 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1025 cache.put(ADDRESS_URI, data);
1026 }};
1027
1028 assertEquals(DATA_UPDATED, data);
1029 }
1030
1031
1032 @Test
1033 @DisplayName("update request -- 404: not found")
1034 public void test_Update_404() throws Exception
1035 {
1036 LOG.info("<-- start of test-case");
1037 withServeStaleFalse();
1038 new Expectations()
1039 {{
1040 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1041 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
1042 response.getStatusLine(); result = NOT_FOUND; minTimes = 0;
1043 response.getAllHeaders(); result = new Header[] { DATE }; minTimes = 0;
1044 response.close(); minTimes = 0;
1045 }};
1046
1047 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_EXPIRED);
1048
1049 new Verifications()
1050 {{
1051 HttpUriRequest request;
1052 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
1053 times = 1;
1054 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1055 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1056 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1057 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1058 cache.put(ADDRESS_URI, data);
1059 }};
1060
1061 assertEquals(DATA_NOT_FOUND, data);
1062 }
1063
1064
1065 @Test
1066 @DisplayName("update request -- 500: server error")
1067 public void test_Update_500() throws Exception
1068 {
1069 LOG.info("<-- start of test-case");
1070 withServeStaleFalse();
1071 new Expectations()
1072 {{
1073 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1074 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
1075 response.getStatusLine(); result = SERVER_ERROR; minTimes = 0;
1076 response.close(); minTimes = 0;
1077 }};
1078
1079 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_EXPIRED);
1080
1081 new Verifications()
1082 {{
1083 HttpUriRequest request;
1084 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
1085 times = 1;
1086 assertEquals(ADDRESS_URI, request.getURI());
1087 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1088 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1089 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1090 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1091 cache.put(ADDRESS_URI, data);
1092 }};
1093
1094 assertEquals(DATA_EXPIRED, data);
1095 }
1096
1097
1098 @Test
1099 @DisplayName("update request -- must revalidate / 304: not modified")
1100 public void test_Update_MustRevalidate_304() throws Exception
1101 {
1102 LOG.info("<-- start of test-case");
1103 withServeStaleFalse();
1104 new Expectations()
1105 {{
1106 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1107 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
1108 response.getStatusLine(); result = NOT_MODIFIED; minTimes = 0;
1109 response.getAllHeaders(); result = new Header[] { DATE, LAST_MODIFIED, ETAG, CACHE_CONTROL_MAX_AGE }; minTimes = 0;
1110 response.close(); minTimes = 0;
1111 }};
1112
1113 HttpResource resource = new HttpResource(resources, fetcher, clock, ADDRESS_URI);
1114 resource.data = DATA_NOT_EXPIRED_REVALIDATION_REQUIRED;
1115
1116 HttpData data = fetcher.fetch(resource.uri, resource.data);
1117
1118 new Verifications()
1119 {{
1120 HttpUriRequest request;
1121 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
1122 times = 1;
1123 assertEquals(ADDRESS_URI, request.getURI());
1124 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1125 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1126 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1127 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1128 cache.put(ADDRESS_URI, data);
1129 }};
1130
1131 assertEquals(DATA_NOT_EXPIRED, data);
1132 }
1133
1134
1135 @Test
1136 @DisplayName("update request -- must-revalidate / 500: server error")
1137 public void test_Update_MustRevalidate_500() throws Exception
1138 {
1139 LOG.info("<-- start of test-case");
1140 withServeStaleFalse();
1141 new Expectations()
1142 {{
1143 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1144 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
1145 response.getStatusLine(); result = SERVER_ERROR; minTimes = 0;
1146 response.close(); minTimes = 0;
1147 }};
1148
1149 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_NOT_EXPIRED_REVALIDATION_REQUIRED);
1150
1151 new Verifications() {{
1152 HttpUriRequest request;
1153 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
1154 times = 1;
1155 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1156 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1157 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1158 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1159 cache.put(ADDRESS_URI, data);
1160 }};
1161
1162 assertEquals(HttpData.SERVER_ERROR, data);
1163 }
1164
1165
1166 @Test
1167 @DisplayName("update request + serve-stale -- 404: not found")
1168 public void test_Update_404_ServeStale() throws Exception
1169 {
1170 LOG.info("<-- start of test-case");
1171 withServeStaleTrue();
1172 new Expectations()
1173 {{
1174 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1175 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
1176 response.getStatusLine(); result = NOT_FOUND; minTimes = 0;
1177 response.close(); minTimes = 0;
1178 }};
1179
1180 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_EXPIRED);
1181
1182 new Verifications()
1183 {{
1184 HttpUriRequest request;
1185 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
1186 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1187 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1188 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1189 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1190 cache.put(ADDRESS_URI, data);
1191 }};
1192
1193 assertEquals(DATA_EXPIRED, data);
1194 }
1195
1196
1197 @Test
1198 @DisplayName("update request + serve-stale -- must-revalidate / 500: server error")
1199 public void test_Update_500_MustRevalidate_ServeStale() throws Exception
1200 {
1201 LOG.info("<-- start of test-case");
1202 withServeStaleTrue();
1203 new Expectations()
1204 {{
1205 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1206 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = response; minTimes = 0;
1207 response.getStatusLine(); result = SERVER_ERROR; minTimes = 0;
1208 response.close(); minTimes = 0;
1209 }};
1210
1211 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_NOT_EXPIRED_REVALIDATION_REQUIRED);
1212
1213 new Verifications()
1214 {{
1215 HttpUriRequest request;
1216 client.execute(request = withCapture(), withInstanceOf(HttpContext.class)); times = 1;
1217 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1218 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1219 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1220 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1221 cache.put(ADDRESS_URI, data);
1222 }};
1223
1224 assertEquals(DATA_NOT_EXPIRED_REVALIDATION_REQUIRED, data);
1225 }
1226
1227
1228 @Test
1229 @DisplayName("update request -- server is down")
1230 public void test_Update_ServerDown() throws Exception
1231 {
1232 LOG.info("<-- start of test-case");
1233 withServeStaleFalse();
1234 new Expectations()
1235 {{
1236 cache.get(withInstanceOf(URI.class), withEqual(HttpData.class)); result = null;
1237 client.execute(withInstanceOf(HttpUriRequest.class), withInstanceOf(HttpContext.class)); result = new HttpHostConnectException(null, null, (InetAddress)null); minTimes = 0;
1238 }};
1239
1240 HttpData data = fetcher.fetch(ADDRESS_URI, DATA_EXPIRED);
1241
1242 new Verifications()
1243 {{
1244 HttpUriRequest request;
1245 client.execute(request = withCapture(), withInstanceOf(HttpContext.class));
1246 times = 1;
1247 assertNotNull(request.getLastHeader(HttpHeaders.IF_NONE_MATCH));
1248 assertEquals(STR_ETAG, request.getLastHeader(HttpHeaders.IF_NONE_MATCH).getValue());
1249 assertNotNull(request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE));
1250 assertEquals(STR_THEN, request.getLastHeader(HttpHeaders.IF_MODIFIED_SINCE).getValue());
1251 cache.put(ADDRESS_URI, data);
1252 }};
1253
1254 assertEquals(DATA_EXPIRED, data);
1255 }
1256 }