1e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/*
2e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Copyright (C) 2011 The Android Open Source Project
3e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *
4e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
5e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * you may not use this file except in compliance with the License.
6e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * You may obtain a copy of the License at
7e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *
8e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *      http://www.apache.org/licenses/LICENSE-2.0
9e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller *
10e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Unless required by applicable law or agreed to in writing, software
11e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
12e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * See the License for the specific language governing permissions and
14e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * limitations under the License.
15e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */
16e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
17e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpackage com.squareup.okhttp.android;
18e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
19e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.AndroidInternal;
2071b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fullerimport com.squareup.okhttp.HttpUrl;
21e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.OkHttpClient;
22e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.OkUrlFactory;
23e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.mockwebserver.MockResponse;
24e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport com.squareup.okhttp.mockwebserver.MockWebServer;
25e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.File;
26e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.InputStream;
27e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.CacheRequest;
28e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.CacheResponse;
29e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.ResponseCache;
30e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.URI;
31e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.net.URLConnection;
32e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.List;
33e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.Map;
3471b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fullerimport org.junit.After;
3571b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fullerimport org.junit.Before;
3671b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fullerimport org.junit.Rule;
3771b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fullerimport org.junit.Test;
3871b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fullerimport org.junit.rules.TemporaryFolder;
39e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
40e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertEquals;
41e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertNotNull;
42e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertNotSame;
43e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertNull;
44e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertSame;
45e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.fail;
46e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
47e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/**
48e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * A port of Android's android.net.http.HttpResponseCacheTest to JUnit4.
49e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */
50e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpublic final class HttpResponseCacheTest {
51e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
52e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Rule public TemporaryFolder cacheRule = new TemporaryFolder();
5371b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller  @Rule public MockWebServer server = new MockWebServer();
54e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
55e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private File cacheDir;
56e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private OkUrlFactory client;
57e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
58e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Before public void setUp() throws Exception {
59e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    cacheDir = cacheRule.getRoot();
60e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    client = new OkUrlFactory(new OkHttpClient());
61e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
62e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
63e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @After public void tearDown() throws Exception {
64e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    ResponseCache.setDefault(null);
65e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
66e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
67e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void install() throws Exception {
68e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache installed = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
69e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertNotNull(installed);
70e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertSame(installed, ResponseCache.getDefault());
71e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertSame(installed, HttpResponseCache.getDefault());
72e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
73e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
74e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void secondEquivalentInstallDoesNothing() throws Exception {
75e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
76e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache another = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
77e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertSame(first, another);
78e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
79e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
80e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void installClosesPreviouslyInstalled() throws Exception {
81e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
82e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    initializeCache(first);
83e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
84e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache another = HttpResponseCache.install(cacheDir, 8 * 1024 * 1024);
85e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    initializeCache(another);
86e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
87e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertNotSame(first, another);
88e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    try {
89e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      first.flush();
90e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      fail();
91e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    } catch (IllegalStateException expected) {
92e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    }
93e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
94e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
95e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void getInstalledWithWrongTypeInstalled() {
96e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    ResponseCache.setDefault(new ResponseCache() {
97e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      @Override
98e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      public CacheResponse get(URI uri, String requestMethod,
99e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller          Map<String, List<String>> requestHeaders) {
100e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        return null;
101e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      }
102e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
103e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      @Override
104e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      public CacheRequest put(URI uri, URLConnection connection) {
105e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        return null;
106e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      }
107e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    });
108e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertNull(HttpResponseCache.getInstalled());
109e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
110e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
111e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void closeCloses() throws Exception {
112e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
113e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    initializeCache(cache);
114e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
115e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    cache.close();
116e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    try {
117e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      cache.flush();
118e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller      fail();
119e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    } catch (IllegalStateException expected) {
120e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    }
121e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
122e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
123e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void closeUninstalls() throws Exception {
124e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
125e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    cache.close();
126e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertNull(ResponseCache.getDefault());
127e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
128e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
129e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void deleteUninstalls() throws Exception {
130e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
131e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    cache.delete();
132e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertNull(ResponseCache.getDefault());
133e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
134e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
135e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  /**
136e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller   * Make sure that statistics tracking are wired all the way through the
137e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller   * wrapper class. http://code.google.com/p/android/issues/detail?id=25418
138e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller   */
139e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  @Test public void statisticsTracking() throws Exception {
140e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
141e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
142e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    server.enqueue(new MockResponse()
143e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        .addHeader("Cache-Control: max-age=60")
144e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller        .setBody("A"));
145e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
14671b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller    URLConnection c1 = openUrl(server.url("/"));
147e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
148e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    InputStream inputStream = c1.getInputStream();
149e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals('A', inputStream.read());
150e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    inputStream.close();
151e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(1, cache.getRequestCount());
152e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(1, cache.getNetworkCount());
153e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(0, cache.getHitCount());
154e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
15571b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller    URLConnection c2 = openUrl(server.url("/"));
156e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals('A', c2.getInputStream().read());
157e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
15871b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller    URLConnection c3 = openUrl(server.url("/"));
159e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals('A', c3.getInputStream().read());
160e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(3, cache.getRequestCount());
161e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(1, cache.getNetworkCount());
162e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    assertEquals(2, cache.getHitCount());
163e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
164e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
165e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  // This mimics the Android HttpHandler, which is found in the com.squareup.okhttp package.
16671b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller  private URLConnection openUrl(HttpUrl url) {
167e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    ResponseCache responseCache = ResponseCache.getDefault();
168e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    AndroidInternal.setResponseCache(client, responseCache);
16971b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller    return client.open(url.url());
170e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
171e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller
172e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private void initializeCache(HttpResponseCache cache) {
173e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    // Ensure the cache is initialized, otherwise various methods are no-ops.
174e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    cache.size();
175e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  }
176e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller}
177