1 #[cfg(not(feature = "cargo"))] 2 mod aconfig_storage_rust_test { 3 use aconfig_storage_file::{FlagInfoBit, FlagValueType, StorageFileType, StoredFlagType}; 4 use aconfig_storage_read_api::{ 5 get_boolean_flag_value, get_flag_attribute, get_flag_read_context, 6 get_package_read_context, get_storage_file_version, mapped_file::get_mapped_file, 7 PackageReadContext, 8 }; 9 use rand::Rng; 10 use std::fs; 11 create_test_storage_files() -> String12 fn create_test_storage_files() -> String { 13 let mut rng = rand::thread_rng(); 14 let number: u32 = rng.gen(); 15 let storage_dir = String::from("/tmp/") + &number.to_string(); 16 if std::fs::metadata(&storage_dir).is_ok() { 17 fs::remove_dir_all(&storage_dir).unwrap(); 18 } 19 let maps_dir = storage_dir.clone() + "/maps"; 20 let boot_dir = storage_dir.clone() + "/boot"; 21 fs::create_dir(&storage_dir).unwrap(); 22 fs::create_dir(maps_dir).unwrap(); 23 fs::create_dir(boot_dir).unwrap(); 24 25 let package_map = storage_dir.clone() + "/maps/mockup.package.map"; 26 let flag_map = storage_dir.clone() + "/maps/mockup.flag.map"; 27 let flag_val = storage_dir.clone() + "/boot/mockup.val"; 28 let flag_info = storage_dir.clone() + "/boot/mockup.info"; 29 fs::copy("./package.map", package_map).unwrap(); 30 fs::copy("./flag.map", flag_map).unwrap(); 31 fs::copy("./flag.val", flag_val).unwrap(); 32 fs::copy("./flag.info", flag_info).unwrap(); 33 34 storage_dir 35 } 36 37 #[test] test_unavailable_stoarge()38 fn test_unavailable_stoarge() { 39 let storage_dir = create_test_storage_files(); 40 // SAFETY: 41 // The safety here is ensured as the test process will not write to temp storage file 42 let err = unsafe { 43 get_mapped_file(&storage_dir, "vendor", StorageFileType::PackageMap).unwrap_err() 44 }; 45 assert_eq!( 46 format!("{:?}", err), 47 format!( 48 "StorageFileNotFound(storage file {}/maps/vendor.package.map does not exist)", 49 storage_dir 50 ) 51 ); 52 } 53 54 #[test] test_package_context_query()55 fn test_package_context_query() { 56 let storage_dir = create_test_storage_files(); 57 // SAFETY: 58 // The safety here is ensured as the test process will not write to temp storage file 59 let package_mapped_file = unsafe { 60 get_mapped_file(&storage_dir, "mockup", StorageFileType::PackageMap).unwrap() 61 }; 62 63 let package_context = 64 get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_1") 65 .unwrap() 66 .unwrap(); 67 let expected_package_context = PackageReadContext { package_id: 0, boolean_start_index: 0 }; 68 assert_eq!(package_context, expected_package_context); 69 70 let package_context = 71 get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_2") 72 .unwrap() 73 .unwrap(); 74 let expected_package_context = PackageReadContext { package_id: 1, boolean_start_index: 3 }; 75 assert_eq!(package_context, expected_package_context); 76 77 let package_context = 78 get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_4") 79 .unwrap() 80 .unwrap(); 81 let expected_package_context = PackageReadContext { package_id: 2, boolean_start_index: 6 }; 82 assert_eq!(package_context, expected_package_context); 83 } 84 85 #[test] test_none_exist_package_context_query()86 fn test_none_exist_package_context_query() { 87 let storage_dir = create_test_storage_files(); 88 // SAFETY: 89 // The safety here is ensured as the test process will not write to temp storage file 90 let package_mapped_file = unsafe { 91 get_mapped_file(&storage_dir, "mockup", StorageFileType::PackageMap).unwrap() 92 }; 93 94 let package_context_option = 95 get_package_read_context(&package_mapped_file, "com.android.aconfig.storage.test_3") 96 .unwrap(); 97 assert_eq!(package_context_option, None); 98 } 99 100 #[test] test_flag_context_query()101 fn test_flag_context_query() { 102 let storage_dir = create_test_storage_files(); 103 // SAFETY: 104 // The safety here is ensured as the test process will not write to temp storage file 105 let flag_mapped_file = 106 unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagMap).unwrap() }; 107 108 let baseline = vec![ 109 (0, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 1u16), 110 (0, "enabled_rw", StoredFlagType::ReadWriteBoolean, 2u16), 111 (2, "enabled_rw", StoredFlagType::ReadWriteBoolean, 1u16), 112 (1, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16), 113 (1, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 1u16), 114 (1, "enabled_ro", StoredFlagType::ReadOnlyBoolean, 2u16), 115 (2, "enabled_fixed_ro", StoredFlagType::FixedReadOnlyBoolean, 0u16), 116 (0, "disabled_rw", StoredFlagType::ReadWriteBoolean, 0u16), 117 ]; 118 for (package_id, flag_name, flag_type, flag_index) in baseline.into_iter() { 119 let flag_context = 120 get_flag_read_context(&flag_mapped_file, package_id, flag_name).unwrap().unwrap(); 121 assert_eq!(flag_context.flag_type, flag_type); 122 assert_eq!(flag_context.flag_index, flag_index); 123 } 124 } 125 126 #[test] test_none_exist_flag_context_query()127 fn test_none_exist_flag_context_query() { 128 let storage_dir = create_test_storage_files(); 129 // SAFETY: 130 // The safety here is ensured as the test process will not write to temp storage file 131 let flag_mapped_file = 132 unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagMap).unwrap() }; 133 let flag_context_option = 134 get_flag_read_context(&flag_mapped_file, 0, "none_exist").unwrap(); 135 assert_eq!(flag_context_option, None); 136 137 let flag_context_option = 138 get_flag_read_context(&flag_mapped_file, 3, "enabled_ro").unwrap(); 139 assert_eq!(flag_context_option, None); 140 } 141 142 #[test] test_boolean_flag_value_query()143 fn test_boolean_flag_value_query() { 144 let storage_dir = create_test_storage_files(); 145 // SAFETY: 146 // The safety here is ensured as the test process will not write to temp storage file 147 let flag_value_file = 148 unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagVal).unwrap() }; 149 let baseline: Vec<bool> = vec![false, true, true, false, true, true, true, true]; 150 for (offset, expected_value) in baseline.into_iter().enumerate() { 151 let flag_value = get_boolean_flag_value(&flag_value_file, offset as u32).unwrap(); 152 assert_eq!(flag_value, expected_value); 153 } 154 } 155 156 #[test] test_invalid_boolean_flag_value_query()157 fn test_invalid_boolean_flag_value_query() { 158 let storage_dir = create_test_storage_files(); 159 // SAFETY: 160 // The safety here is ensured as the test process will not write to temp storage file 161 let flag_value_file = 162 unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagVal).unwrap() }; 163 let err = get_boolean_flag_value(&flag_value_file, 8u32).unwrap_err(); 164 assert_eq!( 165 format!("{:?}", err), 166 "InvalidStorageFileOffset(Flag value offset goes beyond the end of the file.)" 167 ); 168 } 169 170 #[test] test_flag_info_query()171 fn test_flag_info_query() { 172 let storage_dir = create_test_storage_files(); 173 // SAFETY: 174 // The safety here is ensured as the test process will not write to temp storage file 175 let flag_info_file = 176 unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagInfo).unwrap() }; 177 let is_rw: Vec<bool> = vec![true, false, true, true, false, false, false, true]; 178 for (offset, expected_value) in is_rw.into_iter().enumerate() { 179 let attribute = 180 get_flag_attribute(&flag_info_file, FlagValueType::Boolean, offset as u32).unwrap(); 181 assert!((attribute & FlagInfoBit::HasServerOverride as u8) == 0u8); 182 assert_eq!((attribute & FlagInfoBit::IsReadWrite as u8) != 0u8, expected_value); 183 assert!((attribute & FlagInfoBit::HasLocalOverride as u8) == 0u8); 184 } 185 } 186 187 #[test] test_invalid_boolean_flag_info_query()188 fn test_invalid_boolean_flag_info_query() { 189 let storage_dir = create_test_storage_files(); 190 // SAFETY: 191 // The safety here is ensured as the test process will not write to temp storage file 192 let flag_info_file = 193 unsafe { get_mapped_file(&storage_dir, "mockup", StorageFileType::FlagInfo).unwrap() }; 194 let err = get_flag_attribute(&flag_info_file, FlagValueType::Boolean, 8u32).unwrap_err(); 195 assert_eq!( 196 format!("{:?}", err), 197 "InvalidStorageFileOffset(Flag info offset goes beyond the end of the file.)" 198 ); 199 } 200 201 #[test] test_storage_version_query()202 fn test_storage_version_query() { 203 assert_eq!(get_storage_file_version("./package.map").unwrap(), 1); 204 assert_eq!(get_storage_file_version("./flag.map").unwrap(), 1); 205 assert_eq!(get_storage_file_version("./flag.val").unwrap(), 1); 206 assert_eq!(get_storage_file_version("./flag.info").unwrap(), 1); 207 } 208 } 209