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..c8bbf6e862748ddb1a6aca725ccb8ca379b59506 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,94 @@ |
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++) { |
+ callback = new TestUrlRequestCallback(); |
+ request = testFramework.mCronetEngine |
+ .newUrlRequestBuilder(url, callback, callback.getExecutor()) |
+ .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(NetError.ERR_NETWORK_CHANGED, callback.mError.getCronetInternalErrorCode()); |
+ assertEquals("Exception in CronetUrlRequest: net::ERR_NETWORK_CHANGED", |
+ callback.mError.getMessage()); |
} |
} |