aconfig: add flag info read rust api
Bug: b/321077378 Test: atest aconfig_storage_read_api.test; atest aconfig_storage_read_api.test.rust Change-Id: I382ac0145c5d91827952b3ddb01cabefd1539854
This commit is contained in:
parent
eff5363e2d
commit
2ac7a4c2bd
10 changed files with 219 additions and 45 deletions
|
@ -91,9 +91,9 @@ impl FlagInfoHeader {
|
|||
/// bit field for flag info
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum FlagInfoBit {
|
||||
IsSticky = 0,
|
||||
IsReadWrite = 1,
|
||||
HasOverride = 2,
|
||||
IsSticky = 1 << 0,
|
||||
IsReadWrite = 1 << 1,
|
||||
HasOverride = 1 << 2,
|
||||
}
|
||||
|
||||
/// Flag info node struct
|
||||
|
@ -108,9 +108,9 @@ impl fmt::Debug for FlagInfoNode {
|
|||
writeln!(
|
||||
f,
|
||||
"sticky: {}, readwrite: {}, override: {}",
|
||||
self.attributes & (FlagInfoBit::IsSticky as u8),
|
||||
self.attributes & (FlagInfoBit::IsReadWrite as u8),
|
||||
self.attributes & (FlagInfoBit::HasOverride as u8),
|
||||
self.attributes & (FlagInfoBit::IsSticky as u8) != 0,
|
||||
self.attributes & (FlagInfoBit::IsReadWrite as u8) != 0,
|
||||
self.attributes & (FlagInfoBit::HasOverride as u8) != 0,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ use std::fs::File;
|
|||
use std::hash::{Hash, Hasher};
|
||||
use std::io::Read;
|
||||
|
||||
pub use crate::flag_info::{FlagInfoHeader, FlagInfoList, FlagInfoNode};
|
||||
pub use crate::flag_info::{FlagInfoHeader, FlagInfoList, FlagInfoNode, FlagInfoBit};
|
||||
pub use crate::flag_table::{FlagTable, FlagTableHeader, FlagTableNode};
|
||||
pub use crate::flag_value::{FlagValueHeader, FlagValueList};
|
||||
pub use crate::package_table::{PackageTable, PackageTableHeader, PackageTableNode};
|
||||
|
|
|
@ -38,6 +38,7 @@ rust_test_host {
|
|||
"tests/package.map",
|
||||
"tests/flag.map",
|
||||
"tests/flag.val",
|
||||
"tests/flag.info",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
115
tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs
Normal file
115
tools/aconfig/aconfig_storage_read_api/src/flag_info_query.rs
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2024 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.
|
||||
*/
|
||||
|
||||
//! flag value query module defines the flag value file read from mapped bytes
|
||||
|
||||
use crate::{AconfigStorageError, FILE_VERSION};
|
||||
use aconfig_storage_file::{flag_info::FlagInfoHeader, read_u8_from_bytes};
|
||||
use anyhow::anyhow;
|
||||
|
||||
/// Get flag attribute bitfield
|
||||
pub fn find_boolean_flag_attribute(
|
||||
buf: &[u8],
|
||||
flag_offset: u32,
|
||||
) -> Result<u8, AconfigStorageError> {
|
||||
let interpreted_header = FlagInfoHeader::from_bytes(buf)?;
|
||||
if interpreted_header.version > crate::FILE_VERSION {
|
||||
return Err(AconfigStorageError::HigherStorageFileVersion(anyhow!(
|
||||
"Cannot read storage file with a higher version of {} with lib version {}",
|
||||
interpreted_header.version,
|
||||
FILE_VERSION
|
||||
)));
|
||||
}
|
||||
|
||||
let mut head = (interpreted_header.boolean_flag_offset + flag_offset) as usize;
|
||||
|
||||
if head >= interpreted_header.file_size as usize {
|
||||
return Err(AconfigStorageError::InvalidStorageFileOffset(anyhow!(
|
||||
"Flag info offset goes beyond the end of the file."
|
||||
)));
|
||||
}
|
||||
|
||||
let val = read_u8_from_bytes(buf, &mut head)?;
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use aconfig_storage_file::{test_utils::create_test_flag_info_list, FlagInfoBit};
|
||||
|
||||
#[test]
|
||||
// this test point locks down query if flag is sticky
|
||||
fn test_is_flag_sticky() {
|
||||
let flag_info_list = create_test_flag_info_list().into_bytes();
|
||||
for offset in 0..8 {
|
||||
let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
|
||||
assert_eq!((attribute & FlagInfoBit::IsSticky as u8) != 0u8, false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks down query if flag is readwrite
|
||||
fn test_is_flag_readwrite() {
|
||||
let flag_info_list = create_test_flag_info_list().into_bytes();
|
||||
let baseline: Vec<bool> = vec![true, false, true, false, false, false, false, false];
|
||||
for offset in 0..8 {
|
||||
let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
|
||||
assert_eq!(
|
||||
(attribute & FlagInfoBit::IsReadWrite as u8) != 0u8,
|
||||
baseline[offset as usize]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks down query if flag has override
|
||||
fn test_flag_has_override() {
|
||||
let flag_info_list = create_test_flag_info_list().into_bytes();
|
||||
for offset in 0..8 {
|
||||
let attribute = find_boolean_flag_attribute(&flag_info_list[..], offset).unwrap();
|
||||
assert_eq!((attribute & FlagInfoBit::HasOverride as u8) != 0u8, false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks down query beyond the end of boolean section
|
||||
fn test_boolean_out_of_range() {
|
||||
let flag_info_list = create_test_flag_info_list().into_bytes();
|
||||
let error = find_boolean_flag_attribute(&flag_info_list[..], 8).unwrap_err();
|
||||
assert_eq!(
|
||||
format!("{:?}", error),
|
||||
"InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks down query error when file has a higher version
|
||||
fn test_higher_version_storage_file() {
|
||||
let mut info_list = create_test_flag_info_list();
|
||||
info_list.header.version = crate::FILE_VERSION + 1;
|
||||
let flag_info = info_list.into_bytes();
|
||||
let error = find_boolean_flag_attribute(&flag_info[..], 4).unwrap_err();
|
||||
assert_eq!(
|
||||
format!("{:?}", error),
|
||||
format!(
|
||||
"HigherStorageFileVersion(Cannot read storage file with a higher version of {} with lib version {})",
|
||||
crate::FILE_VERSION + 1,
|
||||
crate::FILE_VERSION
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -48,26 +48,13 @@ pub fn find_boolean_flag_value(buf: &[u8], flag_offset: u32) -> Result<bool, Aco
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use aconfig_storage_file::{FlagValueList, StorageFileType};
|
||||
|
||||
pub fn create_test_flag_value_list() -> FlagValueList {
|
||||
let header = FlagValueHeader {
|
||||
version: crate::FILE_VERSION,
|
||||
container: String::from("system"),
|
||||
file_type: StorageFileType::FlagVal as u8,
|
||||
file_size: 35,
|
||||
num_flags: 8,
|
||||
boolean_value_offset: 27,
|
||||
};
|
||||
let booleans: Vec<bool> = vec![false, true, false, false, true, true, false, true];
|
||||
FlagValueList { header, booleans }
|
||||
}
|
||||
use aconfig_storage_file::test_utils::create_test_flag_value_list;
|
||||
|
||||
#[test]
|
||||
// this test point locks down flag value query
|
||||
fn test_flag_value_query() {
|
||||
let flag_value_list = create_test_flag_value_list().into_bytes();
|
||||
let baseline: Vec<bool> = vec![false, true, false, false, true, true, false, true];
|
||||
let baseline: Vec<bool> = vec![false, true, true, false, true, true, true, true];
|
||||
for (offset, expected_value) in baseline.into_iter().enumerate() {
|
||||
let flag_value = find_boolean_flag_value(&flag_value_list[..], offset as u32).unwrap();
|
||||
assert_eq!(flag_value, expected_value);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
//! apis. DO NOT DIRECTLY USE THESE APIS IN YOUR SOURCE CODE. For auto generated flag apis
|
||||
//! please refer to the g3doc go/android-flags
|
||||
|
||||
pub mod flag_info_query;
|
||||
pub mod flag_table_query;
|
||||
pub mod flag_value_query;
|
||||
pub mod mapped_file;
|
||||
|
@ -47,6 +48,7 @@ pub use flag_table_query::FlagOffset;
|
|||
pub use package_table_query::PackageOffset;
|
||||
|
||||
use aconfig_storage_file::{read_u32_from_bytes, FILE_VERSION};
|
||||
use flag_info_query::find_boolean_flag_attribute;
|
||||
use flag_table_query::find_flag_offset;
|
||||
use flag_value_query::find_boolean_flag_value;
|
||||
use package_table_query::find_package_offset;
|
||||
|
@ -145,6 +147,18 @@ pub fn get_storage_file_version(file_path: &str) -> Result<u32, AconfigStorageEr
|
|||
read_u32_from_bytes(&buffer, &mut head)
|
||||
}
|
||||
|
||||
/// Get the boolean flag attribute.
|
||||
///
|
||||
/// \input file: mapped flag info file
|
||||
/// \input offset: boolean flag offset
|
||||
///
|
||||
/// \return
|
||||
/// If the provide offset is valid, it returns the boolean flag attribute bitfiled, otherwise it
|
||||
/// returns the error message.
|
||||
pub fn get_boolean_flag_attribute(file: &Mmap, offset: u32) -> Result<u8, AconfigStorageError> {
|
||||
find_boolean_flag_attribute(file, offset)
|
||||
}
|
||||
|
||||
// *************************************** //
|
||||
// CC INTERLOP
|
||||
// *************************************** //
|
||||
|
@ -315,12 +329,14 @@ mod tests {
|
|||
use crate::mapped_file::get_mapped_file;
|
||||
use crate::test_utils::copy_to_temp_file;
|
||||
use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file;
|
||||
use aconfig_storage_file::FlagInfoBit;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
fn create_test_storage_files() -> [NamedTempFile; 4] {
|
||||
fn create_test_storage_files() -> [NamedTempFile; 5] {
|
||||
let package_map = copy_to_temp_file("./tests/package.map").unwrap();
|
||||
let flag_map = copy_to_temp_file("./tests/flag.map").unwrap();
|
||||
let flag_val = copy_to_temp_file("./tests/flag.val").unwrap();
|
||||
let flag_info = copy_to_temp_file("./tests/flag.info").unwrap();
|
||||
|
||||
let text_proto = format!(
|
||||
r#"
|
||||
|
@ -330,21 +346,23 @@ files {{
|
|||
package_map: "{}"
|
||||
flag_map: "{}"
|
||||
flag_val: "{}"
|
||||
flag_info: "{}"
|
||||
timestamp: 12345
|
||||
}}
|
||||
"#,
|
||||
package_map.path().display(),
|
||||
flag_map.path().display(),
|
||||
flag_val.path().display()
|
||||
flag_val.path().display(),
|
||||
flag_info.path().display()
|
||||
);
|
||||
let pb_file = write_proto_to_temp_file(&text_proto).unwrap();
|
||||
[package_map, flag_map, flag_val, pb_file]
|
||||
[package_map, flag_map, flag_val, flag_info, pb_file]
|
||||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks down flag package offset query
|
||||
fn test_package_offset_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
let package_mapped_file = unsafe {
|
||||
get_mapped_file(&pb_file_path, "mockup", StorageFileType::PackageMap).unwrap()
|
||||
|
@ -375,7 +393,7 @@ files {{
|
|||
#[test]
|
||||
// this test point locks down flag offset query
|
||||
fn test_flag_offset_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
let flag_mapped_file =
|
||||
unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagMap).unwrap() };
|
||||
|
@ -398,9 +416,9 @@ files {{
|
|||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks down flag offset query
|
||||
// this test point locks down flag value query
|
||||
fn test_flag_value_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
let flag_value_file =
|
||||
unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagVal).unwrap() };
|
||||
|
@ -411,11 +429,28 @@ files {{
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks donw flag info query
|
||||
fn test_flag_info_query() {
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
let flag_info_file =
|
||||
unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() };
|
||||
let is_rw: Vec<bool> = vec![true, false, true, false, false, false, false, false];
|
||||
for (offset, expected_value) in is_rw.into_iter().enumerate() {
|
||||
let attribute = get_boolean_flag_attribute(&flag_info_file, offset as u32).unwrap();
|
||||
assert!((attribute & FlagInfoBit::IsSticky as u8) == 0u8);
|
||||
assert_eq!((attribute & FlagInfoBit::IsReadWrite as u8) != 0u8, expected_value);
|
||||
assert!((attribute & FlagInfoBit::HasOverride as u8) == 0u8);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// this test point locks down flag storage file version number query api
|
||||
fn test_storage_version_query() {
|
||||
assert_eq!(get_storage_file_version("./tests/package.map").unwrap(), 1);
|
||||
assert_eq!(get_storage_file_version("./tests/flag.map").unwrap(), 1);
|
||||
assert_eq!(get_storage_file_version("./tests/flag.val").unwrap(), 1);
|
||||
assert_eq!(get_storage_file_version("./tests/flag.info").unwrap(), 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,9 +91,7 @@ pub unsafe fn get_mapped_file(
|
|||
StorageFileType::PackageMap => unsafe { map_file(files_location.package_map()) },
|
||||
StorageFileType::FlagMap => unsafe { map_file(files_location.flag_map()) },
|
||||
StorageFileType::FlagVal => unsafe { map_file(files_location.flag_val()) },
|
||||
StorageFileType::FlagInfo => {
|
||||
Err(MapFileFail(anyhow!("TODO: add support for flag info file")))
|
||||
}
|
||||
StorageFileType::FlagInfo => unsafe { map_file(files_location.flag_info()) },
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ rust_test {
|
|||
"package.map",
|
||||
"flag.map",
|
||||
"flag.val",
|
||||
"flag.info",
|
||||
],
|
||||
test_suites: ["general-tests"],
|
||||
}
|
||||
|
@ -35,6 +36,7 @@ cc_test {
|
|||
"package.map",
|
||||
"flag.map",
|
||||
"flag.val",
|
||||
"flag.info",
|
||||
],
|
||||
test_suites: [
|
||||
"device-tests",
|
||||
|
|
BIN
tools/aconfig/aconfig_storage_read_api/tests/flag.info
Normal file
BIN
tools/aconfig/aconfig_storage_read_api/tests/flag.info
Normal file
Binary file not shown.
|
@ -1,10 +1,10 @@
|
|||
#[cfg(not(feature = "cargo"))]
|
||||
mod aconfig_storage_rust_test {
|
||||
use aconfig_storage_file::protos::storage_record_pb::write_proto_to_temp_file;
|
||||
use aconfig_storage_file::StorageFileType;
|
||||
use aconfig_storage_file::{FlagInfoBit, StorageFileType};
|
||||
use aconfig_storage_read_api::{
|
||||
get_boolean_flag_value, get_flag_offset, get_package_offset, get_storage_file_version,
|
||||
mapped_file::get_mapped_file, PackageOffset,
|
||||
get_boolean_flag_attribute, get_boolean_flag_value, get_flag_offset, get_package_offset,
|
||||
get_storage_file_version, mapped_file::get_mapped_file, PackageOffset,
|
||||
};
|
||||
use std::fs;
|
||||
use tempfile::NamedTempFile;
|
||||
|
@ -15,10 +15,11 @@ mod aconfig_storage_rust_test {
|
|||
file
|
||||
}
|
||||
|
||||
fn create_test_storage_files() -> [NamedTempFile; 4] {
|
||||
fn create_test_storage_files() -> [NamedTempFile; 5] {
|
||||
let package_map = copy_to_temp_file("./package.map");
|
||||
let flag_map = copy_to_temp_file("./flag.map");
|
||||
let flag_val = copy_to_temp_file("./flag.val");
|
||||
let flag_info = copy_to_temp_file("./flag.info");
|
||||
|
||||
let text_proto = format!(
|
||||
r#"
|
||||
|
@ -28,20 +29,22 @@ files {{
|
|||
package_map: "{}"
|
||||
flag_map: "{}"
|
||||
flag_val: "{}"
|
||||
flag_info: "{}"
|
||||
timestamp: 12345
|
||||
}}
|
||||
"#,
|
||||
package_map.path().display(),
|
||||
flag_map.path().display(),
|
||||
flag_val.path().display()
|
||||
flag_val.path().display(),
|
||||
flag_info.path().display()
|
||||
);
|
||||
let pb_file = write_proto_to_temp_file(&text_proto).unwrap();
|
||||
[package_map, flag_map, flag_val, pb_file]
|
||||
[package_map, flag_map, flag_val, flag_info, pb_file]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unavailable_stoarge() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
|
@ -56,7 +59,7 @@ files {{
|
|||
|
||||
#[test]
|
||||
fn test_package_offset_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
|
@ -88,7 +91,7 @@ files {{
|
|||
|
||||
#[test]
|
||||
fn test_none_exist_package_offset_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
|
@ -103,7 +106,7 @@ files {{
|
|||
|
||||
#[test]
|
||||
fn test_flag_offset_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
|
@ -129,7 +132,7 @@ files {{
|
|||
|
||||
#[test]
|
||||
fn test_none_exist_flag_offset_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
|
@ -144,7 +147,7 @@ files {{
|
|||
|
||||
#[test]
|
||||
fn test_boolean_flag_value_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
|
@ -159,7 +162,7 @@ files {{
|
|||
|
||||
#[test]
|
||||
fn test_invalid_boolean_flag_value_query() {
|
||||
let [_package_map, _flag_map, _flag_val, pb_file] = create_test_storage_files();
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
|
@ -172,10 +175,43 @@ files {{
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flag_info_query() {
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
let flag_info_file =
|
||||
unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() };
|
||||
let is_rw: Vec<bool> = vec![true, false, true, false, false, false, false, false];
|
||||
for (offset, expected_value) in is_rw.into_iter().enumerate() {
|
||||
let attribute = get_boolean_flag_attribute(&flag_info_file, offset as u32).unwrap();
|
||||
assert!((attribute & FlagInfoBit::IsSticky as u8) == 0u8);
|
||||
assert_eq!((attribute & FlagInfoBit::IsReadWrite as u8) != 0u8, expected_value);
|
||||
assert!((attribute & FlagInfoBit::HasOverride as u8) == 0u8);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_boolean_flag_info_query() {
|
||||
let [_package_map, _flag_map, _flag_val, _flag_info, pb_file] = create_test_storage_files();
|
||||
let pb_file_path = pb_file.path().display().to_string();
|
||||
// SAFETY:
|
||||
// The safety here is ensured as the test process will not write to temp storage file
|
||||
let flag_info_file =
|
||||
unsafe { get_mapped_file(&pb_file_path, "mockup", StorageFileType::FlagInfo).unwrap() };
|
||||
let err = get_boolean_flag_attribute(&flag_info_file, 8u32).unwrap_err();
|
||||
assert_eq!(
|
||||
format!("{:?}", err),
|
||||
"InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_version_query() {
|
||||
assert_eq!(get_storage_file_version("./package.map").unwrap(), 1);
|
||||
assert_eq!(get_storage_file_version("./flag.map").unwrap(), 1);
|
||||
assert_eq!(get_storage_file_version("./flag.val").unwrap(), 1);
|
||||
assert_eq!(get_storage_file_version("./flag.info").unwrap(), 1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue