Add a "broken test ART APEX" Soong module.
Introduce test APEX module `test_broken_com.android.art`, to be used
in a test exercising ART Mainline Module rollbacks. Instead of the
regular `libart` module, this test APEX includes a `libart-broken`
module, a "broken" version of `libart` which delibaretely crashes
during the creation of a new VM (in `JNI_CreateJavaVM`), thus
trigerring a rollback of this test APEX.
Test: m test_broken_com.android.art
Bug: 204887479
Change-Id: I5ab50dffcf517e05c7008a881cde89c6ae0a12ca
diff --git a/build/apex/Android.bp b/build/apex/Android.bp
index c2e08d5..864f4ca 100644
--- a/build/apex/Android.bp
+++ b/build/apex/Android.bp
@@ -51,7 +51,7 @@
// `art/Android.mk`.
// TODO(b/121117762): Remove this note when both the ART Buildbot and Golem use
// the ART APEX.
-art_runtime_base_native_shared_libs = [
+art_runtime_base_native_shared_libs_minus_libart = [
// External API (having APEX stubs).
"libdexfile",
"libnativebridge",
@@ -63,7 +63,6 @@
"libadbconnection",
// TODO(b/124476339): Clean up the following libraries once "required"
// dependencies work with APEX libraries.
- "libart",
"libart-compiler",
"libartservice",
"libdt_fd_forward",
@@ -76,6 +75,12 @@
// when such a target exists
"libarttools",
]
+// Actual version of ART runtime base libs, used in non-test ART APEXes.
+art_runtime_base_native_shared_libs = ["libart"] +
+ art_runtime_base_native_shared_libs_minus_libart
+// "Broken" version of ART runtime base libs, used for testing purposes.
+art_runtime_base_broken_native_shared_libs = ["libart-broken"] +
+ art_runtime_base_native_shared_libs_minus_libart
art_runtime_base_native_device_only_shared_libs = [
"libperfetto_hprof",
@@ -332,6 +337,28 @@
installable: false,
}
+// "Broken" test APEX, only used for testing, including module
+// `libart-broken` instead of `libart`.
+apex_test {
+ name: "test_broken_com.android.art",
+ defaults: ["com.android.art-defaults"],
+
+ // Only include native libraries in this test APEX. Don't include
+ // binaries (and maybe other artifacts) for now, as they pull
+ // the "non-broken" `libart` module into this test APEX and
+ // overwrite `libart-broken`. Maybe consider creating "broken"
+ // variants of binaries (and other artifacts)?
+ native_shared_libs: art_runtime_base_broken_native_shared_libs,
+ compile_multilib: "both",
+
+ key: "com.android.art.key",
+ manifest: "test_apex_manifest.json",
+ file_contexts: ":com.android.art-file_contexts",
+ certificate: ":com.android.art.certificate",
+ installable: false,
+ min_sdk_version: "31",
+}
+
// Release version of the ART APEX module (not containing debug
// variants nor tools), included in user builds. Also used for
// storage-constrained devices in userdebug and eng builds.
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 9e39632..f219cc0 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -584,8 +584,9 @@
// We always build dex2oat and dependencies, even if the host build is otherwise disabled, since
// they are used to cross compile for the target.
-art_cc_library {
- name: "libart",
+// Properties common to `libart` and `libart-broken`.
+art_cc_defaults {
+ name: "libart_common_defaults",
defaults: [
"libart_defaults",
"libart_nativeunwind_defaults",
@@ -612,12 +613,31 @@
},
},
},
+}
+
+// Release version of the ART runtime library.
+art_cc_library {
+ name: "libart",
+ defaults: ["libart_common_defaults"],
apex_available: [
"com.android.art",
"com.android.art.debug",
],
}
+// "Broken" version of the ART runtime library, used only for testing.
+art_cc_test_library {
+ name: "libart-broken",
+ defaults: ["libart_common_defaults"],
+ stem: "libart",
+ gtest: false,
+ cflags: ["-DART_CRASH_RUNTIME_DELIBERATELY"],
+ apex_available: [
+ "test_broken_com.android.art",
+ ],
+}
+
+// Debug version of the ART runtime library.
art_cc_library {
name: "libartd",
defaults: [
diff --git a/runtime/jni/java_vm_ext.cc b/runtime/jni/java_vm_ext.cc
index e6e341a..053afc9 100644
--- a/runtime/jni/java_vm_ext.cc
+++ b/runtime/jni/java_vm_ext.cc
@@ -1229,6 +1229,13 @@
return JNI_ERR;
}
+ // When `ART_CRASH_RUNTIME_DELIBERATELY` is defined (which happens only in the
+ // case of a test APEX), we crash the runtime here on purpose, to test the
+ // behavior of rollbacks following a failed ART Mainline Module update.
+#ifdef ART_CRASH_RUNTIME_DELIBERATELY
+ LOG(FATAL) << "Runtime crashing deliberately for testing purposes.";
+#endif
+
// Initialize native loader. This step makes sure we have
// everything set up before we start using JNI.
android::InitializeNativeLoader();