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

Commit 7355446c authored by Dennis Shen's avatar Dennis Shen Committed by Gerrit Code Review
Browse files

Merge "aconfig: add rust integration test for aconfig_storage_write_api" into main

parents ee18b355 1d9f0dd2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -77,6 +77,10 @@
      // aconfig_storage_read_api unit tests
      "name": "aconfig_storage_read_api.test"
    },
    {
      // aconfig_storage write api rust integration tests
      "name": "aconfig_storage_write_api.test.rust"
    },
    {
      // aconfig_storage read api rust integration tests
      "name": "aconfig_storage_read_api.test.rust"
+19 −0
Original line number Diff line number Diff line

rust_test {
    name: "aconfig_storage_write_api.test.rust",
    srcs: [
        "storage_write_api_test.rs"
    ],
    rustlibs: [
        "libanyhow",
        "libaconfig_storage_file",
        "libaconfig_storage_read_api",
        "libaconfig_storage_write_api",
        "libprotobuf",
        "libtempfile",
    ],
    data: [
        "flag.val",
    ],
    test_suites: ["general-tests"],
}
+73 −0
Original line number Diff line number Diff line
#[cfg(not(feature = "cargo"))]
mod aconfig_storage_write_api_test {
    use aconfig_storage_file::protos::ProtoStorageFiles;
    use aconfig_storage_read_api::flag_value_query::find_boolean_flag_value;
    use aconfig_storage_write_api::{mapped_file::get_mapped_file, set_boolean_flag_value};

    use protobuf::Message;
    use std::fs::{self, File};
    use std::io::{Read, Write};
    use tempfile::NamedTempFile;

    /// Write storage location record pb to a temp file
    fn write_storage_record_file(flag_val: &str) -> NamedTempFile {
        let text_proto = format!(
            r#"
files {{
    version: 0
    container: "system"
    package_map: "some_package_map"
    flag_map: "some_flag_map"
    flag_val: "{}"
    timestamp: 12345
}}
"#,
            flag_val
        );
        let storage_files: ProtoStorageFiles =
            protobuf::text_format::parse_from_str(&text_proto).unwrap();
        let mut binary_proto_bytes = Vec::new();
        storage_files.write_to_vec(&mut binary_proto_bytes).unwrap();
        let mut file = NamedTempFile::new().unwrap();
        file.write_all(&binary_proto_bytes).unwrap();
        file
    }

    /// Create temp file copy
    fn copy_to_temp_rw_file(source_file: &str) -> NamedTempFile {
        let file = NamedTempFile::new().unwrap();
        fs::copy(source_file, file.path()).unwrap();
        file
    }

    /// Get boolean flag value from offset
    fn get_boolean_flag_value_at_offset(file: &str, offset: u32) -> bool {
        let mut f = File::open(file).unwrap();
        let mut bytes = Vec::new();
        f.read_to_end(&mut bytes).unwrap();
        find_boolean_flag_value(&bytes, offset).unwrap()
    }

    #[test]
    /// Test to lock down flag value update api
    fn test_boolean_flag_value_update() {
        let flag_value_file = copy_to_temp_rw_file("./flag.val");
        let flag_value_path = flag_value_file.path().display().to_string();
        let record_pb_file = write_storage_record_file(&flag_value_path);
        let record_pb_path = record_pb_file.path().display().to_string();

        // SAFETY:
        // The safety here is ensured as only this single threaded test process will
        // write to this file
        let mut file = unsafe { get_mapped_file(&record_pb_path, "system").unwrap() };
        for i in 0..8 {
            set_boolean_flag_value(&mut file, i, true).unwrap();
            let value = get_boolean_flag_value_at_offset(&flag_value_path, i);
            assert!(value);

            set_boolean_flag_value(&mut file, i, false).unwrap();
            let value = get_boolean_flag_value_at_offset(&flag_value_path, i);
            assert!(!value);
        }
    }
}