1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.net; 6 7 import static org.junit.Assert.assertEquals; 8 import static org.junit.Assert.assertFalse; 9 import static org.junit.Assert.assertTrue; 10 import static org.junit.Assert.fail; 11 12 import static org.chromium.net.CronetTestRule.getContext; 13 import static org.chromium.net.CronetTestRule.getTestStorage; 14 15 import android.net.http.HttpEngine; 16 import android.net.http.ExperimentalHttpEngine; 17 import android.net.http.UrlRequest; 18 19 import androidx.test.ext.junit.runners.AndroidJUnit4; 20 import androidx.test.filters.SmallTest; 21 22 import org.junit.After; 23 import org.junit.Before; 24 import org.junit.Rule; 25 import org.junit.Test; 26 import org.junit.runner.RunWith; 27 28 import org.chromium.base.FileUtils; 29 import org.chromium.base.PathUtils; 30 import org.chromium.net.CronetTestRule.OnlyRunNativeCronet; 31 32 import java.io.BufferedReader; 33 import java.io.File; 34 import java.io.FileInputStream; 35 import java.io.FileOutputStream; 36 import java.io.FileReader; 37 import java.util.Arrays; 38 39 /** 40 * Test CronetEngine disk storage. 41 */ 42 @RunWith(AndroidJUnit4.class) 43 public class DiskStorageTest { 44 @Rule 45 public final CronetTestRule mTestRule = new CronetTestRule(); 46 47 private String mReadOnlyStoragePath; 48 49 @Before setUp()50 public void setUp() throws Exception { 51 System.loadLibrary("cronet_tests"); 52 assertTrue(NativeTestServer.startNativeTestServer(getContext())); 53 } 54 55 @After tearDown()56 public void tearDown() throws Exception { 57 if (mReadOnlyStoragePath != null) { 58 FileUtils.recursivelyDeleteFile(new File(mReadOnlyStoragePath), FileUtils.DELETE_ALL); 59 } 60 NativeTestServer.shutdownNativeTestServer(); 61 } 62 63 @Test 64 @SmallTest 65 @OnlyRunNativeCronet 66 // Crashing on Android Cronet Builder, see crbug.com/601409. testReadOnlyStorageDirectory()67 public void testReadOnlyStorageDirectory() throws Exception { 68 mReadOnlyStoragePath = PathUtils.getDataDirectory() + "/read_only"; 69 File readOnlyStorage = new File(mReadOnlyStoragePath); 70 assertTrue(readOnlyStorage.mkdir()); 71 // Setting the storage directory as readonly has no effect. 72 assertTrue(readOnlyStorage.setReadOnly()); 73 ExperimentalHttpEngine.Builder builder = 74 new ExperimentalHttpEngine.Builder(getContext()); 75 builder.setStoragePath(mReadOnlyStoragePath); 76 builder.setEnableHttpCache(HttpEngine.Builder.HTTP_CACHE_DISK, 1024 * 1024); 77 78 HttpEngine cronetEngine = builder.build(); 79 TestUrlRequestCallback callback = new TestUrlRequestCallback(); 80 String url = NativeTestServer.getFileURL("/cacheable.txt"); 81 UrlRequest.Builder requestBuilder = 82 cronetEngine.newUrlRequestBuilder(url, callback, callback.getExecutor()); 83 UrlRequest urlRequest = requestBuilder.build(); 84 urlRequest.start(); 85 callback.blockForDone(); 86 assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); 87 cronetEngine.shutdown(); 88 FileInputStream newVersionFile = null; 89 // Make sure that version file is in readOnlyStoragePath. 90 File versionFile = new File(mReadOnlyStoragePath + "/version"); 91 try { 92 newVersionFile = new FileInputStream(versionFile); 93 byte[] buffer = new byte[] {0, 0, 0, 0}; 94 int bytesRead = newVersionFile.read(buffer, 0, 4); 95 assertEquals(4, bytesRead); 96 assertTrue(Arrays.equals(new byte[] {1, 0, 0, 0}, buffer)); 97 } finally { 98 if (newVersionFile != null) { 99 newVersionFile.close(); 100 } 101 } 102 File diskCacheDir = new File(mReadOnlyStoragePath + "/disk_cache"); 103 assertTrue(diskCacheDir.exists()); 104 File prefsDir = new File(mReadOnlyStoragePath + "/prefs"); 105 assertTrue(prefsDir.exists()); 106 } 107 108 @Test 109 @SmallTest 110 @OnlyRunNativeCronet 111 // Crashing on Android Cronet Builder, see crbug.com/601409. testPurgeOldVersion()112 public void testPurgeOldVersion() throws Exception { 113 String testStorage = getTestStorage(getContext()); 114 File versionFile = new File(testStorage + "/version"); 115 FileOutputStream versionOut = null; 116 try { 117 versionOut = new FileOutputStream(versionFile); 118 versionOut.write(new byte[] {0, 0, 0, 0}, 0, 4); 119 } finally { 120 if (versionOut != null) { 121 versionOut.close(); 122 } 123 } 124 File oldPrefsFile = new File(testStorage + "/local_prefs.json"); 125 FileOutputStream oldPrefsOut = null; 126 try { 127 oldPrefsOut = new FileOutputStream(oldPrefsFile); 128 String dummy = "dummy content"; 129 oldPrefsOut.write(dummy.getBytes(), 0, dummy.length()); 130 } finally { 131 if (oldPrefsOut != null) { 132 oldPrefsOut.close(); 133 } 134 } 135 136 ExperimentalHttpEngine.Builder builder = 137 new ExperimentalHttpEngine.Builder(getContext()); 138 builder.setStoragePath(getTestStorage(getContext())); 139 builder.setEnableHttpCache(HttpEngine.Builder.HTTP_CACHE_DISK, 1024 * 1024); 140 141 HttpEngine cronetEngine = builder.build(); 142 TestUrlRequestCallback callback = new TestUrlRequestCallback(); 143 String url = NativeTestServer.getFileURL("/cacheable.txt"); 144 UrlRequest.Builder requestBuilder = 145 cronetEngine.newUrlRequestBuilder(url, callback, callback.getExecutor()); 146 UrlRequest urlRequest = requestBuilder.build(); 147 urlRequest.start(); 148 callback.blockForDone(); 149 assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); 150 cronetEngine.shutdown(); 151 FileInputStream newVersionFile = null; 152 try { 153 newVersionFile = new FileInputStream(versionFile); 154 byte[] buffer = new byte[] {0, 0, 0, 0}; 155 int bytesRead = newVersionFile.read(buffer, 0, 4); 156 assertEquals(4, bytesRead); 157 assertTrue(Arrays.equals(new byte[] {1, 0, 0, 0}, buffer)); 158 } finally { 159 if (newVersionFile != null) { 160 newVersionFile.close(); 161 } 162 } 163 oldPrefsFile = new File(testStorage + "/local_prefs.json"); 164 assertTrue(!oldPrefsFile.exists()); 165 File diskCacheDir = new File(testStorage + "/disk_cache"); 166 assertTrue(diskCacheDir.exists()); 167 File prefsDir = new File(testStorage + "/prefs"); 168 assertTrue(prefsDir.exists()); 169 } 170 171 @Test 172 @SmallTest 173 @OnlyRunNativeCronet 174 // Tests that if cache version is current, Cronet does not purge the directory. testCacheVersionCurrent()175 public void testCacheVersionCurrent() throws Exception { 176 // Initialize a CronetEngine and shut it down. 177 ExperimentalHttpEngine.Builder builder = 178 new ExperimentalHttpEngine.Builder(getContext()); 179 builder.setStoragePath(getTestStorage(getContext())); 180 builder.setEnableHttpCache(HttpEngine.Builder.HTTP_CACHE_DISK, 1024 * 1024); 181 182 HttpEngine cronetEngine = builder.build(); 183 TestUrlRequestCallback callback = new TestUrlRequestCallback(); 184 String url = NativeTestServer.getFileURL("/cacheable.txt"); 185 UrlRequest.Builder requestBuilder = 186 cronetEngine.newUrlRequestBuilder(url, callback, callback.getExecutor()); 187 UrlRequest urlRequest = requestBuilder.build(); 188 urlRequest.start(); 189 callback.blockForDone(); 190 assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); 191 cronetEngine.shutdown(); 192 193 // Create a dummy file in storage directory. 194 String testStorage = getTestStorage(getContext()); 195 File dummyFile = new File(testStorage + "/dummy.json"); 196 FileOutputStream dummyFileOut = null; 197 String dummyContent = "dummy content"; 198 try { 199 dummyFileOut = new FileOutputStream(dummyFile); 200 dummyFileOut.write(dummyContent.getBytes(), 0, dummyContent.length()); 201 } finally { 202 if (dummyFileOut != null) { 203 dummyFileOut.close(); 204 } 205 } 206 207 // Creates a new CronetEngine and make a request. 208 HttpEngine engine = builder.build(); 209 TestUrlRequestCallback callback2 = new TestUrlRequestCallback(); 210 String url2 = NativeTestServer.getFileURL("/cacheable.txt"); 211 UrlRequest.Builder requestBuilder2 = 212 engine.newUrlRequestBuilder(url2, callback2, callback2.getExecutor()); 213 UrlRequest urlRequest2 = requestBuilder2.build(); 214 urlRequest2.start(); 215 callback2.blockForDone(); 216 assertEquals(200, callback2.mResponseInfo.getHttpStatusCode()); 217 engine.shutdown(); 218 // Dummy file still exists. 219 BufferedReader reader = new BufferedReader(new FileReader(dummyFile)); 220 StringBuilder stringBuilder = new StringBuilder(); 221 String line; 222 while ((line = reader.readLine()) != null) { 223 stringBuilder.append(line); 224 } 225 reader.close(); 226 assertEquals(dummyContent, stringBuilder.toString()); 227 File diskCacheDir = new File(testStorage + "/disk_cache"); 228 assertTrue(diskCacheDir.exists()); 229 File prefsDir = new File(testStorage + "/prefs"); 230 assertTrue(prefsDir.exists()); 231 } 232 233 @Test 234 @SmallTest 235 @OnlyRunNativeCronet 236 // Tests that enableHttpCache throws if storage path not set testEnableHttpCacheThrowsIfStoragePathNotSet()237 public void testEnableHttpCacheThrowsIfStoragePathNotSet() throws Exception { 238 // Initialize a CronetEngine and shut it down. 239 ExperimentalHttpEngine.Builder builder = 240 new ExperimentalHttpEngine.Builder(getContext()); 241 try { 242 builder.setEnableHttpCache(HttpEngine.Builder.HTTP_CACHE_DISK, 1024 * 1024); 243 fail("Enabling http cache without a storage path should throw an exception"); 244 } catch (IllegalArgumentException e) { 245 // Expected 246 } 247 248 HttpEngine cronetEngine = builder.build(); 249 TestUrlRequestCallback callback = new TestUrlRequestCallback(); 250 String url = NativeTestServer.getFileURL("/cacheable.txt"); 251 UrlRequest.Builder requestBuilder = 252 cronetEngine.newUrlRequestBuilder(url, callback, callback.getExecutor()); 253 UrlRequest urlRequest = requestBuilder.build(); 254 urlRequest.start(); 255 callback.blockForDone(); 256 assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); 257 cronetEngine.shutdown(); 258 259 String testStorage = getTestStorage(getContext()); 260 File diskCacheDir = new File(testStorage + "/disk_cache"); 261 assertFalse(diskCacheDir.exists()); 262 File prefsDir = new File(testStorage + "/prefs"); 263 assertFalse(prefsDir.exists()); 264 } 265 266 @Test 267 @SmallTest 268 @OnlyRunNativeCronet 269 // Tests that prefs file is created even if httpcache isn't enabled testPrefsFileCreatedWithoutHttpCache()270 public void testPrefsFileCreatedWithoutHttpCache() throws Exception { 271 // Initialize a CronetEngine and shut it down. 272 String testStorage = getTestStorage(getContext()); 273 ExperimentalHttpEngine.Builder builder = 274 new ExperimentalHttpEngine.Builder(getContext()); 275 builder.setStoragePath(testStorage); 276 277 HttpEngine cronetEngine = builder.build(); 278 TestUrlRequestCallback callback = new TestUrlRequestCallback(); 279 String url = NativeTestServer.getFileURL("/cacheable.txt"); 280 UrlRequest.Builder requestBuilder = 281 cronetEngine.newUrlRequestBuilder(url, callback, callback.getExecutor()); 282 UrlRequest urlRequest = requestBuilder.build(); 283 urlRequest.start(); 284 callback.blockForDone(); 285 assertEquals(200, callback.mResponseInfo.getHttpStatusCode()); 286 cronetEngine.shutdown(); 287 288 File diskCacheDir = new File(testStorage + "/disk_cache"); 289 assertFalse(diskCacheDir.exists()); 290 File prefsDir = new File(testStorage + "/prefs"); 291 assertTrue(prefsDir.exists()); 292 } 293 } 294