diff options
| author | 2021-11-09 12:02:34 -0800 | |
|---|---|---|
| committer | 2021-11-09 12:02:34 -0800 | |
| commit | 0ba15f156807c1b2ccaed4f8fe8bda48b6e08da0 (patch) | |
| tree | 6256e1a8f9259e681ce0344494666937a115daae | |
| parent | 578f7075697d10f8e3e1f1ba4e9e350ebda2fa9f (diff) | |
Move TestableDeviceConfig to modules-utils.
This allows it to be reused by mainline modules.
Bug: 192108282
Test: AppSearchMockingServicesTests ModulesUtilsTests FrameworksMockingServicesTests
Change-Id: I605ae012902141717a0bc3001fb5166c81c53581
14 files changed, 10 insertions, 1312 deletions
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index 6bb127a1b3c5..48a8b1bca99b 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -29,7 +29,10 @@ package { android_test { name: "FrameworksMockingServicesTests", - defaults: ["FrameworkMockingServicesTests-jni-defaults"], + defaults: [ + "FrameworkMockingServicesTests-jni-defaults", + "modules-utils-testable-device-config-defaults", + ], srcs: [ "src/**/*.java", @@ -67,9 +70,7 @@ android_test { ], jni_libs: [ - "libdexmakerjvmtiagent", "libpsi", - "libstaticjvmtiagent", ], certificate: "platform", diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java index 609768c0e62a..766ba72d7cb7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java @@ -38,10 +38,10 @@ import android.provider.DeviceConfig; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.modules.utils.testing.TestableDeviceConfig; import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.appop.AppOpsService; -import com.android.server.testables.TestableDeviceConfig; import com.android.server.wm.ActivityTaskManagerService; import org.junit.Before; diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java index a883293b13b9..303f95565c76 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java @@ -40,10 +40,10 @@ import android.text.TextUtils; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.modules.utils.testing.TestableDeviceConfig; import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.appop.AppOpsService; -import com.android.server.testables.TestableDeviceConfig; import com.android.server.wm.ActivityTaskManagerService; import org.junit.After; diff --git a/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreConfigTest.java b/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreConfigTest.java index ad19a4893153..d747914caa9a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreConfigTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreConfigTest.java @@ -29,7 +29,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.server.testables.TestableDeviceConfig; +import com.android.modules.utils.testing.TestableDeviceConfig; import org.junit.Before; import org.junit.Rule; diff --git a/services/tests/mockingservicestests/src/com/android/server/compat/overrides/AppCompatOverridesServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/compat/overrides/AppCompatOverridesServiceTest.java index 007191f02631..349da03e3f4e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/compat/overrides/AppCompatOverridesServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/compat/overrides/AppCompatOverridesServiceTest.java @@ -59,7 +59,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.compat.CompatibilityOverrideConfig; import com.android.internal.compat.CompatibilityOverridesToRemoveConfig; import com.android.internal.compat.IPlatformCompat; -import com.android.server.testables.TestableDeviceConfig.TestableDeviceConfigRule; +import com.android.modules.utils.testing.TestableDeviceConfig.TestableDeviceConfigRule; import org.junit.Before; import org.junit.Rule; diff --git a/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java index e093f1396385..9fac0c029815 100644 --- a/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java @@ -34,7 +34,7 @@ import android.testing.TestableContext; import androidx.test.platform.app.InstrumentationRegistry; -import com.android.server.testables.TestableDeviceConfig; +import com.android.modules.utils.testing.TestableDeviceConfig; import org.junit.Before; import org.junit.ClassRule; diff --git a/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java b/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java index f94377fe51c2..6a3548178cba 100644 --- a/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/power/ScreenUndimDetectorTest.java @@ -36,7 +36,7 @@ import android.testing.TestableContext; import androidx.test.platform.app.InstrumentationRegistry; -import com.android.server.testables.TestableDeviceConfig; +import com.android.modules.utils.testing.TestableDeviceConfig; import org.junit.Before; import org.junit.ClassRule; diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/MultipleStaticMocksTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/MultipleStaticMocksTest.java deleted file mode 100644 index c0ab70a57327..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/testables/MultipleStaticMocksTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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.google.common.truth.Truth.assertThat; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.dx.mockito.inline.extended.ExtendedMockito; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class MultipleStaticMocksTest { - @Rule - public StaticMockFixtureRule mStaticMockFixtureRule = - new StaticMockFixtureRule(AB::new, CD::new); - - private List<String> mCollected; - - @Test - public void testMultipleStaticMocks() throws Exception { - mCollected = new ArrayList<>(); - int n = 0; - - A.a(); - n = verifyCollected(n, "A.a"); - - D.b(); - n = verifyCollected(n, "D.b"); - - C.b(); - n = verifyCollected(n, "C.b"); - - B.a(); - n = verifyCollected(n, "B.a"); - } - - private int verifyCollected(int n, String... last) { - assertThat(mCollected).hasSize(n + last.length); - assertThat(mCollected.subList(n, mCollected.size())) - .containsExactlyElementsIn(last).inOrder(); - return n + last.length; - } - - private static class A { - /* package */ static void a() {} - /* package */ static void b() {} - } - - private static class B { - /* package */ static void a() {} - /* package */ static void b() {} - } - - private static class C { - /* package */ static void a() {} - /* package */ static void b() {} - } - - private static class D { - /* package */ static void a() {} - /* package */ static void b() {} - } - - /** - * AB StaticMockFixture class that handles two mocked classes, {@link A} and {@link B}. - */ - private class AB implements StaticMockFixture { - @Override - public StaticMockitoSessionBuilder setUpMockedClasses( - StaticMockitoSessionBuilder sessionBuilder) { - sessionBuilder.spyStatic(A.class); - sessionBuilder.spyStatic(B.class); - return sessionBuilder; - } - - @Override - public void setUpMockBehaviors() { - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("A.a"); - return null; - }).when(A::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("A.b"); - return null; - }).when(A::b); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("B.a"); - return null; - }).when(B::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("B.b"); - return null; - }).when(B::b); - } - - @Override - public void tearDown() { - - } - } - - /** - * AB StaticMockFixture class that handles two mocked classes, {@link C} and {@link D}. - */ - private class CD implements StaticMockFixture { - @Override - public StaticMockitoSessionBuilder setUpMockedClasses( - StaticMockitoSessionBuilder sessionBuilder) { - sessionBuilder.spyStatic(C.class); - sessionBuilder.spyStatic(D.class); - return sessionBuilder; - } - - @Override - public void setUpMockBehaviors() { - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("C.a"); - return null; - }).when(C::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("C.b"); - return null; - }).when(C::b); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("D.a"); - return null; - }).when(D::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("D.b"); - return null; - }).when(D::b); - } - - @Override - public void tearDown() { - - } - } -} diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixture.java b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixture.java deleted file mode 100644 index 0303fe1e1eb0..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixture.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 com.android.dx.mockito.inline.extended.StaticMockitoSession; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; - -/** - * Provides support for a set of static mocks for use within a single shared - * {@link StaticMockitoSession}. - */ -public interface StaticMockFixture { - /** - * Adds any required mock or spy classes managed by this {@link StaticMockFixture} to the - * {@link StaticMockitoSessionBuilder} provided. - * - * Call this to set up the classes that this expects to be mocked, by adding them to the - * {@link StaticMockitoSessionBuilder} using - * {@link StaticMockitoSessionBuilder#mockStatic(Class)}, - * {@link StaticMockitoSessionBuilder#spyStatic(Class)} or similar as appropriate. - * - * @param sessionBuilder the {@link StaticMockitoSessionBuilder} to which the classes should be - * added to mock, spy, or otherwise as required - * @return sessionBuilder, to allow for fluent programming - */ - StaticMockitoSessionBuilder setUpMockedClasses(StaticMockitoSessionBuilder sessionBuilder); - - /** - * Configures the behaviours of any mock or spy classes managed by this - * {@link StaticMockFixture}. - * - * Call this after {@link StaticMockitoSessionBuilder#startMocking()} has been called. - * This sets up any default behaviors for the mocks, spys, etc. - */ - void setUpMockBehaviors(); - - /** - * Tear everything down. - */ - void tearDown(); -} diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRule.java b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRule.java deleted file mode 100644 index 3566aee2eba3..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRule.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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.mockitoSession; - -import com.android.dx.mockito.inline.extended.StaticMockitoSession; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; - -import org.junit.AssumptionViolatedException; -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 java.util.function.Supplier; - -/** - * <p>StaticMockFixtureRule is a {@link TestRule} that wraps one or more {@link StaticMockFixture}s - * to set them up and tear it down automatically. This works well when you have no other static - * mocks than the ones supported by their respective {@link StaticMockFixture}s.</p> - * - * <p>StaticMockFixtureRule should be defined as a rule on your test so it can clean up after - * itself. Like the following:</p> - * <pre class="prettyprint"> -* public final StaticMockFixture mStaticMockFixtures = ...; - * @Rule - * public final StaticMockFixtureRule mStaticMockFixtureRule = - * new StaticMockFixtureRule(mStaticMockFixtures); - * </pre> - */ -public class StaticMockFixtureRule implements TestRule { - private StaticMockitoSession mMockitoSession; - private StaticMockFixture[] mStaticMockFixtures; - private Supplier<? extends StaticMockFixture>[] mSupplier; - - /** - * Constructs a StaticMockFixtureRule that always uses the same {@link StaticMockFixture} - * instance(s). - * - * @param staticMockFixtures the {@link StaticMockFixture}(s) to use. - */ - public StaticMockFixtureRule(StaticMockFixture... staticMockFixtures) { - mStaticMockFixtures = staticMockFixtures; - mSupplier = null; - } - - /** - * Constructs a StaticMockFixtureRule that retrieves a new {@link StaticMockFixture} instance - * from one or more {@link Supplier<? extends StaticMockFixture >}s for each test invocation. - * - * @param supplier the {@link Supplier<? extends StaticMockFixture >}(s) that will supply the - * {@link StaticMockFixture}(s). - */ - @SafeVarargs - public StaticMockFixtureRule(Supplier<? extends StaticMockFixture>... supplier) { - mStaticMockFixtures = null; - mSupplier = supplier; - } - - @Override - public Statement apply(Statement base, Description description) { - StaticMockitoSessionBuilder sessionBuilder = getSessionBuilder(); - - if (mSupplier != null) { - mStaticMockFixtures = new StaticMockFixture[mSupplier.length]; - for (int i = 0; i < mSupplier.length; i++) { - mStaticMockFixtures[i] = mSupplier[i].get(); - } - } - - for (int i = 0; i < mStaticMockFixtures.length; i++) { - sessionBuilder = mStaticMockFixtures[i].setUpMockedClasses(sessionBuilder); - } - - mMockitoSession = sessionBuilder.startMocking(); - - for (int i = 0; i < mStaticMockFixtures.length; i++) { - mStaticMockFixtures[i].setUpMockBehaviors(); - } - - return new TestWatcher() { - @Override - protected void succeeded(Description description) { - tearDown(null); - } - - @Override - protected void skipped(AssumptionViolatedException e, Description description) { - tearDown(e); - } - - @Override - protected void failed(Throwable e, Description description) { - tearDown(e); - } - }.apply(base, description); - } - - /** - * This allows overriding the creation of the builder for a new {@link StaticMockitoSession}. - * Mainly for testing, but also useful if you have other requirements for the session. - * - * @return a new {@link StaticMockitoSessionBuilder}. - */ - public StaticMockitoSessionBuilder getSessionBuilder() { - return mockitoSession().strictness(Strictness.LENIENT); - } - - private void tearDown(Throwable e) { - mMockitoSession.finishMocking(e); - - for (int i = mStaticMockFixtures.length - 1; i >= 0; i--) { - mStaticMockFixtures[i].tearDown(); - if (mSupplier != null) { - mStaticMockFixtures[i] = null; - } - } - - if (mSupplier != null) { - mStaticMockFixtures = null; - } - - mMockitoSession = null; - } -} diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRuleTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRuleTest.java deleted file mode 100644 index 8e0ccf01d7a7..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRuleTest.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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 org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static org.mockito.quality.Strictness.LENIENT; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.dx.mockito.inline.extended.StaticMockitoSession; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; - -import org.junit.After; -import org.junit.AssumptionViolatedException; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.Description; -import org.junit.runner.RunWith; -import org.junit.runners.model.Statement; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoSession; - -import java.util.function.Supplier; - -/** Tests that StaticMockFixture manages fixtures and suppliers correctly. */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class StaticMockFixtureRuleTest { - private MockitoSession mMockitoSession; - - @Mock private StaticMockitoSessionBuilder mSessionBuilder; - @Mock private StaticMockitoSession mSession; - @Mock private StaticMockFixture mA1; - @Mock private StaticMockFixture mB1; - @Mock private StaticMockFixture mA2; - @Mock private StaticMockFixture mB2; - @Mock private Supplier<StaticMockFixture> mSupplyA; - @Mock private Supplier<StaticMockFixture> mSupplyB; - @Mock private Statement mStatement; - @Mock private Statement mSkipStatement; - @Mock private Statement mThrowStatement; - @Mock private Description mDescription; - - @Before - public void setUp() throws Throwable { - mMockitoSession = Mockito.mockitoSession() - .strictness(LENIENT) - .initMocks(this) - .startMocking(); - prepareMockBehaviours(); - } - - @After - public void tearDown() { - mMockitoSession.finishMocking(); - } - - private void prepareFixtureMocks(StaticMockFixture... mocks) { - for (StaticMockFixture mock : mocks) { - when(mock.setUpMockedClasses(any())).thenAnswer( - invocation -> invocation.getArgument(0)); - doNothing().when(mock).setUpMockBehaviors(); - } - } - - private void prepareMockBehaviours() throws Throwable { - when(mSessionBuilder.startMocking()).thenReturn(mSession); - when(mSupplyA.get()).thenReturn(mA1, mA2); - when(mSupplyB.get()).thenReturn(mB1, mB2); - prepareFixtureMocks(mA1, mA2, mB1, mB2); - when(mA1.setUpMockedClasses(any())).thenAnswer(invocation -> invocation.getArgument(0)); - doNothing().when(mA1).setUpMockBehaviors(); - when(mB1.setUpMockedClasses(any())).thenAnswer(invocation -> invocation.getArgument(0)); - doNothing().when(mB1).setUpMockBehaviors(); - doNothing().when(mStatement).evaluate(); - doThrow(new AssumptionViolatedException("bad assumption, test should be skipped")) - .when(mSkipStatement).evaluate(); - doThrow(new IllegalArgumentException("bad argument, test should be failed")) - .when(mThrowStatement).evaluate(); - doNothing().when(mA1).tearDown(); - doNothing().when(mB1).tearDown(); - } - - private InOrder mocksInOrder() { - return inOrder(mSessionBuilder, mSession, mSupplyA, mSupplyB, mA1, mA2, mB1, mB2, - mStatement, mSkipStatement, mThrowStatement, mDescription); - } - - private void verifyNoMoreImportantMockInteractions() { - verifyNoMoreInteractions(mSupplyA, mSupplyB, mA1, mA2, mB1, mB2, mStatement, - mSkipStatement, mThrowStatement); - } - - @Test - public void testRuleWorksWithExplicitFixtures() throws Throwable { - InOrder inOrder = mocksInOrder(); - - StaticMockFixtureRule rule = new StaticMockFixtureRule(mA1, mB1) { - @Override public StaticMockitoSessionBuilder getSessionBuilder() { - return mSessionBuilder; - } - }; - Statement runMe = rule.apply(mStatement, mDescription); - - inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mA1).setUpMockBehaviors(); - inOrder.verify(mB1).setUpMockBehaviors(); - - runMe.evaluate(); - - inOrder.verify(mStatement).evaluate(); - // note: tearDown in reverse order - inOrder.verify(mB1).tearDown(); - inOrder.verify(mA1).tearDown(); - - // Round two: use the same fixtures again. - rule.apply(mStatement, mDescription).evaluate(); - - inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mA1).setUpMockBehaviors(); - inOrder.verify(mB1).setUpMockBehaviors(); - inOrder.verify(mStatement).evaluate(); - // note: tearDown in reverse order - inOrder.verify(mB1).tearDown(); - inOrder.verify(mA1).tearDown(); - - verifyNoMoreImportantMockInteractions(); - } - - @Test - public void testRuleWorksWithFixtureSuppliers() throws Throwable { - InOrder inOrder = mocksInOrder(); - - StaticMockFixtureRule rule = new StaticMockFixtureRule(mSupplyA, mSupplyB) { - @Override public StaticMockitoSessionBuilder getSessionBuilder() { - return mSessionBuilder; - } - }; - Statement runMe = rule.apply(mStatement, mDescription); - - inOrder.verify(mSupplyA).get(); - inOrder.verify(mSupplyB).get(); - inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mA1).setUpMockBehaviors(); - inOrder.verify(mB1).setUpMockBehaviors(); - - runMe.evaluate(); - - inOrder.verify(mStatement).evaluate(); - // note: tearDown in reverse order - inOrder.verify(mB1).tearDown(); - inOrder.verify(mA1).tearDown(); - - // Round two: use the same suppliers again to retrieve different fixtures: mA2 and mB2 - rule.apply(mStatement, mDescription).evaluate(); - - inOrder.verify(mSupplyA).get(); - inOrder.verify(mSupplyB).get(); - inOrder.verify(mA2).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mB2).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mA2).setUpMockBehaviors(); - inOrder.verify(mB2).setUpMockBehaviors(); - inOrder.verify(mStatement).evaluate(); - // note: tearDown in reverse order - inOrder.verify(mB2).tearDown(); - inOrder.verify(mA2).tearDown(); - - verifyNoMoreImportantMockInteractions(); - } - - @Test - public void testTearDownOnSkippedTests() throws Throwable { - InOrder inOrder = mocksInOrder(); - - StaticMockFixtureRule rule = new StaticMockFixtureRule(mA1, mB1) { - @Override public StaticMockitoSessionBuilder getSessionBuilder() { - return mSessionBuilder; - } - }; - Statement skipStatement = rule.apply(mSkipStatement, mDescription); - - inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mA1).setUpMockBehaviors(); - inOrder.verify(mB1).setUpMockBehaviors(); - - try { - skipStatement.evaluate(); - fail("AssumptionViolatedException should have been thrown"); - } catch (AssumptionViolatedException e) { - // expected - } - - inOrder.verify(mSkipStatement).evaluate(); - // note: tearDown in reverse order - inOrder.verify(mB1).tearDown(); - inOrder.verify(mA1).tearDown(); - - verifyNoMoreImportantMockInteractions(); - } - - @Test - public void testTearDownOnFailedTests() throws Throwable { - InOrder inOrder = mocksInOrder(); - - StaticMockFixtureRule rule = new StaticMockFixtureRule(mA1, mB1) { - @Override public StaticMockitoSessionBuilder getSessionBuilder() { - return mSessionBuilder; - } - }; - Statement failStatement = rule.apply(mThrowStatement, mDescription); - - inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class)); - inOrder.verify(mA1).setUpMockBehaviors(); - inOrder.verify(mB1).setUpMockBehaviors(); - - try { - failStatement.evaluate(); - fail("IllegalArgumentException should have been thrown"); - } catch (IllegalArgumentException e) { - // expected - } - - inOrder.verify(mThrowStatement).evaluate(); - // note: tearDown in reverse order - inOrder.verify(mB1).tearDown(); - inOrder.verify(mA1).tearDown(); - - verifyNoMoreImportantMockInteractions(); - } -} diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java deleted file mode 100644 index 60a7f78c6949..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 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 org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyFloat; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.when; - -import android.provider.DeviceConfig; -import android.provider.DeviceConfig.Properties; -import android.util.ArrayMap; -import android.util.Pair; - -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; - -import org.junit.rules.TestRule; -import org.mockito.ArgumentMatchers; -import org.mockito.Mockito; -import org.mockito.stubbing.Answer; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; - -/** - * TestableDeviceConfig is a {@link StaticMockFixture} that 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. - */ -public final class TestableDeviceConfig implements StaticMockFixture { - - private Map<DeviceConfig.OnPropertiesChangedListener, Pair<String, Executor>> - mOnPropertiesChangedListenerMap = new HashMap<>(); - private Map<String, String> mKeyValueMap = new ConcurrentHashMap<>(); - - /** - * Clears out all local overrides. - */ - public void clearDeviceConfig() { - mKeyValueMap.clear(); - } - - /** - * {@inheritDoc} - */ - @Override - public StaticMockitoSessionBuilder setUpMockedClasses( - StaticMockitoSessionBuilder sessionBuilder) { - sessionBuilder.spyStatic(DeviceConfig.class); - return sessionBuilder; - } - - /** - * {@inheritDoc} - */ - @Override - public void setUpMockBehaviors() { - doAnswer((Answer<Void>) invocationOnMock -> { - String namespace = invocationOnMock.getArgument(0); - Executor executor = invocationOnMock.getArgument(1); - DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener = - invocationOnMock.getArgument(2); - mOnPropertiesChangedListenerMap.put( - onPropertiesChangedListener, new Pair<>(namespace, executor)); - return null; - }).when(() -> DeviceConfig.addOnPropertiesChangedListener( - anyString(), any(Executor.class), - any(DeviceConfig.OnPropertiesChangedListener.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); - invokeListeners(namespace, getProperties(namespace, name, value)); - return true; - } - ).when(() -> DeviceConfig.setProperty(anyString(), anyString(), anyString(), anyBoolean())); - - doAnswer((Answer<Boolean>) invocationOnMock -> { - String namespace = invocationOnMock.getArgument(0); - String name = invocationOnMock.getArgument(1); - mKeyValueMap.remove(getKey(namespace, name)); - invokeListeners(namespace, getProperties(namespace, name, null)); - return true; - } - ).when(() -> DeviceConfig.deleteProperty(anyString(), anyString())); - - doAnswer((Answer<Boolean>) invocationOnMock -> { - Properties properties = invocationOnMock.getArgument(0); - String namespace = properties.getNamespace(); - Map<String, String> keyValues = new ArrayMap<>(); - for (String name : properties.getKeyset()) { - String value = properties.getString(name, /* defaultValue= */ ""); - mKeyValueMap.put(getKey(namespace, name), value); - keyValues.put(name.toLowerCase(), value); - } - invokeListeners(namespace, getProperties(namespace, keyValues)); - return true; - } - ).when(() -> DeviceConfig.setProperties(any(Properties.class))); - - 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())); - - doAnswer((Answer<Properties>) invocationOnMock -> { - String namespace = invocationOnMock.getArgument(0); - final int varargStartIdx = 1; - Map<String, String> keyValues = new ArrayMap<>(); - if (invocationOnMock.getArguments().length == varargStartIdx) { - mKeyValueMap.entrySet().forEach(entry -> { - Pair<String, String> nameSpaceAndName = getNameSpaceAndName(entry.getKey()); - if (!nameSpaceAndName.first.equals(namespace)) { - return; - } - keyValues.put(nameSpaceAndName.second.toLowerCase(), entry.getValue()); - }); - } else { - for (int i = varargStartIdx; i < invocationOnMock.getArguments().length; ++i) { - String name = invocationOnMock.getArgument(i); - keyValues.put(name.toLowerCase(), mKeyValueMap.get(getKey(namespace, name))); - } - } - return getProperties(namespace, keyValues); - }).when(() -> DeviceConfig.getProperties(anyString(), ArgumentMatchers.<String>any())); - } - - /** - * {@inheritDoc} - */ - @Override - public void tearDown() { - clearDeviceConfig(); - mOnPropertiesChangedListenerMap.clear(); - } - - private static String getKey(String namespace, String name) { - return namespace + "/" + name; - } - - private Pair<String, String> getNameSpaceAndName(String key) { - final String[] values = key.split("/"); - return Pair.create(values[0], values[1]); - } - - private void invokeListeners(String namespace, Properties properties) { - for (DeviceConfig.OnPropertiesChangedListener listener : - mOnPropertiesChangedListenerMap.keySet()) { - if (namespace.equals(mOnPropertiesChangedListenerMap.get(listener).first)) { - mOnPropertiesChangedListenerMap.get(listener).second.execute( - () -> listener.onPropertiesChanged(properties)); - } - } - } - - private Properties getProperties(String namespace, String name, String value) { - return getProperties(namespace, Collections.singletonMap(name.toLowerCase(), value)); - } - - private Properties getProperties(String namespace, Map<String, String> keyValues) { - Properties properties = Mockito.mock(Properties.class); - when(properties.getNamespace()).thenReturn(namespace); - when(properties.getKeyset()).thenReturn(keyValues.keySet()); - when(properties.getBoolean(anyString(), anyBoolean())).thenAnswer( - invocation -> { - String key = invocation.getArgument(0); - boolean defaultValue = invocation.getArgument(1); - final String value = keyValues.get(key.toLowerCase()); - if (value != null) { - return Boolean.parseBoolean(value); - } else { - return defaultValue; - } - } - ); - when(properties.getFloat(anyString(), anyFloat())).thenAnswer( - invocation -> { - String key = invocation.getArgument(0); - float defaultValue = invocation.getArgument(1); - final String value = keyValues.get(key.toLowerCase()); - if (value != null) { - try { - return Float.parseFloat(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } else { - return defaultValue; - } - } - ); - when(properties.getInt(anyString(), anyInt())).thenAnswer( - invocation -> { - String key = invocation.getArgument(0); - int defaultValue = invocation.getArgument(1); - final String value = keyValues.get(key.toLowerCase()); - if (value != null) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } else { - return defaultValue; - } - } - ); - when(properties.getLong(anyString(), anyLong())).thenAnswer( - invocation -> { - String key = invocation.getArgument(0); - long defaultValue = invocation.getArgument(1); - final String value = keyValues.get(key.toLowerCase()); - if (value != null) { - try { - return Long.parseLong(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } else { - return defaultValue; - } - } - ); - when(properties.getString(anyString(), nullable(String.class))).thenAnswer( - invocation -> { - String key = invocation.getArgument(0); - String defaultValue = invocation.getArgument(1); - final String value = keyValues.get(key.toLowerCase()); - if (value != null) { - return value; - } else { - return defaultValue; - } - } - ); - - return properties; - } - - /** - * <p>TestableDeviceConfigRule is a {@link TestRule} that wraps a {@link TestableDeviceConfig} - * to set it up and tear it down automatically. This works well when you have no other static - * mocks.</p> - * - * <p>TestableDeviceConfigRule 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 TestableDeviceConfigRule mTestableDeviceConfigRule = - * new TestableDeviceConfigRule(); - * </pre> - */ - public static class TestableDeviceConfigRule extends StaticMockFixtureRule { - public TestableDeviceConfigRule() { - super(TestableDeviceConfig::new); - } - } -} diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigAndOtherStaticMocksTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigAndOtherStaticMocksTest.java deleted file mode 100644 index 9616d13e42fe..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigAndOtherStaticMocksTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 android.provider.DeviceConfig; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.dx.mockito.inline.extended.ExtendedMockito; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class TestableDeviceConfigAndOtherStaticMocksTest { - @Rule - public StaticMockFixtureRule mStaticMockFixtureRule = - new StaticMockFixtureRule(TestableDeviceConfig::new, AB::new, CD::new); - - private List<String> mCollected; - - @Test - public void testDeviceConfigAndOtherStaticMocks() throws Exception { - mCollected = new ArrayList<>(); - int n = 0; - - String namespace = "foo"; - String flag = "bar"; - String flagValue = "new value"; - - Assert.assertNull(DeviceConfig.getProperty(namespace, flag)); - - A.a(); - verifyCollected(++n, "A.a"); - - DeviceConfig.setProperty(namespace, flag, flagValue, false); - - D.b(); - verifyCollected(++n, "D.b"); - - Assert.assertEquals(flagValue, DeviceConfig.getProperty(namespace, flag)); - - C.b(); - verifyCollected(++n, "C.b"); - - B.a(); - verifyCollected(++n, "B.a"); - } - - private void verifyCollected(int n, String last) { - Assert.assertEquals(n, mCollected.size()); - Assert.assertEquals(last, mCollected.get(n - 1)); - } - - private static class A { - /* package */ static void a() {} - /* package */ static void b() {} - } - - private static class B { - /* package */ static void a() {} - /* package */ static void b() {} - } - - private static class C { - /* package */ static void a() {} - /* package */ static void b() {} - } - - private static class D { - /* package */ static void a() {} - /* package */ static void b() {} - } - - /** - * AB StaticMockFixture class that handles two mocked classes, {@link A} and {@link B}. - */ - private class AB implements StaticMockFixture { - @Override - public StaticMockitoSessionBuilder setUpMockedClasses( - StaticMockitoSessionBuilder sessionBuilder) { - sessionBuilder.spyStatic(A.class); - sessionBuilder.spyStatic(B.class); - return sessionBuilder; - } - - @Override - public void setUpMockBehaviors() { - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("A.a"); - return null; - }).when(A::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("A.b"); - return null; - }).when(A::b); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("B.a"); - return null; - }).when(B::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("B.b"); - return null; - }).when(B::b); - } - - @Override - public void tearDown() { - - } - } - - /** - * AB StaticMockFixture class that handles two mocked classes, {@link C} and {@link D}. - */ - private class CD implements StaticMockFixture { - @Override - public StaticMockitoSessionBuilder setUpMockedClasses( - StaticMockitoSessionBuilder sessionBuilder) { - sessionBuilder.spyStatic(C.class); - sessionBuilder.spyStatic(D.class); - return sessionBuilder; - } - - @Override - public void setUpMockBehaviors() { - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("C.a"); - return null; - }).when(C::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("C.b"); - return null; - }).when(C::b); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("D.a"); - return null; - }).when(D::a); - ExtendedMockito.doAnswer(invocation -> { - mCollected.add("D.b"); - return null; - }).when(D::b); - } - - @Override - public void tearDown() { - - } - } -} diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java deleted file mode 100644 index f9f43876f39a..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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.OnPropertiesChangedListener; - -import static com.google.common.truth.Truth.assertThat; - -import android.app.ActivityThread; -import android.platform.test.annotations.Presubmit; -import android.provider.DeviceConfig; -import android.provider.DeviceConfig.BadConfigException; -import android.provider.DeviceConfig.Properties; - -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.TestableDeviceConfigRule - mTestableDeviceConfig = new TestableDeviceConfig.TestableDeviceConfigRule(); - - @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 setProperties() throws BadConfigException { - String newKey = "key2"; - String newValue = "value2"; - DeviceConfig.setProperties(new Properties.Builder(sNamespace).setString(sKey, - sValue).setString(newKey, newValue).build()); - assertThat(DeviceConfig.getProperty(sNamespace, sKey)).isEqualTo(sValue); - assertThat(DeviceConfig.getProperty(sNamespace, newKey)).isEqualTo(newValue); - } - - @Test - public void deleteProperty() { - DeviceConfig.setProperty(sNamespace, sKey, sValue, false); - assertThat(DeviceConfig.getProperty(sNamespace, sKey)).isEqualTo(sValue); - DeviceConfig.deleteProperty(sNamespace, sKey); - assertThat(DeviceConfig.getProperty(sNamespace, sKey)).isNull(); - String newNamespace = "namespace2"; - String newValue = "value2"; - DeviceConfig.setProperty(newNamespace, sKey, newValue, false); - assertThat(DeviceConfig.getProperty(newNamespace, sKey)).isEqualTo(newValue); - DeviceConfig.deleteProperty(newNamespace, sKey); - assertThat(DeviceConfig.getProperty(newNamespace, sKey)).isNull(); - } - - @Test - public void getProperties_empty() { - String newKey = "key2"; - String newValue = "value2"; - DeviceConfig.setProperty(sNamespace, sKey, sValue, false); - Properties properties = DeviceConfig.getProperties(sNamespace); - assertThat(properties.getString(sKey, null)).isEqualTo(sValue); - assertThat(properties.getString(newKey, null)).isNull(); - - DeviceConfig.setProperty(sNamespace, newKey, newValue, false); - properties = DeviceConfig.getProperties(sNamespace); - assertThat(properties.getString(sKey, null)).isEqualTo(sValue); - assertThat(properties.getString(newKey, null)).isEqualTo(newValue); - - } - - @Test - public void getProperties() { - Properties properties = DeviceConfig.getProperties(sNamespace, sKey); - assertThat(properties.getString(sKey, null)).isNull(); - - DeviceConfig.setProperty(sNamespace, sKey, sValue, false); - properties = DeviceConfig.getProperties(sNamespace, sKey); - assertThat(properties.getString(sKey, null)).isEqualTo(sValue); - - String newKey = "key2"; - String newValue = "value2"; - DeviceConfig.setProperty(sNamespace, newKey, newValue, false); - properties = DeviceConfig.getProperties(sNamespace, sKey, newKey); - assertThat(properties.getString(sKey, null)).isEqualTo(sValue); - assertThat(properties.getString(newKey, null)).isEqualTo(newValue); - - String unsetKey = "key3"; - properties = DeviceConfig.getProperties(sNamespace, newKey, unsetKey); - assertThat(properties.getKeyset()).containsExactly(newKey, unsetKey); - assertThat(properties.getString(newKey, null)).isEqualTo(newValue); - assertThat(properties.getString(unsetKey, null)).isNull(); - } - - @Test - public void testListener_setProperty() throws InterruptedException { - CountDownLatch countDownLatch = new CountDownLatch(1); - - OnPropertiesChangedListener changeListener = (properties) -> { - assertThat(properties.getNamespace()).isEqualTo(sNamespace); - assertThat(properties.getKeyset()).containsExactly(sKey); - assertThat(properties.getString(sKey, "bogus_value")).isEqualTo(sValue); - assertThat(properties.getString("bogus_key", "bogus_value")).isEqualTo("bogus_value"); - countDownLatch.countDown(); - }; - try { - DeviceConfig.addOnPropertiesChangedListener(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.removeOnPropertiesChangedListener(changeListener); - } - } - - @Test - public void testListener_setProperties() throws BadConfigException, InterruptedException { - CountDownLatch countDownLatch = new CountDownLatch(1); - String newKey = "key2"; - String newValue = "value2"; - - OnPropertiesChangedListener changeListener = (properties) -> { - assertThat(properties.getNamespace()).isEqualTo(sNamespace); - assertThat(properties.getKeyset()).containsExactly(sKey, newKey); - assertThat(properties.getString(sKey, "bogus_value")).isEqualTo(sValue); - assertThat(properties.getString(newKey, "bogus_value")).isEqualTo(newValue); - assertThat(properties.getString("bogus_key", "bogus_value")).isEqualTo("bogus_value"); - countDownLatch.countDown(); - }; - try { - DeviceConfig.addOnPropertiesChangedListener(sNamespace, - ActivityThread.currentApplication().getMainExecutor(), changeListener); - DeviceConfig.setProperties(new Properties.Builder(sNamespace).setString(sKey, - sValue).setString(newKey, newValue).build()); - assertThat(countDownLatch.await( - WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue(); - } finally { - DeviceConfig.removeOnPropertiesChangedListener(changeListener); - } - } - - @Test - public void testListener_deleteProperty() throws InterruptedException { - CountDownLatch countDownLatch = new CountDownLatch(1); - - OnPropertiesChangedListener changeListener = (properties) -> { - assertThat(properties.getNamespace()).isEqualTo(sNamespace); - assertThat(properties.getKeyset()).containsExactly(sKey); - assertThat(properties.getString(sKey, "bogus_value")).isEqualTo("bogus_value"); - assertThat(properties.getString("bogus_key", "bogus_value")).isEqualTo("bogus_value"); - countDownLatch.countDown(); - }; - try { - DeviceConfig.addOnPropertiesChangedListener(sNamespace, - ActivityThread.currentApplication().getMainExecutor(), changeListener); - DeviceConfig.deleteProperty(sNamespace, sKey); - assertThat(countDownLatch.await( - WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue(); - } finally { - DeviceConfig.removeOnPropertiesChangedListener(changeListener); - } - } -} - - |