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; | |
14 import org.chromium.base.library_loader.LibraryProcessType; | |
15 import org.chromium.base.test.util.CommandLineFlags; | 13 import org.chromium.base.test.util.CommandLineFlags; |
16 import org.chromium.base.test.util.Feature; | 14 import org.chromium.base.test.util.Feature; |
| 15 import org.chromium.content.browser.test.ChildProcessLauncherTestHelper; |
17 import org.chromium.content.browser.test.util.Criteria; | 16 import org.chromium.content.browser.test.util.Criteria; |
18 import org.chromium.content.browser.test.util.CriteriaHelper; | 17 import org.chromium.content.browser.test.util.CriteriaHelper; |
19 | 18 |
20 import java.util.concurrent.Callable; | 19 import java.util.concurrent.Callable; |
21 | 20 |
22 /** | 21 /** |
23 * Instrumentation tests for ChildProcessLauncher. | 22 * 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 */ | 23 */ |
27 public class ChildProcessLauncherTest extends InstrumentationTestCase { | 24 public class ChildProcessLauncherTest extends InstrumentationTestCase { |
28 // Pseudo command line arguments to instruct the child process to wait until
being killed. | 25 // 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 | 26 // 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. | 27 // channels that are not being set up in this test. |
31 private static final String[] sProcessWaitArguments = { | 28 private static final String[] sProcessWaitArguments = { |
32 "_", "--" + BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER }; | 29 "_", "--" + BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER }; |
33 | 30 |
34 /** | 31 /** |
35 * Tests cleanup for a connection that fails to connect in the first place. | 32 * Tests cleanup for a connection that fails to connect in the first place. |
36 */ | 33 */ |
37 @MediumTest | 34 @MediumTest |
38 @Feature({"ProcessManagement"}) | 35 @Feature({"ProcessManagement"}) |
39 @CommandLineFlags.Add(ChildProcessLauncher.SWITCH_NUM_SANDBOXED_SERVICES_FOR
_TESTING + "=4") | 36 @CommandLineFlags.Add(ChildProcessLauncher.SWITCH_NUM_SANDBOXED_SERVICES_FOR
_TESTING + "=4") |
40 public void testServiceFailedToBind() throws InterruptedException, RemoteExc
eption { | 37 public void testServiceFailedToBind() throws InterruptedException, RemoteExc
eption { |
41 assertEquals(0, allocatedChromeSandboxedConnectionsCount()); | 38 final Context appContext = getInstrumentation().getContext(); |
| 39 assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC
onnectionsCount( |
| 40 appContext)); |
42 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting())
; | 41 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting())
; |
43 | 42 |
44 // Try to allocate a connection to service class in incorrect package. W
e can do that by | 43 // 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 | 44 // using the instrumentation context (getContext()) instead of the app c
ontext |
46 // (getTargetContext()). | 45 // (getTargetContext()). |
47 Context context = getInstrumentation().getContext(); | 46 Context context = getInstrumentation().getContext(); |
48 ChildProcessLauncher.allocateBoundConnectionForTesting( | 47 ChildProcessLauncher.allocateBoundConnectionForTesting( |
49 context, getDefaultChildProcessCreationParams(context.getPackage
Name())); | 48 context, ChildProcessLauncherTestHelper.getChildProcessCreationP
arams( |
| 49 context.getPackageName(), null)); |
50 | 50 |
51 // Verify that the connection is not considered as allocated. | 51 // Verify that the connection is not considered as allocated. |
52 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { | 52 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { |
53 @Override | 53 @Override |
54 public Integer call() { | 54 public Integer call() { |
55 return allocatedChromeSandboxedConnectionsCount(); | 55 return ChildProcessLauncherTestHelper.allocatedChromeSandboxedCo
nnectionsCount( |
| 56 appContext); |
56 } | 57 } |
57 })); | 58 })); |
58 | 59 |
59 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { | 60 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { |
60 @Override | 61 @Override |
61 public Integer call() { | 62 public Integer call() { |
62 return ChildProcessLauncher.connectedServicesCountForTesting(); | 63 return ChildProcessLauncher.connectedServicesCountForTesting(); |
63 } | 64 } |
64 })); | 65 })); |
65 } | 66 } |
66 | 67 |
67 /** | 68 /** |
68 * Tests cleanup for a connection that terminates before setup. | 69 * Tests cleanup for a connection that terminates before setup. |
69 */ | 70 */ |
70 @MediumTest | 71 @MediumTest |
71 @Feature({"ProcessManagement"}) | 72 @Feature({"ProcessManagement"}) |
72 public void testServiceCrashedBeforeSetup() throws InterruptedException, Rem
oteException { | 73 public void testServiceCrashedBeforeSetup() throws InterruptedException, Rem
oteException { |
73 assertEquals(0, allocatedChromeSandboxedConnectionsCount()); | 74 final Context appContext = getInstrumentation().getTargetContext(); |
| 75 assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC
onnectionsCount( |
| 76 appContext)); |
74 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting())
; | 77 assertEquals(0, ChildProcessLauncher.connectedServicesCountForTesting())
; |
75 | 78 |
76 // Start and connect to a new service. | 79 // Start and connect to a new service. |
77 final ChildProcessConnectionImpl connection = startConnection(); | 80 final ChildProcessConnectionImpl connection = |
78 assertEquals(1, allocatedChromeSandboxedConnectionsCount()); | 81 ChildProcessLauncherTestHelper.startConnection(appContext, |
| 82 appContext.getPackageName(), null); |
| 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 = |
113 assertEquals(1, allocatedChromeSandboxedConnectionsCount()); | 122 ChildProcessLauncherTestHelper.startConnection(appContext, |
| 123 appContext.getPackageName(), null); |
| 124 assertEquals(1, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC
onnectionsCount( |
| 125 appContext)); |
114 | 126 |
115 // Initiate the connection setup. | 127 // Initiate the connection setup. |
116 triggerConnectionSetup(connection); | 128 triggerConnectionSetup(connection); |
117 | 129 |
118 // Verify that the connection completes the setup. | 130 // Verify that the connection completes the setup. |
119 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable
<Integer>() { | 131 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable
<Integer>() { |
120 @Override | 132 @Override |
121 public Integer call() { | 133 public Integer call() { |
122 return ChildProcessLauncher.connectedServicesCountForTesting(); | 134 return ChildProcessLauncher.connectedServicesCountForTesting(); |
123 } | 135 } |
124 })); | 136 })); |
125 | 137 |
126 CriteriaHelper.pollInstrumentationThread( | 138 CriteriaHelper.pollInstrumentationThread( |
127 new Criteria("The connection failed to get a pid in setup.") { | 139 new Criteria("The connection failed to get a pid in setup.") { |
128 @Override | 140 @Override |
129 public boolean isSatisfied() { | 141 public boolean isSatisfied() { |
130 return connection.getPid() != 0; | 142 return connection.getPid() != 0; |
131 } | 143 } |
132 }); | 144 }); |
133 | 145 |
134 // Crash the service. | 146 // Crash the service. |
135 assertTrue(connection.crashServiceForTesting()); | 147 assertTrue(connection.crashServiceForTesting()); |
136 | 148 |
137 // Verify that the connection gets cleaned-up. | 149 // Verify that the connection gets cleaned-up. |
138 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { | 150 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { |
139 @Override | 151 @Override |
140 public Integer call() { | 152 public Integer call() { |
141 return allocatedChromeSandboxedConnectionsCount(); | 153 return ChildProcessLauncherTestHelper.allocatedChromeSandboxedCo
nnectionsCount( |
| 154 appContext); |
142 } | 155 } |
143 })); | 156 })); |
144 | 157 |
145 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { | 158 CriteriaHelper.pollInstrumentationThread(Criteria.equals(0, new Callable
<Integer>() { |
146 @Override | 159 @Override |
147 public Integer call() { | 160 public Integer call() { |
148 return ChildProcessLauncher.connectedServicesCountForTesting(); | 161 return ChildProcessLauncher.connectedServicesCountForTesting(); |
149 } | 162 } |
150 })); | 163 })); |
151 | 164 |
152 // Verify that the connection pid remains set after termination. | 165 // Verify that the connection pid remains set after termination. |
153 assertTrue(connection.getPid() != 0); | 166 assertTrue(connection.getPid() != 0); |
154 } | 167 } |
155 | 168 |
156 /** | 169 /** |
157 * Tests spawning a pending process from queue. | 170 * Tests spawning a pending process from queue. |
158 */ | 171 */ |
159 @MediumTest | 172 @MediumTest |
160 @Feature({"ProcessManagement"}) | 173 @Feature({"ProcessManagement"}) |
161 public void testPendingSpawnQueue() throws InterruptedException, RemoteExcep
tion { | 174 public void testPendingSpawnQueue() throws InterruptedException, RemoteExcep
tion { |
162 final Context appContext = getInstrumentation().getTargetContext(); | 175 final Context appContext = getInstrumentation().getTargetContext(); |
163 assertEquals(0, allocatedChromeSandboxedConnectionsCount()); | 176 assertEquals(0, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC
onnectionsCount( |
| 177 appContext)); |
164 | 178 |
165 // Start and connect to a new service. | 179 // Start and connect to a new service. |
166 final ChildProcessConnectionImpl connection = startConnection(); | 180 final ChildProcessConnectionImpl connection = |
167 assertEquals(1, allocatedChromeSandboxedConnectionsCount()); | 181 ChildProcessLauncherTestHelper.startConnection(appContext, |
| 182 appContext.getPackageName(), null); |
| 183 assertEquals(1, ChildProcessLauncherTestHelper.allocatedChromeSandboxedC
onnectionsCount( |
| 184 appContext)); |
168 | 185 |
169 // Queue up a new spawn request. There is no way to kill the pending con
nection, leak it | 186 // Queue up a new spawn request. There is no way to kill the pending con
nection, leak it |
170 // until the browser restart. | 187 // until the browser restart. |
171 final String packageName = appContext.getPackageName(); | 188 final String packageName = appContext.getPackageName(); |
172 final boolean inSandbox = true; | 189 final boolean inSandbox = true; |
173 ChildProcessLauncher.enqueuePendingSpawnForTesting(appContext, sProcessW
aitArguments, | 190 ChildProcessLauncher.enqueuePendingSpawnForTesting(appContext, sProcessW
aitArguments, |
174 getDefaultChildProcessCreationParams(packageName), inSandbox); | 191 ChildProcessLauncherTestHelper.getChildProcessCreationParams(pac
kageName, null), |
| 192 inSandbox); |
175 assertEquals(1, ChildProcessLauncher.pendingSpawnsCountForTesting(appCon
text, packageName, | 193 assertEquals(1, ChildProcessLauncher.pendingSpawnsCountForTesting(appCon
text, packageName, |
176 inSandbox)); | 194 inSandbox)); |
177 | 195 |
178 // Initiate the connection setup. | 196 // Initiate the connection setup. |
179 triggerConnectionSetup(connection); | 197 triggerConnectionSetup(connection); |
180 | 198 |
181 // Verify that the connection completes the setup. | 199 // Verify that the connection completes the setup. |
182 CriteriaHelper.pollInstrumentationThread( | 200 CriteriaHelper.pollInstrumentationThread( |
183 Criteria.equals(1, new Callable<Integer>() { | 201 Criteria.equals(1, new Callable<Integer>() { |
184 @Override | 202 @Override |
(...skipping 19 matching lines...) Expand all Loading... |
204 public Integer call() { | 222 public Integer call() { |
205 return ChildProcessLauncher.pendingSpawnsCountForTesting(appCont
ext, packageName, | 223 return ChildProcessLauncher.pendingSpawnsCountForTesting(appCont
ext, packageName, |
206 inSandbox); | 224 inSandbox); |
207 } | 225 } |
208 })); | 226 })); |
209 | 227 |
210 CriteriaHelper.pollInstrumentationThread( | 228 CriteriaHelper.pollInstrumentationThread( |
211 Criteria.equals(1, new Callable<Integer>() { | 229 Criteria.equals(1, new Callable<Integer>() { |
212 @Override | 230 @Override |
213 public Integer call() { | 231 public Integer call() { |
214 return allocatedChromeSandboxedConnectionsCount(); | 232 return ChildProcessLauncherTestHelper |
| 233 .allocatedChromeSandboxedConnectionsCount(appCon
text); |
215 } | 234 } |
216 })); | 235 })); |
217 | 236 |
218 // Verify that the connection completes the setup for the pending spawn. | 237 // Verify that the connection completes the setup for the pending spawn. |
219 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable
<Integer>() { | 238 CriteriaHelper.pollInstrumentationThread(Criteria.equals(1, new Callable
<Integer>() { |
220 @Override | 239 @Override |
221 public Integer call() { | 240 public Integer call() { |
222 return ChildProcessLauncher.connectedServicesCountForTesting(); | 241 return ChildProcessLauncher.connectedServicesCountForTesting(); |
223 } | 242 } |
224 })); | 243 })); |
225 } | 244 } |
226 | 245 |
227 private ChildProcessConnectionImpl startConnection() throws InterruptedExcep
tion { | |
228 // Allocate a new connection. | |
229 Context context = getInstrumentation().getTargetContext(); | |
230 final ChildProcessConnectionImpl connection = | |
231 (ChildProcessConnectionImpl) ChildProcessLauncher.allocateBoundC
onnectionForTesting( | |
232 context, getDefaultChildProcessCreationParams(context.ge
tPackageName())); | |
233 | |
234 // Wait for the service to connect. | |
235 CriteriaHelper.pollInstrumentationThread( | |
236 new Criteria("The connection wasn't established.") { | |
237 @Override | |
238 public boolean isSatisfied() { | |
239 return connection.isConnected(); | |
240 } | |
241 }); | |
242 return connection; | |
243 } | |
244 | |
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) { | 246 private void triggerConnectionSetup(ChildProcessConnectionImpl connection) { |
260 ChildProcessLauncher.triggerConnectionSetup(connection, sProcessWaitArgu
ments, 1, | 247 ChildProcessLauncher.triggerConnectionSetup(connection, sProcessWaitArgu
ments, 1, |
261 new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_REN
DERER_PROCESS, 0); | 248 new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_REN
DERER_PROCESS, 0); |
262 } | 249 } |
263 | 250 |
264 @Override | 251 @Override |
265 protected void setUp() throws Exception { | 252 protected void setUp() throws Exception { |
266 super.setUp(); | 253 super.setUp(); |
267 LibraryLoader.get(LibraryProcessType.PROCESS_CHILD) | 254 ChildProcessLauncherTestHelper.ensureLibraryInitialized( |
268 .ensureInitialized(getInstrumentation().getTargetContext()); | 255 getInstrumentation().getTargetContext()); |
269 } | 256 } |
270 } | 257 } |
OLD | NEW |