diff options
author | Anton Hansson <hansson@google.com> | 2020-05-28 17:24:29 +0100 |
---|---|---|
committer | Anton Hansson <hansson@google.com> | 2020-06-04 16:19:30 +0100 |
commit | 023c507f4db94440fe004fed43443ab6c831e2d8 (patch) | |
tree | 69a44864b7e76269437252c4f39f79c24cca91c3 | |
parent | 0a45a9c2123a0205d34d62ee98324d9914b080f8 (diff) | |
download | platform_system_apex-023c507f4db94440fe004fed43443ab6c831e2d8.tar.gz platform_system_apex-023c507f4db94440fe004fed43443ab6c831e2d8.tar.bz2 platform_system_apex-023c507f4db94440fe004fed43443ab6c831e2d8.zip |
Add more tests for api updatability
- Add new APIs to the test sdkextensions module, and add a test app
that tries calling the new APIs
- Add sdkinfo to the test media apex as well as sdkext, and verify
the version gets bumped as expected
Bug: 149815613
Test: atest sdkextensions_e2e_test
Change-Id: I522d38d0a922fd4f5cb244ba9d61bdfd3bd3cacf
5 files changed, 241 insertions, 21 deletions
diff --git a/tests/sdkextensions/Android.bp b/tests/sdkextensions/Android.bp index 081233ce..e156d6b2 100644 --- a/tests/sdkextensions/Android.bp +++ b/tests/sdkextensions/Android.bp @@ -18,8 +18,17 @@ java_test_host { libs: ["tradefed"], static_libs: ["apex_e2e_base_test"], data: [ + ":sdkextensions_e2e_test_app", + ":test_com.android.media", ":test_com.android.sdkext", ], test_config: "sdkextensions-e2e-tests.xml", test_suites: ["device-tests"], } + +android_app { + name: "sdkextensions_e2e_test_app", + srcs: ["app-src/**/*.java"], + libs: ["test_framework-sdkextensions-stubs"], + sdk_version: "system_current", +} diff --git a/tests/sdkextensions/AndroidManifest.xml b/tests/sdkextensions/AndroidManifest.xml new file mode 100644 index 00000000..0e4f8d14 --- /dev/null +++ b/tests/sdkextensions/AndroidManifest.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.apex.sdkextensions" + android:versionName="1" + android:versionCode="1"> + <uses-sdk android:minSdkVersion="30" android:targetSdkVersion="30" /> + + <application android:label="SDK Extensions verifier"> + <receiver android:name=".Receiver"> + <intent-filter> + <action android:name="com.android.tests.apex.sdkextensions.MAKE_CALLS_0" /> + </intent-filter> + <intent-filter> + <action android:name="com.android.tests.apex.sdkextensions.MAKE_CALLS_45" /> + </intent-filter> + <intent-filter> + <action android:name="com.android.tests.apex.sdkextensions.GET_SDK_VERSION" /> + </intent-filter> + </receiver> + + </application> +</manifest> diff --git a/tests/sdkextensions/app-src/com/android/tests/apex/sdkextensions/Receiver.java b/tests/sdkextensions/app-src/com/android/tests/apex/sdkextensions/Receiver.java new file mode 100644 index 00000000..0332c1ea --- /dev/null +++ b/tests/sdkextensions/app-src/com/android/tests/apex/sdkextensions/Receiver.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 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.tests.apex.sdkextensions; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.ext.SdkExtensions; +import android.os.ext.test.Test; +import android.util.Log; + +public class Receiver extends BroadcastReceiver { + + private static final String ACTION_GET_SDK_VERSION = + "com.android.tests.apex.sdkextensions.GET_SDK_VERSION"; + private static final String ACTION_MAKE_CALLS_0 = + "com.android.tests.apex.sdkextensions.MAKE_CALLS_0"; + private static final String ACTION_MAKE_CALLS_45 = + "com.android.tests.apex.sdkextensions.MAKE_CALLS_45"; + + @Override + public void onReceive(Context context, Intent intent) { + try { + switch (intent.getAction()) { + case ACTION_GET_SDK_VERSION: + int sdkVersion = SdkExtensions.getExtensionVersion(Build.VERSION_CODES.R); + setResultData(String.valueOf(sdkVersion)); + break; + case ACTION_MAKE_CALLS_0: + makeCallsVersion0(); + setResultData("true"); + break; + case ACTION_MAKE_CALLS_45: + makeCallsVersion45(); + setResultData("true"); + break; + } + } catch (Throwable e) { + Log.e("SdkExtensionsE2E", "Unexpected error/exception", e); + setResultData("Unexpected error or exception in test app, see log for details"); + } + } + + private static void makeCallsVersion0() { + try { + Test test = new Test(); + throw new IllegalStateException("Instantiated test class, but shouldn't be able to"); + } catch (NoClassDefFoundError t) { + // Expected + } + } + + private static void makeCallsVersion45() { + Test test = new Test(); + test.publicMethod(); + test.systemApiMethod(); + try { + test.moduleLibsApiMethod(); + throw new IllegalStateException("Called module-libs method, but shouldn't be able to"); + } catch (NoSuchMethodError t) { + // Expected + } + try { + test.testApiMethod(); + throw new IllegalStateException("Called testapi method, but shouldn't be able to"); + } catch (NoSuchMethodError t) { + // Expected + } + try { + test.hiddenMethod(); + throw new IllegalStateException("Called hidden method, but shouldn't be able to"); + } catch (NoSuchMethodError t) { + // Expected + } + } +} diff --git a/tests/sdkextensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java b/tests/sdkextensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java index f576367d..3ee89133 100644 --- a/tests/sdkextensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java +++ b/tests/sdkextensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java @@ -17,48 +17,118 @@ package com.android.tests.apex.sdkextensions; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.android.tests.apex.ApexE2EBaseHostTest; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.IManagedTestDevice; -import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.util.CommandResult; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.io.IOException; +import java.io.File; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -/** - * Test to check if Apex can be staged, activated and uninstalled successfully. - */ @RunWith(DeviceJUnit4ClassRunner.class) public class SdkExtensionsHostTest extends ApexE2EBaseHostTest { + private static final String APP_FILENAME = "sdkextensions_e2e_test_app.apk"; + private static final String APP_PACKAGE = "com.android.tests.apex.sdkextensions"; + private static final String MEDIA_FILENAME = "test_com.android.media.apex"; + private static final String SDKEXTENSIONS_FILENAME = "test_com.android.sdkext.apex"; + + @Before + public void installTestApp() throws Exception { + File testAppFile = mUtils.getTestFile(APP_FILENAME); + String installResult = getDevice().installPackage(testAppFile, true); + assertNull(installResult); + } + + @After + public void uninstallTestApp() throws Exception { + String uninstallResult = getDevice().uninstallPackage(APP_PACKAGE); + assertNull(uninstallResult); + } + + @Override + protected List<String> getAllApexFilenames() { + return List.of(SDKEXTENSIONS_FILENAME, MEDIA_FILENAME); + } + @Test public void testDefault() throws Exception { - CLog.i("Verifying default version"); - assertEquals(0, getExtensionVersionR()); + assertVersion0(); + } + + @Test + public void upgradeOneApex() throws Exception { + // On the system image, sdkextensions is the only apex with sdkinfo, and it's version 0. + // This test verifies that installing media with sdk version 45 doesn't bump the version. + assertVersion0(); + installApex(MEDIA_FILENAME); + reboot(false); + assertVersion0(); + } + + @Test + public void upgradeTwoApexes() throws Exception { + // On the system image, sdkextensions is the only apex with sdkinfo, and it's version 0. + // This test verifies that installing media with sdk version 45 *and* a new sdkext does bump + // the version. + assertVersion0(); + installApexes(MEDIA_FILENAME, SDKEXTENSIONS_FILENAME); + reboot(false); + assertVersion45(); } @Override - public void additionalCheck() throws DeviceNotAvailableException, IOException { - CLog.i("Reading version"); - int version = getExtensionVersionR(); - assertEquals(45, version); + public void additionalCheck() throws Exception { + // This method is run after the default test in the base class, which just installs sdkext. + assertVersion45(); + } + + private int getExtensionVersionR() throws Exception { + int appValue = Integer.parseInt(broadcast("GET_SDK_VERSION")); + int syspropValue = getExtensionVersionRFromSysprop(); + assertEquals(appValue, syspropValue); + return appValue; + } - CLog.i("Waiting for boot complete"); - assertTrue(((IManagedTestDevice) getDevice()).getMonitor().waitForBootComplete(60000)); + private int getExtensionVersionRFromSysprop() throws Exception { + CommandResult res = getDevice().executeShellV2Command("getprop build.version.extensions.r"); + assertEquals(0, (int) res.getExitCode()); + String syspropString = res.getStdout().replace("\n", ""); + return Integer.parseInt(syspropString); } - private int getExtensionVersionR() throws DeviceNotAvailableException, IOException { - CommandResult commandResult = - getDevice().executeShellV2Command("getprop build.version.extensions.r"); - assertEquals(0, (int) commandResult.getExitCode()); + private String broadcast(String action) throws Exception { + String command = getBroadcastCommand(action); + CommandResult res = getDevice().executeShellV2Command(command); + assertEquals(0, (int) res.getExitCode()); + Matcher matcher = Pattern.compile("data=\"([^\"]+)\"").matcher(res.getStdout()); + assertTrue("Unexpected output from am broadcast: " + res.getStdout(), matcher.find()); + return matcher.group(1); + } + + private void assertVersion0() throws Exception { + assertEquals(0, getExtensionVersionR()); + assertEquals("true", broadcast("MAKE_CALLS_0")); + } + + private void assertVersion45() throws Exception { + assertEquals(45, getExtensionVersionR()); + assertEquals("true", broadcast("MAKE_CALLS_45")); + } - String outputString = commandResult.getStdout().replace("\n", ""); - return Integer.parseInt(outputString); + private static String getBroadcastCommand(String action) { + String cmd = "am broadcast"; + cmd += " -a com.android.tests.apex.sdkextensions." + action; + cmd += " -n com.android.tests.apex.sdkextensions/.Receiver"; + return cmd; } } diff --git a/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java b/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java index 04b51342..0812c6ac 100644 --- a/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java +++ b/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java @@ -122,6 +122,18 @@ public abstract class ApexE2EBaseHostTest extends BaseHostJUnit4Test { return testApexInfo; } + protected final void installApexes(String... filenames) throws Exception { + // We don't use the installApex method from the super class here, because that won't install + // the two apexes into the same session. + String[] args = new String[filenames.length + 1]; + args[0] = "install-multi-package"; + for (int i = 0; i < filenames.length; i++) { + args[i + 1] = mUtils.getTestFile(filenames[i]).getAbsolutePath(); + } + String stdout = getDevice().executeAdbCommand(args); + assertThat(stdout).isNotNull(); + } + protected final void reboot(boolean userspaceReboot) throws Exception { if (userspaceReboot) { assertThat(getDevice().setProperty("test.userspace_reboot.requested", "1")).isTrue(); |