Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.os.RemoteException; | 8 import android.os.RemoteException; |
| 9 import android.test.InstrumentationTestCase; | 9 import android.test.InstrumentationTestCase; |
| 10 import android.test.suitebuilder.annotation.MediumTest; | 10 import android.test.suitebuilder.annotation.MediumTest; |
| 11 | 11 |
| 12 import org.chromium.base.BaseSwitches; | 12 import org.chromium.base.BaseSwitches; |
| 13 import org.chromium.base.library_loader.LibraryLoader; | 13 import org.chromium.base.library_loader.LibraryLoader; |
| 14 import org.chromium.base.library_loader.LibraryProcessType; | 14 import org.chromium.base.library_loader.LibraryProcessType; |
| 15 import org.chromium.base.test.util.CommandLineFlags; | 15 import org.chromium.base.test.util.CommandLineFlags; |
| 16 import org.chromium.base.test.util.Feature; | 16 import org.chromium.base.test.util.Feature; |
| 17 import org.chromium.content.browser.test.ChildProcessLauncherTestHelper; | |
| 17 import org.chromium.content.browser.test.util.Criteria; | 18 import org.chromium.content.browser.test.util.Criteria; |
| 18 import org.chromium.content.browser.test.util.CriteriaHelper; | 19 import org.chromium.content.browser.test.util.CriteriaHelper; |
| 19 | 20 |
| 20 import java.util.concurrent.Callable; | 21 import java.util.concurrent.Callable; |
| 21 | 22 |
| 22 /** | 23 /** |
| 23 * Instrumentation tests for ChildProcessLauncher. | 24 * Instrumentation tests for ChildProcessLauncher. |
| 24 * TODO(hanxi): Add tests for assigning {@ChildConnectionAllocator} for differen t package names | |
| 25 * when render processes can be run in WebAPKs. | |
| 26 */ | 25 */ |
| 27 public class ChildProcessLauncherTest extends InstrumentationTestCase { | 26 public class ChildProcessLauncherTest extends InstrumentationTestCase { |
| 28 // Pseudo command line arguments to instruct the child process to wait until being killed. | 27 // Pseudo command line arguments to instruct the child process to wait until being killed. |
| 29 // Allowing the process to continue would lead to a crash when attempting to initialize IPC | 28 // Allowing the process to continue would lead to a crash when attempting to initialize IPC |
| 30 // channels that are not being set up in this test. | 29 // channels that are not being set up in this test. |
| 31 private static final String[] sProcessWaitArguments = { | 30 private static final String[] sProcessWaitArguments = { |
| 32 "_", "--" + BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER }; | 31 "_", "--" + BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER }; |
| 33 | 32 |
| 34 /** | 33 /** |
| 35 * Tests cleanup for a connection that fails to connect in the first place. | 34 * Tests cleanup for a connection that fails to connect in the first place. |
| 36 */ | 35 */ |
| 37 @MediumTest | 36 @MediumTest |
| 38 @Feature({"ProcessManagement"}) | 37 @Feature({"ProcessManagement"}) |
| 39 @CommandLineFlags.Add(ChildProcessLauncher.SWITCH_NUM_SANDBOXED_SERVICES_FOR _TESTING + "=4") | 38 @CommandLineFlags.Add(ChildProcessLauncher.SWITCH_NUM_SANDBOXED_SERVICES_FOR _TESTING + "=4") |
| 40 public void testServiceFailedToBind() throws InterruptedException, RemoteExc eption { | 39 public void testServiceFailedToBind() throws InterruptedException, RemoteExc eption { |
| 41 assertEquals(0, allocatedChromeSandboxedConnectionsCount()); | 40 final Context appContext = getInstrumentation().getContext(); |
| 41 assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC onnectionsCount( | |
| 42 appContext)); | |
| 42 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting()) ; | 43 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting()) ; |
| 43 | 44 |
| 44 // Try to allocate a connection to service class in incorrect package. W e can do that by | 45 // Try to allocate a connection to service class in incorrect package. W e can do that by |
| 45 // using the instrumentation context (getContext()) instead of the app c ontext | 46 // using the instrumentation context (getContext()) instead of the app c ontext |
| 46 // (getTargetContext()). | 47 // (getTargetContext()). |
| 47 Context context = getInstrumentation().getContext(); | 48 Context context = getInstrumentation().getContext(); |
| 48 ChildProcessLauncher.allocateBoundConnectionForTesting( | 49 ChildProcessLauncher.allocateBoundConnectionForTesting( |
| 49 context, getDefaultChildProcessCreationParams(context.getPackage Name())); | 50 context, ChildProcessLauncherTestHelper.getChildProcessCreationP arams( |
| 51 context.getPackageName(), null)); | |
| 50 | 52 |
| 51 // Verify that the connection is not considered as allocated. | 53 // Verify that the connection is not considered as allocated. |
| 52 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { | 54 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { |
| 53 @Override | 55 @Override |
| 54 public Integer call() { | 56 public Integer call() { |
| 55 return allocatedChromeSandboxedConnectionsCount(); | 57 return ChildProcessLauncherTestHelper.allocatedChromeSandboxedCo nnectionsCount( |
| 58 appContext); | |
| 56 } | 59 } |
| 57 })); | 60 })); |
| 58 | 61 |
| 59 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { | 62 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { |
| 60 @Override | 63 @Override |
| 61 public Integer call() { | 64 public Integer call() { |
| 62 return ChildProcessLauncher.connectedServicesCountForTesting(); | 65 return ChildProcessLauncher.connectedServicesCountForTesting(); |
| 63 } | 66 } |
| 64 })); | 67 })); |
| 65 } | 68 } |
| 66 | 69 |
| 67 /** | 70 /** |
| 68 * Tests cleanup for a connection that terminates before setup. | 71 * Tests cleanup for a connection that terminates before setup. |
| 69 */ | 72 */ |
| 70 @MediumTest | 73 @MediumTest |
| 71 @Feature({"ProcessManagement"}) | 74 @Feature({"ProcessManagement"}) |
| 72 public void testServiceCrashedBeforeSetup() throws InterruptedException, Rem oteException { | 75 public void testServiceCrashedBeforeSetup() throws InterruptedException, Rem oteException { |
| 73 assertEquals(0, allocatedChromeSandboxedConnectionsCount()); | 76 final Context appContext = getInstrumentation().getTargetContext(); |
| 77 assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC onnectionsCount( | |
| 78 appContext)); | |
| 74 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting()) ; | 79 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting()) ; |
| 75 | 80 |
| 76 // Start and connect to a new service. | 81 // Start and connect to a new service. |
| 77 final ChildProcessConnectionImpl connection = startConnection(); | 82 final ChildProcessConnectionImpl connection = startConnection(); |
| 78 assertEquals(1, allocatedChromeSandboxedConnectionsCount()); | 83 assertEquals(1, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC onnectionsCount( |
| 84 appContext)); | |
| 79 | 85 |
| 80 // Verify that the service is not yet set up. | 86 // Verify that the service is not yet set up. |
| 81 assertEquals(0, connection.getPid()); | 87 assertEquals(0, connection.getPid()); |
| 82 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting()) ; | 88 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting()) ; |
| 83 | 89 |
| 84 // Crash the service. | 90 // Crash the service. |
| 85 assertTrue(connection.crashServiceForTesting()); | 91 assertTrue(connection.crashServiceForTesting()); |
| 86 | 92 |
| 87 // Verify that the connection gets cleaned-up. | 93 // Verify that the connection gets cleaned-up. |
| 88 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { | 94 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { |
| 89 @Override | 95 @Override |
| 90 public Integer call() { | 96 public Integer call() { |
| 91 return allocatedChromeSandboxedConnectionsCount(); | 97 return ChildProcessLauncherTestHelper.allocatedChromeSandboxedCo nnectionsCount( |
| 98 appContext); | |
| 92 } | 99 } |
| 93 })); | 100 })); |
| 94 | 101 |
| 95 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { | 102 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { |
| 96 @Override | 103 @Override |
| 97 public Integer call() { | 104 public Integer call() { |
| 98 return ChildProcessLauncher.connectedServicesCountForTesting(); | 105 return ChildProcessLauncher.connectedServicesCountForTesting(); |
| 99 } | 106 } |
| 100 })); | 107 })); |
| 101 } | 108 } |
| 102 | 109 |
| 103 /** | 110 /** |
| 104 * Tests cleanup for a connection that terminates after setup. | 111 * Tests cleanup for a connection that terminates after setup. |
| 105 */ | 112 */ |
| 106 @MediumTest | 113 @MediumTest |
| 107 @Feature({"ProcessManagement"}) | 114 @Feature({"ProcessManagement"}) |
| 108 public void testServiceCrashedAfterSetup() throws InterruptedException, Remo teException { | 115 public void testServiceCrashedAfterSetup() throws InterruptedException, Remo teException { |
| 109 assertEquals(0, allocatedChromeSandboxedConnectionsCount()); | 116 final Context appContext = getInstrumentation().getTargetContext(); |
| 117 assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC onnectionsCount( | |
| 118 appContext)); | |
| 110 | 119 |
| 111 // Start and connect to a new service. | 120 // Start and connect to a new service. |
| 112 final ChildProcessConnectionImpl connection = startConnection(); | 121 final ChildProcessConnectionImpl connection = startConnection(); |
| 113 assertEquals(1, allocatedChromeSandboxedConnectionsCount()); | 122 assertEquals(1, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC onnectionsCount( |
| 123 appContext)); | |
| 114 | 124 |
| 115 // Initiate the connection setup. | 125 // Initiate the connection setup. |
| 116 triggerConnectionSetup(connection); | 126 triggerConnectionSetup(connection); |
| 117 | 127 |
| 118 // Verify that the connection completes the setup. | 128 // Verify that the connection completes the setup. |
| 119 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable <Integer>() { | 129 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable <Integer>() { |
| 120 @Override | 130 @Override |
| 121 public Integer call() { | 131 public Integer call() { |
| 122 return ChildProcessLauncher.connectedServicesCountForTesting(); | 132 return ChildProcessLauncher.connectedServicesCountForTesting(); |
| 123 } | 133 } |
| 124 })); | 134 })); |
| 125 | 135 |
| 126 CriteriaHelper.pollInstrumentationThread( | 136 CriteriaHelper.pollInstrumentationThread( |
| 127 new Criteria("The connection failed to get a pid in setup.") { | 137 new Criteria("The connection failed to get a pid in setup.") { |
| 128 @Override | 138 @Override |
| 129 public boolean isSatisfied() { | 139 public boolean isSatisfied() { |
| 130 return connection.getPid() != 0; | 140 return connection.getPid() != 0; |
| 131 } | 141 } |
| 132 }); | 142 }); |
| 133 | 143 |
| 134 // Crash the service. | 144 // Crash the service. |
| 135 assertTrue(connection.crashServiceForTesting()); | 145 assertTrue(connection.crashServiceForTesting()); |
| 136 | 146 |
| 137 // Verify that the connection gets cleaned-up. | 147 // Verify that the connection gets cleaned-up. |
| 138 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { | 148 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { |
| 139 @Override | 149 @Override |
| 140 public Integer call() { | 150 public Integer call() { |
| 141 return allocatedChromeSandboxedConnectionsCount(); | 151 return ChildProcessLauncherTestHelper.allocatedChromeSandboxedCo nnectionsCount( |
| 152 appContext); | |
| 142 } | 153 } |
| 143 })); | 154 })); |
| 144 | 155 |
| 145 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { | 156 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable <Integer>() { |
| 146 @Override | 157 @Override |
| 147 public Integer call() { | 158 public Integer call() { |
| 148 return ChildProcessLauncher.connectedServicesCountForTesting(); | 159 return ChildProcessLauncher.connectedServicesCountForTesting(); |
| 149 } | 160 } |
| 150 })); | 161 })); |
| 151 | 162 |
| 152 // Verify that the connection pid remains set after termination. | 163 // Verify that the connection pid remains set after termination. |
| 153 assertTrue(connection.getPid() != 0); | 164 assertTrue(connection.getPid() != 0); |
| 154 } | 165 } |
| 155 | 166 |
| 156 /** | 167 /** |
| 157 * Tests spawning a pending process from queue. | 168 * Tests spawning a pending process from queue. |
| 158 */ | 169 */ |
| 159 @MediumTest | 170 @MediumTest |
| 160 @Feature({"ProcessManagement"}) | 171 @Feature({"ProcessManagement"}) |
| 161 public void testPendingSpawnQueue() throws InterruptedException, RemoteExcep tion { | 172 public void testPendingSpawnQueue() throws InterruptedException, RemoteExcep tion { |
| 162 final Context appContext = getInstrumentation().getTargetContext(); | 173 final Context appContext = getInstrumentation().getTargetContext(); |
| 163 assertEquals(0, allocatedChromeSandboxedConnectionsCount()); | 174 assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC onnectionsCount( |
| 175 appContext)); | |
| 164 | 176 |
| 165 // Start and connect to a new service. | 177 // Start and connect to a new service. |
| 166 final ChildProcessConnectionImpl connection = startConnection(); | 178 final ChildProcessConnectionImpl connection = startConnection(); |
| 167 assertEquals(1, allocatedChromeSandboxedConnectionsCount()); | 179 assertEquals(1, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC onnectionsCount( |
| 180 appContext)); | |
| 168 | 181 |
| 169 // Queue up a new spawn request. There is no way to kill the pending con nection, leak it | 182 // Queue up a new spawn request. There is no way to kill the pending con nection, leak it |
| 170 // until the browser restart. | 183 // until the browser restart. |
| 171 final String packageName = appContext.getPackageName(); | 184 final String packageName = appContext.getPackageName(); |
| 172 final boolean inSandbox = true; | 185 final boolean inSandbox = true; |
| 173 ChildProcessLauncher.enqueuePendingSpawnForTesting(appContext, sProcessW aitArguments, | 186 ChildProcessLauncher.enqueuePendingSpawnForTesting(appContext, sProcessW aitArguments, |
| 174 getDefaultChildProcessCreationParams(packageName), inSandbox); | 187 ChildProcessLauncherTestHelper.getChildProcessCreationParams(pac kageName, null), |
| 188 inSandbox); | |
| 175 assertEquals(1, ChildProcessLauncher.pendingSpawnsCountForTesting(appCon text, packageName, | 189 assertEquals(1, ChildProcessLauncher.pendingSpawnsCountForTesting(appCon text, packageName, |
| 176 inSandbox)); | 190 inSandbox)); |
| 177 | 191 |
| 178 // Initiate the connection setup. | 192 // Initiate the connection setup. |
| 179 triggerConnectionSetup(connection); | 193 triggerConnectionSetup(connection); |
| 180 | 194 |
| 181 // Verify that the connection completes the setup. | 195 // Verify that the connection completes the setup. |
| 182 CriteriaHelper.pollInstrumentationThread( | 196 CriteriaHelper.pollInstrumentationThread( |
| 183 Criteria.equals(1, new Callable<Integer>() { | 197 Criteria.equals(1, new Callable<Integer>() { |
| 184 @Override | 198 @Override |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 204 public Integer call() { | 218 public Integer call() { |
| 205 return ChildProcessLauncher.pendingSpawnsCountForTesting(appCont ext, packageName, | 219 return ChildProcessLauncher.pendingSpawnsCountForTesting(appCont ext, packageName, |
| 206 inSandbox); | 220 inSandbox); |
| 207 } | 221 } |
| 208 })); | 222 })); |
| 209 | 223 |
| 210 CriteriaHelper.pollInstrumentationThread( | 224 CriteriaHelper.pollInstrumentationThread( |
| 211 Criteria.equals(1, new Callable<Integer>() { | 225 Criteria.equals(1, new Callable<Integer>() { |
| 212 @Override | 226 @Override |
| 213 public Integer call() { | 227 public Integer call() { |
| 214 return allocatedChromeSandboxedConnectionsCount(); | 228 return ChildProcessLauncherTestHelper |
| 229 .allocatedChromeSandboxedConnectionsCount(appCon text); | |
| 215 } | 230 } |
| 216 })); | 231 })); |
| 217 | 232 |
| 218 // Verify that the connection completes the setup for the pending spawn. | 233 // Verify that the connection completes the setup for the pending spawn. |
| 219 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable <Integer>() { | 234 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable <Integer>() { |
| 220 @Override | 235 @Override |
| 221 public Integer call() { | 236 public Integer call() { |
| 222 return ChildProcessLauncher.connectedServicesCountForTesting(); | 237 return ChildProcessLauncher.connectedServicesCountForTesting(); |
| 223 } | 238 } |
| 224 })); | 239 })); |
| 225 } | 240 } |
| 226 | 241 |
| 227 private ChildProcessConnectionImpl startConnection() throws InterruptedExcep tion { | 242 private ChildProcessConnectionImpl startConnection() throws InterruptedExcep tion { |
| 228 // Allocate a new connection. | 243 // Allocate a new connection. |
| 229 Context context = getInstrumentation().getTargetContext(); | 244 Context context = getInstrumentation().getTargetContext(); |
| 230 final ChildProcessConnectionImpl connection = | 245 final ChildProcessConnectionImpl connection = |
| 231 (ChildProcessConnectionImpl) ChildProcessLauncher.allocateBoundC onnectionForTesting( | 246 (ChildProcessConnectionImpl) ChildProcessLauncher.allocateBoundC onnectionForTesting( |
| 232 context, getDefaultChildProcessCreationParams(context.ge tPackageName())); | 247 context, |
| 248 ChildProcessLauncherTestHelper.getChildProcessCreationPa rams( | |
| 249 context.getPackageName(), null)); | |
| 233 | 250 |
| 234 // Wait for the service to connect. | 251 // Wait for the service to connect. |
| 235 CriteriaHelper.pollInstrumentationThread( | 252 CriteriaHelper.pollInstrumentationThread( |
|
Xi Han
2016/06/21 18:26:58
Tests failed if the "CriteriaHelper.pollInstrument
Maria
2016/06/21 21:32:12
Did ChildProcessLauncherTest failed or ChromeChild
Xi Han
2016/06/22 14:30:11
The ChildProcessLauncherTest failed and I did pass
| |
| 236 new Criteria("The connection wasn't established.") { | 253 new Criteria("The connection wasn't established.") { |
| 237 @Override | 254 @Override |
| 238 public boolean isSatisfied() { | 255 public boolean isSatisfied() { |
| 239 return connection.isConnected(); | 256 return connection.isConnected(); |
| 240 } | 257 } |
| 241 }); | 258 }); |
| 242 return connection; | 259 return connection; |
| 243 } | 260 } |
| 244 | 261 |
| 245 /** | |
| 246 * Returns the number of Chrome's sandboxed connections. | |
| 247 */ | |
| 248 private int allocatedChromeSandboxedConnectionsCount() { | |
| 249 Context context = getInstrumentation().getTargetContext(); | |
| 250 return ChildProcessLauncher.allocatedSandboxedConnectionsCountForTesting ( | |
| 251 context, context.getPackageName()); | |
| 252 } | |
| 253 | |
| 254 private ChildProcessCreationParams getDefaultChildProcessCreationParams(Stri ng packageName) { | |
| 255 return new ChildProcessCreationParams(packageName, 0, | |
| 256 LibraryProcessType.PROCESS_CHILD); | |
| 257 } | |
| 258 | |
| 259 private void triggerConnectionSetup(ChildProcessConnectionImpl connection) { | 262 private void triggerConnectionSetup(ChildProcessConnectionImpl connection) { |
| 260 ChildProcessLauncher.triggerConnectionSetup(connection, sProcessWaitArgu ments, 1, | 263 ChildProcessLauncher.triggerConnectionSetup(connection, sProcessWaitArgu ments, 1, |
| 261 new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_REN DERER_PROCESS, 0); | 264 new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_REN DERER_PROCESS, 0); |
| 262 } | 265 } |
| 263 | 266 |
| 264 @Override | 267 @Override |
| 265 protected void setUp() throws Exception { | 268 protected void setUp() throws Exception { |
| 266 super.setUp(); | 269 super.setUp(); |
| 267 LibraryLoader.get(LibraryProcessType.PROCESS_CHILD) | 270 LibraryLoader.get(LibraryProcessType.PROCESS_CHILD) |
| 268 .ensureInitialized(getInstrumentation().getTargetContext()); | 271 .ensureInitialized(getInstrumentation().getTargetContext()); |
| 269 } | 272 } |
| 270 } | 273 } |
| OLD | NEW |