Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adfa6e80 authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

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
parent 73013990
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -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 = {
+0 −3
Original line number Diff line number Diff line
@@ -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

+89 −8
Original line number Diff line number Diff line
@@ -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<AppStateTracker.Listener> 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<ArrayList<AlarmManagerService.Alarm>> 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) {
+3 −2
Original line number Diff line number Diff line
@@ -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;