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 2010/09/15 22:00:42 UTC

svn commit: r997480 [1/2] - in /httpcomponents/httpclient/trunk/httpclient-cache/src: main/java/org/apache/http/client/cache/ main/java/org/apache/http/impl/client/cache/ test/java/org/apache/http/client/ test/java/org/apache/http/client/cache/ test/ja...

Author: olegk
Date: Wed Sep 15 20:00:41 2010
New Revision: 997480

URL: http://svn.apache.org/viewvc?rev=997480&view=rev
Log:
HTTPCLIENT-994: cache does not allow client to override origin-specified freshness using max-stale
Contributed by Jonathan Moore <jonathan_moore at comcast.com>

Added:
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java   (with props)
Removed:
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/CacheEntry.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntry.java
Modified:
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.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/TestBasicHttpCache.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.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/TestURIExtractor.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java
    httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/client/cache/HttpCacheEntry.java Wed Sep 15 20:00:41 2010
@@ -26,9 +26,6 @@
  */
 package org.apache.http.client.cache;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.Date;
@@ -40,7 +37,6 @@ import org.apache.http.HttpResponse;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.StatusLine;
 import org.apache.http.annotation.Immutable;
-import org.apache.http.message.BasicHeader;
 import org.apache.http.message.HeaderGroup;
 
 /**
@@ -157,43 +153,6 @@ public class HttpCacheEntry implements S
         return this.resource;
     }
 
-    private void writeObject(ObjectOutputStream out) throws IOException {
-
-        // write CacheEntry
-        out.defaultWriteObject();
-
-        // write (non-serializable) responseHeaders
-        if (null == responseHeaders || responseHeaders.getAllHeaders().length < 1)
-            return;
-        int headerCount = responseHeaders.getAllHeaders().length;
-        Header[] headers = responseHeaders.getAllHeaders();
-        String[][] sheaders = new String[headerCount][2];
-        for (int i = 0; i < headerCount; i++) {
-            sheaders[i][0] = headers[i].getName();
-            sheaders[i][1] = headers[i].getValue();
-        }
-        out.writeObject(sheaders);
-
-    }
-
-    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-
-        // read CacheEntry
-        in.defaultReadObject();
-
-        // read (non-serializable) responseHeaders
-        String[][] sheaders = (String[][]) in.readObject();
-        if (null == sheaders || sheaders.length < 1)
-            return;
-        BasicHeader[] headers = new BasicHeader[sheaders.length];
-        for (int i = 0; i < sheaders.length; i++) {
-            String[] sheader = sheaders[i];
-            headers[i] = new BasicHeader(sheader[0], sheader[1]);
-        }
-
-        this.responseHeaders.setHeaders(headers);
-    }
-
     @Override
     public String toString() {
         return "[request date=" + this.requestDate + "; response date=" + this.responseDate

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheValidityPolicy.java Wed Sep 15 20:00:41 2010
@@ -49,8 +49,8 @@ class CacheValidityPolicy {
         super();
     }
 
-    public long getCurrentAgeSecs(final HttpCacheEntry entry) {
-        return getCorrectedInitialAgeSecs(entry) + getResidentTimeSecs(entry);
+    public long getCurrentAgeSecs(final HttpCacheEntry entry, Date now) {
+        return getCorrectedInitialAgeSecs(entry) + getResidentTimeSecs(entry, now);
     }
 
     public long getFreshnessLifetimeSecs(final HttpCacheEntry entry) {
@@ -69,8 +69,8 @@ class CacheValidityPolicy {
         return (diff / 1000);
     }
 
-    public boolean isResponseFresh(final HttpCacheEntry entry) {
-        return (getCurrentAgeSecs(entry) < getFreshnessLifetimeSecs(entry));
+    public boolean isResponseFresh(final HttpCacheEntry entry, Date now) {
+        return (getCurrentAgeSecs(entry, now) < getFreshnessLifetimeSecs(entry));
     }
 
     public boolean isRevalidatable(final HttpCacheEntry entry) {
@@ -166,8 +166,8 @@ class CacheValidityPolicy {
         return new Date();
     }
 
-    protected long getResidentTimeSecs(final HttpCacheEntry entry) {
-        long diff = getCurrentDate().getTime() - entry.getResponseDate().getTime();
+    protected long getResidentTimeSecs(HttpCacheEntry entry, Date now) {
+        long diff = now.getTime() - entry.getResponseDate().getTime();
         return (diff / 1000L);
     }
 
@@ -204,7 +204,8 @@ class CacheValidityPolicy {
         return null;
     }
 
-    protected boolean hasCacheControlDirective(final HttpCacheEntry entry, final String directive) {
+    public boolean hasCacheControlDirective(final HttpCacheEntry entry,
+            final String directive) {
         for (Header h : entry.getHeaders("Cache-Control")) {
             for(HeaderElement elt : h.getElements()) {
                 if (directive.equalsIgnoreCase(elt.getName())) {
@@ -215,4 +216,12 @@ class CacheValidityPolicy {
         return false;
     }
 
+    public long getStalenessSecs(HttpCacheEntry entry, Date now) {
+        long age = getCurrentAgeSecs(entry, now);
+        long freshness = getFreshnessLifetimeSecs(entry);
+        if (age <= freshness) return 0L;
+        return (age - freshness);
+    }
+
+
 }

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedHttpResponseGenerator.java Wed Sep 15 20:00:41 2010
@@ -26,6 +26,8 @@
  */
 package org.apache.http.impl.client.cache;
 
+import java.util.Date;
+
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -66,6 +68,7 @@ class CachedHttpResponseGenerator {
      */
     HttpResponse generateResponse(HttpCacheEntry entry) {
 
+        Date now = new Date();
         HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, entry
                 .getStatusCode(), entry.getReasonPhrase());
 
@@ -76,7 +79,7 @@ class CachedHttpResponseGenerator {
             response.setEntity(entity);
         }
 
-        long age = this.validityStrategy.getCurrentAgeSecs(entry);
+        long age = this.validityStrategy.getCurrentAgeSecs(entry, now);
         if (age > 0) {
             if (age >= Integer.MAX_VALUE) {
                 response.setHeader(HeaderConstants.AGE, "2147483648");

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachedResponseSuitabilityChecker.java Wed Sep 15 20:00:41 2010
@@ -51,15 +51,59 @@ class CachedResponseSuitabilityChecker {
 
     private final Log log = LogFactory.getLog(getClass());
 
+    private final boolean sharedCache;
     private final CacheValidityPolicy validityStrategy;
 
-    CachedResponseSuitabilityChecker(final CacheValidityPolicy validityStrategy) {
+    CachedResponseSuitabilityChecker(final CacheValidityPolicy validityStrategy,
+            CacheConfig config) {
         super();
         this.validityStrategy = validityStrategy;
+        this.sharedCache = config.isSharedCache();
     }
 
-    CachedResponseSuitabilityChecker() {
-        this(new CacheValidityPolicy());
+    CachedResponseSuitabilityChecker(CacheConfig config) {
+        this(new CacheValidityPolicy(), config);
+    }
+
+    private boolean isFreshEnough(HttpCacheEntry entry, HttpRequest request, Date now) {
+        if (validityStrategy.isResponseFresh(entry, now)) return true;
+        if (originInsistsOnFreshness(entry)) return false;
+        long maxstale = getMaxStale(request);
+        if (maxstale == -1) return false;
+        return (maxstale > validityStrategy.getStalenessSecs(entry, now));
+    }
+
+    private boolean originInsistsOnFreshness(HttpCacheEntry entry) {
+        if (validityStrategy.mustRevalidate(entry)) return true;
+        if (!sharedCache) return false;
+        return validityStrategy.proxyRevalidate(entry) ||
+            validityStrategy.hasCacheControlDirective(entry, "s-maxage");
+    }
+
+    private long getMaxStale(HttpRequest request) {
+        long maxstale = -1;
+        for(Header h : request.getHeaders("Cache-Control")) {
+            for(HeaderElement elt : h.getElements()) {
+                if ("max-stale".equals(elt.getName())) {
+                    if ((elt.getValue() == null || "".equals(elt.getValue().trim()))
+                            && maxstale == -1) {
+                        maxstale = Long.MAX_VALUE;
+                    } else {
+                        try {
+                            long val = Long.parseLong(elt.getValue());
+                            if (val < 0) val = 0;
+                            if (maxstale == -1 || val < maxstale) {
+                                maxstale = val;
+                            }
+                        } catch (NumberFormatException nfe) {
+                            // err on the side of preserving semantic transparency
+                            maxstale = 0;
+                        }
+                    }
+                }
+            }
+        }
+        return maxstale;
     }
 
     /**
@@ -74,8 +118,8 @@ class CachedResponseSuitabilityChecker {
      *            {@link HttpCacheEntry}
      * @return boolean yes/no answer
      */
-    public boolean canCachedResponseBeUsed(HttpHost host, HttpRequest request, HttpCacheEntry entry) {
-        if (!validityStrategy.isResponseFresh(entry)) {
+    public boolean canCachedResponseBeUsed(HttpHost host, HttpRequest request, HttpCacheEntry entry, Date now) {
+        if (!isFreshEnough(entry, request, now)) {
             log.debug("Cache entry was not fresh enough");
             return false;
         }
@@ -110,7 +154,7 @@ class CachedResponseSuitabilityChecker {
                 if (HeaderConstants.CACHE_CONTROL_MAX_AGE.equals(elt.getName())) {
                     try {
                         int maxage = Integer.parseInt(elt.getValue());
-                        if (validityStrategy.getCurrentAgeSecs(entry) > maxage) {
+                        if (validityStrategy.getCurrentAgeSecs(entry, now) > maxage) {
                             log.debug("Response from cache was NOT suitable due to max age");
                             return false;
                         }
@@ -137,8 +181,11 @@ class CachedResponseSuitabilityChecker {
 
                 if (HeaderConstants.CACHE_CONTROL_MIN_FRESH.equals(elt.getName())) {
                     try {
-                        int minfresh = Integer.parseInt(elt.getValue());
-                        if (validityStrategy.getFreshnessLifetimeSecs(entry) < minfresh) {
+                        long minfresh = Long.parseLong(elt.getValue());
+                        if (minfresh < 0L) return false;
+                        long age = validityStrategy.getCurrentAgeSecs(entry, now);
+                        long freshness = validityStrategy.getFreshnessLifetimeSecs(entry);
+                        if (freshness - age < minfresh) {
                             log.debug("Response from cache was not suitable due to min fresh " +
                                     "freshness requirement");
                             return false;

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClient.java Wed Sep 15 20:00:41 2010
@@ -115,7 +115,7 @@ public class CachingHttpClient implement
         this.responseCachingPolicy = new ResponseCachingPolicy(maxObjectSizeBytes, sharedCache);
         this.responseGenerator = new CachedHttpResponseGenerator(this.validityPolicy);
         this.cacheableRequestPolicy = new CacheableRequestPolicy();
-        this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy);
+        this.suitabilityChecker = new CachedResponseSuitabilityChecker(this.validityPolicy, config);
         this.conditionalRequestBuilder = new ConditionalRequestBuilder();
 
         this.responseCompliance = new ResponseProtocolCompliance();
@@ -408,9 +408,14 @@ public class CachingHttpClient implement
         }
         cacheHits.getAndIncrement();
 
-        if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry)) {
+        Date now = getCurrentDate();
+        if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) {
+            final HttpResponse cachedResponse = responseGenerator.generateResponse(entry);
             setResponseStatus(context, CacheResponseStatus.CACHE_HIT);
-            return responseGenerator.generateResponse(entry);
+            if (validityPolicy.getStalenessSecs(entry, now) > 0L) {
+                cachedResponse.addHeader("Warning","110 localhost \"Response is stale\"");
+            }
+            return cachedResponse;
         }
 
         if (validityPolicy.isRevalidatable(entry)) {
@@ -421,15 +426,15 @@ public class CachingHttpClient implement
             } catch (IOException ioex) {
                 if (validityPolicy.mustRevalidate(entry)
                     || (isSharedCache() && validityPolicy.proxyRevalidate(entry))
-                    || explicitFreshnessRequest(request, entry)) {
+                    || explicitFreshnessRequest(request, entry, now)) {
                     setResponseStatus(context, CacheResponseStatus.CACHE_MODULE_RESPONSE);
                     return new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_GATEWAY_TIMEOUT, "Gateway Timeout");
                 } else {
+                    final HttpResponse cachedResponse = responseGenerator.generateResponse(entry);
                     setResponseStatus(context, CacheResponseStatus.CACHE_HIT);
-                    HttpResponse response = responseGenerator.generateResponse(entry);
-                    response.addHeader(HeaderConstants.WARNING, "111 localhost \"Revalidation failed\"");
+                    cachedResponse.addHeader(HeaderConstants.WARNING, "111 localhost \"Revalidation failed\"");
                     log.debug("111 revalidation failed due to exception: " + ioex);
-                    return response;
+                    return cachedResponse;
                 }
             } catch (ProtocolException e) {
                 throw new ClientProtocolException(e);
@@ -438,13 +443,13 @@ public class CachingHttpClient implement
         return callBackend(target, request, context);
     }
 
-    private boolean explicitFreshnessRequest(HttpRequest request, HttpCacheEntry entry) {
+    private boolean explicitFreshnessRequest(HttpRequest request, HttpCacheEntry entry, Date now) {
         for(Header h : request.getHeaders("Cache-Control")) {
             for(HeaderElement elt : h.getElements()) {
                 if ("max-stale".equals(elt.getName())) {
                     try {
                         int maxstale = Integer.parseInt(elt.getValue());
-                        long age = validityPolicy.getCurrentAgeSecs(entry);
+                        long age = validityPolicy.getCurrentAgeSecs(entry, now);
                         long lifetime = validityPolicy.getFreshnessLifetimeSecs(entry);
                         if (age - lifetime > maxstale) return true;
                     } catch (NumberFormatException nfe) {

Added: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java?rev=997480&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java (added)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java Wed Sep 15 20:00:41 2010
@@ -0,0 +1,138 @@
+/*
+ * ====================================================================
+ * 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.client.cache;
+
+import static org.easymock.classextension.EasyMock.*;
+import java.util.Date;
+
+import org.apache.http.Header;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.StatusLine;
+import org.apache.http.client.cache.HttpCacheEntry;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicStatusLine;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestHttpCacheEntry {
+
+    private Date now;
+    private Date elevenSecondsAgo;
+    private Date nineSecondsAgo;
+    private Resource mockResource;
+    private StatusLine statusLine;
+
+    @Before
+    public void setUp() {
+        now = new Date();
+        elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
+        nineSecondsAgo = new Date(now.getTime() - 9 * 1000L);
+        statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1,
+                HttpStatus.SC_OK, "OK");
+        mockResource = createMock(Resource.class);
+    }
+
+    private HttpCacheEntry makeEntry(Header[] headers) {
+        return new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo,
+                statusLine, headers, mockResource, null);
+    }
+
+    @Test
+    public void testGetHeadersReturnsCorrectHeaders() {
+        Header[] headers = { new BasicHeader("foo", "fooValue"),
+                new BasicHeader("bar", "barValue1"),
+                new BasicHeader("bar", "barValue2")
+        };
+        HttpCacheEntry entry = makeEntry(headers);
+        Assert.assertEquals(2, entry.getHeaders("bar").length);
+    }
+
+    @Test
+    public void testGetFirstHeaderReturnsCorrectHeader() {
+        Header[] headers = { new BasicHeader("foo", "fooValue"),
+                new BasicHeader("bar", "barValue1"),
+                new BasicHeader("bar", "barValue2")
+        };
+        HttpCacheEntry entry = makeEntry(headers);
+        Assert.assertEquals("barValue1", entry.getFirstHeader("bar").getValue());
+    }
+
+    @Test
+    public void testGetHeadersReturnsEmptyArrayIfNoneMatch() {
+        Header[] headers = { new BasicHeader("foo", "fooValue"),
+                new BasicHeader("bar", "barValue1"),
+                new BasicHeader("bar", "barValue2")
+        };
+        HttpCacheEntry entry = makeEntry(headers);
+
+        Assert.assertEquals(0, entry.getHeaders("baz").length);
+    }
+
+    @Test
+    public void testGetFirstHeaderReturnsNullIfNoneMatch() {
+        Header[] headers = { new BasicHeader("foo", "fooValue"),
+                new BasicHeader("bar", "barValue1"),
+                new BasicHeader("bar", "barValue2")
+        };
+        HttpCacheEntry entry = makeEntry(headers);
+
+        Assert.assertEquals(null, entry.getFirstHeader("quux"));
+    }
+
+    @Test
+    public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() {
+        Header[] headers = new Header[0];
+        HttpCacheEntry entry = makeEntry(headers);
+        Assert.assertFalse(entry.hasVariants());
+    }
+
+    @Test
+    public void testCacheEntryWithOneVaryHeaderHasVariants() {
+        Header[] headers = { new BasicHeader("Vary", "User-Agent") };
+        HttpCacheEntry entry = makeEntry(headers);
+        Assert.assertTrue(entry.hasVariants());
+    }
+
+    @Test
+    public void testCacheEntryWithMultipleVaryHeadersHasVariants() {
+        Header[] headers = { new BasicHeader("Vary", "User-Agent"),
+                new BasicHeader("Vary", "Accept-Encoding")
+        };
+        HttpCacheEntry entry = makeEntry(headers);
+        Assert.assertTrue(entry.hasVariants());
+    }
+
+    @Test
+    public void testCacheEntryWithVaryStarHasVariants(){
+        Header[] headers = { new BasicHeader("Vary", "*") };
+        HttpCacheEntry entry = makeEntry(headers);
+        Assert.assertTrue(entry.hasVariants());
+    }
+
+}

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/client/cache/TestHttpCacheEntry.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

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=997480&r1=997479&r2=997480&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 Sep 15 20:00:41 2010
@@ -27,16 +27,24 @@
 package org.apache.http.impl.client.cache;
 
 import java.io.InputStream;
+import java.util.Date;
 import java.util.Random;
+import java.util.Set;
 
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpMessage;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
 import org.apache.http.RequestLine;
 import org.apache.http.StatusLine;
+import org.apache.http.client.cache.HttpCacheEntry;
 import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.cookie.DateUtils;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicStatusLine;
 
 public class HttpTestUtils {
 
@@ -224,4 +232,60 @@ public class HttpTestUtils {
         return new ByteArrayEntity(getRandomBytes(nbytes));
     }
 
+    public static HttpCacheEntry makeCacheEntry(Date requestDate, Date responseDate) {
+        Date when = new Date((responseDate.getTime() + requestDate.getTime()) / 2);
+        return makeCacheEntry(requestDate, responseDate, getStockHeaders(when));
+    }
+
+    public static Header[] getStockHeaders(Date when) {
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(when)),
+                new BasicHeader("Server", "MockServer/1.0")
+        };
+        return headers;
+    }
+
+    public static HttpCacheEntry makeCacheEntry(Date requestDate,
+            Date responseDate, Header[] headers) {
+        byte[] bytes = getRandomBytes(128);
+        return makeCacheEntry(requestDate, responseDate, headers, bytes);
+    }
+
+    public static HttpCacheEntry makeCacheEntry(Date requestDate,
+            Date responseDate, Header[] headers, byte[] bytes) {
+        Set<String> variants = null;
+        return makeCacheEntry(requestDate, responseDate, headers, bytes,
+                variants);
+    }
+
+    public static HttpCacheEntry makeCacheEntry(Set<String> variants) {
+        Date now = new Date();
+        return makeCacheEntry(now, now, getStockHeaders(now),
+                getRandomBytes(128), variants);
+    }
+
+    public static HttpCacheEntry makeCacheEntry(Date requestDate,
+            Date responseDate, Header[] headers, byte[] bytes,
+            Set<String> variants) {
+        StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
+        return new HttpCacheEntry(requestDate, responseDate, statusLine, headers, new HeapResource(bytes), variants);
+    }
+
+    public static HttpCacheEntry makeCacheEntry(Header[] headers, byte[] bytes) {
+        Date now = new Date();
+        return makeCacheEntry(now, now, headers, bytes);
+    }
+
+    public static HttpCacheEntry makeCacheEntry(byte[] bytes) {
+        return makeCacheEntry(getStockHeaders(new Date()), bytes);
+    }
+
+    public static HttpCacheEntry makeCacheEntry(Header[] headers) {
+        return makeCacheEntry(headers, getRandomBytes(128));
+    }
+
+    public static HttpCacheEntry makeCacheEntry() {
+        Date now = new Date();
+        return makeCacheEntry(now, now);
+    }
 }
\ No newline at end of file

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestBasicHttpCache.java Wed Sep 15 20:00:41 2010
@@ -72,7 +72,7 @@ public class TestBasicHttpCache {
         HttpHost host = new HttpHost("foo.example.com");
         HttpRequest req = new HttpDelete("/bar");
         final String key = (new URIExtractor()).getURI(host, req);
-        HttpCacheEntry entry = new CacheEntry();
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
 
         backing.map.put(key, entry);
 
@@ -200,8 +200,8 @@ public class TestBasicHttpCache {
         final String existingVariantKey = "existingVariantKey";
         final Set<String> existingVariants = new HashSet<String>();
         existingVariants.add(existingVariantKey);
-        final CacheEntry parent = new CacheEntry(existingVariants);
-        final CacheEntry variant = new CacheEntry();
+        final HttpCacheEntry parent = HttpTestUtils.makeCacheEntry(existingVariants);
+        final HttpCacheEntry variant = HttpTestUtils.makeCacheEntry();
 
         HttpCacheEntry result = impl.doGetUpdatedParentEntry(parentKey, parent, variant, variantKey);
         assertEquals(2, result.getVariantURIs().size());
@@ -211,7 +211,7 @@ public class TestBasicHttpCache {
 
     @Test
     public void testStoreInCachePutsNonVariantEntryInPlace() throws Exception {
-        CacheEntry entry = new CacheEntry();
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
         assertFalse(entry.hasVariants());
         HttpHost host = new HttpHost("foo.example.com");
         HttpRequest req = new HttpGet("http://foo.example.com/bar");
@@ -275,7 +275,7 @@ public class TestBasicHttpCache {
 
     @Test
     public void testGetCacheEntryFetchesFromCacheOnCacheHitIfNoVariants() throws Exception {
-        CacheEntry entry = new CacheEntry();
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
         assertFalse(entry.hasVariants());
         HttpHost host = new HttpHost("foo.example.com");
         HttpRequest request = new HttpGet("http://foo.example.com/bar");

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java Wed Sep 15 20:00:41 2010
@@ -64,7 +64,7 @@ public class TestCacheEntryUpdater {
     @Test
     public void testUpdateCacheEntryReturnsDifferentEntryInstance() throws IOException {
 
-        CacheEntry entry = new CacheEntry();
+        HttpCacheEntry entry =HttpTestUtils.makeCacheEntry();
         BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
 
         HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry, requestDate, responseDate, response);
@@ -79,7 +79,7 @@ public class TestCacheEntryUpdater {
                 new BasicHeader("Date", DateUtils.formatDate(responseDate)),
                 new BasicHeader("ETag", "\"etag\"")};
 
-        CacheEntry cacheEntry = new CacheEntry(headers);
+        HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
 
         HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion(
                 "http", 1, 1), HttpStatus.SC_NOT_MODIFIED, ""));
@@ -102,7 +102,7 @@ public class TestCacheEntryUpdater {
                 new BasicHeader("Cache-Control", "private"), new BasicHeader("ETag", "\"etag\""),
                 new BasicHeader("Last-Modified", DateUtils.formatDate(requestDate)),
                 new BasicHeader("Cache-Control", "max-age=0"),};
-        CacheEntry cacheEntry = new CacheEntry(headers);
+        HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
 
         HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion(
                 "http", 1, 1), HttpStatus.SC_NOT_MODIFIED, ""));
@@ -129,7 +129,7 @@ public class TestCacheEntryUpdater {
                 new BasicHeader("Date", DateUtils.formatDate(requestDate)),
                 new BasicHeader("ETag", "\"etag\"")};
 
-        CacheEntry cacheEntry = new CacheEntry(headers);
+        HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
         HttpResponse response = new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion(
                 "http", 1, 1), HttpStatus.SC_NOT_MODIFIED, ""));
         response.setHeaders(new Header[]{
@@ -160,7 +160,7 @@ public class TestCacheEntryUpdater {
         Date twoSecondsAgo = new Date(now.getTime() - 2000L);
         Date oneSecondAgo = new Date(now.getTime() - 1000L);
 
-        CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo);
 
         HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
 

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheInvalidator.java Wed Sep 15 20:00:41 2010
@@ -34,6 +34,7 @@ import org.apache.http.HttpEntityEnclosi
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.ProtocolVersion;
+import org.apache.http.client.cache.HttpCacheEntry;
 import org.apache.http.client.cache.HttpCacheStorage;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
 import org.apache.http.message.BasicHttpRequest;
@@ -49,14 +50,14 @@ public class TestCacheInvalidator {
     private HttpCacheStorage mockStorage;
     private HttpHost host;
     private URIExtractor extractor;
-    private CacheEntry mockEntry;
+    private HttpCacheEntry mockEntry;
 
     @Before
     public void setUp() {
         host = new HttpHost("foo.example.com");
         mockStorage = EasyMock.createMock(HttpCacheStorage.class);
         extractor = new URIExtractor();
-        mockEntry = EasyMock.createMock(CacheEntry.class);
+        mockEntry = EasyMock.createMock(HttpCacheEntry.class);
 
         impl = new CacheInvalidator(extractor, mockStorage);
     }

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheValidityPolicy.java Wed Sep 15 20:00:41 2010
@@ -39,7 +39,10 @@ public class TestCacheValidityPolicy {
 
     @Test
     public void testApparentAgeIsMaxIntIfDateHeaderNotPresent() {
-        CacheEntry entry = new CacheEntry();
+        Header[] headers = {
+                new BasicHeader("Server", "MockServer/1.0")
+        };
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(2147483648L, impl.getApparentAgeSecs(entry));
     }
@@ -53,7 +56,7 @@ public class TestCacheValidityPolicy {
         Header[] headers = new Header[] { new BasicHeader("Date", DateUtils
                 .formatDate(tenSecondsAgo)) };
 
-        CacheEntry entry = new CacheEntry(now, sixSecondsAgo, headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, sixSecondsAgo, headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertEquals(4, impl.getApparentAgeSecs(entry));
@@ -68,7 +71,7 @@ public class TestCacheValidityPolicy {
         Header[] headers = new Header[] { new BasicHeader("Date", DateUtils
                 .formatDate(sixSecondsAgo)) };
 
-        CacheEntry entry  = new CacheEntry(now,tenSecondsAgo,headers);
+        HttpCacheEntry entry  = HttpTestUtils.makeCacheEntry(now,tenSecondsAgo,headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(0, impl.getApparentAgeSecs(entry));
     }
@@ -76,7 +79,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testCorrectedReceivedAgeIsAgeHeaderIfLarger() {
         Header[] headers = new Header[] { new BasicHeader("Age", "10"), };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
@@ -93,7 +96,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testCorrectedReceivedAgeIsApparentAgeIfLarger() {
         Header[] headers = new Header[] { new BasicHeader("Age", "6"), };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
@@ -113,7 +116,7 @@ public class TestCacheValidityPolicy {
         Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
         Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
-        CacheEntry entry = new CacheEntry(tenSecondsAgo, sixSecondsAgo);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, sixSecondsAgo);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertEquals(4, impl.getResponseDelaySecs(entry));
@@ -121,7 +124,7 @@ public class TestCacheValidityPolicy {
 
     @Test
     public void testCorrectedInitialAgeIsCorrectedReceivedAgePlusResponseDelay() {
-        CacheEntry entry = new CacheEntry();
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
             @Override
@@ -143,7 +146,7 @@ public class TestCacheValidityPolicy {
         final Date now = new Date();
         final Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
 
-        CacheEntry entry = new CacheEntry(now, sixSecondsAgo);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, sixSecondsAgo);
 
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
@@ -154,12 +157,12 @@ public class TestCacheValidityPolicy {
 
         };
 
-        Assert.assertEquals(6, impl.getResidentTimeSecs(entry));
+        Assert.assertEquals(6, impl.getResidentTimeSecs(entry, now));
     }
 
     @Test
     public void testCurrentAgeIsCorrectedInitialAgePlusResidentTime() {
-        CacheEntry entry = new CacheEntry();
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
             @Override
@@ -168,17 +171,17 @@ public class TestCacheValidityPolicy {
             }
 
             @Override
-            protected long getResidentTimeSecs(HttpCacheEntry entry) {
+            protected long getResidentTimeSecs(HttpCacheEntry entry, Date d) {
                 return 17;
             }
         };
-        Assert.assertEquals(28, impl.getCurrentAgeSecs(entry));
+        Assert.assertEquals(28, impl.getCurrentAgeSecs(entry, new Date()));
     }
 
     @Test
     public void testFreshnessLifetimeIsSMaxAgeIfPresent() {
         Header[] headers = new Header[] { new BasicHeader("Cache-Control", "s-maxage=10") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
     }
@@ -186,7 +189,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testFreshnessLifetimeIsMaxAgeIfPresent() {
         Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
     }
@@ -195,13 +198,13 @@ public class TestCacheValidityPolicy {
     public void testFreshnessLifetimeIsMostRestrictiveOfMaxAgeAndSMaxAge() {
         Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=10"),
                 new BasicHeader("Cache-Control", "s-maxage=20") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
 
         headers = new Header[] { new BasicHeader("Cache-Control", "max-age=20"),
                 new BasicHeader("Cache-Control", "s-maxage=10") };
-        entry = new CacheEntry(headers);
+        entry = HttpTestUtils.makeCacheEntry(headers);
         Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
     }
 
@@ -214,7 +217,7 @@ public class TestCacheValidityPolicy {
                 new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
                 new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
 
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
     }
@@ -228,7 +231,7 @@ public class TestCacheValidityPolicy {
                 new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
                 new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
 
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(10, impl.getFreshnessLifetimeSecs(entry));
     }
@@ -242,66 +245,78 @@ public class TestCacheValidityPolicy {
                 new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
                 new BasicHeader("Expires", DateUtils.formatDate(sixSecondsAgo)) };
 
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Assert.assertEquals(4, impl.getFreshnessLifetimeSecs(entry));
     }
 
     @Test
     public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() {
-        CacheEntry entry = new CacheEntry();
+        final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+        final Date now = new Date();
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
             @Override
-            public long getCurrentAgeSecs(HttpCacheEntry entry) {
+            public long getCurrentAgeSecs(HttpCacheEntry e, Date d) {
+                Assert.assertSame(entry, e);
+                Assert.assertEquals(now, d);
                 return 6;
             }
 
             @Override
-            public long getFreshnessLifetimeSecs(HttpCacheEntry entry) {
+            public long getFreshnessLifetimeSecs(HttpCacheEntry e) {
+                Assert.assertSame(entry, e);
                 return 10;
             }
         };
 
-        Assert.assertTrue(impl.isResponseFresh(entry));
+        Assert.assertTrue(impl.isResponseFresh(entry, now));
     }
 
     @Test
     public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() {
-        CacheEntry entry = new CacheEntry();
+        final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+        final Date now = new Date();
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
             @Override
-            public long getCurrentAgeSecs(HttpCacheEntry entry) {
+            public long getCurrentAgeSecs(HttpCacheEntry e, Date d) {
+                Assert.assertEquals(now, d);
+                Assert.assertSame(entry, e);
                 return 6;
             }
 
             @Override
-            public long getFreshnessLifetimeSecs(HttpCacheEntry entry) {
+            public long getFreshnessLifetimeSecs(HttpCacheEntry e) {
+                Assert.assertSame(entry, e);
                 return 6;
             }
         };
 
-        Assert.assertFalse(impl.isResponseFresh(entry));
+        Assert.assertFalse(impl.isResponseFresh(entry, now));
     }
 
     @Test
     public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() {
-        CacheEntry entry = new CacheEntry();
+        final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
+        final Date now = new Date();
         CacheValidityPolicy impl = new CacheValidityPolicy() {
 
             @Override
-            public long getCurrentAgeSecs(HttpCacheEntry entry) {
+            public long getCurrentAgeSecs(HttpCacheEntry e, Date d) {
+                Assert.assertEquals(now, d);
+                Assert.assertSame(entry, e);
                 return 10;
             }
 
             @Override
-            public long getFreshnessLifetimeSecs(HttpCacheEntry entry) {
+            public long getFreshnessLifetimeSecs(HttpCacheEntry e) {
+                Assert.assertSame(entry, e);
                 return 6;
             }
         };
 
-        Assert.assertFalse(impl.isResponseFresh(entry));
+        Assert.assertFalse(impl.isResponseFresh(entry, now));
     }
 
     @Test
@@ -311,7 +326,7 @@ public class TestCacheValidityPolicy {
                 new BasicHeader("Expires", DateUtils.formatDate(new Date())),
                 new BasicHeader("ETag", "somevalue")};
 
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertTrue(impl.isRevalidatable(entry));
@@ -324,7 +339,7 @@ public class TestCacheValidityPolicy {
                 new BasicHeader("Expires", DateUtils.formatDate(new Date())),
                 new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())) };
 
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertTrue(impl.isRevalidatable(entry));
@@ -337,7 +352,7 @@ public class TestCacheValidityPolicy {
                 new BasicHeader("Expires", DateUtils.formatDate(new Date())),
                 new BasicHeader("Cache-Control", "public") };
 
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertFalse(impl.isRevalidatable(entry));
@@ -347,7 +362,7 @@ public class TestCacheValidityPolicy {
     public void testMalformedDateHeaderIsIgnored() {
 
         Header[] headers = new Header[] { new BasicHeader("Date", "asdf") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Date d = impl.getDateValue(entry);
@@ -359,7 +374,7 @@ public class TestCacheValidityPolicy {
     public void testMalformedContentLengthReturnsNegativeOne() {
 
         Header[] headers = new Header[] { new BasicHeader("Content-Length", "asdf") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy();
         long length = impl.getContentLengthValue(entry);
@@ -371,31 +386,31 @@ public class TestCacheValidityPolicy {
     public void testNegativeAgeHeaderValueReturnsMaxAge() {
 
         Header[] headers = new Header[] { new BasicHeader("Age", "-100") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy();
         long length = impl.getAgeValue(entry);
 
-        Assert.assertEquals(CacheEntry.MAX_AGE, length);
+        Assert.assertEquals(CacheValidityPolicy.MAX_AGE, length);
     }
 
     @Test
     public void testMalformedAgeHeaderValueReturnsMaxAge() {
 
         Header[] headers = new Header[] { new BasicHeader("Age", "asdf") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy();
         long length = impl.getAgeValue(entry);
 
-        Assert.assertEquals(CacheEntry.MAX_AGE, length);
+        Assert.assertEquals(CacheValidityPolicy.MAX_AGE, length);
     }
 
     @Test
     public void testMalformedCacheControlMaxAgeHeaderReturnsZero() {
 
         Header[] headers = new Header[] { new BasicHeader("Cache-Control", "max-age=asdf") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy();
         long maxage = impl.getMaxAge(entry);
@@ -406,7 +421,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testMalformedExpirationDateReturnsNull() {
         Header[] headers = new Header[] { new BasicHeader("Expires", "asdf") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
 
         CacheValidityPolicy impl = new CacheValidityPolicy();
         Date expirationDate = impl.getExpirationDate(entry);
@@ -417,7 +432,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testMustRevalidateIsFalseIfDirectiveNotPresent() {
         Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertFalse(impl.mustRevalidate(entry));
@@ -426,7 +441,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testMustRevalidateIsTrueWhenDirectiveIsPresent() {
         Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, must-revalidate") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertTrue(impl.mustRevalidate(entry));
@@ -435,7 +450,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testProxyRevalidateIsFalseIfDirectiveNotPresent() {
         Header[] headers = new Header[] { new BasicHeader("Cache-Control","public") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertFalse(impl.proxyRevalidate(entry));
@@ -444,7 +459,7 @@ public class TestCacheValidityPolicy {
     @Test
     public void testProxyRevalidateIsTrueWhenDirectiveIsPresent() {
         Header[] headers = new Header[] { new BasicHeader("Cache-Control","public, proxy-revalidate") };
-        CacheEntry entry = new CacheEntry(headers);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
         CacheValidityPolicy impl = new CacheValidityPolicy();
 
         Assert.assertTrue(impl.proxyRevalidate(entry));

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedHttpResponseGenerator.java Wed Sep 15 20:00:41 2010
@@ -30,6 +30,7 @@ import java.util.Date;
 
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.cache.HttpCacheEntry;
 import org.apache.http.impl.cookie.DateUtils;
 import org.apache.http.message.BasicHeader;
 import org.easymock.classextension.EasyMock;
@@ -39,13 +40,14 @@ import org.junit.Test;
 
 public class TestCachedHttpResponseGenerator {
 
-    private CacheEntry entry;
+    private HttpCacheEntry entry;
     private CacheValidityPolicy mockValidityPolicy;
     private CachedHttpResponseGenerator impl;
+    private Date now;
 
     @Before
     public void setUp() {
-        Date now = new Date();
+        now = new Date();
         Date sixSecondsAgo = new Date(now.getTime() - 6 * 1000L);
         Date eightSecondsAgo = new Date(now.getTime() - 8 * 1000L);
         Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
@@ -54,7 +56,7 @@ public class TestCachedHttpResponseGener
                 new BasicHeader("Expires", DateUtils.formatDate(tenSecondsFromNow)),
                 new BasicHeader("Content-Length", "150") };
 
-        entry = new CacheEntry(tenSecondsAgo, sixSecondsAgo, hdrs);
+        entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, sixSecondsAgo, hdrs);
         mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class);
         impl = new CachedHttpResponseGenerator(mockValidityPolicy);
     }
@@ -66,7 +68,7 @@ public class TestCachedHttpResponseGener
     @Test
     public void testResponseHasContentLength() {
         byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
-        CacheEntry entry = new CacheEntry(buf);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(buf);
 
         HttpResponse response = impl.generateResponse(entry);
 
@@ -82,7 +84,7 @@ public class TestCachedHttpResponseGener
 
         Header[] hdrs = new Header[] { new BasicHeader("Transfer-Encoding", "chunked") };
         byte[] buf = new byte[] { 1, 2, 3, 4, 5 };
-        CacheEntry entry = new CacheEntry(hdrs, buf);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(hdrs, buf);
 
         HttpResponse response = impl.generateResponse(entry);
 
@@ -134,19 +136,20 @@ public class TestCachedHttpResponseGener
 
     @Test
     public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() {
-        currentAge(CacheEntry.MAX_AGE + 1L);
+        currentAge(CacheValidityPolicy.MAX_AGE + 1L);
         replayMocks();
 
         HttpResponse response = impl.generateResponse(entry);
 
         Header ageHdr = response.getFirstHeader("Age");
         Assert.assertNotNull(ageHdr);
-        Assert.assertEquals(CacheEntry.MAX_AGE, Long.parseLong(ageHdr.getValue()));
+        Assert.assertEquals(CacheValidityPolicy.MAX_AGE, Long.parseLong(ageHdr.getValue()));
     }
 
     private void currentAge(long sec) {
         EasyMock.expect(
-                mockValidityPolicy.getCurrentAgeSecs(entry)).andReturn(sec);
+                mockValidityPolicy.getCurrentAgeSecs(EasyMock.same(entry),
+                        EasyMock.isA(Date.class))).andReturn(sec);
     }
 
 }

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachedResponseSuitabilityChecker.java Wed Sep 15 20:00:41 2010
@@ -26,8 +26,14 @@
  */
 package org.apache.http.impl.client.cache;
 
+import java.util.Date;
+
+import org.apache.http.Header;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.cache.HttpCacheEntry;
+import org.apache.http.impl.cookie.DateUtils;
 import org.apache.http.message.BasicHeader;
 import org.apache.http.message.BasicHttpRequest;
 import org.easymock.classextension.EasyMock;
@@ -37,20 +43,34 @@ import org.junit.Test;
 
 public class TestCachedResponseSuitabilityChecker {
 
+    private Date now;
+    private Date elevenSecondsAgo;
+    private Date tenSecondsAgo;
+    private Date nineSecondsAgo;
+
     private HttpHost host;
     private HttpRequest request;
-    private CacheEntry entry;
+    private HttpCacheEntry entry;
     private CacheValidityPolicy mockValidityPolicy;
     private CachedResponseSuitabilityChecker impl;
 
     @Before
     public void setUp() {
+        now = new Date();
+        elevenSecondsAgo = new Date(now.getTime() - 11 * 1000L);
+        tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
+        nineSecondsAgo = new Date(now.getTime() - 9 * 1000L);
+
         host = new HttpHost("foo.example.com");
-        request = new BasicHttpRequest("GET", "/foo");
+        request = new BasicHttpRequest("GET", "/foo", HttpVersion.HTTP_1_1);
         mockValidityPolicy = EasyMock.createMock(CacheValidityPolicy.class);
-        entry = new CacheEntry();
+        entry = HttpTestUtils.makeCacheEntry();
 
-        impl = new CachedResponseSuitabilityChecker(mockValidityPolicy);
+        impl = new CachedResponseSuitabilityChecker(new CacheConfig());
+    }
+
+    private HttpCacheEntry getEntry(Header[] headers) {
+        return HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, headers);
     }
 
     public void replayMocks() {
@@ -63,187 +83,144 @@ public class TestCachedResponseSuitabili
 
     @Test
     public void testNotSuitableIfContentLengthHeaderIsWrong() {
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(false);
-
-        replayMocks();
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-
-        verifyMocks();
-
-        Assert.assertFalse(result);
-    }
-
-    @Test
-    public void testSuitableIfContentLengthHeaderIsRight() {
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-
-        replayMocks();
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-
-        verifyMocks();
-
-        Assert.assertTrue(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","1")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testSuitableIfCacheEntryIsFresh() {
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-
-        verifyMocks();
-
-        Assert.assertTrue(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testNotSuitableIfCacheEntryIsNotFresh() {
-        responseIsFresh(false);
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-
-        verifyMocks();
-
-        Assert.assertFalse(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=5"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testNotSuitableIfRequestHasNoCache() {
         request.addHeader("Cache-Control", "no-cache");
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-        verifyMocks();
-        Assert.assertFalse(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testNotSuitableIfAgeExceedsRequestMaxAge() {
         request.addHeader("Cache-Control", "max-age=10");
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-        currentAge(20L);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-        verifyMocks();
-        Assert.assertFalse(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testSuitableIfFreshAndAgeIsUnderRequestMaxAge() {
-        request.addHeader("Cache-Control", "max-age=10");
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-        currentAge(5L);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-        verifyMocks();
-        Assert.assertTrue(result);
+        request.addHeader("Cache-Control", "max-age=15");
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testSuitableIfFreshAndFreshnessLifetimeGreaterThanRequestMinFresh() {
         request.addHeader("Cache-Control", "min-fresh=10");
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-        freshnessLifetime(15L);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-        verifyMocks();
-        Assert.assertTrue(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testNotSuitableIfFreshnessLifetimeLessThanRequestMinFresh() {
         request.addHeader("Cache-Control", "min-fresh=10");
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-        freshnessLifetime(5L);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-        verifyMocks();
-        Assert.assertFalse(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=15"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
-    // this is compliant but possibly misses some cache hits; would
-    // need to change logic to add Warning header if we allowed this
     @Test
-    public void testNotSuitableEvenIfStaleButPermittedByRequestMaxStale() {
+    public void testSuitableEvenIfStaleButPermittedByRequestMaxStale() {
         request.addHeader("Cache-Control", "max-stale=10");
-        responseIsFresh(false);
-
-        replayMocks();
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=5"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
+    }
 
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-        verifyMocks();
-        Assert.assertFalse(result);
+    @Test
+    public void testNotSuitableIfStaleButTooStaleForRequestMaxStale() {
+        request.addHeader("Cache-Control", "max-stale=2");
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=5"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
+
     @Test
     public void testMalformedCacheControlMaxAgeRequestHeaderCausesUnsuitableEntry() {
         request.addHeader(new BasicHeader("Cache-Control", "max-age=foo"));
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-
-        verifyMocks();
-
-        Assert.assertFalse(result);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
     @Test
     public void testMalformedCacheControlMinFreshRequestHeaderCausesUnsuitableEntry() {
         request.addHeader(new BasicHeader("Cache-Control", "min-fresh=foo"));
-
-        responseIsFresh(true);
-        contentLengthMatchesActualLength(true);
-
-        replayMocks();
-
-        boolean result = impl.canCachedResponseBeUsed(host, request, entry);
-
-        verifyMocks();
-
-        Assert.assertFalse(result);
-    }
-
-    private void currentAge(long sec) {
-        EasyMock.expect(
-                mockValidityPolicy.getCurrentAgeSecs(entry)).andReturn(sec);
+        Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
+                new BasicHeader("Cache-Control", "max-age=3600"),
+                new BasicHeader("Content-Length","128")
+        };
+        entry = getEntry(headers);
+        Assert.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
     }
 
-    private void freshnessLifetime(long sec) {
-        EasyMock.expect(
-                mockValidityPolicy.getFreshnessLifetimeSecs(entry)).andReturn(sec);
-    }
-
-    private void responseIsFresh(boolean fresh) {
-        EasyMock.expect(
-                mockValidityPolicy.isResponseFresh(entry)).andReturn(fresh);
-    }
-
-    private void contentLengthMatchesActualLength(boolean b) {
-        EasyMock.expect(
-                mockValidityPolicy.contentLengthHeaderMatchesActualLength(entry)).andReturn(b);
-    }
 }
\ No newline at end of file

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCachingHttpClient.java Wed Sep 15 20:00:41 2010
@@ -81,7 +81,7 @@ public class TestCachingHttpClient {
     private CachedResponseSuitabilityChecker mockSuitabilityChecker;
     private ResponseCachingPolicy mockResponsePolicy;
     private HttpResponse mockBackendResponse;
-    private CacheEntry mockCacheEntry;
+    private HttpCacheEntry mockCacheEntry;
     private CachedHttpResponseGenerator mockResponseGenerator;
     private ClientConnectionManager mockConnectionManager;
     private ResponseHandler<Object> mockHandler;
@@ -113,7 +113,7 @@ public class TestCachingHttpClient {
         mockHandler = EasyMock.createMock(ResponseHandler.class);
         mockBackendResponse = EasyMock.createMock(HttpResponse.class);
         mockUriRequest = EasyMock.createMock(HttpUriRequest.class);
-        mockCacheEntry = EasyMock.createMock(CacheEntry.class);
+        mockCacheEntry = EasyMock.createMock(HttpCacheEntry.class);
         mockResponseGenerator = EasyMock.createMock(CachedHttpResponseGenerator.class);
         mockCachedResponse = EasyMock.createMock(HttpResponse.class);
         mockConditionalRequestBuilder = EasyMock.createMock(ConditionalRequestBuilder.class);
@@ -361,6 +361,7 @@ public class TestCachingHttpClient {
         cacheEntrySuitable(true);
         responseIsGeneratedFromCache();
         requestIsFatallyNonCompliant(null);
+        entryHasStaleness(0L);
 
         replayMocks();
         HttpResponse result = impl.execute(host, request, context);
@@ -706,6 +707,7 @@ public class TestCachingHttpClient {
         cacheEntrySuitable(true);
         getCacheEntryReturns(mockCacheEntry);
         responseIsGeneratedFromCache();
+        entryHasStaleness(0L);
 
         replayMocks();
         impl.execute(host, request, context);
@@ -1147,7 +1149,15 @@ public class TestCachingHttpClient {
                 mockSuitabilityChecker.canCachedResponseBeUsed(
                         EasyMock.<HttpHost>anyObject(),
                         EasyMock.<HttpRequest>anyObject(),
-                        EasyMock.<HttpCacheEntry>anyObject())).andReturn(suitable);
+                        EasyMock.<HttpCacheEntry>anyObject(),
+                        EasyMock.<Date>anyObject())).andReturn(suitable);
+    }
+
+    private void entryHasStaleness(long staleness) {
+        EasyMock.expect(mockValidityPolicy.getStalenessSecs(
+                EasyMock.<HttpCacheEntry>anyObject(),
+                EasyMock.<Date>anyObject()
+                )).andReturn(staleness);
     }
 
     private void responseIsGeneratedFromCache() {

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestConditionalRequestBuilder.java Wed Sep 15 20:00:41 2010
@@ -33,6 +33,7 @@ import org.apache.http.HeaderElement;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolException;
+import org.apache.http.client.cache.HttpCacheEntry;
 import org.apache.http.impl.cookie.DateUtils;
 import org.apache.http.message.BasicHeader;
 import org.apache.http.message.BasicHttpRequest;
@@ -62,7 +63,7 @@ public class TestConditionalRequestBuild
                 new BasicHeader("Date", DateUtils.formatDate(new Date())),
                 new BasicHeader("Last-Modified", lastModified) };
 
-        CacheEntry cacheEntry = new CacheEntry(headers);
+        HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
         HttpRequest newRequest = impl.buildConditionalRequest(request, cacheEntry);
 
         Assert.assertNotSame(request, newRequest);
@@ -94,7 +95,7 @@ public class TestConditionalRequestBuild
                 new BasicHeader("Last-Modified", DateUtils.formatDate(new Date())),
                 new BasicHeader("ETag", theETag) };
 
-        CacheEntry cacheEntry = new CacheEntry(headers);
+        HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(headers);
 
         HttpRequest newRequest = impl.buildConditionalRequest(request, cacheEntry);
 
@@ -126,7 +127,7 @@ public class TestConditionalRequestBuild
                 new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
                 new BasicHeader("ETag", "\"etag\""),
                 new BasicHeader("Cache-Control","max-age=5, must-revalidate") };
-        CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders);
+        HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders);
 
         HttpRequest result = impl.buildConditionalRequest(request, cacheEntry);
 
@@ -154,7 +155,7 @@ public class TestConditionalRequestBuild
                 new BasicHeader("Date", DateUtils.formatDate(tenSecondsAgo)),
                 new BasicHeader("ETag", "\"etag\""),
                 new BasicHeader("Cache-Control","max-age=5, proxy-revalidate") };
-        CacheEntry cacheEntry = new CacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders);
+        HttpCacheEntry cacheEntry = HttpTestUtils.makeCacheEntry(elevenSecondsAgo, nineSecondsAgo, cacheEntryHeaders);
 
         HttpRequest result = impl.buildConditionalRequest(request, cacheEntry);
 

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRecommendations.java Wed Sep 15 20:00:41 2010
@@ -93,7 +93,7 @@ public class TestProtocolRecommendations
     }
 
     private void testDoesNotReturnStaleResponseOnError(HttpRequest req2)
-    throws Exception, IOException {
+            throws Exception, IOException {
         HttpRequest req1 = requestToPopulateStaleCacheEntry();
 
         backendExpectsAnyRequest().andThrow(new IOException());
@@ -170,7 +170,7 @@ public class TestProtocolRecommendations
         HttpRequest req2 = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
         req2.setHeader("Cache-Control","max-stale=20");
 
-        backendExpectsAnyRequest().andThrow(new IOException());
+        backendExpectsAnyRequest().andThrow(new IOException()).times(0,1);
 
         replayMocks();
         impl.execute(host, req1);

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestProtocolRequirements.java Wed Sep 15 20:00:41 2010
@@ -44,6 +44,7 @@ import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
 import org.apache.http.ProtocolVersion;
 import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.cache.HttpCacheEntry;
 import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.impl.client.RequestWrapper;
@@ -2219,7 +2220,7 @@ public class TestProtocolRequirements ex
         byte[] bytes = new byte[128];
         (new Random()).nextBytes(bytes);
 
-        CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
 
         impl = new CachingHttpClient(mockBackend, mockCache, params);
 
@@ -2269,7 +2270,7 @@ public class TestProtocolRequirements ex
         byte[] bytes = new byte[128];
         (new Random()).nextBytes(bytes);
 
-        CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
 
         impl = new CachingHttpClient(mockBackend, mockCache, params);
         request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1);
@@ -2317,7 +2318,7 @@ public class TestProtocolRequirements ex
         byte[] bytes = new byte[128];
         (new Random()).nextBytes(bytes);
 
-        CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
 
         impl = new CachingHttpClient(mockBackend, mockCache, params);
         request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1);
@@ -2519,7 +2520,7 @@ public class TestProtocolRequirements ex
         byte[] bytes = new byte[128];
         (new Random()).nextBytes(bytes);
 
-        CacheEntry entry = new CacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
 
         impl = new CachingHttpClient(mockBackend, mockCache, params);
         request = new BasicHttpRequest("GET", "/thing", HttpVersion.HTTP_1_1);
@@ -2570,7 +2571,7 @@ public class TestProtocolRequirements ex
         byte[] bytes = new byte[128];
         (new Random()).nextBytes(bytes);
 
-        CacheEntry entry = new CacheEntry(requestTime, responseTime, hdrs, bytes);
+        HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(requestTime, responseTime, hdrs, bytes);
 
         impl = new CachingHttpClient(mockBackend, mockCache, params);
 

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestURIExtractor.java Wed Sep 15 20:00:41 2010
@@ -30,6 +30,7 @@ import org.apache.http.Header;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpVersion;
+import org.apache.http.client.cache.HttpCacheEntry;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.message.BasicHeader;
 import org.apache.http.message.BasicHttpRequest;
@@ -46,13 +47,13 @@ public class TestURIExtractor {
 
     URIExtractor extractor;
     private HttpHost host;
-    private CacheEntry mockEntry;
+    private HttpCacheEntry mockEntry;
     private HttpRequest mockRequest;
 
     @Before
     public void setUp() throws Exception {
         host = new HttpHost("foo.example.com");
-        mockEntry = EasyMock.createMock(CacheEntry.class);
+        mockEntry = EasyMock.createMock(HttpCacheEntry.class);
         mockRequest = EasyMock.createMock(HttpRequest.class);
         extractor = new URIExtractor();
     }

Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java?rev=997480&r1=997479&r2=997480&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/ehcache/TestEhcacheHttpCacheStorage.java Wed Sep 15 20:00:41 2010
@@ -39,7 +39,7 @@ import org.apache.http.client.cache.Http
 import org.apache.http.client.cache.HttpCacheUpdateCallback;
 import org.apache.http.client.cache.HttpCacheUpdateException;
 import org.apache.http.impl.client.cache.CacheConfig;
-import org.apache.http.impl.client.cache.CacheEntry;
+import org.apache.http.impl.client.cache.HttpTestUtils;
 import org.easymock.EasyMock;
 import org.junit.Test;
 
@@ -70,7 +70,7 @@ public class TestEhcacheHttpCacheStorage
     @Test
     public void testCachePut() throws IOException {
         final String key = "foo";
-        final HttpCacheEntry value = new CacheEntry();
+        final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
 
         Element e = new Element(key, new byte[]{});
 
@@ -98,7 +98,7 @@ public class TestEhcacheHttpCacheStorage
     @Test
     public void testCacheGet() throws IOException {
         final String key = "foo";
-        final HttpCacheEntry cachedValue = new CacheEntry();
+        final HttpCacheEntry cachedValue = HttpTestUtils.makeCacheEntry();
 
         Element element = new Element(key, new byte[]{});
 
@@ -128,7 +128,7 @@ public class TestEhcacheHttpCacheStorage
     @Test
     public void testCacheUpdateNullEntry() throws IOException, HttpCacheUpdateException {
         final String key = "foo";
-        final HttpCacheEntry updatedValue = new CacheEntry();
+        final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
 
         Element element = new Element(key, new byte[]{});
 
@@ -154,8 +154,8 @@ public class TestEhcacheHttpCacheStorage
     @Test
     public void testCacheUpdate() throws IOException, HttpCacheUpdateException {
         final String key = "foo";
-        final HttpCacheEntry existingValue = new CacheEntry();
-        final HttpCacheEntry updatedValue = new CacheEntry();
+        final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry();
+        final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
 
         Element existingElement = new Element(key, new byte[]{});
 
@@ -182,8 +182,8 @@ public class TestEhcacheHttpCacheStorage
     @Test
     public void testSingleCacheUpdateRetry() throws IOException, HttpCacheUpdateException {
         final String key = "foo";
-        final HttpCacheEntry existingValue = new CacheEntry();
-        final HttpCacheEntry updatedValue = new CacheEntry();
+        final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry();
+        final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
 
         Element existingElement = new Element(key, new byte[]{});
 
@@ -214,8 +214,8 @@ public class TestEhcacheHttpCacheStorage
     @Test
     public void testCacheUpdateFail() throws IOException, HttpCacheUpdateException {
         final String key = "foo";
-        final HttpCacheEntry existingValue = new CacheEntry();
-        final HttpCacheEntry updatedValue = new CacheEntry();
+        final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry();
+        final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
 
         Element existingElement = new Element(key, new byte[]{});