Loading tests/robotests/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,10 @@ android_robolectric_test { java_library { name: "Settings-robo-testutils", srcs: ["testutils/**/*.java"], srcs: [ "testutils/**/*.java", "testutils/**/*.kt", ], libs: [ "Robolectric_all-target_upstream", "Settings-core", Loading tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java +10 −1 Original line number Diff line number Diff line Loading @@ -63,12 +63,14 @@ import android.widget.TextView; import com.android.settings.R; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SystemProperty; import com.android.settings.widget.RingProgressBar; import com.airbnb.lottie.LottieAnimationView; import com.airbnb.lottie.LottieTask; import com.google.android.setupdesign.GlifLayout; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; Loading Loading @@ -111,15 +113,23 @@ public class FingerprintEnrollEnrollingTest { private final int[] mSfpsStageThresholds = new int[]{0, 9, 13, 19, 25}; private final int[] mUdfpsStageThresholds = new int[]{0, 13, 17, 22}; private final SystemProperty mSystemProperty = new SystemProperty(); private FingerprintEnrollEnrolling mActivity; private Context mContext; @Before public void setUp() { MockitoAnnotations.initMocks(this); mSystemProperty.override("robolectric.createActivityContexts", "true"); FakeFeatureFactory.setupForTest(); } @After public void tearDown() { mSystemProperty.close(); } @Test public void fingerprintUdfpsEnrollSuccessProgress_shouldNotVibrate() { initializeActivityFor(TYPE_UDFPS_OPTICAL); Loading Loading @@ -645,7 +655,6 @@ public class FingerprintEnrollEnrollingTest { } private void createActivity() { System.setProperty("robolectric.createActivityContexts", "true"); final Bundle savedInstanceState = new Bundle(); savedInstanceState.putInt(KEY_STATE_PREVIOUS_ROTATION, Surface.ROTATION_90); Loading tests/robotests/src/com/android/settings/display/DisplayScreenTest.kt +8 −8 Original line number Diff line number Diff line Loading @@ -21,9 +21,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.internal.widget.LockPatternUtils import com.android.settings.flags.Flags import com.android.settings.testutils.FakeFeatureFactory import com.android.settings.testutils.SystemProperty import com.android.settingslib.preference.CatalystScreenTestCase import com.google.common.truth.Truth.assertThat import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt Loading Loading @@ -66,12 +66,11 @@ class DisplayScreenTest : CatalystScreenTestCase() { assertThat(preferenceScreenCreator.isAvailable(contextWrapper)).isFalse() } @Ignore("robolectric.createActivityContexts cause other test failure") override fun migration() { // avoid UnsupportedOperationException when getDisplay from context System.setProperty("robolectric.createActivityContexts", "true") val lockPatternUtils = mock<LockPatternUtils> { on { isSecure(anyInt()) } doReturn true } SystemProperty("robolectric.createActivityContexts", "true").use { val lockPatternUtils = mock<LockPatternUtils> { on { isSecure(anyInt()) } doReturn true } FakeFeatureFactory.setupForTest().securityFeatureProvider.stub { on { getLockPatternUtils(any()) } doReturn lockPatternUtils } Loading @@ -79,3 +78,4 @@ class DisplayScreenTest : CatalystScreenTestCase() { super.migration() } } } tests/robotests/testutils/com/android/settings/testutils/SystemProperty.kt 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.settings.testutils /** * Helper class to override system properties. * * [System.setProperty] changes the static state in the JVM, which is shared by all tests. Hence, * there is chance that test cases are dependent/interfered due to system property unexpectedly. * This helper class backs up the old properties when invoking [override] and restore the old * properties in [close] to avoid flaky testing. */ class SystemProperty(overrides: Map<String, String?> = mapOf()) : AutoCloseable { private val oldProperties = mutableMapOf<String, String?>() constructor(key: String, value: String?) : this(mapOf(key to value)) init { override(overrides) } fun override(key: String, value: String?) = override(mapOf(key to value)) fun override(overrides: Map<String, String?>) { // back up system properties for the overrides for (key in overrides.keys) { // only back up the oldest property if (!oldProperties.containsKey(key)) { oldProperties[key] = System.getProperty(key) } } overrides.overrideProperties() } override fun close() { // restore the backed up properties oldProperties.overrideProperties() oldProperties.clear() } private fun Map<String, String?>.overrideProperties() { for ((key, value) in this) { if (value != null) { System.setProperty(key, value) } else { System.clearProperty(key) } } } } Loading
tests/robotests/Android.bp +4 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,10 @@ android_robolectric_test { java_library { name: "Settings-robo-testutils", srcs: ["testutils/**/*.java"], srcs: [ "testutils/**/*.java", "testutils/**/*.kt", ], libs: [ "Robolectric_all-target_upstream", "Settings-core", Loading
tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java +10 −1 Original line number Diff line number Diff line Loading @@ -63,12 +63,14 @@ import android.widget.TextView; import com.android.settings.R; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SystemProperty; import com.android.settings.widget.RingProgressBar; import com.airbnb.lottie.LottieAnimationView; import com.airbnb.lottie.LottieTask; import com.google.android.setupdesign.GlifLayout; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; Loading Loading @@ -111,15 +113,23 @@ public class FingerprintEnrollEnrollingTest { private final int[] mSfpsStageThresholds = new int[]{0, 9, 13, 19, 25}; private final int[] mUdfpsStageThresholds = new int[]{0, 13, 17, 22}; private final SystemProperty mSystemProperty = new SystemProperty(); private FingerprintEnrollEnrolling mActivity; private Context mContext; @Before public void setUp() { MockitoAnnotations.initMocks(this); mSystemProperty.override("robolectric.createActivityContexts", "true"); FakeFeatureFactory.setupForTest(); } @After public void tearDown() { mSystemProperty.close(); } @Test public void fingerprintUdfpsEnrollSuccessProgress_shouldNotVibrate() { initializeActivityFor(TYPE_UDFPS_OPTICAL); Loading Loading @@ -645,7 +655,6 @@ public class FingerprintEnrollEnrollingTest { } private void createActivity() { System.setProperty("robolectric.createActivityContexts", "true"); final Bundle savedInstanceState = new Bundle(); savedInstanceState.putInt(KEY_STATE_PREVIOUS_ROTATION, Surface.ROTATION_90); Loading
tests/robotests/src/com/android/settings/display/DisplayScreenTest.kt +8 −8 Original line number Diff line number Diff line Loading @@ -21,9 +21,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.internal.widget.LockPatternUtils import com.android.settings.flags.Flags import com.android.settings.testutils.FakeFeatureFactory import com.android.settings.testutils.SystemProperty import com.android.settingslib.preference.CatalystScreenTestCase import com.google.common.truth.Truth.assertThat import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt Loading Loading @@ -66,12 +66,11 @@ class DisplayScreenTest : CatalystScreenTestCase() { assertThat(preferenceScreenCreator.isAvailable(contextWrapper)).isFalse() } @Ignore("robolectric.createActivityContexts cause other test failure") override fun migration() { // avoid UnsupportedOperationException when getDisplay from context System.setProperty("robolectric.createActivityContexts", "true") val lockPatternUtils = mock<LockPatternUtils> { on { isSecure(anyInt()) } doReturn true } SystemProperty("robolectric.createActivityContexts", "true").use { val lockPatternUtils = mock<LockPatternUtils> { on { isSecure(anyInt()) } doReturn true } FakeFeatureFactory.setupForTest().securityFeatureProvider.stub { on { getLockPatternUtils(any()) } doReturn lockPatternUtils } Loading @@ -79,3 +78,4 @@ class DisplayScreenTest : CatalystScreenTestCase() { super.migration() } } }
tests/robotests/testutils/com/android/settings/testutils/SystemProperty.kt 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.settings.testutils /** * Helper class to override system properties. * * [System.setProperty] changes the static state in the JVM, which is shared by all tests. Hence, * there is chance that test cases are dependent/interfered due to system property unexpectedly. * This helper class backs up the old properties when invoking [override] and restore the old * properties in [close] to avoid flaky testing. */ class SystemProperty(overrides: Map<String, String?> = mapOf()) : AutoCloseable { private val oldProperties = mutableMapOf<String, String?>() constructor(key: String, value: String?) : this(mapOf(key to value)) init { override(overrides) } fun override(key: String, value: String?) = override(mapOf(key to value)) fun override(overrides: Map<String, String?>) { // back up system properties for the overrides for (key in overrides.keys) { // only back up the oldest property if (!oldProperties.containsKey(key)) { oldProperties[key] = System.getProperty(key) } } overrides.overrideProperties() } override fun close() { // restore the backed up properties oldProperties.overrideProperties() oldProperties.clear() } private fun Map<String, String?>.overrideProperties() { for ((key, value) in this) { if (value != null) { System.setProperty(key, value) } else { System.clearProperty(key) } } } }