Merge "Add tests for device config changes" into sc-dev

This commit is contained in:
JW Wang
2021-03-06 14:34:36 +00:00
committed by Android (Google) Code Review
2 changed files with 103 additions and 11 deletions

View File

@@ -182,6 +182,9 @@ public class PackageWatchdog {
private final Runnable mSaveToFile = this::saveToFile; private final Runnable mSaveToFile = this::saveToFile;
private final SystemClock mSystemClock; private final SystemClock mSystemClock;
private final BootThreshold mBootThreshold; private final BootThreshold mBootThreshold;
private final DeviceConfig.OnPropertiesChangedListener
mOnPropertyChangedListener = this::onPropertyChanged;
// The set of packages that have been synced with the ExplicitHealthCheckController // The set of packages that have been synced with the ExplicitHealthCheckController
@GuardedBy("mLock") @GuardedBy("mLock")
private Set<String> mRequestedHealthCheckPackages = new ArraySet<>(); private Set<String> mRequestedHealthCheckPackages = new ArraySet<>();
@@ -669,12 +672,20 @@ public class PackageWatchdog {
} }
} }
@VisibleForTesting
long getTriggerFailureCount() { long getTriggerFailureCount() {
synchronized (mLock) { synchronized (mLock) {
return mTriggerFailureCount; return mTriggerFailureCount;
} }
} }
@VisibleForTesting
long getTriggerFailureDurationMs() {
synchronized (mLock) {
return mTriggerFailureDurationMs;
}
}
/** /**
* Serializes and syncs health check requests with the {@link ExplicitHealthCheckController}. * 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}. */ /** Adds a {@link DeviceConfig#OnPropertiesChangedListener}. */
private void setPropertyChangedListenerLocked() { private void setPropertyChangedListenerLocked() {
DeviceConfig.addOnPropertiesChangedListener( DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_ROLLBACK, DeviceConfig.NAMESPACE_ROLLBACK,
mContext.getMainExecutor(), mContext.getMainExecutor(),
(properties) -> { mOnPropertyChangedListener);
if (!DeviceConfig.NAMESPACE_ROLLBACK.equals(properties.getNamespace())) { }
return;
} @VisibleForTesting
try { void removePropertyChangedListener() {
updateConfigs(); DeviceConfig.removeOnPropertiesChangedListener(mOnPropertyChangedListener);
} catch (Exception ignore) {
Slog.w(TAG, "Failed to reload device config changes");
}
});
} }
/** /**

View File

@@ -23,7 +23,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
@@ -79,11 +78,15 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
/** /**
* Test PackageWatchdog. * Test PackageWatchdog.
*/ */
public class PackageWatchdogTest { 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_A = "com.package.a";
private static final String APP_B = "com.package.b"; private static final String APP_B = "com.package.b";
private static final String APP_C = "com.package.c"; private static final String APP_C = "com.package.c";
@@ -109,6 +112,16 @@ public class PackageWatchdogTest {
private MockitoSession mSession; private MockitoSession mSession;
private HashMap<String, String> mSystemSettingsMap; 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 @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@@ -176,6 +189,10 @@ public class PackageWatchdogTest {
public void tearDown() throws Exception { public void tearDown() throws Exception {
dropShellPermissions(); dropShellPermissions();
mSession.finishMocking(); mSession.finishMocking();
// Clean up listeners since too many listeners will delay notifications significantly
for (PackageWatchdog watchdog : mAllocatedWatchdogs) {
watchdog.removePropertyChangedListener();
}
mAllocatedWatchdogs.clear(); mAllocatedWatchdogs.clear();
} }
@@ -1282,6 +1299,66 @@ public class PackageWatchdogTest {
assertTrue(readPkg.isEqualTo(expectedPkg)); 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) { private void adoptShellPermissions(String... permissions) {
InstrumentationRegistry InstrumentationRegistry
.getInstrumentation() .getInstrumentation()