X-Git-Url: https://juplo.de/gitweb/?a=blobdiff_plain;f=dist%2Fhttp-resources%2F2.0.0%2Fxref-test%2Fde%2Fjuplo%2Fhttpresources%2FHttpResourceFetcherTest.html;fp=dist%2Fhttp-resources%2F2.0.0%2Fxref-test%2Fde%2Fjuplo%2Fhttpresources%2FHttpResourceFetcherTest.html;h=6748a5d1a45cb90c019e281ec9770e6e9bd01797;hb=96ec104e2974d001e9bc82c3af8b21029b2042d4;hp=0000000000000000000000000000000000000000;hpb=de1fa457a1c69c673d4dd5c0a2c9af568f74ea12;p=website diff --git a/dist/http-resources/2.0.0/xref-test/de/juplo/httpresources/HttpResourceFetcherTest.html b/dist/http-resources/2.0.0/xref-test/de/juplo/httpresources/HttpResourceFetcherTest.html new file mode 100644 index 00000000..6748a5d1 --- /dev/null +++ b/dist/http-resources/2.0.0/xref-test/de/juplo/httpresources/HttpResourceFetcherTest.html @@ -0,0 +1,1269 @@ + + + +HttpResourceFetcherTest xref + + + +
View Javadoc
+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   * Tests the inner class {@link HttpResourceFetcher}.
+34   * @author Kai Moritz
+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       // Should not be called...
+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); // << Flag "revalidate" is cleared, because header ist not set
+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 }
+
+
+ + +