You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2013/06/19 21:50:03 UTC
svn commit: r1494755 [1/4] - in
/httpcomponents/httpclient/trunk/httpclient-cache: ./
src/test/java/org/apache/http/impl/client/cache/
Author: olegk
Date: Wed Jun 19 19:50:02 2013
New Revision: 1494755
URL: http://svn.apache.org/r1494755
Log:
HTTPASYNC-46: HttpClient cache test cases can be shared with HttpAsyncClient
Contributed by James Leigh <james at 3roundstones.com>
Added:
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java (with props)
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExecChain.java
- copied, changed from r1494747, httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java
Modified:
httpcomponents/httpclient/trunk/httpclient-cache/pom.xml
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestHttpCacheJiraNumber1147.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolAllowedBehavior.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolDeviations.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestRFC5861Compliance.java
Modified: httpcomponents/httpclient/trunk/httpclient-cache/pom.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/pom.xml?rev=1494755&r1=1494754&r2=1494755&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/pom.xml (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/pom.xml Wed Jun 19 19:50:02 2013
@@ -112,6 +112,18 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java?rev=1494755&r1=1494754&r2=1494755&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/AbstractProtocolTest.java Wed Jun 19 19:50:02 2013
@@ -33,6 +33,7 @@ import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
+import org.apache.http.client.cache.HttpCacheContext;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpExecutionAware;
import org.apache.http.client.methods.HttpRequestWrapper;
@@ -55,9 +56,10 @@ public abstract class AbstractProtocolTe
protected ClientExecChain mockBackend;
protected HttpCache mockCache;
protected HttpRequestWrapper request;
+ protected HttpCacheContext context;
protected CloseableHttpResponse originResponse;
protected CacheConfig config;
- protected CachingExec impl;
+ protected ClientExecChain impl;
protected HttpCache cache;
public static HttpRequestWrapper eqRequest(final HttpRequestWrapper in) {
@@ -65,6 +67,11 @@ public abstract class AbstractProtocolTe
return null;
}
+ public static HttpResponse eqResponse(final HttpResponse in) {
+ EasyMock.reportMatcher(new ResponseEquivalent(in));
+ return null;
+ }
+
@Before
public void setUp() {
host = new HttpHost("foo.example.com");
@@ -75,6 +82,8 @@ public abstract class AbstractProtocolTe
request = HttpRequestWrapper.wrap(new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1));
+ context = HttpCacheContext.create();
+
originResponse = Proxies.enhanceResponse(HttpTestUtils.make200Response());
config = CacheConfig.custom()
@@ -85,7 +94,16 @@ public abstract class AbstractProtocolTe
cache = new BasicHttpCache(config);
mockBackend = EasyMock.createNiceMock(ClientExecChain.class);
mockCache = EasyMock.createNiceMock(HttpCache.class);
- impl = new CachingExec(mockBackend, cache, config);
+ impl = createCachingExecChain(mockBackend, cache, config);
+ }
+
+ protected ClientExecChain createCachingExecChain(final ClientExecChain backend,
+ final HttpCache cache, final CacheConfig config) {
+ return new CachingExec(backend, cache, config);
+ }
+
+ protected boolean supportsRangeAndContentRangeHeaders(final ClientExecChain impl) {
+ return impl instanceof CachingExec && ((CachingExec) impl).supportsRangeAndContentRangeHeaders();
}
protected void replayMocks() {
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java?rev=1494755&r1=1494754&r2=1494755&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/HttpTestUtils.java Wed Jun 19 19:50:02 2013
@@ -244,6 +244,12 @@ public class HttpTestUtils {
r2));
}
+ /* Assert.asserts that two requests are morally equivalent. */
+ public static boolean equivalent(final HttpResponse r1, final HttpResponse r2) {
+ return (equivalent(r1.getStatusLine(), r2.getStatusLine()) && isEndToEndHeaderSubset(r1,
+ r2));
+ }
+
public static byte[] getRandomBytes(final int nbytes) {
final byte[] bytes = new byte[nbytes];
(new Random()).nextBytes(bytes);
Added: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java?rev=1494755&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java Wed Jun 19 19:50:02 2013
@@ -0,0 +1,54 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.client.cache;
+
+import org.apache.http.HttpResponse;
+import org.easymock.IArgumentMatcher;
+
+public class ResponseEquivalent implements IArgumentMatcher {
+
+ private final HttpResponse expected;
+
+ public ResponseEquivalent(final HttpResponse expected) {
+ this.expected = expected;
+ }
+
+ public boolean matches(final Object actual) {
+ if (!(actual instanceof HttpResponse)) {
+ return false;
+ }
+ final HttpResponse other = (HttpResponse) actual;
+ return HttpTestUtils.equivalent(expected, other);
+ }
+
+ public void appendTo(final StringBuffer buf) {
+ buf.append("eqRequest(");
+ buf.append(expected);
+ buf.append(")");
+ }
+
+}
Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ResponseEquivalent.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java?rev=1494755&r1=1494754&r2=1494755&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingExec.java Wed Jun 19 19:50:02 2013
@@ -29,7 +29,6 @@ package org.apache.http.impl.client.cach
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.isNull;
import static org.easymock.EasyMock.same;
@@ -37,58 +36,33 @@ import static org.easymock.classextensio
import static org.easymock.classextension.EasyMock.createNiceMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
import java.io.IOException;
-import java.io.InputStream;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
-import junit.framework.AssertionFailedError;
-
-import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
-import org.apache.http.StatusLine;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.cache.CacheResponseStatus;
-import org.apache.http.client.cache.HttpCacheContext;
import org.apache.http.client.cache.HttpCacheEntry;
-import org.apache.http.client.cache.HttpCacheStorage;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpExecutionAware;
-import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestWrapper;
-import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.client.utils.DateUtils;
import org.apache.http.conn.routing.HttpRoute;
-import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.execchain.ClientExecChain;
-import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicHttpResponse;
-import org.apache.http.util.EntityUtils;
-import org.easymock.Capture;
import org.easymock.IExpectationSetters;
import org.easymock.classextension.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-public class TestCachingExec {
+public class TestCachingExec extends TestCachingExecChain {
private static final String GET_CURRENT_DATE = "getCurrentDate";
@@ -101,68 +75,33 @@ public class TestCachingExec {
private CachingExec impl;
private boolean mockedImpl;
- private CacheValidityPolicy mockValidityPolicy;
- private CacheableRequestPolicy mockRequestPolicy;
- private ClientExecChain mockBackend;
- private HttpCache mockCache;
- private HttpCacheStorage mockStorage;
- private CachedResponseSuitabilityChecker mockSuitabilityChecker;
- private ResponseCachingPolicy mockResponsePolicy;
private CloseableHttpResponse mockBackendResponse;
- private HttpCacheEntry mockCacheEntry;
- private CachedHttpResponseGenerator mockResponseGenerator;
- private ResponseHandler<Object> mockHandler;
- private HttpUriRequest mockUriRequest;
- private CloseableHttpResponse mockCachedResponse;
- private ConditionalRequestBuilder mockConditionalRequestBuilder;
- private HttpRequest mockConditionalRequest;
- private StatusLine mockStatusLine;
- private ResponseProtocolCompliance mockResponseProtocolCompliance;
- private RequestProtocolCompliance mockRequestProtocolCompliance;
- private CacheConfig config;
- private AsynchronousValidator asyncValidator;
private Date requestDate;
private Date responseDate;
- private HttpRoute route;
- private HttpHost host;
- private HttpRequestWrapper request;
- private HttpCacheContext context;
- private HttpCacheEntry entry;
- @SuppressWarnings("unchecked")
@Before
public void setUp() {
- mockRequestPolicy = createNiceMock(CacheableRequestPolicy.class);
- mockValidityPolicy = createNiceMock(CacheValidityPolicy.class);
- mockBackend = createNiceMock(ClientExecChain.class);
- mockCache = createNiceMock(HttpCache.class);
- mockSuitabilityChecker = createNiceMock(CachedResponseSuitabilityChecker.class);
- mockResponsePolicy = createNiceMock(ResponseCachingPolicy.class);
- mockHandler = createNiceMock(ResponseHandler.class);
+ super.setUp();
+
mockBackendResponse = createNiceMock(CloseableHttpResponse.class);
- mockUriRequest = createNiceMock(HttpUriRequest.class);
- mockCacheEntry = createNiceMock(HttpCacheEntry.class);
- mockResponseGenerator = createNiceMock(CachedHttpResponseGenerator.class);
- mockCachedResponse = createNiceMock(CloseableHttpResponse.class);
- mockConditionalRequestBuilder = createNiceMock(ConditionalRequestBuilder.class);
- mockConditionalRequest = createNiceMock(HttpRequest.class);
- mockStatusLine = createNiceMock(StatusLine.class);
- mockResponseProtocolCompliance = createNiceMock(ResponseProtocolCompliance.class);
- mockRequestProtocolCompliance = createNiceMock(RequestProtocolCompliance.class);
- mockStorage = createNiceMock(HttpCacheStorage.class);
- config = CacheConfig.DEFAULT;
- asyncValidator = new AsynchronousValidator(config);
requestDate = new Date(System.currentTimeMillis() - 1000);
responseDate = new Date();
- host = new HttpHost("foo.example.com");
- route = new HttpRoute(host);
- request = HttpRequestWrapper.wrap(
- new BasicHttpRequest("GET", "/stuff", HttpVersion.HTTP_1_1));
- context = HttpCacheContext.create();
- entry = HttpTestUtils.makeCacheEntry();
- impl = new CachingExec(
+ }
+
+ @Override
+ public ClientExecChain createCachingExecChain(final ClientExecChain mockBackend,
+ final HttpCache mockCache, final CacheValidityPolicy mockValidityPolicy,
+ final ResponseCachingPolicy mockResponsePolicy,
+ final CachedHttpResponseGenerator mockResponseGenerator,
+ final CacheableRequestPolicy mockRequestPolicy,
+ final CachedResponseSuitabilityChecker mockSuitabilityChecker,
+ final ConditionalRequestBuilder mockConditionalRequestBuilder,
+ final ResponseProtocolCompliance mockResponseProtocolCompliance,
+ final RequestProtocolCompliance mockRequestProtocolCompliance,
+ final CacheConfig config, final AsynchronousValidator asyncValidator) {
+ return impl = new CachingExec(
mockBackend,
mockCache,
mockValidityPolicy,
@@ -177,140 +116,28 @@ public class TestCachingExec {
asyncValidator);
}
- private void replayMocks() {
- replay(mockRequestPolicy);
- replay(mockValidityPolicy);
- replay(mockSuitabilityChecker);
- replay(mockResponsePolicy);
- replay(mockCacheEntry);
- replay(mockResponseGenerator);
- replay(mockBackend);
- replay(mockCache);
- replay(mockHandler);
+ @Override
+ public ClientExecChain createCachingExecChain(final ClientExecChain backend,
+ final HttpCache cache, final CacheConfig config) {
+ return impl = new CachingExec(backend, cache, config);
+ }
+
+ protected void replayMocks() {
+ super.replayMocks();
replay(mockBackendResponse);
- replay(mockUriRequest);
- replay(mockCachedResponse);
- replay(mockConditionalRequestBuilder);
- replay(mockConditionalRequest);
- replay(mockStatusLine);
- replay(mockResponseProtocolCompliance);
- replay(mockRequestProtocolCompliance);
- replay(mockStorage);
if (mockedImpl) {
replay(impl);
}
}
- private void verifyMocks() {
- verify(mockRequestPolicy);
- verify(mockValidityPolicy);
- verify(mockSuitabilityChecker);
- verify(mockResponsePolicy);
- verify(mockCacheEntry);
- verify(mockResponseGenerator);
- verify(mockBackend);
- verify(mockCache);
- verify(mockHandler);
+ protected void verifyMocks() {
+ super.verifyMocks();
verify(mockBackendResponse);
- verify(mockUriRequest);
- verify(mockCachedResponse);
- verify(mockConditionalRequestBuilder);
- verify(mockConditionalRequest);
- verify(mockStatusLine);
- verify(mockResponseProtocolCompliance);
- verify(mockRequestProtocolCompliance);
- verify(mockStorage);
if (mockedImpl) {
verify(impl);
}
}
- @Test
- public void testCacheableResponsesGoIntoCache() throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
- final HttpResponse resp1 = HttpTestUtils.make200Response();
- resp1.setHeader("Cache-Control","max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
-
- replayMocks();
- impl.execute(route, req1);
- impl.execute(route, req2);
- verifyMocks();
- }
-
- @Test
- public void testOlderCacheableResponsesDoNotGoIntoCache() throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final Date now = new Date();
- final Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
- final HttpResponse resp1 = HttpTestUtils.make200Response();
- resp1.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Cache-Control", "max-age=3600");
- resp1.setHeader("Etag", "\"new-etag\"");
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
- req2.setHeader("Cache-Control","no-cache");
- final HttpResponse resp2 = HttpTestUtils.make200Response();
- resp2.setHeader("ETag", "\"old-etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(fiveSecondsAgo));
- resp2.setHeader("Cache-Control","max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp2);
-
- final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
-
- replayMocks();
- impl.execute(route, req1);
- impl.execute(route, req2);
- final HttpResponse result = impl.execute(route, req3);
- verifyMocks();
-
- assertEquals("\"new-etag\"", result.getFirstHeader("ETag").getValue());
- }
-
- @Test
- public void testNewerCacheableResponsesReplaceExistingCacheEntry() throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final Date now = new Date();
- final Date fiveSecondsAgo = new Date(now.getTime() - 5 * 1000L);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
- final HttpResponse resp1 = HttpTestUtils.make200Response();
- resp1.setHeader("Date", DateUtils.formatDate(fiveSecondsAgo));
- resp1.setHeader("Cache-Control", "max-age=3600");
- resp1.setHeader("Etag", "\"old-etag\"");
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
- req2.setHeader("Cache-Control","max-age=0");
- final HttpResponse resp2 = HttpTestUtils.make200Response();
- resp2.setHeader("ETag", "\"new-etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp2.setHeader("Cache-Control","max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp2);
-
- final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
-
- replayMocks();
- impl.execute(route, req1);
- impl.execute(route, req2);
- final HttpResponse result = impl.execute(route, req3);
- verifyMocks();
-
- assertEquals("\"new-etag\"", result.getFirstHeader("ETag").getValue());
- }
-
@Test
public void testRequestThatCannotBeServedFromCacheCausesBackendRequest() throws Exception {
@@ -328,16 +155,6 @@ public class TestCachingExec {
Assert.assertSame(mockBackendResponse, result);
}
- private void requestIsFatallyNonCompliant(final RequestProtocolError error) {
- final List<RequestProtocolError> errors = new ArrayList<RequestProtocolError>();
- if (error != null) {
- errors.add(error);
- }
- expect(
- mockRequestProtocolCompliance.requestIsFatallyNonCompliant(request)).andReturn(
- errors);
- }
-
@Test
public void testCacheMissCausesBackendRequest() throws Exception {
mockImplMethods(CALL_BACKEND);
@@ -478,23 +295,6 @@ public class TestCachingExec {
}
@Test
- public void testSuitableCacheEntryDoesNotCauseBackendRequest() throws Exception {
- cacheInvalidatorWasCalled();
- requestPolicyAllowsCaching(true);
- getCacheEntryReturns(mockCacheEntry);
- cacheEntrySuitable(true);
- responseIsGeneratedFromCache();
- requestIsFatallyNonCompliant(null);
- entryHasStaleness(0L);
-
- replayMocks();
- final HttpResponse result = impl.execute(route, request, context);
- verifyMocks();
-
- Assert.assertSame(mockCachedResponse, result);
- }
-
- @Test
public void testCallBackendMakesBackEndRequestAndHandlesResponse() throws Exception {
mockImplMethods(GET_CURRENT_DATE, HANDLE_BACKEND_RESPONSE);
final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
@@ -510,1268 +310,6 @@ public class TestCachingExec {
verifyMocks();
}
- @Test
- public void testNonCacheableResponseIsNotCachedAndIsReturnedAsIs() throws Exception {
- final CacheConfig config = CacheConfig.DEFAULT;
- impl = new CachingExec(mockBackend,
- new BasicHttpCache(new HeapResourceFactory(), mockStorage, config),
- config);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(HttpTestUtils.makeDefaultRequest());
- final HttpResponse resp1 = HttpTestUtils.make200Response();
- resp1.setHeader("Cache-Control","no-cache");
-
- expect(mockStorage.getEntry(isA(String.class))).andReturn(null).anyTimes();
- mockStorage.removeEntry(isA(String.class));
- expectLastCall().anyTimes();
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- final HttpResponse result = impl.execute(route, req1);
- verifyMocks();
-
- assertTrue(HttpTestUtils.semanticallyTransparent(resp1, result));
- }
-
- @Test
- public void testResponseIsGeneratedWhenCacheEntryIsUsable() throws Exception {
-
- requestIsFatallyNonCompliant(null);
- cacheInvalidatorWasCalled();
- requestPolicyAllowsCaching(true);
- cacheEntrySuitable(true);
- getCacheEntryReturns(mockCacheEntry);
- responseIsGeneratedFromCache();
- entryHasStaleness(0L);
-
- replayMocks();
- impl.execute(route, request, context);
- verifyMocks();
- }
-
- @Test
- public void testNonCompliantRequestWrapsAndReThrowsProtocolException() throws Exception {
-
- final ClientProtocolException expected = new ClientProtocolException("ouch");
-
- requestIsFatallyNonCompliant(null);
- mockRequestProtocolCompliance.makeRequestCompliant((HttpRequestWrapper)anyObject());
- expectLastCall().andThrow(expected);
-
- boolean gotException = false;
- replayMocks();
- try {
- impl.execute(route, request, context);
- } catch (final ClientProtocolException ex) {
- Assert.assertSame(expected, ex);
- gotException = true;
- }
- verifyMocks();
- Assert.assertTrue(gotException);
- }
-
- @Test
- public void testSetsModuleGeneratedResponseContextForCacheOptionsResponse()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req = HttpRequestWrapper.wrap(new BasicHttpRequest("OPTIONS","*",HttpVersion.HTTP_1_1));
- req.setHeader("Max-Forwards","0");
-
- impl.execute(route, req, context);
- Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
- context.getCacheResponseStatus());
- }
-
- @Test
- public void testSetsModuleGeneratedResponseContextForFatallyNoncompliantRequest()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req.setHeader("Range","bytes=0-50");
- req.setHeader("If-Range","W/\"weak-etag\"");
-
- impl.execute(route, req, context);
- Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
- context.getCacheResponseStatus());
- }
-
- @Test
- public void testRecordsClientProtocolInViaHeaderIfRequestNotServableFromCache()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req = HttpRequestWrapper.wrap(
- new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_0));
- req.setHeader("Cache-Control","no-cache");
- final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content");
- final Capture<HttpRequestWrapper> cap = new Capture<HttpRequestWrapper>();
-
- backendCaptureRequestAndReturn(cap, resp);
-
- replayMocks();
- impl.execute(route, req, context);
- verifyMocks();
-
- final HttpRequest captured = cap.getValue();
- final String via = captured.getFirstHeader("Via").getValue();
- final String proto = via.split("\\s+")[0];
- Assert.assertTrue("http/1.0".equalsIgnoreCase(proto) ||
- "1.0".equalsIgnoreCase(proto));
- }
-
- @Test
- public void testSetsCacheMissContextIfRequestNotServableFromCache()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req.setHeader("Cache-Control","no-cache");
- final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content");
-
- backendExpectsAnyRequestAndReturn(resp);
-
- replayMocks();
- impl.execute(route, req, context);
- verifyMocks();
- Assert.assertEquals(CacheResponseStatus.CACHE_MISS,
- context.getCacheResponseStatus());
- }
-
- @Test
- public void testSetsViaHeaderOnResponseIfRequestNotServableFromCache()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req.setHeader("Cache-Control","no-cache");
- final HttpResponse resp = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content");
-
- backendExpectsAnyRequestAndReturn(resp);
-
- replayMocks();
- final HttpResponse result = impl.execute(route, req);
- verifyMocks();
- Assert.assertNotNull(result.getFirstHeader("Via"));
- }
-
- @Test
- public void testSetsViaHeaderOnResponseForCacheMiss()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(new Date()));
- resp1.setHeader("Cache-Control","public, max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- final HttpResponse result = impl.execute(route, req1);
- verifyMocks();
- Assert.assertNotNull(result.getFirstHeader("Via"));
- }
-
- @Test
- public void testSetsCacheHitContextIfRequestServedFromCache()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(new Date()));
- resp1.setHeader("Cache-Control","public, max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- impl.execute(route, req1);
- impl.execute(route, req2, context);
- verifyMocks();
- Assert.assertEquals(CacheResponseStatus.CACHE_HIT,
- context.getCacheResponseStatus());
- }
-
- @Test
- public void testSetsViaHeaderOnResponseIfRequestServedFromCache()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(new Date()));
- resp1.setHeader("Cache-Control","public, max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertNotNull(result.getFirstHeader("Via"));
- }
-
- @Test
- public void testReturns304ForIfModifiedSinceHeaderIfRequestServedFromCache()
- throws Exception {
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req2.addHeader("If-Modified-Since", DateUtils.formatDate(now));
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=3600");
- resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testReturns304ForIfModifiedSinceHeaderIf304ResponseInCache() throws Exception {
- final Date now = new Date();
- final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L);
- final Date inTenMinutes = new Date(now.getTime() + 600 * 1000L);
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req1.addHeader("If-Modified-Since", DateUtils.formatDate(oneHourAgo));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req2.addHeader("If-Modified-Since", DateUtils.formatDate(oneHourAgo));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified");
- resp1.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Cache-control", "max-age=600");
- resp1.setHeader("Expires", DateUtils.formatDate(inTenMinutes));
-
- expect(mockBackend.execute(
- same(route),
- isA(HttpRequestWrapper.class),
- isA(HttpClientContext.class),
- (HttpExecutionAware) isNull())).andReturn(Proxies.enhanceResponse(resp1)).once();
-
- expect(mockBackend.execute(
- same(route),
- isA(HttpRequestWrapper.class),
- isA(HttpClientContext.class),
- (HttpExecutionAware) isNull())).andThrow(
- new AssertionFailedError("Should have reused cached 304 response")).anyTimes();
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
- Assert.assertFalse(result.containsHeader("Last-Modified"));
- }
-
- @Test
- public void testReturns200ForIfModifiedSinceDateIsLess() throws Exception {
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(new Date()));
- resp1.setHeader("Cache-Control", "public, max-age=3600");
- resp1.setHeader("Last-Modified", DateUtils.formatDate(new Date()));
-
- // The variant has been modified since this date
- req2.addHeader("If-Modified-Since", DateUtils
- .formatDate(tenSecondsAgo));
-
- final HttpResponse resp2 = HttpTestUtils.make200Response();
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testReturns200ForIfModifiedSinceDateIsInvalid()
- throws Exception {
- final Date now = new Date();
- final Date tenSecondsAfter = new Date(now.getTime() + 10 * 1000L);
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(new Date()));
- resp1.setHeader("Cache-Control", "public, max-age=3600");
- resp1.setHeader("Last-Modified", DateUtils.formatDate(new Date()));
-
- // invalid date (date in the future)
- req2.addHeader("If-Modified-Since", DateUtils
- .formatDate(tenSecondsAfter));
-
- backendExpectsAnyRequestAndReturn(resp1).times(2);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testReturns304ForIfNoneMatchHeaderIfRequestServedFromCache()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req2.addHeader("If-None-Match", "*");
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(new Date()));
- resp1.setHeader("Cache-Control", "public, max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testReturns200ForIfNoneMatchHeaderFails() throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(new Date()));
- resp1.setHeader("Cache-Control", "public, max-age=3600");
-
- req2.addHeader("If-None-Match", "\"abc\"");
-
- final HttpResponse resp2 = HttpTestUtils.make200Response();
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(200, result.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testReturns304ForIfNoneMatchHeaderAndIfModifiedSinceIfRequestServedFromCache()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=3600");
- resp1.setHeader("Last-Modified", DateUtils.formatDate(new Date()));
-
- req2.addHeader("If-None-Match", "*");
- req2.addHeader("If-Modified-Since", DateUtils.formatDate(now));
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testReturns200ForIfNoneMatchHeaderFailsIfModifiedSinceIgnored()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req2.addHeader("If-None-Match", "\"abc\"");
- req2.addHeader("If-Modified-Since", DateUtils.formatDate(now));
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=3600");
- resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
- Assert.assertEquals(200, result.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testSetsValidatedContextIfRequestWasSuccessfullyValidated()
- throws Exception {
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control","public, max-age=5");
-
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp2.setEntity(HttpTestUtils.makeBody(128));
- resp2.setHeader("Content-Length","128");
- resp2.setHeader("ETag","\"etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp2.setHeader("Cache-Control","public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
-
- replayMocks();
- impl.execute(route, req1);
- impl.execute(route, req2, context);
- verifyMocks();
- Assert.assertEquals(CacheResponseStatus.VALIDATED,
- context.getCacheResponseStatus());
- }
-
- @Test
- public void testSetsViaHeaderIfRequestWasSuccessfullyValidated()
- throws Exception {
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control","public, max-age=5");
-
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp2.setEntity(HttpTestUtils.makeBody(128));
- resp2.setHeader("Content-Length","128");
- resp2.setHeader("ETag","\"etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp2.setHeader("Cache-Control","public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2, context);
- verifyMocks();
- Assert.assertNotNull(result.getFirstHeader("Via"));
- }
-
-
- @Test
- public void testSetsModuleResponseContextIfValidationRequiredButFailed()
- throws Exception {
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control","public, max-age=5, must-revalidate");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndThrows(new IOException());
-
- replayMocks();
- impl.execute(route, req1);
- impl.execute(route, req2, context);
- verifyMocks();
- Assert.assertEquals(CacheResponseStatus.CACHE_MODULE_RESPONSE,
- context.getCacheResponseStatus());
- }
-
- @Test
- public void testSetsModuleResponseContextIfValidationFailsButNotRequired()
- throws Exception {
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control","public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndThrows(new IOException());
-
- replayMocks();
- impl.execute(route, req1);
- impl.execute(route, req2, context);
- verifyMocks();
- Assert.assertEquals(CacheResponseStatus.CACHE_HIT,
- context.getCacheResponseStatus());
- }
-
- @Test
- public void testSetViaHeaderIfValidationFailsButNotRequired()
- throws Exception {
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length","128");
- resp1.setHeader("ETag","\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control","public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndThrows(new IOException());
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2, context);
- verifyMocks();
- Assert.assertNotNull(result.getFirstHeader("Via"));
- }
-
- @Test
- public void testReturns304ForIfNoneMatchPassesIfRequestServedFromOrigin()
- throws Exception {
-
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=5");
-
- req2.addHeader("If-None-Match", "\"etag\"");
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_NOT_MODIFIED, "Not Modified");
- resp2.setHeader("ETag", "\"etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp2.setHeader("Cache-Control", "public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
-
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testReturns200ForIfNoneMatchFailsIfRequestServedFromOrigin()
- throws Exception {
-
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=5");
-
- req2.addHeader("If-None-Match", "\"etag\"");
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp2.setEntity(HttpTestUtils.makeBody(128));
- resp2.setHeader("Content-Length", "128");
- resp2.setHeader("ETag", "\"newetag\"");
- resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp2.setHeader("Cache-Control", "public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
-
- Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testReturns304ForIfModifiedSincePassesIfRequestServedFromOrigin()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=5");
-
- req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo));
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_NOT_MODIFIED, "Not Modified");
- resp2.setHeader("ETag", "\"etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
- resp2.setHeader("Cache-Control", "public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
-
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testReturns200ForIfModifiedSinceFailsIfRequestServedFromOrigin()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Last-Modified", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=5");
-
- req2.addHeader("If-Modified-Since", DateUtils.formatDate(tenSecondsAgo));
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp2.setEntity(HttpTestUtils.makeBody(128));
- resp2.setHeader("Content-Length", "128");
- resp2.setHeader("ETag", "\"newetag\"");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Last-Modified", DateUtils.formatDate(now));
- resp2.setHeader("Cache-Control", "public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
-
- replayMocks();
- impl.execute(route, req1);
- final HttpResponse result = impl.execute(route, req2);
- verifyMocks();
-
- Assert.assertEquals(HttpStatus.SC_OK, result.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testVariantMissServerIfReturns304CacheReturns200() throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final Date now = new Date();
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req1.addHeader("Accept-Encoding", "gzip");
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("Etag", "\"gzip_etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Vary", "Accept-Encoding");
- resp1.setHeader("Cache-Control", "public, max-age=3600");
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req2.addHeader("Accept-Encoding", "deflate");
-
- final HttpRequestWrapper req2Server = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req2Server.addHeader("Accept-Encoding", "deflate");
- req2Server.addHeader("If-None-Match", "\"gzip_etag\"");
-
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp2.setEntity(HttpTestUtils.makeBody(128));
- resp2.setHeader("Content-Length", "128");
- resp2.setHeader("Etag", "\"deflate_etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp2.setHeader("Vary", "Accept-Encoding");
- resp2.setHeader("Cache-Control", "public, max-age=3600");
-
- final HttpRequestWrapper req3 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req3.addHeader("Accept-Encoding", "gzip,deflate");
-
- final HttpRequestWrapper req3Server = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req3Server.addHeader("Accept-Encoding", "gzip,deflate");
- req3Server.addHeader("If-None-Match", "\"gzip_etag\",\"deflate_etag\"");
-
- final HttpResponse resp3 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp3.setEntity(HttpTestUtils.makeBody(128));
- resp3.setHeader("Content-Length", "128");
- resp3.setHeader("Etag", "\"gzip_etag\"");
- resp3.setHeader("Date", DateUtils.formatDate(now));
- resp3.setHeader("Vary", "Accept-Encoding");
- resp3.setHeader("Cache-Control", "public, max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
- backendExpectsAnyRequestAndReturn(resp3);
-
- replayMocks();
- final HttpResponse result1 = impl.execute(route, req1);
-
- final HttpResponse result2 = impl.execute(route, req2);
-
- final HttpResponse result3 = impl.execute(route, req3);
-
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_OK, result1.getStatusLine().getStatusCode());
- Assert.assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode());
- Assert.assertEquals(HttpStatus.SC_OK, result3.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testVariantsMissServerReturns304CacheReturns304() throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
- final Date now = new Date();
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req1.addHeader("Accept-Encoding", "gzip");
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp1.setEntity(HttpTestUtils.makeBody(128));
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("Etag", "\"gzip_etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Vary", "Accept-Encoding");
- resp1.setHeader("Cache-Control", "public, max-age=3600");
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req2.addHeader("Accept-Encoding", "deflate");
-
- final HttpRequestWrapper req2Server = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req2Server.addHeader("Accept-Encoding", "deflate");
- req2Server.addHeader("If-None-Match", "\"gzip_etag\"");
-
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
- resp2.setEntity(HttpTestUtils.makeBody(128));
- resp2.setHeader("Content-Length", "128");
- resp2.setHeader("Etag", "\"deflate_etag\"");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp2.setHeader("Vary", "Accept-Encoding");
- resp2.setHeader("Cache-Control", "public, max-age=3600");
-
- final HttpRequestWrapper req4 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req4.addHeader("Accept-Encoding", "gzip,identity");
- req4.addHeader("If-None-Match", "\"gzip_etag\"");
-
- final HttpRequestWrapper req4Server = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com"));
- req4Server.addHeader("Accept-Encoding", "gzip,identity");
- req4Server.addHeader("If-None-Match", "\"gzip_etag\"");
-
- final HttpResponse resp4 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not Modified");
- resp4.setHeader("Etag", "\"gzip_etag\"");
- resp4.setHeader("Date", DateUtils.formatDate(now));
- resp4.setHeader("Vary", "Accept-Encoding");
- resp4.setHeader("Cache-Control", "public, max-age=3600");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
- backendExpectsAnyRequestAndReturn(resp4);
-
- replayMocks();
- final HttpResponse result1 = impl.execute(route, req1);
-
- final HttpResponse result2 = impl.execute(route, req2);
-
- final HttpResponse result4 = impl.execute(route, req4);
- verifyMocks();
- Assert.assertEquals(HttpStatus.SC_OK, result1.getStatusLine().getStatusCode());
- Assert.assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode());
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, result4.getStatusLine().getStatusCode());
-
- }
-
- @Test
- public void testSocketTimeoutExceptionIsNotSilentlyCatched()
- throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(),
- CacheConfig.DEFAULT);
- final Date now = new Date();
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
- "http://foo.example.com"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_OK, "OK");
- resp1.setEntity(new InputStreamEntity(new InputStream() {
- private boolean closed = false;
-
- @Override
- public void close() throws IOException {
- closed = true;
- }
-
- @Override
- public int read() throws IOException {
- if (closed) {
- throw new SocketException("Socket closed");
- }
- throw new SocketTimeoutException("Read timed out");
- }
- }, 128));
- resp1.setHeader("Date", DateUtils.formatDate(now));
-
- backendExpectsAnyRequestAndReturn(resp1);
-
- replayMocks();
- try {
- final HttpResponse result1 = impl.execute(route, req1);
- EntityUtils.toString(result1.getEntity());
- Assert.fail("We should have had a SocketTimeoutException");
- } catch (final SocketTimeoutException e) {
- }
- verifyMocks();
-
- }
-
- @Test
- public void testIsSharedCache() {
- Assert.assertTrue(config.isSharedCache());
- }
-
- @Test
- public void testTreatsCacheIOExceptionsAsCacheMiss()
- throws Exception {
-
- impl = new CachingExec(mockBackend, mockCache, CacheConfig.DEFAULT);
- final CloseableHttpResponse resp = Proxies.enhanceResponse(HttpTestUtils.make200Response());
-
- mockCache.flushInvalidatedCacheEntriesFor(host, request);
- expectLastCall().andThrow(new IOException()).anyTimes();
- mockCache.flushInvalidatedCacheEntriesFor(isA(HttpHost.class), isA(HttpRequest.class), isA(HttpResponse.class));
- expectLastCall().anyTimes();
- expect(mockCache.getCacheEntry(same(host),
- isA(HttpRequest.class)))
- .andThrow(new IOException()).anyTimes();
- expect(mockCache.getVariantCacheEntriesWithEtags(same(host),
- isA(HttpRequest.class)))
- .andThrow(new IOException()).anyTimes();
- expect(mockCache.cacheAndReturnResponse(same(host),
- isA(HttpRequest.class), isA(HttpResponse.class),
- isA(Date.class), isA(Date.class)))
- .andReturn(resp).anyTimes();
- expect(mockBackend.execute(
- same(route),
- isA(HttpRequestWrapper.class),
- isA(HttpClientContext.class),
- (HttpExecutionAware) isNull())).andReturn(resp);
-
- replayMocks();
- final HttpResponse result = impl.execute(route, request);
- verifyMocks();
- Assert.assertSame(resp, result);
- }
-
- @Test
- public void testIfOnlyIfCachedAndNoCacheEntryBackendNotCalled() throws Exception {
- impl = new CachingExec(mockBackend, new BasicHttpCache(), CacheConfig.DEFAULT);
-
- request.addHeader("Cache-Control", "only-if-cached");
-
- final HttpResponse resp = impl.execute(route, request);
-
- Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testIfOnlyIfCachedAndEntryNotSuitableBackendNotCalled() throws Exception {
-
- request.setHeader("Cache-Control", "only-if-cached");
-
- entry = HttpTestUtils.makeCacheEntry(new Header[]{new BasicHeader("Cache-Control", "must-revalidate")});
-
- requestIsFatallyNonCompliant(null);
- cacheInvalidatorWasCalled();
- requestPolicyAllowsCaching(true);
- getCacheEntryReturns(entry);
- cacheEntrySuitable(false);
-
- replayMocks();
- final HttpResponse resp = impl.execute(route, request);
- verifyMocks();
-
- Assert.assertEquals(HttpStatus.SC_GATEWAY_TIMEOUT, resp.getStatusLine().getStatusCode());
- }
-
- @Test
- public void testIfOnlyIfCachedAndEntryExistsAndIsSuitableReturnsEntry() throws Exception {
-
- request.setHeader("Cache-Control", "only-if-cached");
-
- requestIsFatallyNonCompliant(null);
- cacheInvalidatorWasCalled();
- requestPolicyAllowsCaching(true);
- getCacheEntryReturns(entry);
- cacheEntrySuitable(true);
- responseIsGeneratedFromCache();
- entryHasStaleness(0);
-
- replayMocks();
- final HttpResponse resp = impl.execute(route, request);
- verifyMocks();
-
- Assert.assertSame(mockCachedResponse, resp);
- }
-
- @Test
- public void testDoesNotSetConnectionInContextOnCacheHit() throws Exception {
- final DummyBackend backend = new DummyBackend();
- final HttpResponse response = HttpTestUtils.make200Response();
- response.setHeader("Cache-Control", "max-age=3600");
- backend.setResponse(response);
- impl = new CachingExec(backend);
- final HttpClientContext ctx = HttpClientContext.create();
- impl.execute(route, request);
- impl.execute(route, request, ctx);
- assertNull(ctx.getConnection());
- }
-
- @Test
- public void testSetsTargetHostInContextOnCacheHit() throws Exception {
- final DummyBackend backend = new DummyBackend();
- final HttpResponse response = HttpTestUtils.make200Response();
- response.setHeader("Cache-Control", "max-age=3600");
- backend.setResponse(response);
- impl = new CachingExec(backend);
- final HttpClientContext ctx = HttpClientContext.create();
- impl.execute(route, request);
- impl.execute(route, request, ctx);
- assertSame(host, ctx.getTargetHost());
- }
-
- @Test
- public void testSetsRouteInContextOnCacheHit() throws Exception {
- final DummyBackend backend = new DummyBackend();
- final HttpResponse response = HttpTestUtils.make200Response();
- response.setHeader("Cache-Control", "max-age=3600");
- backend.setResponse(response);
- impl = new CachingExec(backend);
- final HttpClientContext ctx = HttpClientContext.create();
- impl.execute(route, request);
- impl.execute(route, request, ctx);
- assertSame(route, ctx.getHttpRoute());
- }
-
- @Test
- public void testSetsRequestInContextOnCacheHit() throws Exception {
- final DummyBackend backend = new DummyBackend();
- final HttpResponse response = HttpTestUtils.make200Response();
- response.setHeader("Cache-Control", "max-age=3600");
- backend.setResponse(response);
- impl = new CachingExec(backend);
- final HttpClientContext ctx = HttpClientContext.create();
- impl.execute(route, request);
- impl.execute(route, request, ctx);
- assertSame(request, ctx.getRequest());
- }
-
- @Test
- public void testSetsResponseInContextOnCacheHit() throws Exception {
- final DummyBackend backend = new DummyBackend();
- final HttpResponse response = HttpTestUtils.make200Response();
- response.setHeader("Cache-Control", "max-age=3600");
- backend.setResponse(response);
- impl = new CachingExec(backend);
- final HttpClientContext ctx = HttpClientContext.create();
- impl.execute(route, request);
- final HttpResponse result = impl.execute(route, request, ctx);
- assertSame(result, ctx.getResponse());
- }
-
- @Test
- public void testSetsRequestSentInContextOnCacheHit() throws Exception {
- final DummyBackend backend = new DummyBackend();
- final HttpResponse response = HttpTestUtils.make200Response();
- response.setHeader("Cache-Control", "max-age=3600");
- backend.setResponse(response);
- impl = new CachingExec(backend);
- final HttpClientContext ctx = HttpClientContext.create();
- impl.execute(route, request);
- impl.execute(route, request, ctx);
- assertTrue(ctx.isRequestSent());
- }
-
- @Test
- public void testCanCacheAResponseWithoutABody() throws Exception {
- final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, "No Content");
- response.setHeader("Date", DateUtils.formatDate(new Date()));
- response.setHeader("Cache-Control","max-age=300");
- final DummyBackend backend = new DummyBackend();
- backend.setResponse(response);
- impl = new CachingExec(backend);
- impl.execute(route, request);
- impl.execute(route, request);
- assertEquals(1, backend.getExecutions());
- }
-
- @Test
- public void testNoEntityForIfNoneMatchRequestNotYetInCache() throws Exception {
-
- final Date now = new Date();
- final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(),
- CacheConfig.DEFAULT);
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet(
- "http://foo.example.com/"));
- req1.addHeader("If-None-Match", "\"etag\"");
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
- HttpStatus.SC_NOT_MODIFIED, "Not modified");
- resp1.setHeader("Content-Length", "128");
- resp1.setHeader("ETag", "\"etag\"");
- resp1.setHeader("Date", DateUtils.formatDate(tenSecondsAgo));
- resp1.setHeader("Cache-Control", "public, max-age=5");
-
- backendExpectsAnyRequestAndReturn(resp1);
- replayMocks();
- final HttpResponse result = impl.execute(route, req1);
- verifyMocks();
-
- assertEquals(HttpStatus.SC_NOT_MODIFIED, result.getStatusLine()
- .getStatusCode());
- assertNull("The 304 response messages MUST NOT contain a message-body",
- result.getEntity());
- }
-
- @Test
- public void testNotModifiedResponseUpdatesCacheEntryWhenNoEntity() throws Exception {
-
- final Date now = new Date();
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(),CacheConfig.DEFAULT);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req1.addHeader("If-None-Match", "etag");
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req2.addHeader("If-None-Match", "etag");
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified");
- resp1.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Cache-Control","max-age=0");
- resp1.setHeader("Etag", "etag");
-
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp2.setHeader("Cache-Control","max-age=0");
- resp1.setHeader("Etag", "etag");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
- replayMocks();
- final HttpResponse result1 = impl.execute(route, req1);
- final HttpResponse result2 = impl.execute(route, req2);
- verifyMocks();
-
- assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode());
- assertEquals("etag", result1.getFirstHeader("Etag").getValue());
- assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getStatusLine().getStatusCode());
- assertEquals("etag", result2.getFirstHeader("Etag").getValue());
- }
-
- @Test
- public void testNotModifiedResponseWithVaryUpdatesCacheEntryWhenNoEntity() throws Exception {
-
- final Date now = new Date();
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(),CacheConfig.DEFAULT);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req1.addHeader("If-None-Match", "etag");
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req2.addHeader("If-None-Match", "etag");
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified");
- resp1.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Cache-Control","max-age=0");
- resp1.setHeader("Etag", "etag");
- resp1.setHeader("Vary", "Accept-Encoding");
-
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp2.setHeader("Cache-Control","max-age=0");
- resp1.setHeader("Etag", "etag");
- resp1.setHeader("Vary", "Accept-Encoding");
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2);
- replayMocks();
- final HttpResponse result1 = impl.execute(route, req1);
- final HttpResponse result2 = impl.execute(route, req2);
- verifyMocks();
-
- assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode());
- assertEquals("etag", result1.getFirstHeader("Etag").getValue());
- assertEquals(HttpStatus.SC_NOT_MODIFIED, result2.getStatusLine().getStatusCode());
- assertEquals("etag", result2.getFirstHeader("Etag").getValue());
- }
-
- @Test
- public void testDoesNotSend304ForNonConditionalRequest() throws Exception {
-
- final Date now = new Date();
- final Date inOneMinute = new Date(System.currentTimeMillis()+60000);
-
- impl = new CachingExec(mockBackend, new BasicHttpCache(),CacheConfig.DEFAULT);
-
- final HttpRequestWrapper req1 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
- req1.addHeader("If-None-Match", "etag");
-
- final HttpRequestWrapper req2 = HttpRequestWrapper.wrap(new HttpGet("http://foo.example.com/"));
-
- final HttpResponse resp1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_NOT_MODIFIED, "Not modified");
- resp1.setHeader("Date", DateUtils.formatDate(now));
- resp1.setHeader("Cache-Control","public, max-age=60");
- resp1.setHeader("Expires",DateUtils.formatDate(inOneMinute));
- resp1.setHeader("Etag", "etag");
- resp1.setHeader("Vary", "Accept-Encoding");
-
- final HttpResponse resp2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "Ok");
- resp2.setHeader("Date", DateUtils.formatDate(now));
- resp2.setHeader("Cache-Control","public, max-age=60");
- resp2.setHeader("Expires",DateUtils.formatDate(inOneMinute));
- resp2.setHeader("Etag", "etag");
- resp2.setHeader("Vary", "Accept-Encoding");
- resp2.setEntity(HttpTestUtils.makeBody(128));
-
- backendExpectsAnyRequestAndReturn(resp1);
- backendExpectsAnyRequestAndReturn(resp2).anyTimes();
- replayMocks();
- final HttpResponse result1 = impl.execute(route, req1);
- final HttpResponse result2 = impl.execute(route, req2);
- verifyMocks();
-
- assertEquals(HttpStatus.SC_NOT_MODIFIED, result1.getStatusLine().getStatusCode());
- assertNull(result1.getEntity());
- assertEquals(HttpStatus.SC_OK, result2.getStatusLine().getStatusCode());
- Assert.assertNotNull(result2.getEntity());
- }
-
- private IExpectationSetters<CloseableHttpResponse> backendExpectsAnyRequestAndReturn(
- final HttpResponse response) throws Exception {
- final CloseableHttpResponse resp = mockBackend.execute(
- EasyMock.isA(HttpRoute.class),
- EasyMock.isA(HttpRequestWrapper.class),
- EasyMock.isA(HttpClientContext.class),
- EasyMock.<HttpExecutionAware>isNull());
- return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response));
- }
-
private IExpectationSetters<CloseableHttpResponse> implExpectsAnyRequestAndReturn(
final CloseableHttpResponse response) throws Exception {
final CloseableHttpResponse resp = impl.callBackend(
@@ -1782,50 +320,6 @@ public class TestCachingExec {
return EasyMock.expect(resp).andReturn(response);
}
- private IExpectationSetters<CloseableHttpResponse> backendExpectsRequestAndReturn(
- final HttpRequestWrapper request, final HttpResponse response) throws Exception {
- final CloseableHttpResponse resp = mockBackend.execute(
- EasyMock.isA(HttpRoute.class),
- EasyMock.eq(request),
- EasyMock.isA(HttpClientContext.class),
- EasyMock.<HttpExecutionAware>isNull());
- return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response));
- }
-
- private IExpectationSetters<CloseableHttpResponse> backendExpectsRequestAndReturn(
- final HttpRequestWrapper request, final CloseableHttpResponse response) throws Exception {
- final CloseableHttpResponse resp = mockBackend.execute(
- EasyMock.isA(HttpRoute.class),
- EasyMock.eq(request),
- EasyMock.isA(HttpClientContext.class),
- EasyMock.<HttpExecutionAware>isNull());
- return EasyMock.expect(resp).andReturn(response);
- }
-
- private IExpectationSetters<CloseableHttpResponse> backendExpectsAnyRequestAndThrows(
- final Throwable throwable) throws Exception {
- final CloseableHttpResponse resp = mockBackend.execute(
- EasyMock.isA(HttpRoute.class),
- EasyMock.isA(HttpRequestWrapper.class),
- EasyMock.isA(HttpClientContext.class),
- EasyMock.<HttpExecutionAware>isNull());
- return EasyMock.expect(resp).andThrow(throwable);
- }
-
- private IExpectationSetters<CloseableHttpResponse> backendCaptureRequestAndReturn(
- final Capture<HttpRequestWrapper> cap, final HttpResponse response) throws Exception {
- final CloseableHttpResponse resp = mockBackend.execute(
- EasyMock.isA(HttpRoute.class),
- EasyMock.capture(cap),
- EasyMock.isA(HttpClientContext.class),
- EasyMock.<HttpExecutionAware>isNull());
- return EasyMock.expect(resp).andReturn(Proxies.enhanceResponse(response));
- }
-
- private void getCacheEntryReturns(final HttpCacheEntry result) throws IOException {
- expect(mockCache.getCacheEntry(host, request)).andReturn(result);
- }
-
private void getVariantCacheEntriesReturns(final Map<String,Variant> result) throws IOException {
expect(mockCache.getVariantCacheEntriesWithEtags(host, request)).andReturn(result);
}
@@ -1836,62 +330,10 @@ public class TestCachingExec {
(HttpRequest)anyObject());
}
- private void cacheEntryValidatable(final boolean b) {
- expect(mockValidityPolicy.isRevalidatable(
- (HttpCacheEntry)anyObject())).andReturn(b);
- }
-
- private void cacheEntryMustRevalidate(final boolean b) {
- expect(mockValidityPolicy.mustRevalidate(mockCacheEntry))
- .andReturn(b);
- }
-
- private void cacheEntryProxyRevalidate(final boolean b) {
- expect(mockValidityPolicy.proxyRevalidate(mockCacheEntry))
- .andReturn(b);
- }
-
- private void mayReturnStaleWhileRevalidating(final boolean b) {
- expect(mockValidityPolicy.mayReturnStaleWhileRevalidating(
- (HttpCacheEntry)anyObject(), (Date)anyObject())).andReturn(b);
- }
-
- private void conditionalRequestBuilderReturns(final HttpRequestWrapper validate)
- throws Exception {
- expect(mockConditionalRequestBuilder.buildConditionalRequest(
- request, entry)).andReturn(validate);
-}
-
private void getCurrentDateReturns(final Date date) {
expect(impl.getCurrentDate()).andReturn(date);
}
- private void requestPolicyAllowsCaching(final boolean allow) {
- expect(mockRequestPolicy.isServableFromCache(
- (HttpRequest)anyObject())).andReturn(allow);
- }
-
- private void cacheEntrySuitable(final boolean suitable) {
- expect(
- mockSuitabilityChecker.canCachedResponseBeUsed(
- (HttpHost)anyObject(),
- (HttpRequest)anyObject(),
- (HttpCacheEntry)anyObject(),
- (Date)anyObject())).andReturn(suitable);
- }
-
- private void entryHasStaleness(final long staleness) {
- expect(mockValidityPolicy.getStalenessSecs(
- (HttpCacheEntry)anyObject(),
- (Date)anyObject()
- )).andReturn(staleness);
- }
-
- private void responseIsGeneratedFromCache() {
- expect(mockResponseGenerator.generateResponse(
- (HttpCacheEntry)anyObject())).andReturn(mockCachedResponse);
- }
-
private void handleBackendResponseReturnsResponse(final HttpRequestWrapper request, final HttpResponse response)
throws IOException {
expect(