Merge "Add tests for device config changes" into sc-dev
This commit is contained in:
@@ -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");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user