diff options
author | JW Wang <wangchun@google.com> | 2021-03-04 15:31:29 +0800 |
---|---|---|
committer | JW Wang <wangchun@google.com> | 2021-03-05 10:22:29 +0800 |
commit | f6d9f9d84d7800d77729b5e7903674f607c8f203 (patch) | |
tree | 1bf3d917ccab5e997963b765d9a646dcfc1366b7 | |
parent | d38c0368af9d35c5aa2a08bc3bc433218f85b17e (diff) |
Add tests for device config changes
Test device config changes are propagated correctly to the watchdog.
* Keep polling until the config value becomes the expected one.
* Remove listeners at the end of each test - too many device config
listeners will delay the notification significantly ( > 1 min)
according to my local experiments.
Bug: 181820350
Test: atest PackageWatchdogTest
Change-Id: Ia5e89b69a8052f49e6400f6b22313249d523786c
-rw-r--r-- | services/core/java/com/android/server/PackageWatchdog.java | 35 | ||||
-rw-r--r-- | tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java | 79 |
2 files changed, 103 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index f5c2aacaebb0..960922ed2192 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -182,6 +182,9 @@ public class PackageWatchdog { private final Runnable mSaveToFile = this::saveToFile; private final SystemClock mSystemClock; private final BootThreshold mBootThreshold; + private final DeviceConfig.OnPropertiesChangedListener + mOnPropertyChangedListener = this::onPropertyChanged; + // The set of packages that have been synced with the ExplicitHealthCheckController @GuardedBy("mLock") private Set<String> mRequestedHealthCheckPackages = new ArraySet<>(); @@ -669,12 +672,20 @@ public class PackageWatchdog { } } + @VisibleForTesting long getTriggerFailureCount() { synchronized (mLock) { return mTriggerFailureCount; } } + @VisibleForTesting + long getTriggerFailureDurationMs() { + synchronized (mLock) { + return mTriggerFailureDurationMs; + } + } + /** * Serializes and syncs health check requests with the {@link ExplicitHealthCheckController}. */ @@ -983,21 +994,25 @@ public class PackageWatchdog { } } + private void onPropertyChanged(DeviceConfig.Properties properties) { + try { + updateConfigs(); + } catch (Exception ignore) { + Slog.w(TAG, "Failed to reload device config changes"); + } + } + /** Adds a {@link DeviceConfig#OnPropertiesChangedListener}. */ private void setPropertyChangedListenerLocked() { DeviceConfig.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_ROLLBACK, mContext.getMainExecutor(), - (properties) -> { - if (!DeviceConfig.NAMESPACE_ROLLBACK.equals(properties.getNamespace())) { - return; - } - try { - updateConfigs(); - } catch (Exception ignore) { - Slog.w(TAG, "Failed to reload device config changes"); - } - }); + mOnPropertyChangedListener); + } + + @VisibleForTesting + void removePropertyChangedListener() { + DeviceConfig.removeOnPropertiesChangedListener(mOnPropertyChangedListener); } /** diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 5381009fdf2b..96bbf82cfba7 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -23,7 +23,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; @@ -79,11 +78,15 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import java.util.function.Supplier; /** * Test PackageWatchdog. */ public class PackageWatchdogTest { + private static final long RETRY_MAX_COUNT = 30; + private static final long RETRY_TIMEOUT_MILLIS = 500; + private static final String APP_A = "com.package.a"; private static final String APP_B = "com.package.b"; private static final String APP_C = "com.package.c"; @@ -109,6 +112,16 @@ public class PackageWatchdogTest { private MockitoSession mSession; private HashMap<String, String> mSystemSettingsMap; + private boolean retry(Supplier<Boolean> supplier) throws Exception { + for (int i = 0; i < RETRY_MAX_COUNT; ++i) { + if (supplier.get()) { + return true; + } + Thread.sleep(RETRY_TIMEOUT_MILLIS); + } + return false; + } + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -176,6 +189,10 @@ public class PackageWatchdogTest { public void tearDown() throws Exception { dropShellPermissions(); mSession.finishMocking(); + // Clean up listeners since too many listeners will delay notifications significantly + for (PackageWatchdog watchdog : mAllocatedWatchdogs) { + watchdog.removePropertyChangedListener(); + } mAllocatedWatchdogs.clear(); } @@ -1282,6 +1299,66 @@ public class PackageWatchdogTest { assertTrue(readPkg.isEqualTo(expectedPkg)); } + /** + * Tests device config changes are propagated correctly. + */ + @Test + public void testDeviceConfigChange_explicitHealthCheckEnabled() throws Exception { + TestController controller = new TestController(); + PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */); + assertThat(controller.mIsEnabled).isTrue(); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK, + PackageWatchdog.PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED, + Boolean.toString(false), /*makeDefault*/false); + retry(() -> !controller.mIsEnabled); + assertThat(controller.mIsEnabled).isFalse(); + } + + /** + * Tests device config changes are propagated correctly. + */ + @Test + public void testDeviceConfigChange_triggerFailureCount() throws Exception { + PackageWatchdog watchdog = createWatchdog(); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK, + PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT, + Integer.toString(777), false); + retry(() -> watchdog.getTriggerFailureCount() == 777); + assertThat(watchdog.getTriggerFailureCount()).isEqualTo(777); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK, + PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT, + Integer.toString(0), false); + retry(() -> watchdog.getTriggerFailureCount() + == PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT); + assertThat(watchdog.getTriggerFailureCount()).isEqualTo( + PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT); + } + + /** + * Tests device config changes are propagated correctly. + */ + @Test + public void testDeviceConfigChange_triggerFailureDurationMs() throws Exception { + PackageWatchdog watchdog = createWatchdog(); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK, + PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS, + Integer.toString(888), false); + retry(() -> watchdog.getTriggerFailureDurationMs() == 888); + assertThat(watchdog.getTriggerFailureDurationMs()).isEqualTo(888); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK, + PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS, + Integer.toString(0), false); + retry(() -> watchdog.getTriggerFailureDurationMs() + == PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS); + assertThat(watchdog.getTriggerFailureDurationMs()).isEqualTo( + PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS); + } + private void adoptShellPermissions(String... permissions) { InstrumentationRegistry .getInstrumentation() |