Merge "Add TestableDeviceConfig"
This commit is contained in:
committed by
Android (Google) Code Review
commit
388dc11c3e
@@ -18,15 +18,11 @@ package android.provider;
|
||||
|
||||
import static android.provider.DeviceConfig.OnPropertyChangedListener;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static junit.framework.Assert.fail;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.content.ContentResolver;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
@@ -37,8 +33,8 @@ import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/** Tests that ensure appropriate settings are backed up. */
|
||||
@Presubmit
|
||||
@@ -51,8 +47,6 @@ public class DeviceConfigTest {
|
||||
private static final String sValue = "value1";
|
||||
private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
deleteViaContentProvider(sNamespace, sKey);
|
||||
@@ -61,14 +55,14 @@ public class DeviceConfigTest {
|
||||
@Test
|
||||
public void getProperty_empty() {
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertNull(result);
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetProperty_sameNamespace() {
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertEquals(sValue, result);
|
||||
assertThat(result).isEqualTo(sValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,7 +70,7 @@ public class DeviceConfigTest {
|
||||
String newNamespace = "namespace2";
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
String result = DeviceConfig.getProperty(newNamespace, sKey);
|
||||
assertNull(result);
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,9 +80,9 @@ public class DeviceConfigTest {
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
DeviceConfig.setProperty(newNamespace, sKey, newValue, false);
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertEquals(sValue, result);
|
||||
assertThat(result).isEqualTo(sValue);
|
||||
result = DeviceConfig.getProperty(newNamespace, sKey);
|
||||
assertEquals(newValue, result);
|
||||
assertThat(result).isEqualTo(newValue);
|
||||
|
||||
// clean up
|
||||
deleteViaContentProvider(newNamespace, sKey);
|
||||
@@ -100,59 +94,30 @@ public class DeviceConfigTest {
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
DeviceConfig.setProperty(sNamespace, sKey, newValue, false);
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertEquals(newValue, result);
|
||||
assertThat(result).isEqualTo(newValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListener() {
|
||||
setPropertyAndAssertSuccessfulChange(sNamespace, sKey, sValue);
|
||||
}
|
||||
public void testListener() throws InterruptedException {
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
|
||||
private void setPropertyAndAssertSuccessfulChange(String setNamespace, String setName,
|
||||
String setValue) {
|
||||
final AtomicBoolean success = new AtomicBoolean();
|
||||
OnPropertyChangedListener changeListener = (namespace, name, value) -> {
|
||||
assertThat(namespace).isEqualTo(sNamespace);
|
||||
assertThat(name).isEqualTo(sKey);
|
||||
assertThat(value).isEqualTo(sValue);
|
||||
countDownLatch.countDown();
|
||||
};
|
||||
|
||||
OnPropertyChangedListener changeListener = new OnPropertyChangedListener() {
|
||||
@Override
|
||||
public void onPropertyChanged(String namespace, String name, String value) {
|
||||
assertEquals(setNamespace, namespace);
|
||||
assertEquals(setName, name);
|
||||
assertEquals(setValue, value);
|
||||
success.set(true);
|
||||
|
||||
synchronized (mLock) {
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
Executor executor = ActivityThread.currentApplication().getMainExecutor();
|
||||
DeviceConfig.addOnPropertyChangedListener(setNamespace, executor, changeListener);
|
||||
try {
|
||||
DeviceConfig.setProperty(setNamespace, setName, setValue, false);
|
||||
|
||||
final long startTimeMillis = SystemClock.uptimeMillis();
|
||||
synchronized (mLock) {
|
||||
while (true) {
|
||||
if (success.get()) {
|
||||
return;
|
||||
}
|
||||
final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
|
||||
if (elapsedTimeMillis >= WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS) {
|
||||
fail("Could not change setting for "
|
||||
+ WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS + " ms");
|
||||
}
|
||||
final long remainingTimeMillis = WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS
|
||||
- elapsedTimeMillis;
|
||||
try {
|
||||
mLock.wait(remainingTimeMillis);
|
||||
} catch (InterruptedException ie) {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
DeviceConfig.addOnPropertyChangedListener(sNamespace,
|
||||
ActivityThread.currentApplication().getMainExecutor(), changeListener);
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
assertThat(countDownLatch.await(
|
||||
WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
|
||||
} finally {
|
||||
DeviceConfig.removeOnPropertyChangedListener(changeListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean deleteViaContentProvider(String namespace, String key) {
|
||||
@@ -160,7 +125,7 @@ public class DeviceConfigTest {
|
||||
String compositeName = namespace + "/" + key;
|
||||
Bundle result = resolver.call(
|
||||
DeviceConfig.CONTENT_URI, Settings.CALL_METHOD_DELETE_CONFIG, compositeName, null);
|
||||
assertNotNull(result);
|
||||
assertThat(result).isNotNull();
|
||||
return compositeName.equals(result.getString(Settings.NameValueTable.VALUE));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ android_test {
|
||||
"androidx.test.runner",
|
||||
"mockito-target-extended-minus-junit4",
|
||||
"platform-test-annotations",
|
||||
"truth-prebuilt",
|
||||
],
|
||||
|
||||
libs: [
|
||||
|
||||
@@ -28,28 +28,24 @@ import static android.provider.DeviceConfig.ActivityManager.KEY_USE_COMPACTION;
|
||||
import static com.android.server.am.ActivityManagerService.Injector;
|
||||
import static com.android.server.am.AppCompactor.compactActionIntToString;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.appop.AppOpsService;
|
||||
import com.android.server.testables.TestableDeviceConfig;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -59,42 +55,21 @@ import java.util.concurrent.TimeUnit;
|
||||
* Build/Install/Run:
|
||||
* atest FrameworksServicesTests:AppCompactorTest
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public final class AppCompactorTest {
|
||||
|
||||
private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
|
||||
"device_config delete activity_manager";
|
||||
|
||||
@Mock private AppOpsService mAppOpsService;
|
||||
@Mock
|
||||
private AppOpsService mAppOpsService;
|
||||
private AppCompactor mCompactorUnderTest;
|
||||
private HandlerThread mHandlerThread;
|
||||
private Handler mHandler;
|
||||
private CountDownLatch mCountDown;
|
||||
|
||||
private static void clearDeviceConfig() throws IOException {
|
||||
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_USE_COMPACTION);
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_1);
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_2);
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_1);
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_2);
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_3);
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_4);
|
||||
uiDevice.executeShellCommand(
|
||||
CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_STATSD_SAMPLE_RATE);
|
||||
}
|
||||
@Rule
|
||||
public TestableDeviceConfig mDeviceConfig = new TestableDeviceConfig();
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
clearDeviceConfig();
|
||||
public void setUp() {
|
||||
mHandlerThread = new HandlerThread("");
|
||||
mHandlerThread.start();
|
||||
mHandler = new Handler(mHandlerThread.getLooper());
|
||||
@@ -111,38 +86,37 @@ public final class AppCompactorTest {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
public void tearDown() {
|
||||
mHandlerThread.quit();
|
||||
mCountDown = null;
|
||||
clearDeviceConfig();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void init_setsDefaults() {
|
||||
mCompactorUnderTest.init();
|
||||
assertThat(mCompactorUnderTest.useCompaction(),
|
||||
is(mCompactorUnderTest.DEFAULT_USE_COMPACTION));
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome, is(
|
||||
compactActionIntToString(mCompactorUnderTest.DEFAULT_COMPACT_ACTION_1)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull, is(
|
||||
compactActionIntToString(mCompactorUnderTest.DEFAULT_COMPACT_ACTION_2)));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_2));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4));
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate,
|
||||
is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE));
|
||||
assertThat(mCompactorUnderTest.useCompaction()).isEqualTo(
|
||||
AppCompactor.DEFAULT_USE_COMPACTION);
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo(
|
||||
compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo(
|
||||
compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_2);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_3);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_4);
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(
|
||||
AppCompactor.DEFAULT_STATSD_SAMPLE_RATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void init_withDeviceConfigSetsParameters() {
|
||||
// When the DeviceConfig already has a flag value stored (note this test will need to
|
||||
// change if the default value changes from false).
|
||||
assertThat(mCompactorUnderTest.DEFAULT_USE_COMPACTION, is(false));
|
||||
assertThat(AppCompactor.DEFAULT_USE_COMPACTION).isFalse();
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_USE_COMPACTION, "true", false);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
@@ -169,62 +143,63 @@ public final class AppCompactorTest {
|
||||
|
||||
// Then calling init will read and set that flag.
|
||||
mCompactorUnderTest.init();
|
||||
assertThat(mCompactorUnderTest.useCompaction(), is(true));
|
||||
assertThat(mCompactorUnderTest.mCompactionThread.isAlive(), is(true));
|
||||
assertThat(mCompactorUnderTest.useCompaction()).isTrue();
|
||||
assertThat(mCompactorUnderTest.mCompactionThread.isAlive()).isTrue();
|
||||
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome,
|
||||
is(compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull,
|
||||
is(compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1)));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1));
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate,
|
||||
is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f));
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo(
|
||||
compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo(
|
||||
compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1);
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(
|
||||
AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useCompaction_listensToDeviceConfigChanges() throws InterruptedException {
|
||||
assertThat(mCompactorUnderTest.useCompaction(),
|
||||
is(mCompactorUnderTest.DEFAULT_USE_COMPACTION));
|
||||
assertThat(mCompactorUnderTest.useCompaction()).isEqualTo(
|
||||
AppCompactor.DEFAULT_USE_COMPACTION);
|
||||
// When we call init and change some the flag value...
|
||||
mCompactorUnderTest.init();
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_USE_COMPACTION, "true", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then that new flag value is updated in the implementation.
|
||||
assertThat(mCompactorUnderTest.useCompaction(), is(true));
|
||||
assertThat(mCompactorUnderTest.mCompactionThread.isAlive(), is(true));
|
||||
assertThat(mCompactorUnderTest.useCompaction()).isTrue();
|
||||
assertThat(mCompactorUnderTest.mCompactionThread.isAlive()).isTrue();
|
||||
|
||||
// And again, setting the flag the other way.
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_USE_COMPACTION, "false", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCompactorUnderTest.useCompaction(), is(false));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
assertThat(mCompactorUnderTest.useCompaction()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useCompaction_listensToDeviceConfigChangesBadValues() throws InterruptedException {
|
||||
assertThat(mCompactorUnderTest.useCompaction(),
|
||||
is(mCompactorUnderTest.DEFAULT_USE_COMPACTION));
|
||||
assertThat(mCompactorUnderTest.useCompaction()).isEqualTo(
|
||||
AppCompactor.DEFAULT_USE_COMPACTION);
|
||||
mCompactorUnderTest.init();
|
||||
|
||||
// When we push an invalid flag value...
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_USE_COMPACTION, "foobar", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then we set the default.
|
||||
assertThat(mCompactorUnderTest.useCompaction(), is(AppCompactor.DEFAULT_USE_COMPACTION));
|
||||
assertThat(mCompactorUnderTest.useCompaction()).isEqualTo(
|
||||
AppCompactor.DEFAULT_USE_COMPACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -236,19 +211,19 @@ public final class AppCompactorTest {
|
||||
// There are four possible values for compactAction[Some|Full].
|
||||
for (int i = 1; i < 5; i++) {
|
||||
mCountDown = new CountDownLatch(2);
|
||||
int expectedSome = (mCompactorUnderTest.DEFAULT_COMPACT_ACTION_1 + i) % 4 + 1;
|
||||
int expectedSome = (AppCompactor.DEFAULT_COMPACT_ACTION_1 + i) % 4 + 1;
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_ACTION_1, Integer.toString(expectedSome), false);
|
||||
int expectedFull = (mCompactorUnderTest.DEFAULT_COMPACT_ACTION_2 + i) % 4 + 1;
|
||||
int expectedFull = (AppCompactor.DEFAULT_COMPACT_ACTION_2 + i) % 4 + 1;
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_ACTION_2, Integer.toString(expectedFull), false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then the updates are reflected in the flags.
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome,
|
||||
is(compactActionIntToString(expectedSome)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull,
|
||||
is(compactActionIntToString(expectedFull)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo(
|
||||
compactActionIntToString(expectedSome));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo(
|
||||
compactActionIntToString(expectedFull));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,25 +237,25 @@ public final class AppCompactorTest {
|
||||
KEY_COMPACT_ACTION_1, "foo", false);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_ACTION_2, "foo", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then the default values are reflected in the flag
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome,
|
||||
is(compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull,
|
||||
is(compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo(
|
||||
compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo(
|
||||
compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2));
|
||||
|
||||
mCountDown = new CountDownLatch(2);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_ACTION_1, "", false);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_ACTION_2, "", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome,
|
||||
is(compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull,
|
||||
is(compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2)));
|
||||
assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo(
|
||||
compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1));
|
||||
assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo(
|
||||
compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -301,22 +276,22 @@ public final class AppCompactorTest {
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_THROTTLE_4,
|
||||
Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then those flags values are reflected in the compactor.
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compactThrottle_listensToDeviceConfigChangesBadValues()
|
||||
throws IOException, InterruptedException {
|
||||
throws InterruptedException {
|
||||
mCompactorUnderTest.init();
|
||||
|
||||
// When one of the throttles is overridden with a bad value...
|
||||
@@ -324,58 +299,55 @@ public final class AppCompactorTest {
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_THROTTLE_1, "foo", false);
|
||||
// Then all the throttles have the defaults set.
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_2));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4));
|
||||
clearDeviceConfig();
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_2);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_3);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_4);
|
||||
|
||||
// Repeat for each of the throttle keys.
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_THROTTLE_2, "foo", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_2));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4));
|
||||
clearDeviceConfig();
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_2);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_3);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_4);
|
||||
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_THROTTLE_3, "foo", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_2));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4));
|
||||
clearDeviceConfig();
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_2);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_3);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_4);
|
||||
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_THROTTLE_4, "foo", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_1));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_2));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3));
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
|
||||
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_1);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_2);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_3);
|
||||
assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
|
||||
AppCompactor.DEFAULT_COMPACT_THROTTLE_4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -387,11 +359,11 @@ public final class AppCompactorTest {
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_STATSD_SAMPLE_RATE,
|
||||
Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then that override is reflected in the compactor.
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate,
|
||||
is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f));
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(
|
||||
AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -403,11 +375,11 @@ public final class AppCompactorTest {
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_STATSD_SAMPLE_RATE, "foo", false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then that override is reflected in the compactor.
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate,
|
||||
is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE));
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(
|
||||
AppCompactor.DEFAULT_STATSD_SAMPLE_RATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -420,19 +392,19 @@ public final class AppCompactorTest {
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_STATSD_SAMPLE_RATE,
|
||||
Float.toString(-1.0f), false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then the values is capped in the range.
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate, is(0.0f));
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(0.0f);
|
||||
|
||||
mCountDown = new CountDownLatch(1);
|
||||
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
|
||||
KEY_COMPACT_STATSD_SAMPLE_RATE,
|
||||
Float.toString(1.01f), false);
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
|
||||
assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
|
||||
|
||||
// Then the values is capped in the range.
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate, is(1.0f));
|
||||
assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(1.0f);
|
||||
}
|
||||
|
||||
private class TestInjector extends Injector {
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.testables;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* TestableDeviceConfig uses ExtendedMockito to replace the real implementation of DeviceConfig
|
||||
* with essentially a local HashMap in the callers process. This allows for unit testing that do not
|
||||
* modify the real DeviceConfig on the device at all.
|
||||
*
|
||||
* <p>TestableDeviceConfig should be defined as a rule on your test so it can clean up after itself.
|
||||
* Like the following:</p>
|
||||
* <pre class="prettyprint">
|
||||
* @Rule
|
||||
* public final TestableDeviceConfig mTestableDeviceConfig = new TestableDeviceConfig();
|
||||
* </pre>
|
||||
*/
|
||||
public final class TestableDeviceConfig implements TestRule {
|
||||
|
||||
private StaticMockitoSession mMockitoSession;
|
||||
private Map<DeviceConfig.OnPropertyChangedListener, Pair<String, Executor>>
|
||||
mOnPropertyChangedListenerMap = new HashMap<>();
|
||||
private Map<String, String> mKeyValueMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Clears out all local overrides.
|
||||
*/
|
||||
public void clearDeviceConfig() {
|
||||
mKeyValueMap.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
mMockitoSession = mockitoSession()
|
||||
.initMocks(this)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.spyStatic(DeviceConfig.class)
|
||||
.startMocking();
|
||||
|
||||
doAnswer((Answer<Void>) invocationOnMock -> {
|
||||
String namespace = invocationOnMock.getArgument(0);
|
||||
Executor executor = invocationOnMock.getArgument(1);
|
||||
DeviceConfig.OnPropertyChangedListener onPropertyChangedListener =
|
||||
invocationOnMock.getArgument(2);
|
||||
mOnPropertyChangedListenerMap.put(
|
||||
onPropertyChangedListener, new Pair<>(namespace, executor));
|
||||
return null;
|
||||
}).when(() -> DeviceConfig.addOnPropertyChangedListener(
|
||||
anyString(), any(Executor.class),
|
||||
any(DeviceConfig.OnPropertyChangedListener.class)));
|
||||
|
||||
doAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
String namespace = invocationOnMock.getArgument(0);
|
||||
String name = invocationOnMock.getArgument(1);
|
||||
String value = invocationOnMock.getArgument(2);
|
||||
mKeyValueMap.put(getKey(namespace, name), value);
|
||||
for (DeviceConfig.OnPropertyChangedListener listener :
|
||||
mOnPropertyChangedListenerMap.keySet()) {
|
||||
if (namespace.equals(mOnPropertyChangedListenerMap.get(listener).first)) {
|
||||
mOnPropertyChangedListenerMap.get(listener).second.execute(
|
||||
() -> listener.onPropertyChanged(namespace, name, value));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
).when(() -> DeviceConfig.setProperty(anyString(), anyString(), anyString(), anyBoolean()));
|
||||
|
||||
doAnswer((Answer<String>) invocationOnMock -> {
|
||||
String namespace = invocationOnMock.getArgument(0);
|
||||
String name = invocationOnMock.getArgument(1);
|
||||
return mKeyValueMap.get(getKey(namespace, name));
|
||||
}).when(() -> DeviceConfig.getProperty(anyString(), anyString()));
|
||||
|
||||
|
||||
return new TestWatcher() {
|
||||
@Override
|
||||
protected void succeeded(Description description) {
|
||||
mMockitoSession.finishMocking();
|
||||
mOnPropertyChangedListenerMap.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void failed(Throwable e, Description description) {
|
||||
mMockitoSession.finishMocking(e);
|
||||
mOnPropertyChangedListenerMap.clear();
|
||||
}
|
||||
}.apply(base, description);
|
||||
}
|
||||
|
||||
private static String getKey(String namespace, String name) {
|
||||
return namespace + "/" + name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.testables;
|
||||
|
||||
import static android.provider.DeviceConfig.OnPropertyChangedListener;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.DeviceConfig;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/** Tests that ensure appropriate settings are backed up. */
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class TestableDeviceConfigTest {
|
||||
private static final String sNamespace = "namespace1";
|
||||
private static final String sKey = "key1";
|
||||
private static final String sValue = "value1";
|
||||
private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec
|
||||
|
||||
@Rule
|
||||
public TestableDeviceConfig mTestableDeviceConfig = new TestableDeviceConfig();
|
||||
|
||||
@Test
|
||||
public void getProperty_empty() {
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetProperty_sameNamespace() {
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertThat(result).isEqualTo(sValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetProperty_differentNamespace() {
|
||||
String newNamespace = "namespace2";
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
String result = DeviceConfig.getProperty(newNamespace, sKey);
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetProperty_multipleNamespaces() {
|
||||
String newNamespace = "namespace2";
|
||||
String newValue = "value2";
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
DeviceConfig.setProperty(newNamespace, sKey, newValue, false);
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertThat(result).isEqualTo(sValue);
|
||||
result = DeviceConfig.getProperty(newNamespace, sKey);
|
||||
assertThat(result).isEqualTo(newValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetProperty_overrideValue() {
|
||||
String newValue = "value2";
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
DeviceConfig.setProperty(sNamespace, sKey, newValue, false);
|
||||
String result = DeviceConfig.getProperty(sNamespace, sKey);
|
||||
assertThat(result).isEqualTo(newValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListener() throws InterruptedException {
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
|
||||
OnPropertyChangedListener changeListener = (namespace, name, value) -> {
|
||||
assertThat(namespace).isEqualTo(sNamespace);
|
||||
assertThat(name).isEqualTo(sKey);
|
||||
assertThat(value).isEqualTo(sValue);
|
||||
countDownLatch.countDown();
|
||||
};
|
||||
try {
|
||||
DeviceConfig.addOnPropertyChangedListener(sNamespace,
|
||||
ActivityThread.currentApplication().getMainExecutor(), changeListener);
|
||||
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
|
||||
assertThat(countDownLatch.await(
|
||||
WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
|
||||
} finally {
|
||||
DeviceConfig.removeOnPropertyChangedListener(changeListener);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user