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

Commit 4f6f1284 authored by Dennis Shen's avatar Dennis Shen
Browse files

aosp: reenable the filtered out test point in atest

A more systematic fix. Now for each test point, we create temp file
copies at temp dir and explicitly set the file permission of these temp
files. This should bypass the issue that test build artifact file
permission are not guaranteed. Because we will generate these test
storage files on the fly at run time.

Bug: b/324459233
Test: atest aconfig_storage_file.test
Change-Id: Iaa7083be6cc49421090ab4c74e54c4bcf8e35801
parent 0b0f11fe
Loading
Loading
Loading
Loading
+3 −27
Original line number Diff line number Diff line
@@ -47,38 +47,14 @@ genrule {
    cmd: "rm -f $(out);cp -f $(in) $(out);chmod -w $(out)",
}

genrule {
    name: "rw.package.map",
    out: ["tests/tmp.rw.package.map"],
    srcs: ["tests/package.map"],
    cmd: "rm -f $(out);cp -f $(in) $(out);chmod +w $(out)",
}

genrule {
    name: "rw.flag.map",
    out: ["tests/tmp.rw.flag.map"],
    srcs: ["tests/flag.map"],
    cmd: "rm -f $(out);cp -f $(in) $(out);chmod +w $(out)",
}

genrule {
    name: "rw.flag.val",
    out: ["tests/tmp.rw.flag.val"],
    srcs: ["tests/flag.val"],
    cmd: "rm -f $(out);cp -f $(in) $(out);chmod +w $(out)",
}

rust_test_host {
    name: "aconfig_storage_file.test",
    test_suites: ["general-tests"],
    defaults: ["aconfig_storage_file.defaults"],
    data: [
        ":ro.package.map",
        ":ro.flag.map",
        ":ro.flag.val",
        ":rw.package.map",
        ":rw.flag.map",
        ":rw.flag.val",
        "tests/package.map",
        "tests/flag.map",
        "tests/flag.val",
    ],
}

+50 −46
Original line number Diff line number Diff line
@@ -259,32 +259,38 @@ pub fn get_boolean_flag_value(container: &str, offset: u32) -> Result<bool, Acon
#[cfg(test)]
mod tests {
    use super::*;
    use crate::test_utils::{
        create_temp_storage_files_for_test, get_binary_storage_proto_bytes,
        set_temp_storage_files_to_read_only, write_bytes_to_temp_file,
    };
    use crate::test_utils::{write_storage_text_to_temp_file, TestStorageFileSet};

    fn create_test_storage_files(read_only: bool) -> TestStorageFileSet {
        TestStorageFileSet::new(
            "./tests/package.map",
            "./tests/flag.map",
            "./tests/flag.val",
            read_only,
        )
        .unwrap()
    }

    #[test]
    // this test point locks down flag package offset query
    fn test_package_offset_query() {
        #[cfg(feature = "cargo")]
        create_temp_storage_files_for_test();

        set_temp_storage_files_to_read_only();
        let text_proto = r#"
files {
        let ro_files = create_test_storage_files(true);
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "./tests/tmp.ro.package.map"
    flag_map: "./tests/tmp.ro.flag.map"
    flag_val: "./tests/tmp.ro.flag.val"
    package_map: "{}"
    flag_map: "{}"
    flag_val: "{}"
    timestamp: 12345
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file_full_path = file.path().display().to_string();
}}
"#,
            ro_files.package_map.name, ro_files.flag_map.name, ro_files.flag_val.name
        );

        let file = write_storage_text_to_temp_file(&text_proto).unwrap();
        let file_full_path = file.path().display().to_string();
        let package_offset = get_package_offset_impl(
            &file_full_path,
            "system",
@@ -319,24 +325,23 @@ files {
    #[test]
    // this test point locks down flag offset query
    fn test_flag_offset_query() {
        #[cfg(feature = "cargo")]
        create_temp_storage_files_for_test();

        set_temp_storage_files_to_read_only();
        let text_proto = r#"
files {
        let ro_files = create_test_storage_files(true);
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "./tests/tmp.ro.package.map"
    flag_map: "./tests/tmp.ro.flag.map"
    flag_val: "./tests/tmp.ro.flag.val"
    package_map: "{}"
    flag_map: "{}"
    flag_val: "{}"
    timestamp: 12345
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file_full_path = file.path().display().to_string();
}}
"#,
            ro_files.package_map.name, ro_files.flag_map.name, ro_files.flag_val.name
        );

        let file = write_storage_text_to_temp_file(&text_proto).unwrap();
        let file_full_path = file.path().display().to_string();
        let baseline = vec![
            (0, "enabled_ro", 1u16),
            (0, "enabled_rw", 2u16),
@@ -359,24 +364,23 @@ files {
    #[test]
    // this test point locks down flag offset query
    fn test_flag_value_query() {
        #[cfg(feature = "cargo")]
        create_temp_storage_files_for_test();

        set_temp_storage_files_to_read_only();
        let text_proto = r#"
files {
        let ro_files = create_test_storage_files(true);
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "./tests/tmp.ro.package.map"
    flag_map: "./tests/tmp.ro.flag.map"
    flag_val: "./tests/tmp.ro.flag.val"
    package_map: "{}"
    flag_map: "{}"
    flag_val: "{}"
    timestamp: 12345
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file_full_path = file.path().display().to_string();
}}
"#,
            ro_files.package_map.name, ro_files.flag_map.name, ro_files.flag_val.name
        );

        let file = write_storage_text_to_temp_file(&text_proto).unwrap();
        let file_full_path = file.path().display().to_string();
        let baseline: Vec<bool> = vec![false; 8];
        for (offset, expected_value) in baseline.into_iter().enumerate() {
            let flag_value =
+78 −62
Original line number Diff line number Diff line
@@ -148,10 +148,7 @@ pub(crate) fn get_mapped_file(
#[cfg(test)]
mod tests {
    use super::*;
    use crate::test_utils::{
        create_temp_storage_files_for_test, get_binary_storage_proto_bytes,
        set_temp_storage_files_to_read_only, write_bytes_to_temp_file,
    };
    use crate::test_utils::{write_storage_text_to_temp_file, TestStorageFileSet};

    #[test]
    fn test_find_storage_file_location() {
@@ -173,10 +170,8 @@ files {
    timestamp: 54321
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file = write_storage_text_to_temp_file(text_proto).unwrap();
        let file_full_path = file.path().display().to_string();

        let file_info = find_container_storage_location(&file_full_path, "system").unwrap();
        assert_eq!(file_info.version(), 0);
        assert_eq!(file_info.container(), "system");
@@ -213,100 +208,121 @@ files {
        assert_eq!(mmaped_file[..], content[..]);
    }

    fn create_test_storage_files(read_only: bool) -> TestStorageFileSet {
        TestStorageFileSet::new(
            "./tests/package.map",
            "./tests/flag.map",
            "./tests/flag.val",
            read_only,
        )
        .unwrap()
    }

    #[test]
    fn test_mapped_file_contents() {
        #[cfg(feature = "cargo")]
        create_temp_storage_files_for_test();

        set_temp_storage_files_to_read_only();
        let text_proto = r#"
files {
        let ro_files = create_test_storage_files(true);
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "./tests/tmp.ro.package.map"
    flag_map: "./tests/tmp.ro.flag.map"
    flag_val: "./tests/tmp.ro.flag.val"
    package_map: "{}"
    flag_map: "{}"
    flag_val: "{}"
    timestamp: 12345
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file_full_path = file.path().display().to_string();
}}
"#,
            ro_files.package_map.name, ro_files.flag_map.name, ro_files.flag_val.name
        );

        let file = write_storage_text_to_temp_file(&text_proto).unwrap();
        let file_full_path = file.path().display().to_string();
        map_and_verify(
            &file_full_path,
            StorageFileSelection::PackageMap,
            "./tests/tmp.ro.package.map",
            &ro_files.package_map.name,
        );
        map_and_verify(&file_full_path, StorageFileSelection::FlagMap, "./tests/tmp.ro.flag.map");
        map_and_verify(&file_full_path, StorageFileSelection::FlagVal, "./tests/tmp.ro.flag.val");
        map_and_verify(&file_full_path, StorageFileSelection::FlagMap, &ro_files.flag_map.name);
        map_and_verify(&file_full_path, StorageFileSelection::FlagVal, &ro_files.flag_val.name);
    }

    #[test]
    #[cfg(feature = "cargo")]
    fn test_map_non_read_only_file() {
        #[cfg(feature = "cargo")]
        create_temp_storage_files_for_test();

        set_temp_storage_files_to_read_only();
        let text_proto = r#"
files {
        let ro_files = create_test_storage_files(true);
        let rw_files = create_test_storage_files(false);
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "./tests/tmp.rw.package.map"
    flag_map: "./tests/tmp.rw.flag.map"
    flag_val: "./tests/tmp.rw.flag.val"
    package_map: "{}"
    flag_map: "{}"
    flag_val: "{}"
    timestamp: 12345
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file_full_path = file.path().display().to_string();
}}
"#,
            rw_files.package_map.name, ro_files.flag_map.name, ro_files.flag_val.name
        );

        let file = write_storage_text_to_temp_file(&text_proto).unwrap();
        let file_full_path = file.path().display().to_string();
        let error = map_container_storage_files(&file_full_path, "system").unwrap_err();
        assert_eq!(
            format!("{:?}", error),
            "MapFileFail(fail to map non read only storage file ./tests/tmp.rw.package.map)"
            format!(
                "MapFileFail(fail to map non read only storage file {})",
                rw_files.package_map.name
            )
        );

        let text_proto = r#"
files {
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "./tests/tmp.ro.package.map"
    flag_map: "./tests/tmp.rw.flag.map"
    flag_val: "./tests/tmp.rw.flag.val"
    package_map: "{}"
    flag_map: "{}"
    flag_val: "{}"
    timestamp: 12345
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file_full_path = file.path().display().to_string();
}}
"#,
            ro_files.package_map.name, rw_files.flag_map.name, ro_files.flag_val.name
        );

        let file = write_storage_text_to_temp_file(&text_proto).unwrap();
        let file_full_path = file.path().display().to_string();
        let error = map_container_storage_files(&file_full_path, "system").unwrap_err();
        assert_eq!(
            format!("{:?}", error),
            "MapFileFail(fail to map non read only storage file ./tests/tmp.rw.flag.map)"
            format!(
                "MapFileFail(fail to map non read only storage file {})",
                rw_files.flag_map.name
            )
        );

        let text_proto = r#"
files {
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "./tests/tmp.ro.package.map"
    flag_map: "./tests/tmp.ro.flag.map"
    flag_val: "./tests/tmp.rw.flag.val"
    package_map: "{}"
    flag_map: "{}"
    flag_val: "{}"
    timestamp: 12345
}
"#;
        let binary_proto_bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
        let file = write_bytes_to_temp_file(&binary_proto_bytes).unwrap();
        let file_full_path = file.path().display().to_string();
}}
"#,
            ro_files.package_map.name, ro_files.flag_map.name, rw_files.flag_val.name
        );

        let file = write_storage_text_to_temp_file(&text_proto).unwrap();
        let file_full_path = file.path().display().to_string();
        let error = map_container_storage_files(&file_full_path, "system").unwrap_err();
        assert_eq!(
            format!("{:?}", error),
            "MapFileFail(fail to map non read only storage file ./tests/tmp.rw.flag.val)"
            format!(
                "MapFileFail(fail to map non read only storage file {})",
                rw_files.flag_val.name
            )
        );
    }
}
+48 −46
Original line number Diff line number Diff line
@@ -19,12 +19,8 @@ use anyhow::Result;
use protobuf::Message;
use std::fs;
use std::io::Write;
use std::path::Path;
use std::sync::Once;
use tempfile::NamedTempFile;

static INIT: Once = Once::new();

pub(crate) fn get_binary_storage_proto_bytes(text_proto: &str) -> Result<Vec<u8>> {
    let storage_files: ProtoStorageFiles = protobuf::text_format::parse_from_str(text_proto)?;
    let mut binary_proto = Vec::new();
@@ -32,59 +28,65 @@ pub(crate) fn get_binary_storage_proto_bytes(text_proto: &str) -> Result<Vec<u8>
    Ok(binary_proto)
}

pub(crate) fn write_bytes_to_temp_file(bytes: &[u8]) -> Result<NamedTempFile> {
pub(crate) fn write_storage_text_to_temp_file(text_proto: &str) -> Result<NamedTempFile> {
    let bytes = get_binary_storage_proto_bytes(text_proto).unwrap();
    let mut file = NamedTempFile::new()?;
    let _ = file.write_all(&bytes);
    Ok(file)
}

fn has_same_content(file1: &Path, file2: &Path) -> Result<bool> {
    let bytes1 = fs::read(file1)?;
    let bytes2 = fs::read(file2)?;
    if bytes1.len() != bytes2.len() {
        return Ok(false);
fn set_file_read_only(file: &NamedTempFile) {
    let mut perms = fs::metadata(file.path()).unwrap().permissions();
    if !perms.readonly() {
        perms.set_readonly(true);
        fs::set_permissions(file.path(), perms).unwrap();
    }
    for (i, &b1) in bytes1.iter().enumerate() {
        if b1 != bytes2[i] {
            return Ok(false);
}

fn set_file_read_write(file: &NamedTempFile) {
    let mut perms = fs::metadata(file.path()).unwrap().permissions();
    if perms.readonly() {
        perms.set_readonly(false);
        fs::set_permissions(file.path(), perms).unwrap();
    }
    Ok(true)
}

pub(crate) fn create_temp_storage_files_for_test() {
    INIT.call_once(|| {
        let file_paths = [
            ("./tests/package.map", "./tests/tmp.ro.package.map"),
            ("./tests/flag.map", "./tests/tmp.ro.flag.map"),
            ("./tests/flag.val", "./tests/tmp.ro.flag.val"),
            ("./tests/package.map", "./tests/tmp.rw.package.map"),
            ("./tests/flag.map", "./tests/tmp.rw.flag.map"),
            ("./tests/flag.val", "./tests/tmp.rw.flag.val"),
        ];
        for (file_path, copied_file_path) in file_paths.into_iter() {
            let file_path = Path::new(&file_path);
            let copied_file_path = Path::new(&copied_file_path);
            if copied_file_path.exists() && !has_same_content(file_path, copied_file_path).unwrap()
            {
                fs::remove_file(copied_file_path).unwrap();
pub(crate) struct TestStorageFile {
    pub file: NamedTempFile,
    pub name: String,
}
            if !copied_file_path.exists() {
                fs::copy(file_path, copied_file_path).unwrap();

impl TestStorageFile {
    pub(crate) fn new(source_file: &str, read_only: bool) -> Result<Self> {
        let file = NamedTempFile::new()?;
        fs::copy(source_file, file.path())?;
        if read_only {
            set_file_read_only(&file);
        } else {
            set_file_read_write(&file);
        }
        let name = file.path().display().to_string();
        Ok(Self { file, name })
    }
    });
}

pub(crate) fn set_temp_storage_files_to_read_only() {
    let file_paths =
        ["./tests/tmp.ro.package.map", "./tests/tmp.ro.flag.map", "./tests/tmp.ro.flag.val"];
    for file_path in file_paths.into_iter() {
        let file_path = Path::new(&file_path);
        let mut perms = fs::metadata(file_path).unwrap().permissions();
        if !perms.readonly() {
            perms.set_readonly(true);
            fs::set_permissions(file_path, perms).unwrap();
pub(crate) struct TestStorageFileSet {
    pub package_map: TestStorageFile,
    pub flag_map: TestStorageFile,
    pub flag_val: TestStorageFile,
}

impl TestStorageFileSet {
    pub(crate) fn new(
        package_map_path: &str,
        flag_map_path: &str,
        flag_val_path: &str,
        read_only: bool,
    ) -> Result<Self> {
        Ok(Self {
            package_map: TestStorageFile::new(package_map_path, read_only)?,
            flag_map: TestStorageFile::new(flag_map_path, read_only)?,
            flag_val: TestStorageFile::new(flag_val_path, read_only)?,
        })
    }
}