OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.chrome.browser.background_task_scheduler; | |
6 | |
7 import static org.junit.Assert.assertEquals; | |
8 import static org.junit.Assert.assertFalse; | |
9 import static org.junit.Assert.assertTrue; | |
10 import static org.mockito.Mockito.any; | |
11 import static org.mockito.Mockito.doAnswer; | |
12 import static org.mockito.Mockito.doNothing; | |
13 import static org.mockito.Mockito.doReturn; | |
14 import static org.mockito.Mockito.doThrow; | |
15 import static org.mockito.Mockito.eq; | |
16 import static org.mockito.Mockito.times; | |
17 import static org.mockito.Mockito.verify; | |
18 | |
19 import android.content.Context; | |
20 | |
21 import org.junit.Before; | |
22 import org.junit.Test; | |
23 import org.junit.runner.RunWith; | |
24 import org.mockito.ArgumentCaptor; | |
25 import org.mockito.Captor; | |
26 import org.mockito.Mock; | |
27 import org.mockito.MockitoAnnotations; | |
28 import org.mockito.invocation.InvocationOnMock; | |
29 import org.mockito.stubbing.Answer; | |
30 import org.robolectric.RuntimeEnvironment; | |
31 import org.robolectric.annotation.Config; | |
32 import org.robolectric.util.ReflectionHelpers; | |
33 | |
34 import org.chromium.base.library_loader.LibraryProcessType; | |
35 import org.chromium.base.library_loader.LoaderErrors; | |
36 import org.chromium.base.library_loader.ProcessInitException; | |
37 import org.chromium.base.test.util.Feature; | |
38 import org.chromium.chrome.browser.init.BrowserParts; | |
39 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | |
40 import org.chromium.components.background_task_scheduler.BackgroundTask; | |
41 import org.chromium.components.background_task_scheduler.TaskIds; | |
42 import org.chromium.components.background_task_scheduler.TaskParameters; | |
43 import org.chromium.content.browser.BrowserStartupController; | |
44 import org.chromium.testing.local.LocalRobolectricTestRunner; | |
45 | |
46 import java.util.concurrent.CountDownLatch; | |
47 import java.util.concurrent.TimeUnit; | |
48 | |
49 /** Unit tests for {@link BackgroundTaskScheduler}. */ | |
50 @RunWith(LocalRobolectricTestRunner.class) | |
51 @Config(manifest = Config.NONE) | |
52 public class NativeBackgroundTaskTest { | |
53 private enum InitializerSetup { | |
54 SUCCESS, | |
55 FAILURE, | |
56 EXCEPTION, | |
57 } | |
58 | |
59 private static final TaskParameters TASK_PARAMETERS = | |
60 TaskParameters.create(TaskIds.TEST).build(); | |
61 | |
62 @Mock | |
63 private BrowserStartupController mBrowserStartupController; | |
64 @Mock | |
65 private ChromeBrowserInitializer mChromeBrowserInitializer; | |
66 @Captor | |
67 ArgumentCaptor<BrowserParts> mBrowserParts; | |
68 | |
69 private static class TaskFinishedCallback implements BackgroundTask.TaskFini shedCallback { | |
70 private boolean mWasCalled; | |
71 private boolean mNeedsReschedule; | |
72 private CountDownLatch mCallbackLatch; | |
73 | |
74 TaskFinishedCallback() { | |
75 mCallbackLatch = new CountDownLatch(1); | |
76 } | |
77 | |
78 @Override | |
79 public void taskFinished(boolean needsReschedule) { | |
80 mNeedsReschedule = needsReschedule; | |
81 mWasCalled = true; | |
82 mCallbackLatch.countDown(); | |
83 } | |
84 | |
85 boolean wasCalled() { | |
86 return mWasCalled; | |
87 } | |
88 | |
89 boolean needsRescheduling() { | |
90 return mNeedsReschedule; | |
91 } | |
92 | |
93 boolean waitOnCallback() { | |
94 return waitOnLatch(mCallbackLatch); | |
95 } | |
96 } | |
97 | |
98 private static class TestNativeBackgroundTask extends NativeBackgroundTask { | |
99 @StartBeforeNativeResult | |
100 private int mStartBeforeNativeResult; | |
101 private boolean mWasOnStartTaskWithNativeCalled; | |
102 private boolean mNeedsReschedulingAfterStop; | |
103 private CountDownLatch mStartWithNativeLatch; | |
104 private boolean mWasOnStopTaskWithNativeCalled; | |
105 private boolean mWasOnStopTaskBeforeNativeLoadedCalled; | |
106 | |
107 public TestNativeBackgroundTask() { | |
108 mWasOnStartTaskWithNativeCalled = false; | |
109 mStartBeforeNativeResult = LOAD_NATIVE; | |
110 mNeedsReschedulingAfterStop = false; | |
111 mStartWithNativeLatch = new CountDownLatch(1); | |
112 } | |
113 | |
114 @Override | |
115 protected int onStartTaskBeforeNativeLoaded( | |
116 Context context, TaskParameters taskParameters, TaskFinishedCall back callback) { | |
117 return mStartBeforeNativeResult; | |
118 } | |
119 | |
120 @Override | |
121 protected void onStartTaskWithNative( | |
122 Context context, TaskParameters taskParameters, TaskFinishedCall back callback) { | |
123 assertEquals(RuntimeEnvironment.application, context); | |
124 assertEquals(TASK_PARAMETERS, taskParameters); | |
125 mWasOnStartTaskWithNativeCalled = true; | |
126 mStartWithNativeLatch.countDown(); | |
127 } | |
128 | |
129 @Override | |
130 protected boolean onStopTaskBeforeNativeLoaded( | |
131 Context context, TaskParameters taskParameters) { | |
132 mWasOnStopTaskBeforeNativeLoadedCalled = true; | |
133 return mNeedsReschedulingAfterStop; | |
134 } | |
135 | |
136 @Override | |
137 protected boolean onStopTaskWithNative(Context context, TaskParameters t askParameters) { | |
138 mWasOnStopTaskWithNativeCalled = true; | |
139 return mNeedsReschedulingAfterStop; | |
140 } | |
141 | |
142 @Override | |
143 public void reschedule(Context context) {} | |
144 | |
145 boolean waitOnStartWithNativeCallback() { | |
146 return waitOnLatch(mStartWithNativeLatch); | |
147 } | |
148 | |
149 boolean wasOnStartTaskWithNativeCalled() { | |
150 return mWasOnStartTaskWithNativeCalled; | |
151 } | |
152 | |
153 boolean wasOnStopTaskWithNativeCalled() { | |
154 return mWasOnStopTaskWithNativeCalled; | |
155 } | |
156 | |
157 boolean wasOnStopTaskBeforeNativeLoadedCalled() { | |
158 return mWasOnStopTaskBeforeNativeLoadedCalled; | |
159 } | |
160 | |
161 void setStartTaskBeforeNativeResult(@StartBeforeNativeResult int result) { | |
162 mStartBeforeNativeResult = result; | |
163 } | |
164 | |
165 void setNeedsReschedulingAfterStop(boolean needsReschedulingAfterStop) { | |
166 mNeedsReschedulingAfterStop = needsReschedulingAfterStop; | |
167 } | |
168 } | |
169 | |
170 @Before | |
171 public void setUp() { | |
172 MockitoAnnotations.initMocks(this); | |
173 ReflectionHelpers.setField(mBrowserStartupController, "mLibraryProcessTy pe", | |
174 LibraryProcessType.PROCESS_BROWSER); | |
175 BrowserStartupController.overrideInstanceForTest(mBrowserStartupControll er); | |
176 ChromeBrowserInitializer.setForTesting(mChromeBrowserInitializer); | |
177 } | |
178 | |
179 private void setUpChromeBrowserInitializer(InitializerSetup setup) { | |
180 doNothing().when(mChromeBrowserInitializer).handlePreNativeStartup(any(B rowserParts.class)); | |
181 try { | |
182 switch (setup) { | |
183 case SUCCESS: | |
184 doAnswer(new Answer<Void>() { | |
185 @Override | |
186 public Void answer(InvocationOnMock invocation) { | |
187 mBrowserParts.getValue().finishNativeInitialization( ); | |
188 return null; | |
189 } | |
190 }) | |
191 .when(mChromeBrowserInitializer) | |
192 .handlePostNativeStartup(eq(true), mBrowserParts.cap ture()); | |
193 break; | |
194 case FAILURE: | |
195 doAnswer(new Answer<Void>() { | |
196 @Override | |
197 public Void answer(InvocationOnMock invocation) { | |
198 mBrowserParts.getValue().onStartupFailure(); | |
199 return null; | |
200 } | |
201 }) | |
202 .when(mChromeBrowserInitializer) | |
203 .handlePostNativeStartup(eq(true), mBrowserParts.cap ture()); | |
204 break; | |
205 case EXCEPTION: | |
206 doThrow(new ProcessInitException( | |
207 LoaderErrors.LOADER_ERROR_NATIVE_LIBRARY_LOA D_FAILED)) | |
208 .when(mChromeBrowserInitializer) | |
209 .handlePostNativeStartup(eq(true), any(BrowserParts. class)); | |
210 break; | |
211 default: | |
212 assert false; | |
213 } | |
214 } catch (ProcessInitException e) { | |
215 // Exception ignored, as try-catch is required by language. | |
216 } | |
217 } | |
218 | |
219 private void verifyStartupCalls(int expectedPreNativeCalls, int expectedPost NativeCalls) { | |
220 try { | |
221 verify(mChromeBrowserInitializer, times(expectedPreNativeCalls)) | |
222 .handlePreNativeStartup(any(BrowserParts.class)); | |
223 verify(mChromeBrowserInitializer, times(expectedPostNativeCalls)) | |
224 .handlePostNativeStartup(eq(true), any(BrowserParts.class)); | |
225 } catch (ProcessInitException e) { | |
226 // Exception ignored, as try-catch is required by language. | |
227 } | |
228 } | |
229 | |
230 private static boolean waitOnLatch(CountDownLatch latch) { | |
231 try { | |
232 // All tests are expected to get it done much faster | |
233 return latch.await(1, TimeUnit.SECONDS); | |
nyquist
2017/05/23 20:14:29
Our devices are sometimes incredibly slow for weir
fgorski
2017/05/23 21:35:02
Done.
| |
234 } catch (InterruptedException e) { | |
235 return false; | |
236 } | |
237 } | |
238 | |
239 @Test | |
240 @Feature("BackgroundTaskScheduler") | |
241 public void testOnStartTask_Done_BeforeNativeLoaded() { | |
242 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
243 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
244 task.setStartTaskBeforeNativeResult(NativeBackgroundTask.DONE); | |
245 assertFalse(task.onStartTask(RuntimeEnvironment.application, TASK_PARAME TERS, callback)); | |
246 | |
247 verify(mBrowserStartupController, times(0)).isStartupSuccessfullyComplet ed(); | |
248 verifyStartupCalls(0, 0); | |
249 assertFalse(task.wasOnStartTaskWithNativeCalled()); | |
250 assertFalse(callback.wasCalled()); | |
251 } | |
252 | |
253 @Test | |
254 @Feature("BackgroundTaskScheduler") | |
255 public void testOnStartTask_Reschedule_BeforeNativeLoaded() { | |
256 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
257 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
258 task.setStartTaskBeforeNativeResult(NativeBackgroundTask.RESCHEDULE); | |
259 assertTrue(task.onStartTask(RuntimeEnvironment.application, TASK_PARAMET ERS, callback)); | |
260 | |
261 assertTrue(callback.waitOnCallback()); | |
262 verify(mBrowserStartupController, times(0)).isStartupSuccessfullyComplet ed(); | |
263 verifyStartupCalls(0, 0); | |
264 assertFalse(task.wasOnStartTaskWithNativeCalled()); | |
265 assertTrue(callback.wasCalled()); | |
266 assertTrue(callback.needsRescheduling()); | |
267 } | |
268 | |
269 @Test | |
270 @Feature("BackgroundTaskScheduler") | |
271 public void testOnStartTask_NativeAlreadyLoaded() { | |
272 doReturn(true).when(mBrowserStartupController).isStartupSuccessfullyComp leted(); | |
273 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
274 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
275 task.onStartTask(RuntimeEnvironment.application, TASK_PARAMETERS, callba ck); | |
276 | |
277 assertTrue(task.waitOnStartWithNativeCallback()); | |
278 verify(mBrowserStartupController, times(1)).isStartupSuccessfullyComplet ed(); | |
279 verifyStartupCalls(0, 0); | |
280 assertTrue(task.wasOnStartTaskWithNativeCalled()); | |
281 assertFalse(callback.wasCalled()); | |
282 } | |
283 | |
284 @Test | |
285 @Feature("BackgroundTaskScheduler") | |
286 public void testOnStartTask_NativeInitialization_Success() { | |
287 doReturn(false).when(mBrowserStartupController).isStartupSuccessfullyCom pleted(); | |
288 setUpChromeBrowserInitializer(InitializerSetup.SUCCESS); | |
289 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
290 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
291 task.onStartTask(RuntimeEnvironment.application, TASK_PARAMETERS, callba ck); | |
292 | |
293 assertTrue(task.waitOnStartWithNativeCallback()); | |
294 verify(mBrowserStartupController, times(1)).isStartupSuccessfullyComplet ed(); | |
295 verifyStartupCalls(1, 1); | |
296 assertTrue(task.wasOnStartTaskWithNativeCalled()); | |
297 assertFalse(callback.wasCalled()); | |
298 } | |
299 | |
300 @Test | |
301 @Feature("BackgroundTaskScheduler") | |
302 public void testOnStartTask_NativeInitialization_Failure() { | |
303 doReturn(false).when(mBrowserStartupController).isStartupSuccessfullyCom pleted(); | |
304 setUpChromeBrowserInitializer(InitializerSetup.FAILURE); | |
305 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
306 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
307 task.onStartTask(RuntimeEnvironment.application, TASK_PARAMETERS, callba ck); | |
308 | |
309 assertTrue(callback.waitOnCallback()); | |
310 verify(mBrowserStartupController, times(1)).isStartupSuccessfullyComplet ed(); | |
311 verifyStartupCalls(1, 1); | |
312 assertFalse(task.wasOnStartTaskWithNativeCalled()); | |
313 assertTrue(callback.wasCalled()); | |
314 assertTrue(callback.needsRescheduling()); | |
315 } | |
316 | |
317 @Test | |
318 @Feature("BackgroundTaskScheduler") | |
319 public void testOnStartTask_NativeInitialization_Throws() { | |
320 doReturn(false).when(mBrowserStartupController).isStartupSuccessfullyCom pleted(); | |
321 setUpChromeBrowserInitializer(InitializerSetup.EXCEPTION); | |
322 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
323 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
324 task.onStartTask(RuntimeEnvironment.application, TASK_PARAMETERS, callba ck); | |
325 | |
326 assertTrue(callback.waitOnCallback()); | |
327 verify(mBrowserStartupController, times(1)).isStartupSuccessfullyComplet ed(); | |
328 verifyStartupCalls(1, 1); | |
329 assertFalse(task.wasOnStartTaskWithNativeCalled()); | |
330 assertTrue(callback.wasCalled()); | |
331 assertTrue(callback.needsRescheduling()); | |
332 } | |
333 | |
334 @Test | |
335 @Feature("BackgroundTaskScheduler") | |
336 public void testOnStopTask_BeforeNativeLoaded_NeedsRescheduling() { | |
337 doReturn(false).when(mBrowserStartupController).isStartupSuccessfullyCom pleted(); | |
338 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
339 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
340 task.setNeedsReschedulingAfterStop(true); | |
341 | |
342 assertTrue(task.onStopTask(RuntimeEnvironment.application, TASK_PARAMETE RS)); | |
343 assertTrue(task.wasOnStopTaskBeforeNativeLoadedCalled()); | |
344 assertFalse(task.wasOnStopTaskWithNativeCalled()); | |
345 } | |
346 | |
347 @Test | |
348 @Feature("BackgroundTaskScheduler") | |
349 public void testOnStopTask_BeforeNativeLoaded_DoesntNeedRescheduling() { | |
350 doReturn(false).when(mBrowserStartupController).isStartupSuccessfullyCom pleted(); | |
351 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
352 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
353 task.setNeedsReschedulingAfterStop(false); | |
354 | |
355 assertFalse(task.onStopTask(RuntimeEnvironment.application, TASK_PARAMET ERS)); | |
356 assertTrue(task.wasOnStopTaskBeforeNativeLoadedCalled()); | |
357 assertFalse(task.wasOnStopTaskWithNativeCalled()); | |
358 } | |
359 | |
360 @Test | |
361 @Feature("BackgroundTaskScheduler") | |
362 public void testOnStopTask_NativeLoaded_NeedsRescheduling() { | |
363 doReturn(true).when(mBrowserStartupController).isStartupSuccessfullyComp leted(); | |
364 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
365 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
366 task.setNeedsReschedulingAfterStop(true); | |
367 | |
368 assertTrue(task.onStopTask(RuntimeEnvironment.application, TASK_PARAMETE RS)); | |
369 assertFalse(task.wasOnStopTaskBeforeNativeLoadedCalled()); | |
370 assertTrue(task.wasOnStopTaskWithNativeCalled()); | |
371 } | |
372 | |
373 @Test | |
374 @Feature("BackgroundTaskScheduler") | |
375 public void testOnStopTask_NativeLoaded_DoesntNeedRescheduling() { | |
376 doReturn(true).when(mBrowserStartupController).isStartupSuccessfullyComp leted(); | |
377 TaskFinishedCallback callback = new TaskFinishedCallback(); | |
378 TestNativeBackgroundTask task = new TestNativeBackgroundTask(); | |
379 task.setNeedsReschedulingAfterStop(false); | |
380 | |
381 assertFalse(task.onStopTask(RuntimeEnvironment.application, TASK_PARAMET ERS)); | |
382 assertFalse(task.wasOnStopTaskBeforeNativeLoadedCalled()); | |
383 assertTrue(task.wasOnStopTaskWithNativeCalled()); | |
384 } | |
385 } | |
OLD | NEW |