Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb798ae9 authored by Harry Cutts's avatar Harry Cutts
Browse files

TestableSettingsProvider: tear down properly

We were finding that if a test that had to change settings (such as
com.android.test.input.AnrTest) ran after one that used TestableContext,
it would fail because its settings changes weren't applied.

This was because when its test finished, TestableContext would run the
same clearValuesAndCheck method that it used on setup. This cleared any
saved settings from the TestableSettingsProvider and reset the
Settings.ContentProviderHolder caches that still pointed to it, but it
would then make some settings put and get calls using the
TestableContext (and its content resolver), which would prime those
caches with the TestableSettingsProvider again. When subsequent tests
tried to make settings changes, they would go into the
TestableSettingsProvider's mValues hashmap and wouldn't get applied.

Instead, create a separate unregister method that only clears the
Settings.ContentProviderHolder caches, and call that on teardown.

Bug: 339924248
Test: $ atest TestableSettingsProviderTest
Test: $ atest --no-group-test \
    InputTests:com.android.server.input.debug.TouchpadDebugViewTest \
    InputTests:com.android.server.input.debug.TouchpadDebugViewControllerTests \
    InputTests:com.android.test.input.AnrTest
Flag: TEST_ONLY
Change-Id: If42843a32609c84bcc21127703dab25d5bd3fc64
parent d14beb99
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -535,14 +535,14 @@ public class TestableContext extends ContextWrapper implements TestRule {
            @Override
            protected void succeeded(Description description) {
                if (mSettingsProvider != null) {
                    mSettingsProvider.clearValuesAndCheck(TestableContext.this);
                    mSettingsProvider.unregister();
                }
            }

            @Override
            protected void failed(Throwable e, Description description) {
                if (mSettingsProvider != null) {
                    mSettingsProvider.clearValuesAndCheck(TestableContext.this);
                    mSettingsProvider.unregister();
                }
            }
        }.apply(base, description);
+6 −0
Original line number Diff line number Diff line
@@ -70,6 +70,12 @@ public class TestableSettingsProvider extends MockContentProvider {
        mValues.clear();
    }

    void unregister() {
        Settings.Global.clearProviderForTest();
        Settings.Secure.clearProviderForTest();
        Settings.System.clearProviderForTest();
    }

    public Bundle call(String method, String arg, Bundle extras) {
        // Methods are "GET_system", "GET_global", "PUT_secure", etc.
        int userId = extras.getInt(Settings.CALL_METHOD_USER_KEY, UserHandle.USER_CURRENT);
+19 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package android.testing;
import static org.junit.Assert.*;

import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
@@ -37,9 +38,9 @@ public class TestableSettingsProviderTest {
    public static final String NONEXISTENT_SETTING = "nonexistent_setting";
    private static final String TAG = "TestableSettingsProviderTest";
    private ContentResolver mContentResolver;
    private final Context mRealContext = InstrumentationRegistry.getContext();
    @Rule
    public final TestableContext mContext =
            new TestableContext(InstrumentationRegistry.getContext());
    public final TestableContext mContext = new TestableContext(mRealContext);

    @Before
    public void setup() {
@@ -93,11 +94,25 @@ public class TestableSettingsProviderTest {
    }

    @Test
    public void testRelease() {
    public void testClearValues() {
        // Verify different value.
        assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
        mContext.getSettingsProvider().clearValuesAndCheck(mContext);
        // Verify actual value after release.
        // After clearing, the value should be fetched from the underlying real context.
        assertEquals("1", Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));
    }

    @Test
    public void testUnregister() {
        // With the TestableSettingsProvider still in use, we should see the overridden value of
        // DEVICE_PROVISIONED.
        assertNull(Global.getString(mContentResolver, Global.DEVICE_PROVISIONED));

        mContext.getSettingsProvider().unregister();

        // After unregistering, the real value should be returned when we use the real context, even
        // though the TestableSettingsProvider still exists with the overridden value.
        assertEquals("1",
                Global.getString(mRealContext.getContentResolver(), Global.DEVICE_PROVISIONED));
    }
}