Chromium Code Reviews| Index: components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java |
| diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java |
| index 18c3d729a7d21a7d92c049c7420a71dae3b3ba3b..535f9f4f3b907a67066e064eac1f64e6129f411e 100644 |
| --- a/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java |
| +++ b/components/cronet/android/test/javatests/src/org/chromium/net/SdchTest.java |
| @@ -4,70 +4,90 @@ |
| package org.chromium.net; |
| +import android.os.ConditionVariable; |
| import android.test.suitebuilder.annotation.SmallTest; |
| +import org.chromium.base.Log; |
| import org.chromium.base.test.util.Feature; |
| +import org.chromium.net.SdchTestUtil.SdchObserverCallback; |
| +import java.io.BufferedReader; |
| +import java.io.FileReader; |
| +import java.io.IOException; |
| +import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| +import java.util.List; |
| import java.util.Map; |
| /** |
| * Tests Sdch support. |
| */ |
| public class SdchTest extends CronetTestBase { |
| + private static final String TAG = Log.makeTag("SdchTest"); |
| private CronetTestActivity mActivity; |
| - private void setUp(boolean enableSdch) { |
| - UrlRequestContextConfig config = new UrlRequestContextConfig(); |
| - config.enableSDCH(enableSdch); |
| - config.setLibraryName("cronet_tests"); |
| - config.enableHttpCache(UrlRequestContextConfig.HttpCache.IN_MEMORY, 100 * 1024); |
| - String[] commandLineArgs = {CronetTestActivity.CONFIG_KEY, config.toString()}; |
| - mActivity = launchCronetTestAppWithUrlAndCommandLineArgs(null, commandLineArgs); |
| - mActivity.startNetLog(); |
| - |
| - // Registers custom DNS mapping for legacy ChromiumUrlRequestFactory. |
| - ChromiumUrlRequestFactory factory = (ChromiumUrlRequestFactory) mActivity.mRequestFactory; |
| - long legacyAdapter = factory.getRequestContext().getUrlRequestContextAdapterForTesting(); |
| - assertTrue(legacyAdapter != 0); |
| - NativeTestServer.registerHostResolverProc(legacyAdapter, true); |
| - |
| - // Registers custom DNS mapping for CronetUrlRequestContext. |
| - CronetUrlRequestContext requestContext = |
| - (CronetUrlRequestContext) mActivity.mUrlRequestContext; |
| - long adapter = requestContext.getUrlRequestContextAdapter(); |
| - assertTrue(adapter != 0); |
| - NativeTestServer.registerHostResolverProc(adapter, false); |
| - |
| - // Starts NativeTestServer. |
| + private enum SDCH { |
| + ENABLED, |
| + DISABLED, |
| + } |
| + |
| + private enum API { |
| + LEGACY, |
| + ASYNC, |
| + } |
| + |
| + private void setUp(SDCH setting, API api) { |
| + List<String> commandLineArgs = new ArrayList<String>(); |
| + commandLineArgs.add(CronetTestActivity.CACHE_KEY); |
| + commandLineArgs.add(CronetTestActivity.CACHE_DISK); |
| + if (setting == SDCH.ENABLED) { |
| + commandLineArgs.add(CronetTestActivity.SDCH_KEY); |
| + commandLineArgs.add(CronetTestActivity.SDCH_ENABLE); |
| + } |
| + |
| + String[] args = new String[commandLineArgs.size()]; |
| + mActivity = |
| + launchCronetTestAppWithUrlAndCommandLineArgs(null, commandLineArgs.toArray(args)); |
| + long urlRequestContextAdapter = (api == API.LEGACY) |
| + ? getContextAdapter((ChromiumUrlRequestFactory) mActivity.mRequestFactory) |
| + : getContextAdapter((CronetUrlRequestContext) mActivity.mUrlRequestContext); |
| + NativeTestServer.registerHostResolverProc(urlRequestContextAdapter, api == API.LEGACY); |
| + // Start NativeTestServer. |
| assertTrue(NativeTestServer.startNativeTestServer(getInstrumentation().getTargetContext())); |
| } |
| @Override |
| protected void tearDown() throws Exception { |
| NativeTestServer.shutdownNativeTestServer(); |
| - mActivity.stopNetLog(); |
| super.tearDown(); |
| } |
| @SmallTest |
| @Feature({"Cronet"}) |
| public void testSdchEnabled_LegacyAPI() throws Exception { |
| - setUp(true); |
| + setUp(SDCH.ENABLED, API.LEGACY); |
| + String targetUrl = NativeTestServer.getSdchURL() + "/sdch/test"; |
| + long contextAdapter = |
| + getContextAdapter((ChromiumUrlRequestFactory) mActivity.mRequestFactory); |
| + Callback callback = new Callback(); |
|
mef
2015/05/21 17:29:44
Optional: I think 'Callback' is too generic, so it
xunjieli
2015/05/21 17:45:26
Done.
|
| + assertTrue(SdchTestUtil.registerSdchObserverCallback( |
| + targetUrl, contextAdapter, callback, true /** Legacy API */)); |
| + |
| // Make a request to /sdch/index which advertises the dictionary. |
| - TestHttpUrlRequestListener listener1 = startAndWaitForComplete_LegacyAPI( |
| - NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| + TestHttpUrlRequestListener listener1 = |
| + startAndWaitForComplete_LegacyAPI(mActivity.mRequestFactory, |
| + NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| assertEquals(200, listener1.mHttpStatusCode); |
| assertEquals("This is an index page.\n", listener1.mResponseAsString); |
| assertEquals(Arrays.asList("/sdch/dict/LeQxM80O"), |
| listener1.mResponseHeaders.get("Get-Dictionary")); |
| - waitForDictionaryAdded("LeQxM80O", true); |
| + callback.waitForDictionaryAdded("LeQxM80O"); |
| // Make a request to fetch encoded response at /sdch/test. |
| TestHttpUrlRequestListener listener2 = |
| - startAndWaitForComplete_LegacyAPI(NativeTestServer.getSdchURL() + "/sdch/test"); |
| + startAndWaitForComplete_LegacyAPI(mActivity.mRequestFactory, targetUrl); |
| assertEquals(200, listener2.mHttpStatusCode); |
| assertEquals("The quick brown fox jumps over the lazy dog.\n", listener2.mResponseAsString); |
| } |
| @@ -75,11 +95,12 @@ public class SdchTest extends CronetTestBase { |
| @SmallTest |
| @Feature({"Cronet"}) |
| public void testSdchDisabled_LegacyAPI() throws Exception { |
| - setUp(false); |
| + setUp(SDCH.DISABLED, API.LEGACY); |
| // Make a request to /sdch/index. |
| // Since Sdch is not enabled, no dictionary should be advertised. |
| - TestHttpUrlRequestListener listener = startAndWaitForComplete_LegacyAPI( |
| - NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| + TestHttpUrlRequestListener listener = |
| + startAndWaitForComplete_LegacyAPI(mActivity.mRequestFactory, |
| + NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| assertEquals(200, listener.mHttpStatusCode); |
| assertEquals("This is an index page.\n", listener.mResponseAsString); |
| assertEquals(null, listener.mResponseHeaders.get("Get-Dictionary")); |
| @@ -88,21 +109,20 @@ public class SdchTest extends CronetTestBase { |
| @SmallTest |
| @Feature({"Cronet"}) |
| public void testDictionaryNotFound_LegacyAPI() throws Exception { |
| - setUp(true); |
| + setUp(SDCH.ENABLED, API.LEGACY); |
| // Make a request to /sdch/index which advertises a bad dictionary that |
| // does not exist. |
| - TestHttpUrlRequestListener listener1 = startAndWaitForComplete_LegacyAPI( |
| - NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound"); |
| + TestHttpUrlRequestListener listener1 = |
| + startAndWaitForComplete_LegacyAPI(mActivity.mRequestFactory, |
| + NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound"); |
| assertEquals(200, listener1.mHttpStatusCode); |
| assertEquals("This is an index page.\n", listener1.mResponseAsString); |
| assertEquals(Arrays.asList("/sdch/dict/NotFound"), |
| listener1.mResponseHeaders.get("Get-Dictionary")); |
| - waitForDictionaryAdded("NotFound", true); |
| - |
| - // Make a request to fetch /sdch/test, and make sure Sdch encoding is not used. |
| - TestHttpUrlRequestListener listener2 = |
| - startAndWaitForComplete_LegacyAPI(NativeTestServer.getSdchURL() + "/sdch/test"); |
| + // Make a request to fetch /sdch/test, and make sure request succeeds. |
| + TestHttpUrlRequestListener listener2 = startAndWaitForComplete_LegacyAPI( |
| + mActivity.mRequestFactory, NativeTestServer.getSdchURL() + "/sdch/test"); |
| assertEquals(200, listener2.mHttpStatusCode); |
| assertEquals("Sdch is not used.\n", listener2.mResponseAsString); |
| } |
| @@ -110,32 +130,68 @@ public class SdchTest extends CronetTestBase { |
| @SmallTest |
| @Feature({"Cronet"}) |
| public void testSdchEnabled() throws Exception { |
| - setUp(true); |
| + setUp(SDCH.ENABLED, API.ASYNC); |
| + String targetUrl = NativeTestServer.getSdchURL() + "/sdch/test"; |
| + long contextAdapter = |
| + getContextAdapter((CronetUrlRequestContext) mActivity.mUrlRequestContext); |
| + Callback callback = new Callback(); |
| + assertTrue(SdchTestUtil.registerSdchObserverCallback( |
| + targetUrl, contextAdapter, callback, false /** Legacy API */)); |
| + |
| // Make a request to /sdch which advertises the dictionary. |
| - TestUrlRequestListener listener1 = |
| - startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| + TestUrlRequestListener listener1 = startAndWaitForComplete(mActivity.mUrlRequestContext, |
| + NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| assertEquals(200, listener1.mResponseInfo.getHttpStatusCode()); |
| assertEquals("This is an index page.\n", listener1.mResponseAsString); |
| assertEquals(Arrays.asList("/sdch/dict/LeQxM80O"), |
| listener1.mResponseInfo.getAllHeaders().get("Get-Dictionary")); |
| - waitForDictionaryAdded("LeQxM80O", false); |
| + callback.waitForDictionaryAdded("LeQxM80O"); |
| // Make a request to fetch encoded response at /sdch/test. |
| TestUrlRequestListener listener2 = |
| - startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/test"); |
| - assertEquals(200, listener1.mResponseInfo.getHttpStatusCode()); |
| + startAndWaitForComplete(mActivity.mUrlRequestContext, targetUrl); |
| + assertEquals(200, listener2.mResponseInfo.getHttpStatusCode()); |
| assertEquals("The quick brown fox jumps over the lazy dog.\n", listener2.mResponseAsString); |
| + |
| + // Wait for a bit until SimpleCache finished closing entries before |
| + // calling shutdown on the UrlRequestContext. |
| + // TODO(xunjieli): Remove once crbug.com/486120 is fixed. |
| + Thread.sleep(5000); |
| + mActivity.mUrlRequestContext.shutdown(); |
| + |
| + // Shutting down the context will make JsonPrefStore to flush pending |
| + // writes to disk. |
| + String dictUrl = NativeTestServer.getSdchURL() + "/sdch/dict/LeQxM80O"; |
| + assertTrue(fileContainsString("local_prefs.json", dictUrl)); |
| + |
| + // Test persistence. |
| + CronetUrlRequestContext newContext = new CronetUrlRequestContext( |
| + getInstrumentation().getTargetContext(), mActivity.getContextConfig()); |
| + |
| + long newContextAdapter = getContextAdapter(newContext); |
| + NativeTestServer.registerHostResolverProc(newContextAdapter, false); |
| + Callback newCallback = new Callback(); |
| + // Only wait for dictionaries when they are yet to be loaded. |
| + if (SdchTestUtil.registerSdchObserverCallback( |
| + targetUrl, newContextAdapter, newCallback, false /** Legacy API */)) { |
| + newCallback.waitForDictionaryAdded("LeQxM80O"); |
| + } |
| + |
| + // Make a request to fetch encoded response at /sdch/test. |
| + TestUrlRequestListener listener3 = startAndWaitForComplete(newContext, targetUrl); |
| + assertEquals(200, listener3.mResponseInfo.getHttpStatusCode()); |
| + assertEquals("The quick brown fox jumps over the lazy dog.\n", listener3.mResponseAsString); |
| } |
| @SmallTest |
| @Feature({"Cronet"}) |
| public void testSdchDisabled() throws Exception { |
| - setUp(false); |
| + setUp(SDCH.DISABLED, API.ASYNC); |
| // Make a request to /sdch. |
| // Since Sdch is not enabled, no dictionary should be advertised. |
| - TestUrlRequestListener listener = |
| - startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| + TestUrlRequestListener listener = startAndWaitForComplete(mActivity.mUrlRequestContext, |
| + NativeTestServer.getSdchURL() + "/sdch/index?q=LeQxM80O"); |
| assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); |
| assertEquals("This is an index page.\n", listener.mResponseAsString); |
| assertEquals(null, listener.mResponseInfo.getAllHeaders().get("Get-Dictionary")); |
| @@ -144,75 +200,81 @@ public class SdchTest extends CronetTestBase { |
| @SmallTest |
| @Feature({"Cronet"}) |
| public void testDictionaryNotFound() throws Exception { |
| - setUp(true); |
| + setUp(SDCH.ENABLED, API.ASYNC); |
| // Make a request to /sdch/index which advertises a bad dictionary that |
| // does not exist. |
| - TestUrlRequestListener listener1 = |
| - startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound"); |
| + TestUrlRequestListener listener1 = startAndWaitForComplete(mActivity.mUrlRequestContext, |
| + NativeTestServer.getSdchURL() + "/sdch/index?q=NotFound"); |
| assertEquals(200, listener1.mResponseInfo.getHttpStatusCode()); |
| assertEquals("This is an index page.\n", listener1.mResponseAsString); |
| assertEquals(Arrays.asList("/sdch/dict/NotFound"), |
| listener1.mResponseInfo.getAllHeaders().get("Get-Dictionary")); |
| - waitForDictionaryAdded("NotFound", false); |
| - |
| // Make a request to fetch /sdch/test, and make sure Sdch encoding is not used. |
| - TestUrlRequestListener listener2 = |
| - startAndWaitForComplete(NativeTestServer.getSdchURL() + "/sdch/test"); |
| + TestUrlRequestListener listener2 = startAndWaitForComplete( |
| + mActivity.mUrlRequestContext, NativeTestServer.getSdchURL() + "/sdch/test"); |
| assertEquals(200, listener2.mResponseInfo.getHttpStatusCode()); |
| assertEquals("Sdch is not used.\n", listener2.mResponseAsString); |
| } |
| - /** |
| - * Helper method to wait for dictionary to be fetched and added to the list of available |
| - * dictionaries. |
| - */ |
| - private void waitForDictionaryAdded(String dict, boolean isLegacyAPI) throws Exception { |
| - // Since Http cache is enabled, making a request to the dictionary explicitly will |
| - // be served from the cache. |
| - String url = NativeTestServer.getSdchURL() + "/sdch/dict/" + dict; |
| - if (isLegacyAPI) { |
| - TestHttpUrlRequestListener listener = startAndWaitForComplete_LegacyAPI(url); |
| - if (dict.equals("NotFound")) { |
| - assertEquals(404, listener.mHttpStatusCode); |
| - } else { |
| - assertEquals(200, listener.mHttpStatusCode); |
| - assertTrue(listener.mWasCached); |
| - } |
| - } else { |
| - TestUrlRequestListener listener = startAndWaitForComplete(url); |
| - if (dict.equals("NotFound")) { |
| - assertEquals(404, listener.mResponseInfo.getHttpStatusCode()); |
| - } else { |
| - assertEquals(200, listener.mResponseInfo.getHttpStatusCode()); |
| - assertTrue(listener.mResponseInfo.wasCached()); |
| - } |
| + private static class Callback extends SdchObserverCallback { |
| + ConditionVariable mBlock = new ConditionVariable(); |
| + private String mLastAddedDict; |
| + |
| + @Override |
| + public void onDictionaryAdded(String url) { |
| + Log.i(TAG, "Dictionary %s is added ", url); |
| + mLastAddedDict = url; |
| + mBlock.open(); |
| } |
| - // Now wait for dictionary to be added to the manager, which occurs |
| - // asynchronously. |
| - // TODO(xunjieli): Rather than setting an arbitrary delay, consider |
| - // implementing a SdchObserver to watch for dictionary add events once |
| - // add event is implemented in SdchObserver. |
| - Thread.sleep(1000); |
| + |
| + public void waitForDictionaryAdded(String dictName) { |
| + mBlock.block(); |
| + mBlock.close(); |
| + assertTrue(mLastAddedDict.contains(dictName)); |
| + } |
| + } |
| + |
| + private long getContextAdapter(ChromiumUrlRequestFactory factory) { |
| + return factory.getRequestContext().getUrlRequestContextAdapter(); |
| + } |
| + |
| + private long getContextAdapter(CronetUrlRequestContext requestContext) { |
| + return requestContext.getUrlRequestContextAdapter(); |
| } |
| - private TestHttpUrlRequestListener startAndWaitForComplete_LegacyAPI(String url) |
| - throws Exception { |
| + private TestHttpUrlRequestListener startAndWaitForComplete_LegacyAPI( |
| + HttpUrlRequestFactory factory, String url) throws Exception { |
| Map<String, String> headers = new HashMap<String, String>(); |
| TestHttpUrlRequestListener listener = new TestHttpUrlRequestListener(); |
| - HttpUrlRequest request = mActivity.mRequestFactory.createRequest( |
| + HttpUrlRequest request = factory.createRequest( |
| url, HttpUrlRequest.REQUEST_PRIORITY_MEDIUM, headers, listener); |
| request.start(); |
| listener.blockForComplete(); |
| return listener; |
| } |
| - private TestUrlRequestListener startAndWaitForComplete(String url) throws Exception { |
| + private TestUrlRequestListener startAndWaitForComplete( |
| + UrlRequestContext requestContext, String url) throws Exception { |
| TestUrlRequestListener listener = new TestUrlRequestListener(); |
| - UrlRequest request = |
| - mActivity.mUrlRequestContext.createRequest(url, listener, listener.getExecutor()); |
| + UrlRequest request = requestContext.createRequest(url, listener, listener.getExecutor()); |
| request.start(); |
| listener.blockForDone(); |
| return listener; |
| } |
| + |
| + // Returns whether a file contains a particular string. |
| + private boolean fileContainsString(String filename, String content) throws IOException { |
| + BufferedReader reader = |
| + new BufferedReader(new FileReader(mActivity.getTestStorage() + "/" + filename)); |
| + String line; |
| + while ((line = reader.readLine()) != null) { |
| + if (line.contains(content)) { |
| + reader.close(); |
| + return true; |
| + } |
| + } |
| + reader.close(); |
| + return false; |
| + } |
| } |