From adfa6e804a29707d2e8746a06517c5c08f80d1a3 Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Fri, 19 Oct 2018 17:32:08 -0700 Subject: [PATCH] Fix AlarmManagerServiceTest and add some more tests The tests were failing due to an NPE in SettingsProvider. Mocking the content resolver to separate test code from internal details. Added couple more tests. Test: atest FrameworksMockingServicesTests:AlarmManagerServiceTest Bug: 111454659 Change-Id: Ie9784a4645f4559254894a3904f0c156167d49c6 --- .../android/server/AlarmManagerService.java | 21 ++-- .../tests/mockingservicestests/Android.mk | 3 - .../server/AlarmManagerServiceTest.java | 97 +++++++++++++++++-- .../server/am/PersistentConnectionTest.java | 5 +- 4 files changed, 106 insertions(+), 20 deletions(-) diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index af33cbc0ac1c8..38b9647c15b44 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -285,14 +285,21 @@ class AlarmManagerService extends SystemService { @VisibleForTesting final class Constants extends ContentObserver { // Key names stored in the settings value. - private static final String KEY_MIN_FUTURITY = "min_futurity"; - private static final String KEY_MIN_INTERVAL = "min_interval"; - private static final String KEY_MAX_INTERVAL = "max_interval"; - private static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time"; - private static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time"; - private static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION + @VisibleForTesting + static final String KEY_MIN_FUTURITY = "min_futurity"; + @VisibleForTesting + static final String KEY_MIN_INTERVAL = "min_interval"; + @VisibleForTesting + static final String KEY_MAX_INTERVAL = "max_interval"; + @VisibleForTesting + static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time"; + @VisibleForTesting + static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time"; + @VisibleForTesting + static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION = "allow_while_idle_whitelist_duration"; - private static final String KEY_LISTENER_TIMEOUT = "listener_timeout"; + @VisibleForTesting + static final String KEY_LISTENER_TIMEOUT = "listener_timeout"; // Keys for specifying throttling delay based on app standby bucketing private final String[] KEYS_APP_STANDBY_DELAY = { diff --git a/services/tests/mockingservicestests/Android.mk b/services/tests/mockingservicestests/Android.mk index b83a79fc232cd..01bd91ecb9120 100644 --- a/services/tests/mockingservicestests/Android.mk +++ b/services/tests/mockingservicestests/Android.mk @@ -20,14 +20,11 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_STATIC_JAVA_LIBRARIES := \ - frameworks-base-testutils \ services.core \ services.net \ androidx-test \ mockito-target-extended-minus-junit4 \ platform-test-annotations \ - ShortcutManagerTestUtils \ - truth-prebuilt \ LOCAL_JAVA_LIBRARIES := android.test.mock android.test.base android.test.runner diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java index 877c8fad30865..f85ffc84e7887 100644 --- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java @@ -30,10 +30,20 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; +import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_LONG_TIME; +import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_SHORT_TIME; +import static com.android.server.AlarmManagerService.Constants + .KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION; +import static com.android.server.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT; +import static com.android.server.AlarmManagerService.Constants.KEY_MAX_INTERVAL; +import static com.android.server.AlarmManagerService.Constants.KEY_MIN_FUTURITY; +import static com.android.server.AlarmManagerService.Constants.KEY_MIN_INTERVAL; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; @@ -45,6 +55,7 @@ import android.app.IActivityManager; import android.app.IUidObserver; import android.app.PendingIntent; import android.app.usage.UsageStatsManagerInternal; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.os.Handler; @@ -52,7 +63,9 @@ import android.os.Looper; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserHandle; +import android.provider.Settings; import android.util.Log; +import android.util.SparseArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -68,6 +81,9 @@ import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; + +import java.util.ArrayList; @SmallTest @RunWith(AndroidJUnit4.class) @@ -80,6 +96,8 @@ public class AlarmManagerServiceTest { private AlarmManagerService mService; @Mock + private ContentResolver mMockResolver; + @Mock private IActivityManager mIActivityManager; @Mock private UsageStatsManagerInternal mUsageStatsManagerInternal; @@ -186,9 +204,11 @@ public class AlarmManagerServiceTest { public final void setUp() throws Exception { mMockingSession = mockitoSession() .initMocks(this) - .mockStatic(ActivityManager.class, Answers.CALLS_REAL_METHODS) + .spyStatic(ActivityManager.class) .mockStatic(LocalServices.class) - .mockStatic(Looper.class, Answers.CALLS_REAL_METHODS) + .spyStatic(Looper.class) + .spyStatic(Settings.Global.class) + .strictness(Strictness.WARN) .startMocking(); doReturn(mIActivityManager).when(ActivityManager::getService); doReturn(mAppStateTracker).when(() -> LocalServices.getService(AppStateTracker.class)); @@ -201,15 +221,19 @@ public class AlarmManagerServiceTest { .thenReturn(STANDBY_BUCKET_ACTIVE); doReturn(Looper.getMainLooper()).when(Looper::myLooper); - final Context context = InstrumentationRegistry.getTargetContext(); - mInjector = spy(new Injector(context)); + final Context context = spy(InstrumentationRegistry.getTargetContext()); + when(context.getContentResolver()).thenReturn(mMockResolver); + doNothing().when(mMockResolver).registerContentObserver(any(), anyBoolean(), any()); + doReturn("min_futurity=0").when(() -> + Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS)); + mInjector = new Injector(context); mService = new AlarmManagerService(context, mInjector); spyOn(mService); doNothing().when(mService).publishBinderService(any(), any()); mService.onStart(); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); - mService.mConstants.MIN_FUTURITY = 0; + assertEquals(0, mService.mConstants.MIN_FUTURITY); assertEquals(mService.mSystemUiUid, SYSTEM_UI_UID); assertEquals(mService.mClockReceiver, mClockReceiver); assertEquals(mService.mWakeLock, mWakeLock); @@ -235,7 +259,6 @@ public class AlarmManagerServiceTest { final long triggerTime = mNowElapsedTest + 5000; final PendingIntent alarmPi = getNewMockPendingIntent(); setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi); - verify(mInjector).setAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime); assertEquals(triggerTime, mTestTimer.getElapsed()); } @@ -256,13 +279,46 @@ public class AlarmManagerServiceTest { verify(mWakeLock, timeout(DEFAULT_TIMEOUT)).release(); } + @Test + public void testUpdateConstants() { + final StringBuilder constantsBuilder = new StringBuilder(); + constantsBuilder.append(KEY_MIN_FUTURITY); + constantsBuilder.append("=5,"); + constantsBuilder.append(KEY_MIN_INTERVAL); + constantsBuilder.append("=10,"); + constantsBuilder.append(KEY_MAX_INTERVAL); + constantsBuilder.append("=15,"); + constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_SHORT_TIME); + constantsBuilder.append("=20,"); + constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_LONG_TIME); + constantsBuilder.append("=25,"); + constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); + constantsBuilder.append("=30,"); + constantsBuilder.append(KEY_LISTENER_TIMEOUT); + constantsBuilder.append("=35,"); + + doReturn(constantsBuilder.toString()).when(() -> Settings.Global.getString(mMockResolver, + Settings.Global.ALARM_MANAGER_CONSTANTS)); + mService.mConstants.onChange(false, null); + assertEquals(5, mService.mConstants.MIN_FUTURITY); + assertEquals(10, mService.mConstants.MIN_INTERVAL); + assertEquals(15, mService.mConstants.MAX_INTERVAL); + assertEquals(20, mService.mConstants.ALLOW_WHILE_IDLE_SHORT_TIME); + assertEquals(25, mService.mConstants.ALLOW_WHILE_IDLE_LONG_TIME); + assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION); + assertEquals(35, mService.mConstants.LISTENER_TIMEOUT); + } + @Test public void testMinFuturity() { - mService.mConstants.MIN_FUTURITY = 10; + doReturn("min_futurity=10").when(() -> + Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS)); + mService.mConstants.onChange(false, null); + assertEquals(10, mService.mConstants.MIN_FUTURITY); final long triggerTime = mNowElapsedTest + 1; final long expectedTriggerTime = mNowElapsedTest + mService.mConstants.MIN_FUTURITY; setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, getNewMockPendingIntent()); - verify(mInjector).setAlarm(ELAPSED_REALTIME_WAKEUP, expectedTriggerTime); + assertEquals(expectedTriggerTime, mTestTimer.getElapsed()); } @Test @@ -344,6 +400,31 @@ public class AlarmManagerServiceTest { () -> (mTestTimer.getElapsed() == expectedNextTrigger))); } + @Test + public void testAlarmRestrictedInBatterSaver() throws PendingIntent.CanceledException { + final ArgumentCaptor listenerArgumentCaptor = + ArgumentCaptor.forClass(AppStateTracker.Listener.class); + verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture()); + + final PendingIntent alarmPi = getNewMockPendingIntent(); + when(mAppStateTracker.areAlarmsRestricted(TEST_CALLING_UID, TEST_CALLING_PACKAGE, + false)).thenReturn(true); + setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 2, alarmPi); + assertEquals(mNowElapsedTest + 2, mTestTimer.getElapsed()); + + final SparseArray> restrictedAlarms = + mService.mPendingBackgroundAlarms; + assertNull(restrictedAlarms.get(TEST_CALLING_UID)); + + mNowElapsedTest = mTestTimer.expire(); + pollingCheck(DEFAULT_TIMEOUT, () -> (restrictedAlarms.get(TEST_CALLING_UID) != null)); + + listenerArgumentCaptor.getValue().unblockAlarmsForUid(TEST_CALLING_UID); + verify(alarmPi).send(any(Context.class), eq(0), any(Intent.class), any(), + any(Handler.class), isNull(), any()); + assertNull(restrictedAlarms.get(TEST_CALLING_UID)); + } + @After public void tearDown() { if (mMockingSession != null) { diff --git a/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java index 26e77eb166cac..8f39b4ab11d3e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java @@ -32,9 +32,10 @@ import android.os.IBinder; import android.os.Looper; import android.os.UserHandle; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; +import androidx.test.filters.SmallTest; + import org.mockito.ArgumentMatchers; import java.util.ArrayList; @@ -44,7 +45,7 @@ import java.util.Collections; @SmallTest public class PersistentConnectionTest extends AndroidTestCase { private static final String TAG = "PersistentConnectionTest"; - + private static class MyConnection extends PersistentConnection { public long uptimeMillis = 12345;