Index: components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java |
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java b/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java |
index 0d391b041b33539fd19e225b131b632eac191a89..ab9296e98b37f9f980207313df0225cbe867d138 100644 |
--- a/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java |
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/NQETest.java |
@@ -7,10 +7,11 @@ package org.chromium.net; |
import android.os.StrictMode; |
import android.support.test.filters.SmallTest; |
+import org.json.JSONObject; |
+ |
import org.chromium.base.Log; |
import org.chromium.base.annotations.JNINamespace; |
import org.chromium.base.annotations.SuppressFBWarnings; |
-import org.chromium.base.test.util.DisabledTest; |
import org.chromium.base.test.util.Feature; |
import org.chromium.base.test.util.MetricsUtils.HistogramDelta; |
import org.chromium.net.MetricsTestUtil.TestExecutor; |
@@ -126,8 +127,8 @@ public class NQETest extends CronetTestBase { |
// Returns whether a file contains a particular string. |
@SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE") |
- private boolean fileContainsString(String filename, String content) throws IOException { |
- File file = new File(getTestStorage(getContext()) + "/prefs/" + filename); |
+ private boolean prefsFileContainsString(String content) throws IOException { |
+ File file = new File(getTestStorage(getContext()) + "/prefs/local_prefs.json"); |
FileInputStream fileInputStream = new FileInputStream(file); |
byte[] data = new byte[(int) file.length()]; |
fileInputStream.read(data); |
@@ -137,7 +138,6 @@ public class NQETest extends CronetTestBase { |
@SmallTest |
@Feature({"Cronet"}) |
- @DisabledTest(message = "Disabled due to flaky assert. See crbug.com/710626") |
public void testQuicDisabled() throws Exception { |
ExperimentalCronetEngine.Builder cronetEngineBuilder = |
new ExperimentalCronetEngine.Builder(getContext()); |
@@ -214,7 +214,7 @@ public class NQETest extends CronetTestBase { |
Log.i(TAG, "Still waiting for pref file update....."); |
Thread.sleep(12000); |
try { |
- if (fileContainsString("local_prefs.json", "network_qualities")) { |
+ if (prefsFileContainsString("network_qualities")) { |
break; |
} |
} catch (FileNotFoundException e) { |
@@ -222,9 +222,156 @@ public class NQETest extends CronetTestBase { |
// flushed to the disk. |
} |
} |
- assertTrue(fileContainsString("local_prefs.json", "network_qualities")); |
+ assertTrue(prefsFileContainsString("network_qualities")); |
cronetEngine.shutdown(); |
assertTrue(writeCountHistogram.getDelta() > 0); |
} |
+ |
+ @SmallTest |
+ @OnlyRunNativeCronet |
+ @Feature({"Cronet"}) |
+ public void testPrefsWriteRead() throws Exception { |
+ // When the loop is run for the first time, network quality is written to the disk. The |
+ // test verifies that in the next loop, the network quality is read back. |
+ for (int i = 0; i <= 1; ++i) { |
+ ExperimentalCronetEngine.Builder cronetEngineBuilder = |
+ new ExperimentalCronetEngine.Builder(getContext()); |
+ assert RttThroughputValues.INVALID_RTT_THROUGHPUT < 0; |
+ Executor listenersExecutor = |
+ Executors.newSingleThreadExecutor(new ExecutorThreadFactory()); |
+ TestNetworkQualityRttListener rttListener = |
+ new TestNetworkQualityRttListener(listenersExecutor); |
+ cronetEngineBuilder.enableNetworkQualityEstimator(true).enableHttp2(true).enableQuic( |
+ false); |
+ cronetEngineBuilder.setStoragePath(getTestStorage(getContext())); |
+ |
+ JSONObject nqeOptions = new JSONObject().put("persistent_cache_reading_enabled", true); |
+ JSONObject experimentalOptions = |
+ new JSONObject().put("NetworkQualityEstimator", nqeOptions); |
+ |
+ cronetEngineBuilder.setExperimentalOptions(experimentalOptions.toString()); |
+ final ExperimentalCronetEngine cronetEngine = cronetEngineBuilder.build(); |
+ cronetEngine.configureNetworkQualityEstimatorForTesting(true, true, true); |
+ cronetEngine.addRttListener(rttListener); |
+ |
+ HistogramDelta writeCountHistogram = new HistogramDelta("NQE.Prefs.WriteCount", 1); |
+ assertEquals(0, writeCountHistogram.getDelta()); // Sanity check. |
+ |
+ HistogramDelta readCountHistogram = new HistogramDelta("NQE.Prefs.ReadCount", 1); |
+ assertEquals(0, readCountHistogram.getDelta()); // Sanity check. |
+ |
+ HistogramDelta readPrefsSizeHistogram = new HistogramDelta("NQE.Prefs.ReadSize", 1); |
+ assertEquals(0, readPrefsSizeHistogram.getDelta()); // Sanity check. |
+ |
+ // NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE: 3 |
+ HistogramDelta cachedRttHistogram = new HistogramDelta("NQE.RTT.ObservationSource", 3); |
+ assertEquals(0, cachedRttHistogram.getDelta()); // Sanity check. |
+ |
+ TestUrlRequestCallback callback = new TestUrlRequestCallback(); |
+ UrlRequest.Builder builder = |
+ cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.getExecutor()); |
+ UrlRequest urlRequest = builder.build(); |
+ urlRequest.start(); |
+ callback.blockForDone(); |
+ |
+ // Wait for RTT observation (at the URL request layer) to be posted. |
+ rttListener.waitUntilFirstUrlRequestRTTReceived(); |
+ |
+ // Prefs must be read at startup. |
+ assertTrue(readCountHistogram.getDelta() > 0); |
+ |
+ // Check RTT observation count after throughput observation has been received. This |
+ // ensures |
+ // that executor has finished posting the RTT observation to the RTT listeners. |
+ assertTrue(rttListener.rttObservationCount() > 0); |
+ |
+ // Verify that effective connection type callback is received and |
+ // effective connection type is correctly set. |
+ assertTrue(cronetEngine.getEffectiveConnectionType() |
+ != EffectiveConnectionType.TYPE_UNKNOWN); |
+ |
+ cronetEngine.shutdown(); |
+ |
+ if (i == 0) { |
+ // Verify that the cached estimates were written to the prefs. |
+ assertTrue(prefsFileContainsString("network_qualities")); |
+ } |
+ |
+ // Stored network quality in the pref should be read in the second iteration. |
+ assertEquals(readPrefsSizeHistogram.getDelta() > 0, i > 0); |
+ assertEquals(cachedRttHistogram.getDelta() > 0, i > 0); |
+ } |
+ } |
+ |
+ @SmallTest |
+ @Feature({"Cronet"}) |
+ public void testQuicDisabledWithParams() throws Exception { |
+ ExperimentalCronetEngine.Builder cronetEngineBuilder = |
+ new ExperimentalCronetEngine.Builder(getContext()); |
+ Executor listenersExecutor = Executors.newSingleThreadExecutor(new ExecutorThreadFactory()); |
+ TestNetworkQualityRttListener rttListener = |
+ new TestNetworkQualityRttListener(listenersExecutor); |
+ TestNetworkQualityThroughputListener throughputListener = |
+ new TestNetworkQualityThroughputListener(listenersExecutor); |
+ |
+ // Force the effective connection type to "2G". |
+ JSONObject nqeOptions = new JSONObject().put("force_effective_connection_type", "Slow-2G"); |
+ // Add one more extra param two times to ensure robustness. |
+ nqeOptions.put("some_other_param_1", "value1"); |
+ nqeOptions.put("some_other_param_2", "value2"); |
+ JSONObject experimentalOptions = |
+ new JSONObject().put("NetworkQualityEstimator", nqeOptions); |
+ experimentalOptions.put("SomeOtherFieldTrialName", new JSONObject()); |
+ |
+ cronetEngineBuilder.enableNetworkQualityEstimator(true).enableHttp2(true).enableQuic(false); |
+ cronetEngineBuilder.setExperimentalOptions(experimentalOptions.toString()); |
+ final ExperimentalCronetEngine cronetEngine = cronetEngineBuilder.build(); |
+ cronetEngine.configureNetworkQualityEstimatorForTesting(true, true, false); |
+ |
+ cronetEngine.addRttListener(rttListener); |
+ cronetEngine.addThroughputListener(throughputListener); |
+ |
+ TestUrlRequestCallback callback = new TestUrlRequestCallback(); |
+ UrlRequest.Builder builder = |
+ cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.getExecutor()); |
+ UrlRequest urlRequest = builder.build(); |
+ urlRequest.start(); |
+ callback.blockForDone(); |
+ |
+ // Throughput observation is posted to the network quality estimator on the network thread |
+ // after the UrlRequest is completed. The observations are then eventually posted to |
+ // throughput listeners on the executor provided to network quality. |
+ throughputListener.waitUntilFirstThroughputObservationReceived(); |
+ |
+ // Wait for RTT observation (at the URL request layer) to be posted. |
+ rttListener.waitUntilFirstUrlRequestRTTReceived(); |
+ |
+ assertTrue(throughputListener.throughputObservationCount() > 0); |
+ |
+ // Check RTT observation count after throughput observation has been received. This ensures |
+ // that executor has finished posting the RTT observation to the RTT listeners. |
+ assertTrue(rttListener.rttObservationCount() > 0); |
+ |
+ // NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST |
+ assertTrue(rttListener.rttObservationCount(0) > 0); |
+ |
+ // NETWORK_QUALITY_OBSERVATION_SOURCE_TCP |
+ assertTrue(rttListener.rttObservationCount(1) > 0); |
+ |
+ // NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC |
+ assertEquals(0, rttListener.rttObservationCount(2)); |
+ |
+ // Verify that the listeners were notified on the expected thread. |
+ assertEquals(mNetworkQualityThread, rttListener.getThread()); |
+ assertEquals(mNetworkQualityThread, throughputListener.getThread()); |
+ |
+ // Verify that effective connection type callback is received and effective connection type |
+ // is correctly set to the forced value. This also verifies that the configuration params |
+ // from Cronet embedders were correctly read by NetworkQualityEstimator. |
+ assertEquals( |
+ EffectiveConnectionType.TYPE_SLOW_2G, cronetEngine.getEffectiveConnectionType()); |
+ |
+ cronetEngine.shutdown(); |
+ } |
} |