| Index: components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
|
| diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
|
| index 95f35eed336afe712c640f82540cbb353600e2fb..3d12bb4366fde4f1b87ffff108f4b6e07e4b6f75 100644
|
| --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
|
| +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
|
| @@ -11,6 +11,7 @@ import android.content.ContextWrapper;
|
| import android.os.ConditionVariable;
|
| import android.os.Handler;
|
| import android.os.Looper;
|
| +import android.os.StrictMode;
|
| import android.test.suitebuilder.annotation.SmallTest;
|
|
|
| import org.chromium.base.PathUtils;
|
| @@ -30,6 +31,7 @@ import java.util.LinkedList;
|
| import java.util.NoSuchElementException;
|
| import java.util.concurrent.Executor;
|
| import java.util.concurrent.Executors;
|
| +import java.util.concurrent.ThreadFactory;
|
|
|
| /**
|
| * Test CronetEngine.
|
| @@ -48,6 +50,9 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| private String mUrl500;
|
| CronetTestFramework mTestFramework;
|
|
|
| + // Thread on which network quality listeners should be notified.
|
| + private Thread mNetworkQualityThread;
|
| +
|
| @Override
|
| protected void setUp() throws Exception {
|
| super.setUp();
|
| @@ -125,45 +130,25 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| }
|
| }
|
|
|
| - static class TestNetworkQualityListener
|
| - implements NetworkQualityRttListener, NetworkQualityThroughputListener {
|
| - // Lock to ensure that observation counts can be updated and read by different threads.
|
| - private final Object mLock = new Object();
|
| - private final ConditionVariable mWaitForThroughput;
|
| - private int mRttObservationCount;
|
| - private int mThroughputObservationCount;
|
| -
|
| - TestNetworkQualityListener(ConditionVariable waitForThroughput) {
|
| - mWaitForThroughput = waitForThroughput;
|
| - }
|
| -
|
| - @Override
|
| - public void onRttObservation(int rttMs, long when, int source) {
|
| - synchronized (mLock) {
|
| - mRttObservationCount++;
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onThroughputObservation(int throughputKbps, long when, int source) {
|
| - synchronized (mLock) {
|
| - if (mWaitForThroughput != null) {
|
| - mWaitForThroughput.open();
|
| + private class ExecutorThreadFactory implements ThreadFactory {
|
| + public Thread newThread(final Runnable r) {
|
| + mNetworkQualityThread = new Thread(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + StrictMode.ThreadPolicy threadPolicy = StrictMode.getThreadPolicy();
|
| + try {
|
| + StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
|
| + .detectNetwork()
|
| + .penaltyLog()
|
| + .penaltyDeath()
|
| + .build());
|
| + r.run();
|
| + } finally {
|
| + StrictMode.setThreadPolicy(threadPolicy);
|
| + }
|
| }
|
| - mThroughputObservationCount++;
|
| - }
|
| - }
|
| -
|
| - public int rttObservationCount() {
|
| - synchronized (mLock) {
|
| - return mRttObservationCount;
|
| - }
|
| - }
|
| -
|
| - public int throughputObservationCount() {
|
| - synchronized (mLock) {
|
| - return mThroughputObservationCount;
|
| - }
|
| + });
|
| + return mNetworkQualityThread;
|
| }
|
| }
|
|
|
| @@ -240,15 +225,21 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| @SmallTest
|
| @Feature({"Cronet"})
|
| public void testRealTimeNetworkQualityObservationsNotEnabled() throws Exception {
|
| - mTestFramework = startCronetTestFramework();
|
| - TestNetworkQualityListener networkQualityListener = new TestNetworkQualityListener(null);
|
| + CronetEngine.Builder mCronetEngineBuilder = new CronetEngine.Builder(getContext());
|
| + mTestFramework =
|
| + startCronetTestFrameworkWithUrlAndCronetEngineBuilder(null, mCronetEngineBuilder);
|
| + Executor networkQualityExecutor = Executors.newSingleThreadExecutor();
|
| + TestNetworkQualityRttListener rttListener =
|
| + new TestNetworkQualityRttListener(networkQualityExecutor);
|
| + TestNetworkQualityThroughputListener throughputListener =
|
| + new TestNetworkQualityThroughputListener(networkQualityExecutor, null);
|
| try {
|
| - mTestFramework.mCronetEngine.addRttListener(networkQualityListener);
|
| + mTestFramework.mCronetEngine.addRttListener(rttListener);
|
| fail("Should throw an exception.");
|
| } catch (IllegalStateException e) {
|
| }
|
| try {
|
| - mTestFramework.mCronetEngine.addThroughputListener(networkQualityListener);
|
| + mTestFramework.mCronetEngine.addThroughputListener(throughputListener);
|
| fail("Should throw an exception.");
|
| } catch (IllegalStateException e) {
|
| }
|
| @@ -257,45 +248,144 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| mTestFramework.mCronetEngine.createRequest(mUrl, callback, callback.getExecutor());
|
| urlRequest.start();
|
| callback.blockForDone();
|
| - assertEquals(0, networkQualityListener.rttObservationCount());
|
| - assertEquals(0, networkQualityListener.throughputObservationCount());
|
| + assertEquals(0, rttListener.rttObservationCount());
|
| + assertEquals(0, throughputListener.throughputObservationCount());
|
| + mTestFramework.mCronetEngine.shutdown();
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Cronet"})
|
| + public void testRealTimeNetworkQualityObservationsNotEnabled_LegacyAPI() throws Exception {
|
| + mTestFramework = startCronetTestFramework();
|
| + TestNetworkQualityRttListener rttListener = new TestNetworkQualityRttListener();
|
| + try {
|
| + mTestFramework.mCronetEngine.addRttListener(rttListener);
|
| + fail("Should throw an exception.");
|
| + } catch (IllegalStateException e) {
|
| + }
|
| + TestUrlRequestCallback callback = new TestUrlRequestCallback();
|
| + UrlRequest urlRequest =
|
| + mTestFramework.mCronetEngine.createRequest(mUrl, callback, callback.getExecutor());
|
| + urlRequest.start();
|
| + callback.blockForDone();
|
| + assertEquals(0, rttListener.rttObservationCount());
|
| mTestFramework.mCronetEngine.shutdown();
|
| }
|
|
|
| @SmallTest
|
| @Feature({"Cronet"})
|
| public void testRealTimeNetworkQualityObservationsListenerRemoved() throws Exception {
|
| + CronetEngine.Builder mCronetEngineBuilder = new CronetEngine.Builder(getContext());
|
| + TestExecutor networkQualityExecutor = new TestExecutor();
|
| + TestNetworkQualityRttListener rttListener =
|
| + new TestNetworkQualityRttListener(networkQualityExecutor);
|
| + mCronetEngineBuilder.enableNetworkQualityEstimator(true);
|
| + mTestFramework =
|
| + startCronetTestFrameworkWithUrlAndCronetEngineBuilder(null, mCronetEngineBuilder);
|
| + mTestFramework.mCronetEngine.configureNetworkQualityEstimatorForTesting(true, true);
|
| +
|
| + mTestFramework.mCronetEngine.addRttListener(rttListener);
|
| + mTestFramework.mCronetEngine.removeRttListener(rttListener);
|
| + TestUrlRequestCallback callback = new TestUrlRequestCallback();
|
| + UrlRequest urlRequest =
|
| + mTestFramework.mCronetEngine.createRequest(mUrl, callback, callback.getExecutor());
|
| + urlRequest.start();
|
| + callback.blockForDone();
|
| + networkQualityExecutor.runAllTasks();
|
| + assertEquals(0, rttListener.rttObservationCount());
|
| + mTestFramework.mCronetEngine.shutdown();
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Cronet"})
|
| + public void testRealTimeNetworkQualityObservationsListenerRemoved_LegacyAPI() throws Exception {
|
| mTestFramework = startCronetTestFramework();
|
| TestExecutor testExecutor = new TestExecutor();
|
| - TestNetworkQualityListener networkQualityListener = new TestNetworkQualityListener(null);
|
| - mTestFramework.mCronetEngine.enableNetworkQualityEstimatorForTesting(
|
| - true, true, testExecutor);
|
| - mTestFramework.mCronetEngine.addRttListener(networkQualityListener);
|
| - mTestFramework.mCronetEngine.addThroughputListener(networkQualityListener);
|
| - mTestFramework.mCronetEngine.removeRttListener(networkQualityListener);
|
| - mTestFramework.mCronetEngine.removeThroughputListener(networkQualityListener);
|
| + TestNetworkQualityRttListener rttListener = new TestNetworkQualityRttListener();
|
| + mTestFramework.mCronetEngine.enableNetworkQualityEstimator(testExecutor);
|
| + mTestFramework.mCronetEngine.configureNetworkQualityEstimatorForTesting(true, true);
|
| + mTestFramework.mCronetEngine.addRttListener(rttListener);
|
| + mTestFramework.mCronetEngine.removeRttListener(rttListener);
|
| TestUrlRequestCallback callback = new TestUrlRequestCallback();
|
| UrlRequest urlRequest =
|
| mTestFramework.mCronetEngine.createRequest(mUrl, callback, callback.getExecutor());
|
| urlRequest.start();
|
| callback.blockForDone();
|
| testExecutor.runAllTasks();
|
| - assertEquals(0, networkQualityListener.rttObservationCount());
|
| - assertEquals(0, networkQualityListener.throughputObservationCount());
|
| + assertEquals(0, rttListener.rttObservationCount());
|
| mTestFramework.mCronetEngine.shutdown();
|
| }
|
|
|
| @SmallTest
|
| @Feature({"Cronet"})
|
| - public void testRealTimeNetworkQualityObservations() throws Exception {
|
| + public void testRealTimeNetworkQualityObservationsQuicDisabled() throws Exception {
|
| + CronetEngine.Builder mCronetEngineBuilder = new CronetEngine.Builder(getContext());
|
| + Executor requestFinishedListenerExecutor =
|
| + Executors.newSingleThreadExecutor(new ExecutorThreadFactory());
|
| + Executor listenersExecutor = Executors.newSingleThreadExecutor(new ExecutorThreadFactory());
|
| + ConditionVariable waitForThroughput = new ConditionVariable();
|
| + TestNetworkQualityRttListener rttListener =
|
| + new TestNetworkQualityRttListener(listenersExecutor);
|
| + TestNetworkQualityThroughputListener throughputListener =
|
| + new TestNetworkQualityThroughputListener(listenersExecutor, waitForThroughput);
|
| + mCronetEngineBuilder.enableHTTP2(true).enableQUIC(false).enableNetworkQualityEstimator(
|
| + true);
|
| + mTestFramework =
|
| + startCronetTestFrameworkWithUrlAndCronetEngineBuilder(null, mCronetEngineBuilder);
|
| + mTestFramework.mCronetEngine.configureNetworkQualityEstimatorForTesting(true, true);
|
| + // requestFinishedListenerExecutor should not be used for notifying the RTT and
|
| + // throughput listeners.
|
| + mTestFramework.mCronetEngine.setRequestFinishedListenerExecutor(
|
| + requestFinishedListenerExecutor);
|
| +
|
| + mTestFramework.mCronetEngine.addRttListener(rttListener);
|
| + mTestFramework.mCronetEngine.addThroughputListener(throughputListener);
|
| +
|
| + TestUrlRequestCallback callback = new TestUrlRequestCallback();
|
| + UrlRequest urlRequest =
|
| + mTestFramework.mCronetEngine.createRequest(mUrl, callback, callback.getExecutor());
|
| + 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.
|
| + waitForThroughput.block();
|
| + 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());
|
| +
|
| + mTestFramework.mCronetEngine.shutdown();
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Cronet"})
|
| + public void testRealTimeNetworkQualityObservations_LegacyAPI() throws Exception {
|
| mTestFramework = startCronetTestFramework();
|
| Executor executor = Executors.newSingleThreadExecutor();
|
| ConditionVariable waitForThroughput = new ConditionVariable();
|
| - TestNetworkQualityListener networkQualityListener =
|
| - new TestNetworkQualityListener(waitForThroughput);
|
| - mTestFramework.mCronetEngine.enableNetworkQualityEstimatorForTesting(true, true, executor);
|
| - mTestFramework.mCronetEngine.addRttListener(networkQualityListener);
|
| - mTestFramework.mCronetEngine.addThroughputListener(networkQualityListener);
|
| + TestNetworkQualityRttListener rttListener = new TestNetworkQualityRttListener();
|
| + TestNetworkQualityThroughputListener throughputListener =
|
| + new TestNetworkQualityThroughputListener(executor, waitForThroughput);
|
| + mTestFramework.mCronetEngine.enableNetworkQualityEstimator(executor);
|
| + mTestFramework.mCronetEngine.configureNetworkQualityEstimatorForTesting(true, true);
|
| + mTestFramework.mCronetEngine.addRttListener(rttListener);
|
| + mTestFramework.mCronetEngine.addThroughputListener(throughputListener);
|
| TestUrlRequestCallback callback = new TestUrlRequestCallback();
|
| UrlRequest urlRequest =
|
| mTestFramework.mCronetEngine.createRequest(mUrl, callback, callback.getExecutor());
|
| @@ -306,15 +396,16 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| // after the UrlRequest is completed. The observations are then eventually posted to
|
| // throughput listeners on the executor provided to network quality.
|
| waitForThroughput.block();
|
| - assertTrue(networkQualityListener.throughputObservationCount() > 0);
|
| + 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(networkQualityListener.rttObservationCount() > 0);
|
| + assertTrue(rttListener.rttObservationCount() > 0);
|
|
|
| mTestFramework.mCronetEngine.shutdown();
|
| }
|
|
|
| + // TODO(tbansal): http://crbug.com/618034 Remove this.
|
| private static class TestRequestFinishedListener
|
| implements CronetEngine.RequestFinishedListener {
|
| private UrlRequestInfo mRequestInfo = null;
|
| @@ -330,7 +421,7 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| @SmallTest
|
| @Feature({"Cronet"})
|
| @SuppressWarnings("deprecation")
|
| - public void testRequestFinishedListener() throws Exception {
|
| + public void testRequestFinishedListener_LegacyAPI() throws Exception {
|
| mTestFramework = startCronetTestFramework();
|
| TestExecutor testExecutor = new TestExecutor();
|
| TestRequestFinishedListener requestFinishedListener = new TestRequestFinishedListener();
|
| @@ -360,13 +451,50 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| mTestFramework.mCronetEngine.shutdown();
|
| }
|
|
|
| + @SmallTest
|
| + @Feature({"Cronet"})
|
| + @SuppressWarnings("deprecation")
|
| + public void testRequestFinishedListenerWithExecutorSetLater_LegacyAPI() throws Exception {
|
| + CronetEngine.Builder mCronetEngineBuilder = new CronetEngine.Builder(getContext());
|
| + TestExecutor testExecutor = new TestExecutor();
|
| + mCronetEngineBuilder.enableHTTP2(true).enableQUIC(false).enableNetworkQualityEstimator(
|
| + true);
|
| + mTestFramework =
|
| + startCronetTestFrameworkWithUrlAndCronetEngineBuilder(null, mCronetEngineBuilder);
|
| + TestRequestFinishedListener requestFinishedListener = new TestRequestFinishedListener();
|
| + mTestFramework.mCronetEngine.setRequestFinishedListenerExecutor(testExecutor);
|
| + mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
|
| + TestUrlRequestCallback callback = new TestUrlRequestCallback();
|
| + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder(
|
| + mUrl, callback, callback.getExecutor(), mTestFramework.mCronetEngine);
|
| + urlRequestBuilder.addRequestAnnotation("request annotation")
|
| + .addRequestAnnotation(this)
|
| + .build()
|
| + .start();
|
| + callback.blockForDone();
|
| + testExecutor.runAllTasks();
|
| +
|
| + CronetEngine.UrlRequestInfo requestInfo = requestFinishedListener.mRequestInfo;
|
| + assertNotNull("RequestFinishedListener must be called", requestInfo);
|
| + assertEquals(mUrl, requestInfo.getUrl());
|
| + assertNotNull(requestInfo.getResponseInfo());
|
| + assertEquals(newHashSet("request annotation", this), // Use sets for unordered comparison.
|
| + new HashSet<Object>(requestInfo.getAnnotations()));
|
| + CronetEngine.UrlRequestMetrics metrics = requestInfo.getMetrics();
|
| + assertNotNull("UrlRequestInfo.getMetrics() must not be null", metrics);
|
| + assertTrue(metrics.getTotalTimeMs() > 0);
|
| + assertTrue(metrics.getTotalTimeMs() >= metrics.getTtfbMs());
|
| + assertTrue(metrics.getReceivedBytesCount() > 0);
|
| + mTestFramework.mCronetEngine.shutdown();
|
| + }
|
| +
|
| /*
|
| @SmallTest
|
| @Feature({"Cronet"})
|
| @SuppressWarnings("deprecation")
|
| */
|
| @FlakyTest(message = "https://crbug.com/592444")
|
| - public void testRequestFinishedListenerFailedRequest() throws Exception {
|
| + public void testRequestFinishedListenerFailedRequest_LegacyAPI() throws Exception {
|
| String connectionRefusedUrl = "http://127.0.0.1:3";
|
| mTestFramework = startCronetTestFramework();
|
| TestExecutor testExecutor = new TestExecutor();
|
| @@ -396,7 +524,7 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| @SmallTest
|
| @Feature({"Cronet"})
|
| @SuppressWarnings("deprecation")
|
| - public void testRequestFinishedListenerRemoved() throws Exception {
|
| + public void testRequestFinishedListenerRemoved_LegacyAPI() throws Exception {
|
| mTestFramework = startCronetTestFramework();
|
| TestExecutor testExecutor = new TestExecutor();
|
| TestRequestFinishedListener requestFinishedListener = new TestRequestFinishedListener();
|
| @@ -418,7 +546,7 @@ public class CronetUrlRequestContextTest extends CronetTestBase {
|
| @SmallTest
|
| @Feature({"Cronet"})
|
| @SuppressWarnings("deprecation")
|
| - public void testRequestFinishedListenerDisabled() throws Exception {
|
| + public void testRequestFinishedListenerDisabled_LegacyAPI() throws Exception {
|
| mTestFramework = startCronetTestFramework();
|
| TestExecutor testExecutor = new TestExecutor();
|
| TestRequestFinishedListener requestFinishedListener = new TestRequestFinishedListener();
|
|
|