Check API version levels for backcompat tests
Check that vendor API level is set and that the board API level >=
202504 when running backcompat tests to check for Secretkeeper nodes.
If those 2 conditions are not met, Secretkeeper is assumed not supported
and we skip over the nodes related to Secretkeeper.
Bug: 394770084
Test: TH
Change-Id: I4846e1f3252615b4829f754c256696bb13903389
diff --git a/tests/backcompat_test/Android.bp b/tests/backcompat_test/Android.bp
index aa1e089..d47487a 100644
--- a/tests/backcompat_test/Android.bp
+++ b/tests/backcompat_test/Android.bp
@@ -14,6 +14,7 @@
"libanyhow",
"liblibc",
"libnix",
+ "librustutils",
"libvmclient",
"liblog_rust",
],
diff --git a/tests/backcompat_test/src/main.rs b/tests/backcompat_test/src/main.rs
index b92049d..eaf3365 100644
--- a/tests/backcompat_test/src/main.rs
+++ b/tests/backcompat_test/src/main.rs
@@ -25,6 +25,7 @@
use anyhow::anyhow;
use anyhow::Context;
use anyhow::Error;
+use anyhow::Result;
use log::info;
use std::fs::read_to_string;
use std::fs::File;
@@ -46,11 +47,11 @@
/// Runs a protected VM and validates it against a golden device tree.
#[test]
-fn test_device_tree_protected_compat() -> Result<(), Error> {
+fn test_device_tree_protected_compat() -> Result<()> {
run_test(true, GOLDEN_DEVICE_TREE_PROTECTED)
}
-fn run_test(protected: bool, golden_dt: &str) -> Result<(), Error> {
+fn run_test(protected: bool, golden_dt: &str) -> Result<()> {
let kernel = Some(open_payload(VMBASE_EXAMPLE_KERNEL_PATH)?);
android_logger::init_once(
android_logger::Config::default()
@@ -142,7 +143,8 @@
{
return Err(anyhow!("failed to execute dtc"));
}
- let dtcompare_res = Command::new("./dtcompare")
+ let mut dtcompare_cmd = Command::new("./dtcompare");
+ dtcompare_cmd
.arg("--dt1")
.arg("dump_dt_golden.dtb")
.arg("--dt2")
@@ -162,12 +164,23 @@
.arg("/chosen/linux,initrd-start")
.arg("--ignore-path-value")
.arg("/chosen/linux,initrd-end")
- .arg("--ignore-path-value")
- .arg("/avf/secretkeeper_public_key")
.arg("--ignore-path")
- .arg("/avf/name")
- .output()
- .context("failed to execute dtcompare")?;
+ .arg("/avf/name");
+ // Check if Secretkeeper is advertised. If not, check the vendor API level. Secretkeeper is
+ // required as of 202504, and if missing, the test should fail.
+ // Otherwise, ignore the fields, as they are not required.
+ if service.isUpdatableVmSupported()? {
+ dtcompare_cmd.arg("--ignore-path-value").arg("/avf/secretkeeper_public_key");
+ } else if vsr_api_level()? >= 202504 {
+ return Err(anyhow!("Secretkeeper support missing on vendor API >= 202504. Secretkeeper needs to be implemented."));
+ } else {
+ dtcompare_cmd
+ .arg("--ignore-path")
+ .arg("/avf/secretkeeper_public_key")
+ .arg("--ignore-path")
+ .arg("/avf/untrusted/defer-rollback-protection");
+ }
+ let dtcompare_res = dtcompare_cmd.output().context("failed to execute dtcompare")?;
if !dtcompare_res.status.success() {
if !Command::new("./dtc_static")
.arg("-I")
@@ -202,7 +215,17 @@
Ok(())
}
-fn open_payload(path: &str) -> Result<ParcelFileDescriptor, Error> {
+fn open_payload(path: &str) -> Result<ParcelFileDescriptor> {
let file = File::open(path).with_context(|| format!("Failed to open VM image {path}"))?;
Ok(ParcelFileDescriptor::new(file))
}
+
+fn vsr_api_level() -> Result<i32> {
+ get_sysprop_i32("ro.vendor.api_level")
+}
+
+fn get_sysprop_i32(prop: &str) -> Result<i32> {
+ let res = rustutils::system_properties::read(prop)?;
+ res.map(|val| val.parse::<i32>().with_context(|| format!("Failed to read {prop}")))
+ .unwrap_or(Ok(-1))
+}