diff options
| -rw-r--r-- | core/tests/coretests/src/android/provider/DeviceConfigTest.java | 85 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/Android.bp | 1 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java (renamed from services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java) | 288 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java | 131 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java | 115 |
5 files changed, 402 insertions, 218 deletions
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java index 17e9654b651a..5d5754bc41be 100644 --- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java +++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java @@ -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); + + OnPropertyChangedListener changeListener = (namespace, name, value) -> { + assertThat(namespace).isEqualTo(sNamespace); + assertThat(name).isEqualTo(sKey); + assertThat(value).isEqualTo(sValue); + countDownLatch.countDown(); + }; - private void setPropertyAndAssertSuccessfulChange(String setNamespace, String setName, - String setValue) { - final AtomicBoolean success = new AtomicBoolean(); - - 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)); } diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index ebc816dc45da..782196dc0048 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -23,6 +23,7 @@ android_test { "androidx.test.runner", "mockito-target-extended-minus-junit4", "platform-test-annotations", + "truth-prebuilt", ], libs: [ diff --git a/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java index 63015be6ef3f..d32f1f77b88f 100644 --- a/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java @@ -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.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.useCompaction()).isTrue(); + assertThat(mCompactorUnderTest.mCompactionThread.isAlive()).isTrue(); + + 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 { diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java new file mode 100644 index 000000000000..b76682269c2e --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java @@ -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; + } + +} diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java new file mode 100644 index 000000000000..39b5840f12d8 --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java @@ -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); + } + } + +} + + |