Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 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.offlinepages; | |
| 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.anyBoolean; | |
| 12 import static org.mockito.Mockito.doReturn; | |
| 13 import static org.mockito.Mockito.eq; | |
| 14 import static org.mockito.Mockito.times; | |
| 15 import static org.mockito.Mockito.verify; | |
| 16 | |
| 17 import android.app.Activity; | |
| 18 import android.content.Context; | |
| 19 import android.os.Bundle; | |
| 20 | |
| 21 import org.junit.After; | |
| 22 import org.junit.Before; | |
| 23 import org.junit.Rule; | |
| 24 import org.junit.Test; | |
| 25 import org.junit.runner.RunWith; | |
| 26 import org.mockito.ArgumentCaptor; | |
| 27 import org.mockito.ArgumentMatchers; | |
| 28 import org.mockito.Captor; | |
| 29 import org.mockito.Mock; | |
| 30 import org.mockito.MockitoAnnotations; | |
| 31 import org.robolectric.RuntimeEnvironment; | |
| 32 import org.robolectric.annotation.Config; | |
| 33 | |
| 34 import org.chromium.base.ActivityState; | |
| 35 import org.chromium.base.ApplicationStatus; | |
| 36 import org.chromium.base.BaseSwitches; | |
| 37 import org.chromium.base.Callback; | |
| 38 import org.chromium.base.CommandLine; | |
| 39 import org.chromium.base.ContextUtils; | |
| 40 import org.chromium.base.SysUtils; | |
| 41 import org.chromium.base.test.util.Feature; | |
| 42 import org.chromium.chrome.browser.DisableHistogramsRule; | |
| 43 import org.chromium.chrome.browser.background_task_scheduler.NativeBackgroundTas k; | |
| 44 import org.chromium.components.background_task_scheduler.BackgroundTask; | |
| 45 import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler ; | |
| 46 import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler Factory; | |
| 47 import org.chromium.components.background_task_scheduler.TaskIds; | |
| 48 import org.chromium.components.background_task_scheduler.TaskInfo; | |
| 49 import org.chromium.components.background_task_scheduler.TaskParameters; | |
| 50 import org.chromium.net.ConnectionType; | |
| 51 import org.chromium.testing.local.LocalRobolectricTestRunner; | |
| 52 | |
| 53 /** | |
| 54 * Unit tests for OfflineBackgroundTask. | |
| 55 */ | |
| 56 @RunWith(LocalRobolectricTestRunner.class) | |
| 57 @Config(manifest = Config.NONE, shadows = {ShadowDeviceConditions.class}) | |
| 58 public class OfflineBackgroundTaskTest { | |
| 59 private static final boolean REQUIRE_POWER = true; | |
| 60 private static final boolean REQUIRE_UNMETERED = true; | |
| 61 private static final boolean POWER_CONNECTED = true; | |
| 62 private static final int MINIMUM_BATTERY_LEVEL = 33; | |
| 63 private static final String IS_LOW_END_DEVICE_SWITCH = | |
| 64 "--" + BaseSwitches.ENABLE_LOW_END_DEVICE_MODE; | |
| 65 | |
| 66 @Rule | |
| 67 public DisableHistogramsRule mDisableHistogramsRule = new DisableHistogramsR ule(); | |
| 68 | |
| 69 private Bundle mTaskExtras; | |
| 70 private long mTestTime; | |
| 71 private TriggerConditions mTriggerConditions = | |
| 72 new TriggerConditions(!REQUIRE_POWER, MINIMUM_BATTERY_LEVEL, REQUIRE _UNMETERED); | |
| 73 private DeviceConditions mDeviceConditions = new DeviceConditions( | |
| 74 !POWER_CONNECTED, MINIMUM_BATTERY_LEVEL + 5, ConnectionType.CONNECTI ON_3G); | |
| 75 private Activity mTestActivity; | |
| 76 | |
| 77 @Mock | |
| 78 private BackgroundSchedulerProcessor mBackgroundSchedulerProcessor; | |
| 79 | |
| 80 @Mock | |
| 81 private BackgroundTaskScheduler mTaskScheduler; | |
| 82 @Mock | |
| 83 private BackgroundTask.TaskFinishedCallback mTaskFinishedCallback; | |
| 84 @Mock | |
| 85 private Callback<Boolean> mInternalBooleanCallback; | |
| 86 @Captor | |
| 87 private ArgumentCaptor<TaskInfo> mTaskInfo; | |
| 88 | |
| 89 @Before | |
| 90 public void setUp() throws Exception { | |
| 91 MockitoAnnotations.initMocks(this); | |
| 92 ContextUtils.initApplicationContextForTests(RuntimeEnvironment.applicati on); | |
| 93 BackgroundTaskSchedulerFactory.setSchedulerForTesting(mTaskScheduler); | |
| 94 doReturn(true) | |
| 95 .when(mTaskScheduler) | |
| 96 .schedule(eq(RuntimeEnvironment.application), mTaskInfo.capture( )); | |
| 97 | |
| 98 ShadowDeviceConditions.setCurrentConditions(mDeviceConditions); | |
| 99 | |
| 100 // Set up background scheduler processor mock. | |
| 101 BackgroundSchedulerProcessor.setInstanceForTesting(mBackgroundSchedulerP rocessor); | |
| 102 | |
| 103 // Build a bundle with trigger conditions. | |
| 104 mTaskExtras = new Bundle(); | |
| 105 TaskExtrasPacker.packTimeInBundle(mTaskExtras); | |
| 106 TaskExtrasPacker.packTriggerConditionsInBundle(mTaskExtras, mTriggerCond itions); | |
| 107 | |
| 108 // Run tests as a low-end device. | |
| 109 CommandLine.init(new String[] {"testcommand", IS_LOW_END_DEVICE_SWITCH}) ; | |
| 110 | |
| 111 // Set up single, stopped Activity. | |
| 112 ApplicationStatus.destroyForJUnitTests(); | |
| 113 mTestActivity = new Activity(); | |
| 114 ApplicationStatus.onStateChangeForTesting(mTestActivity, ActivityState.C REATED); | |
| 115 ApplicationStatus.onStateChangeForTesting(mTestActivity, ActivityState.S TOPPED); | |
| 116 } | |
| 117 | |
| 118 @After | |
| 119 public void tearDown() throws Exception { | |
| 120 // Clean up static state for subsequent Robolectric tests. | |
| 121 CommandLine.reset(); | |
| 122 SysUtils.reset(); | |
| 123 ApplicationStatus.destroyForJUnitTests(); | |
| 124 } | |
| 125 | |
| 126 private void setupScheduledProcessingWithResult(boolean result) { | |
| 127 doReturn(result) | |
| 128 .when(mBackgroundSchedulerProcessor) | |
| 129 .startScheduledProcessing( | |
| 130 any(DeviceConditions.class), ArgumentMatchers.<Callback< Boolean>>any()); | |
| 131 } | |
| 132 | |
| 133 @Test | |
| 134 @Feature({"OfflinePages"}) | |
| 135 public void testCheckConditions_BatteryConditions_LowBattery_NoPower() { | |
| 136 // Setup low battery conditions with no power connected. | |
| 137 DeviceConditions deviceConditionsLowBattery = new DeviceConditions( | |
| 138 !POWER_CONNECTED, MINIMUM_BATTERY_LEVEL - 1, ConnectionType.CONN ECTION_WIFI); | |
| 139 ShadowDeviceConditions.setCurrentConditions(deviceConditionsLowBattery); | |
| 140 | |
| 141 // Verify that conditions for processing are not met. | |
| 142 assertFalse( | |
| 143 OfflineBackgroundTask.checkConditions(RuntimeEnvironment.applica tion, mTaskExtras)); | |
| 144 | |
| 145 // Check impact on starting before native loaded. | |
| 146 TaskParameters params = TaskParameters.create(TaskIds.OFFLINE_PAGES_BACK GROUND_JOB_ID) | |
| 147 .addExtras(mTaskExtras) | |
| 148 .build(); | |
| 149 | |
| 150 assertEquals(NativeBackgroundTask.RESCHEDULE, | |
| 151 new OfflineBackgroundTask().onStartTaskBeforeNativeLoaded( | |
|
Pete Williamson
2017/05/25 17:30:53
It feels a bit odd to me to have the function unde
fgorski
2017/05/25 21:41:50
I applied that, but only to the calls returning a
| |
| 152 RuntimeEnvironment.application, params, mTaskFinishedCal lback)); | |
| 153 verify(mTaskFinishedCallback, times(0)).taskFinished(anyBoolean()); | |
|
Pete Williamson
2017/05/25 17:30:53
It seems a bit counter intuitive that you are veri
fgorski
2017/05/25 21:41:50
Done.
| |
| 154 } | |
| 155 | |
| 156 @Test | |
| 157 @Feature({"OfflinePages"}) | |
| 158 public void testCheckConditions_BatteryConditions_LowBattery_WithPower() { | |
| 159 // Set battery percentage below minimum level, but connect power. | |
| 160 DeviceConditions deviceConditionsPowerConnected = new DeviceConditions( | |
| 161 POWER_CONNECTED, MINIMUM_BATTERY_LEVEL - 1, ConnectionType.CONNE CTION_WIFI); | |
| 162 ShadowDeviceConditions.setCurrentConditions(deviceConditionsPowerConnect ed); | |
| 163 | |
| 164 // Now verify that same battery level, with power connected, will pass t he conditions. | |
| 165 assertTrue( | |
| 166 OfflineBackgroundTask.checkConditions(RuntimeEnvironment.applica tion, mTaskExtras)); | |
| 167 | |
| 168 // Check impact on starting before native loaded. | |
| 169 TaskParameters params = TaskParameters.create(TaskIds.OFFLINE_PAGES_BACK GROUND_JOB_ID) | |
| 170 .addExtras(mTaskExtras) | |
| 171 .build(); | |
| 172 | |
| 173 assertEquals(NativeBackgroundTask.LOAD_NATIVE, | |
| 174 new OfflineBackgroundTask().onStartTaskBeforeNativeLoaded( | |
| 175 RuntimeEnvironment.application, params, mTaskFinishedCal lback)); | |
| 176 verify(mTaskFinishedCallback, times(0)).taskFinished(anyBoolean()); | |
| 177 } | |
| 178 | |
| 179 @Test | |
| 180 @Feature({"OfflinePages"}) | |
| 181 public void testCheckConditions_OnLowEndDevice_ActivityStarted() { | |
| 182 // Transition the test Activity to a running state. | |
| 183 ApplicationStatus.onStateChangeForTesting(mTestActivity, ActivityState.S TARTED); | |
| 184 | |
| 185 // Verify that conditions for processing are not met. | |
| 186 assertFalse( | |
| 187 OfflineBackgroundTask.checkConditions(RuntimeEnvironment.applica tion, mTaskExtras)); | |
| 188 | |
| 189 // Check impact on starting before native loaded. | |
| 190 TaskParameters params = TaskParameters.create(TaskIds.OFFLINE_PAGES_BACK GROUND_JOB_ID) | |
| 191 .addExtras(mTaskExtras) | |
| 192 .build(); | |
| 193 | |
| 194 assertEquals(NativeBackgroundTask.RESCHEDULE, | |
| 195 new OfflineBackgroundTask().onStartTaskBeforeNativeLoaded( | |
| 196 RuntimeEnvironment.application, params, mTaskFinishedCal lback)); | |
| 197 verify(mTaskFinishedCallback, times(0)).taskFinished(anyBoolean()); | |
| 198 } | |
| 199 | |
| 200 @Test | |
| 201 @Feature({"OfflinePages"}) | |
| 202 public void testCheckConditions_OnLowEndDevice_ActivityStopped() { | |
| 203 // Switch activity state to stopped. | |
| 204 ApplicationStatus.onStateChangeForTesting(mTestActivity, ActivityState.S TOPPED); | |
| 205 | |
| 206 // Now verify that condition check passes when Activity is stopped. | |
| 207 assertTrue( | |
| 208 OfflineBackgroundTask.checkConditions(RuntimeEnvironment.applica tion, mTaskExtras)); | |
| 209 | |
| 210 // Check impact on starting before native loaded. | |
| 211 TaskParameters params = TaskParameters.create(TaskIds.OFFLINE_PAGES_BACK GROUND_JOB_ID) | |
| 212 .addExtras(mTaskExtras) | |
| 213 .build(); | |
| 214 | |
| 215 assertEquals(NativeBackgroundTask.LOAD_NATIVE, | |
| 216 new OfflineBackgroundTask().onStartTaskBeforeNativeLoaded( | |
| 217 RuntimeEnvironment.application, params, mTaskFinishedCal lback)); | |
| 218 verify(mTaskFinishedCallback, times(0)).taskFinished(anyBoolean()); | |
| 219 } | |
| 220 | |
| 221 @Test | |
| 222 @Feature({"OfflinePages"}) | |
| 223 public void testOnStartTaskWithNative_BackupScheduleIfExecutingTask() { | |
| 224 setupScheduledProcessingWithResult(true); | |
| 225 | |
| 226 TaskParameters params = TaskParameters.create(TaskIds.OFFLINE_PAGES_BACK GROUND_JOB_ID) | |
| 227 .addExtras(mTaskExtras) | |
| 228 .build(); | |
| 229 | |
| 230 new OfflineBackgroundTask().onStartTaskWithNative( | |
| 231 RuntimeEnvironment.application, params, mTaskFinishedCallback); | |
| 232 | |
| 233 verify(mTaskScheduler, times(1)) | |
| 234 .schedule(eq(RuntimeEnvironment.application), any(TaskInfo.class )); | |
| 235 verify(mTaskFinishedCallback, times(0)).taskFinished(anyBoolean()); | |
| 236 } | |
| 237 | |
| 238 @Test | |
| 239 @Feature({"OfflinePages"}) | |
| 240 public void testOnStartTaskWithNative_RescheduleThroughCallbackWhenRunning() { | |
| 241 setupScheduledProcessingWithResult(false); | |
| 242 | |
| 243 TaskParameters params = TaskParameters.create(TaskIds.OFFLINE_PAGES_BACK GROUND_JOB_ID) | |
| 244 .addExtras(mTaskExtras) | |
| 245 .build(); | |
| 246 | |
| 247 new OfflineBackgroundTask().onStartTaskWithNative( | |
| 248 RuntimeEnvironment.application, params, mTaskFinishedCallback); | |
| 249 | |
| 250 verify(mTaskScheduler, times(0)).schedule(any(Context.class), any(TaskIn fo.class)); | |
| 251 verify(mTaskFinishedCallback, times(1)).taskFinished(eq(true)); | |
| 252 } | |
| 253 | |
| 254 @Test | |
| 255 @Feature({"OfflinePages"}) | |
| 256 public void testStartBackgroundRequests() { | |
| 257 setupScheduledProcessingWithResult(true); | |
| 258 | |
| 259 assertTrue(OfflineBackgroundTask.startScheduledProcessing(mBackgroundSch edulerProcessor, | |
| 260 RuntimeEnvironment.application, mTaskExtras, mInternalBooleanCal lback)); | |
| 261 | |
| 262 // Check with BackgroundSchedulerProcessor that processing started. | |
| 263 verify(mBackgroundSchedulerProcessor, times(1)) | |
| 264 .startScheduledProcessing(eq(mDeviceConditions), eq(mInternalBoo leanCallback)); | |
| 265 } | |
| 266 | |
| 267 @Test | |
| 268 @Feature({"OfflinePages"}) | |
| 269 public void testStartBackgroundRequestsNotStarted() { | |
| 270 // Processing will not be started here. | |
| 271 setupScheduledProcessingWithResult(false); | |
| 272 | |
| 273 assertFalse(OfflineBackgroundTask.startScheduledProcessing(mBackgroundSc hedulerProcessor, | |
| 274 RuntimeEnvironment.application, mTaskExtras, mInternalBooleanCal lback)); | |
| 275 | |
| 276 // Check with BackgroundSchedulerProcessor that it did not start. | |
| 277 verify(mBackgroundSchedulerProcessor, times(1)) | |
| 278 .startScheduledProcessing(eq(mDeviceConditions), eq(mInternalBoo leanCallback)); | |
| 279 } | |
| 280 } | |
| OLD | NEW |