Chromium Code Reviews| Index: components/cronet/android/test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java |
| diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java |
| index 5f844cece4722791fced01a3be049bda431f082a..8835b259e6981b2418651be5dfc65ea3b79e6650 100644 |
| --- a/components/cronet/android/test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java |
| +++ b/components/cronet/android/test/javatests/src/org/chromium/net/NetworkChangeNotifierTest.java |
| @@ -4,28 +4,95 @@ |
| package org.chromium.net; |
| +import static android.system.OsConstants.AF_INET; |
| +import static android.system.OsConstants.SOCK_STREAM; |
| + |
| +import android.annotation.TargetApi; |
| +import android.os.Build; |
| +import android.system.Os; |
| import android.test.suitebuilder.annotation.SmallTest; |
| +import org.chromium.base.ThreadUtils; |
| import org.chromium.base.test.util.Feature; |
| -import org.chromium.net.test.util.NetworkChangeNotifierTestUtil; |
| + |
| +import java.io.FileDescriptor; |
| +import java.net.InetAddress; |
| +import java.net.InetSocketAddress; |
| +import java.util.concurrent.atomic.AtomicBoolean; |
| /** |
| - * Tests that NetworkChangeNotifier is initialized. |
| + * Test NetworkChangeNotifier. |
| */ |
| public class NetworkChangeNotifierTest extends CronetTestBase { |
| /** |
| - * Adds a IPAddressObserver and checks whether it receives notifications. |
| - * This serves as an indirect way to test that Cronet has an active |
| - * network notifier. |
| + * Verify NetworkChangeNotifier signals trigger appropriate action, like |
| + * aborting pending connect() jobs. |
| */ |
| @SmallTest |
| @Feature({"Cronet"}) |
| - public void testNetworkChangeNotifierIsInitialized() throws Exception { |
| + @OnlyRunNativeCronet |
| + @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
| + public void testNetworkChangeNotifier() throws Exception { |
| CronetTestFramework testFramework = startCronetTestFramework(); |
| assertNotNull(testFramework); |
| - // Let Cronet UI thread initialization complete so |
| - // NetworkChangeNotifier is initialized for the test. |
| - NetworkChangeNotifierTestUtil.flushUiThreadTaskQueue(); |
| - assertTrue(NetworkChangeNotifierUtil.isTestIPAddressObserverCalled()); |
| + |
| + // Os and OsConstants aren't exposed until Lollipop so we cannot run this test. |
| + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { |
| + return; |
| + } |
| + |
| + // Bind a listening socket to a local port. The socket won't be used to accept any |
| + // connections, but rather to get connection stuck waiting to connect. |
| + FileDescriptor s = Os.socket(AF_INET, SOCK_STREAM, 0); |
| + // Bind to all addresses (indicated by special 0.0.0.0 value) and a random port (indicated |
| + // by special 0 value). |
| + Os.bind(s, InetAddress.getByAddress(null, new byte[] {0, 0, 0, 0}), 0); |
| + // Set backlog to 0 so connections end up stuck waiting to connect(). |
| + Os.listen(s, 0); |
| + |
| + // Make URL pointing at this local port, where requests will get stuck connecting. |
| + String url = "http://localhost:" + ((InetSocketAddress) Os.getsockname(s)).getPort(); |
| + |
| + // Launch a few requests at this local port. Four seems to be the magic number where |
| + // that request and any further request get stuck connecting. |
| + TestUrlRequestCallback callback = null; |
| + UrlRequest request = null; |
| + for (int i = 0; i < 4; i++) { |
|
kapishnikov
2016/10/20 17:25:46
Why do we need 4 requests? Do we care about the fa
pauljensen
2016/10/21 02:27:33
We just need to fill up the connect queue. I try
|
| + callback = new TestUrlRequestCallback(); |
| + request = new UrlRequest |
|
kapishnikov
2016/10/20 17:25:46
Use mCronetEngine.newUrlRequestBuilder(...)
pauljensen
2016/10/24 18:52:53
Done.
|
| + .Builder(url, callback, callback.getExecutor(), |
| + testFramework.mCronetEngine) |
| + .build(); |
| + request.start(); |
| + } |
| + |
| + // Wait for request to get to connecting stage |
| + final AtomicBoolean requestConnecting = new AtomicBoolean(); |
| + while (!requestConnecting.get()) { |
| + request.getStatus(new UrlRequest.StatusListener() { |
| + @Override |
| + public void onStatus(int status) { |
| + requestConnecting.set(status == UrlRequest.Status.CONNECTING); |
| + } |
| + }); |
| + Thread.sleep(100); |
| + } |
| + |
| + // Simulate network change which should abort connect jobs |
| + ThreadUtils.postOnUiThread(new Runnable() { |
| + @Override |
| + public void run() { |
| + NetworkChangeNotifier.getInstance().notifyObserversOfConnectionTypeChange( |
| + ConnectionType.CONNECTION_4G); |
| + } |
| + }); |
| + |
| + // Wait for ERR_NETWORK_CHANGED |
| + callback.blockForDone(); |
| + assertNotNull(callback.mError); |
| + assertTrue(callback.mOnErrorCalled); |
| + assertEquals(-21, callback.mError.getCronetInternalErrorCode()); |
|
kapishnikov
2016/10/20 17:25:46
-21 => NetError.ERR_NETWORK_CHANGED
pauljensen
2016/10/24 18:52:53
Done.
|
| + assertEquals("Exception in CronetUrlRequest: net::ERR_NETWORK_CHANGED", |
| + callback.mError.getMessage()); |
| } |
| } |