Index: chrome/android/javatests/src/org/chromium/chrome/browser/ChromeChildProcessLauncherTest.java |
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeChildProcessLauncherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeChildProcessLauncherTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3f74ab8381a25d5604fb9db532518d9c360927fd |
--- /dev/null |
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeChildProcessLauncherTest.java |
@@ -0,0 +1,124 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser; |
+ |
+import android.app.Service; |
+import android.content.Context; |
+import android.os.RemoteException; |
+import android.test.InstrumentationTestCase; |
+import android.test.suitebuilder.annotation.MediumTest; |
+ |
+import org.chromium.base.library_loader.LibraryLoader; |
+import org.chromium.base.library_loader.LibraryProcessType; |
+import org.chromium.base.test.util.CommandLineFlags; |
+import org.chromium.base.test.util.Feature; |
+import org.chromium.content.browser.ChildProcessConnectionImpl; |
+import org.chromium.content.browser.ChildProcessLauncher; |
+import org.chromium.content.browser.test.ChildProcessLauncherTestHelper; |
+import org.chromium.content.browser.test.util.Criteria; |
+import org.chromium.content.browser.test.util.CriteriaHelper; |
+import org.chromium.webapk.lib.common.WebApkSandboxedProcessService; |
+ |
+/** |
+ * Instrumentation tests for ChildProcessLauncher. |
+ */ |
+public class ChromeChildProcessLauncherTest extends InstrumentationTestCase { |
+ private static final String TESTING_WEB_APK_PACKAGE_NAME = "org.chromium.webapk.template.test"; |
+ |
+ /** |
+ * Tests service number of connections for WebAPKs and regular tabs are assigned properly, |
+ * i.e. from different ChildConnectionAllocators. |
+ */ |
+ @MediumTest |
+ @Feature({"ProcessManagement", "webapk"}) |
+ public void testServiceNumberAllocation() throws InterruptedException, RemoteException { |
+ Context appContext = getInstrumentation().getTargetContext(); |
+ assertEquals(0, ChildProcessLauncher.allocatedSandboxedConnectionsCountForTesting( |
+ appContext, TESTING_WEB_APK_PACKAGE_NAME)); |
+ assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedConnectionsCount( |
+ appContext)); |
+ |
+ // Start and connect to a new service of a WebAPK. |
+ ChildProcessConnectionImpl webapkConnection = |
+ startConnection(TESTING_WEB_APK_PACKAGE_NAME, WebApkSandboxedProcessService.class); |
+ // Start and connect to a new service for a regular tab. |
+ ChildProcessConnectionImpl tabConnection = |
+ startConnection(appContext.getPackageName(), null); |
+ |
+ // Verify that one connection is allocated for a WebAPK and a regular tab respectively. |
+ assertEquals(1, ChildProcessLauncher.allocatedSandboxedConnectionsCountForTesting( |
+ appContext, TESTING_WEB_APK_PACKAGE_NAME)); |
+ assertEquals(1, ChildProcessLauncherTestHelper.allocatedChromeSandboxedConnectionsCount( |
+ appContext)); |
+ |
+ // Verify that connections allocated for a WebAPK and the regular tab are from different |
+ // ChildConnectionAllocators, since both ChildConnectionAllocators start allocating |
+ // connections from number 0. |
+ assertEquals(0, webapkConnection.getServiceNumber()); |
+ assertEquals(0, tabConnection.getServiceNumber()); |
+ } |
+ |
+ /** |
+ * Tests that after reaching the maximum allowed connections for a WebAPK, we can't allocate |
+ * a new connection to the WebAPK, but we can still allocate a connection for a regular tab. |
+ */ |
+ @MediumTest |
+ @Feature({"ProcessManagement", "webapk"}) |
+ @CommandLineFlags.Add(ChildProcessLauncher.SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING + "=1") |
+ public void testExceedMaximumConnectionNumber() throws InterruptedException, RemoteException { |
+ Context appContext = getInstrumentation().getTargetContext(); |
+ assertEquals(0, ChildProcessLauncher.allocatedSandboxedConnectionsCountForTesting( |
+ appContext, TESTING_WEB_APK_PACKAGE_NAME)); |
+ |
+ // Setup a connection for a WebAPK to reach the maximum allowed connection number. |
+ ChildProcessConnectionImpl webapkConnection = |
+ startConnection(TESTING_WEB_APK_PACKAGE_NAME, WebApkSandboxedProcessService.class); |
+ assertNotNull(webapkConnection); |
+ |
+ // Verify that there isn't any connection available for the WebAPK. |
+ ChildProcessConnectionImpl exceedNumberWebapkConnection = |
+ startConnection(TESTING_WEB_APK_PACKAGE_NAME, WebApkSandboxedProcessService.class); |
+ assertNull(exceedNumberWebapkConnection); |
+ |
+ // Verify that we can still allocate connection for a regular tab. |
+ ChildProcessConnectionImpl tabConnection = |
+ startConnection(appContext.getPackageName(), null); |
+ assertNotNull(tabConnection); |
+ } |
+ |
+ /** |
+ * Returns whether the connection is established and connected. Return false if the connection |
+ * isn't either established nor connected. |
+ */ |
+ private ChildProcessConnectionImpl startConnection(String packageName, |
+ Class<? extends Service> servicecClass) throws InterruptedException { |
+ // Allocate a new connection. |
+ Context context = getInstrumentation().getTargetContext(); |
+ final ChildProcessConnectionImpl connection = |
+ (ChildProcessConnectionImpl) ChildProcessLauncher.allocateBoundConnectionForTesting( |
+ context, ChildProcessLauncherTestHelper.getChildProcessCreationParams( |
+ packageName, servicecClass)); |
+ |
+ if (connection == null) { |
+ return null; |
+ } |
+ // Wait for the service to connect. |
+ CriteriaHelper.pollInstrumentationThread( |
+ new Criteria("The connection wasn't established.") { |
+ @Override |
+ public boolean isSatisfied() { |
+ return connection.isConnected(); |
+ } |
+ }); |
+ return connection; |
+ } |
+ |
+ @Override |
+ protected void setUp() throws Exception { |
+ super.setUp(); |
+ LibraryLoader.get(LibraryProcessType.PROCESS_CHILD) |
+ .ensureInitialized(getInstrumentation().getTargetContext()); |
+ } |
+} |