1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 use crate::storage_files_manager::StorageFilesManager;
18 use crate::utils::{read_pb_from_file, remove_file, write_pb_to_file};
19 use crate::AconfigdError;
20 use aconfigd_protos::{
21     ProtoFlagOverrideMessage, ProtoFlagQueryMessage, ProtoFlagQueryReturnMessage,
22     ProtoListStorageMessage, ProtoListStorageMessageMsg, ProtoNewStorageMessage,
23     ProtoOTAFlagStagingMessage, ProtoPersistStorageRecords, ProtoRemoveLocalOverrideMessage,
24     ProtoStorageRequestMessage, ProtoStorageRequestMessageMsg, ProtoStorageRequestMessages,
25     ProtoStorageReturnMessage, ProtoStorageReturnMessages,
26 };
27 use log::{debug, error, warn};
28 use std::io::{Read, Write};
29 use std::os::unix::net::UnixStream;
30 use std::path::{Path, PathBuf};
31 
32 // Aconfigd that is capable of doing both one shot storage file init and socket service
33 #[derive(Debug)]
34 pub struct Aconfigd {
35     pub root_dir: PathBuf,
36     pub persist_storage_records: PathBuf,
37     pub(crate) storage_manager: StorageFilesManager,
38 }
39 
40 impl Aconfigd {
41     /// Constructor
new(root_dir: &Path, records: &Path) -> Self42     pub fn new(root_dir: &Path, records: &Path) -> Self {
43         Self {
44             root_dir: root_dir.to_path_buf(),
45             persist_storage_records: records.to_path_buf(),
46             storage_manager: StorageFilesManager::new(root_dir),
47         }
48     }
49 
50     /// Remove old boot storage record
remove_boot_files(&mut self) -> Result<(), AconfigdError>51     pub fn remove_boot_files(&mut self) -> Result<(), AconfigdError> {
52         let boot_dir = self.root_dir.join("boot");
53         let pb = read_pb_from_file::<ProtoPersistStorageRecords>(&self.persist_storage_records)?;
54         for entry in pb.records.iter() {
55             let boot_value_file = boot_dir.join(entry.container().to_owned() + ".val");
56             let boot_info_file = boot_dir.join(entry.container().to_owned() + ".info");
57             if boot_value_file.exists() {
58                 remove_file(&boot_value_file)?;
59             }
60             if boot_info_file.exists() {
61                 remove_file(&boot_info_file)?;
62             }
63         }
64         Ok(())
65     }
66 
67     /// Initialize aconfigd from persist storage records
initialize_from_storage_record(&mut self) -> Result<(), AconfigdError>68     pub fn initialize_from_storage_record(&mut self) -> Result<(), AconfigdError> {
69         let boot_dir = self.root_dir.join("boot");
70         let pb = read_pb_from_file::<ProtoPersistStorageRecords>(&self.persist_storage_records)?;
71         for entry in pb.records.iter() {
72             self.storage_manager.add_storage_files_from_pb(entry);
73         }
74         Ok(())
75     }
76 
77     /// Initialize platform storage files, create or update existing persist storage files and
78     /// create new boot storage files for each platform partitions
initialize_platform_storage(&mut self) -> Result<(), AconfigdError>79     pub fn initialize_platform_storage(&mut self) -> Result<(), AconfigdError> {
80         for container in ["system", "product", "vendor"] {
81             let aconfig_dir = PathBuf::from("/".to_string() + container + "/etc/aconfig");
82             let default_package_map = aconfig_dir.join("package.map");
83             let default_flag_map = aconfig_dir.join("flag.map");
84             let default_flag_val = aconfig_dir.join("flag.val");
85             let default_flag_info = aconfig_dir.join("flag.info");
86 
87             if !default_package_map.exists()
88                 || !default_flag_map.exists()
89                 || !default_flag_val.exists()
90                 || !default_flag_info.exists()
91             {
92                 debug!("skip {} initialization due to missing storage files", container);
93                 continue;
94             }
95 
96             if std::fs::metadata(&default_flag_val)
97                 .map_err(|errmsg| AconfigdError::FailToGetFileMetadata {
98                     file: default_flag_val.display().to_string(),
99                     errmsg,
100                 })?
101                 .len()
102                 == 0
103             {
104                 debug!("skip {} initialization due to zero sized storage files", container);
105                 continue;
106             }
107 
108             self.storage_manager.add_or_update_container_storage_files(
109                 container,
110                 &default_package_map,
111                 &default_flag_map,
112                 &default_flag_val,
113                 &default_flag_info,
114             )?;
115 
116             self.storage_manager
117                 .write_persist_storage_records_to_file(&self.persist_storage_records)?;
118         }
119 
120         self.storage_manager.apply_staged_ota_flags()?;
121 
122         for container in ["system", "product", "vendor"] {
123             self.storage_manager.apply_all_staged_overrides(container)?;
124         }
125 
126         Ok(())
127     }
128 
129     /// Initialize mainline storage files, create or update existing persist storage files and
130     /// create new boot storage files for each mainline container
initialize_mainline_storage(&mut self) -> Result<(), AconfigdError>131     pub fn initialize_mainline_storage(&mut self) -> Result<(), AconfigdError> {
132         // get all the apex dirs to visit
133         let mut dirs_to_visit = Vec::new();
134         let apex_dir = PathBuf::from("/apex");
135         for entry in std::fs::read_dir(&apex_dir)
136             .map_err(|errmsg| AconfigdError::FailToReadApexDir { errmsg })?
137         {
138             match entry {
139                 Ok(entry) => {
140                     let path = entry.path();
141                     if !path.is_dir() {
142                         continue;
143                     }
144                     if let Some(base_name) = path.file_name() {
145                         if let Some(dir_name) = base_name.to_str() {
146                             if dir_name.starts_with('.') {
147                                 continue;
148                             }
149                             if dir_name.find('@').is_some() {
150                                 continue;
151                             }
152                             if dir_name == "sharedlibs" {
153                                 continue;
154                             }
155                             dirs_to_visit.push(dir_name.to_string());
156                         }
157                     }
158                 }
159                 Err(errmsg) => {
160                     warn!("failed to visit entry: {}", errmsg);
161                 }
162             }
163         }
164 
165         // initialize each container
166         for container in dirs_to_visit.iter() {
167             let etc_dir = apex_dir.join(container).join("etc");
168             let default_package_map = etc_dir.join("package.map");
169             let default_flag_map = etc_dir.join("flag.map");
170             let default_flag_val = etc_dir.join("flag.val");
171             let default_flag_info = etc_dir.join("flag.info");
172 
173             if !default_package_map.exists()
174                 || !default_flag_val.exists()
175                 || !default_flag_val.exists()
176                 || !default_flag_map.exists()
177             {
178                 continue;
179             }
180 
181             if std::fs::metadata(&default_flag_val)
182                 .map_err(|errmsg| AconfigdError::FailToGetFileMetadata {
183                     file: default_flag_val.display().to_string(),
184                     errmsg,
185                 })?
186                 .len()
187                 == 0
188             {
189                 continue;
190             }
191 
192             self.storage_manager.add_or_update_container_storage_files(
193                 container,
194                 &default_package_map,
195                 &default_flag_map,
196                 &default_flag_val,
197                 &default_flag_info,
198             )?;
199 
200             self.storage_manager
201                 .write_persist_storage_records_to_file(&self.persist_storage_records)?;
202 
203             self.storage_manager.apply_all_staged_overrides(container)?;
204         }
205 
206         Ok(())
207     }
208 
209     /// Handle a flag override request
handle_flag_override( &mut self, request_pb: &ProtoFlagOverrideMessage, ) -> Result<ProtoStorageReturnMessage, AconfigdError>210     fn handle_flag_override(
211         &mut self,
212         request_pb: &ProtoFlagOverrideMessage,
213     ) -> Result<ProtoStorageReturnMessage, AconfigdError> {
214         self.storage_manager.override_flag_value(
215             request_pb.package_name(),
216             request_pb.flag_name(),
217             request_pb.flag_value(),
218             request_pb.override_type(),
219         )?;
220         let mut return_pb = ProtoStorageReturnMessage::new();
221         return_pb.mut_flag_override_message();
222         Ok(return_pb)
223     }
224 
225     /// Handle ota flag staging request
handle_ota_staging( &mut self, request_pb: &ProtoOTAFlagStagingMessage, ) -> Result<ProtoStorageReturnMessage, AconfigdError>226     fn handle_ota_staging(
227         &mut self,
228         request_pb: &ProtoOTAFlagStagingMessage,
229     ) -> Result<ProtoStorageReturnMessage, AconfigdError> {
230         let ota_flags_pb_file = self.root_dir.join("flags").join("ota.pb");
231         write_pb_to_file::<ProtoOTAFlagStagingMessage>(request_pb, &ota_flags_pb_file)?;
232         let mut return_pb = ProtoStorageReturnMessage::new();
233         return_pb.mut_ota_staging_message();
234         Ok(return_pb)
235     }
236 
237     /// Handle new container storage request
handle_new_storage( &mut self, request_pb: &ProtoNewStorageMessage, ) -> Result<ProtoStorageReturnMessage, AconfigdError>238     fn handle_new_storage(
239         &mut self,
240         request_pb: &ProtoNewStorageMessage,
241     ) -> Result<ProtoStorageReturnMessage, AconfigdError> {
242         self.storage_manager.add_or_update_container_storage_files(
243             request_pb.container(),
244             Path::new(request_pb.package_map()),
245             Path::new(request_pb.flag_map()),
246             Path::new(request_pb.flag_value()),
247             Path::new(request_pb.flag_info()),
248         )?;
249 
250         self.storage_manager
251             .write_persist_storage_records_to_file(&self.persist_storage_records)?;
252         self.storage_manager.apply_all_staged_overrides(request_pb.container())?;
253 
254         let mut return_pb = ProtoStorageReturnMessage::new();
255         return_pb.mut_new_storage_message();
256         Ok(return_pb)
257     }
258 
259     /// Handle flag query request
handle_flag_query( &mut self, request_pb: &ProtoFlagQueryMessage, ) -> Result<ProtoStorageReturnMessage, AconfigdError>260     fn handle_flag_query(
261         &mut self,
262         request_pb: &ProtoFlagQueryMessage,
263     ) -> Result<ProtoStorageReturnMessage, AconfigdError> {
264         let mut return_pb = ProtoStorageReturnMessage::new();
265         match self
266             .storage_manager
267             .get_flag_snapshot(request_pb.package_name(), request_pb.flag_name())?
268         {
269             Some(snapshot) => {
270                 let result = return_pb.mut_flag_query_message();
271                 result.set_container(snapshot.container);
272                 result.set_package_name(snapshot.package);
273                 result.set_flag_name(snapshot.flag);
274                 result.set_server_flag_value(snapshot.server_value);
275                 result.set_local_flag_value(snapshot.local_value);
276                 result.set_boot_flag_value(snapshot.boot_value);
277                 result.set_default_flag_value(snapshot.default_value);
278                 result.set_is_readwrite(snapshot.is_readwrite);
279                 result.set_has_server_override(snapshot.has_server_override);
280                 result.set_has_local_override(snapshot.has_local_override);
281                 Ok(return_pb)
282             }
283             None => Err(AconfigdError::FlagDoesNotExist {
284                 flag: request_pb.package_name().to_string() + "." + request_pb.flag_name(),
285             }),
286         }
287     }
288 
289     /// Handle local override removal request
handle_local_override_removal( &mut self, request_pb: &ProtoRemoveLocalOverrideMessage, ) -> Result<ProtoStorageReturnMessage, AconfigdError>290     fn handle_local_override_removal(
291         &mut self,
292         request_pb: &ProtoRemoveLocalOverrideMessage,
293     ) -> Result<ProtoStorageReturnMessage, AconfigdError> {
294         if request_pb.remove_all() {
295             self.storage_manager.remove_all_local_overrides()?;
296         } else {
297             self.storage_manager
298                 .remove_local_override(request_pb.package_name(), request_pb.flag_name())?;
299         }
300         let mut return_pb = ProtoStorageReturnMessage::new();
301         return_pb.mut_remove_local_override_message();
302         Ok(return_pb)
303     }
304 
305     /// Handle storage reset request
handle_storage_reset(&mut self) -> Result<ProtoStorageReturnMessage, AconfigdError>306     fn handle_storage_reset(&mut self) -> Result<ProtoStorageReturnMessage, AconfigdError> {
307         self.storage_manager.reset_all_storage()?;
308         let mut return_pb = ProtoStorageReturnMessage::new();
309         return_pb.mut_reset_storage_message();
310         Ok(return_pb)
311     }
312 
313     /// Handle list storage request
handle_list_storage( &mut self, request_pb: &ProtoListStorageMessage, ) -> Result<ProtoStorageReturnMessage, AconfigdError>314     fn handle_list_storage(
315         &mut self,
316         request_pb: &ProtoListStorageMessage,
317     ) -> Result<ProtoStorageReturnMessage, AconfigdError> {
318         let flags = match &request_pb.msg {
319             Some(ProtoListStorageMessageMsg::All(_)) => self.storage_manager.list_all_flags(),
320             Some(ProtoListStorageMessageMsg::Container(container)) => {
321                 self.storage_manager.list_flags_in_container(container)
322             }
323             Some(ProtoListStorageMessageMsg::PackageName(package)) => {
324                 self.storage_manager.list_flags_in_package(package)
325             }
326             _ => Err(AconfigdError::InvalidSocketRequest {
327                 errmsg: "Invalid list storage type".to_string(),
328             }),
329         }?;
330         let mut return_pb = ProtoStorageReturnMessage::new();
331         let result = return_pb.mut_list_storage_message();
332         result.flags = flags
333             .into_iter()
334             .map(|f| {
335                 let mut snapshot = ProtoFlagQueryReturnMessage::new();
336                 snapshot.set_container(f.container);
337                 snapshot.set_package_name(f.package);
338                 snapshot.set_flag_name(f.flag);
339                 snapshot.set_server_flag_value(f.server_value);
340                 snapshot.set_local_flag_value(f.local_value);
341                 snapshot.set_boot_flag_value(f.boot_value);
342                 snapshot.set_default_flag_value(f.default_value);
343                 snapshot.set_is_readwrite(f.is_readwrite);
344                 snapshot.set_has_server_override(f.has_server_override);
345                 snapshot.set_has_local_override(f.has_local_override);
346                 snapshot
347             })
348             .collect();
349         Ok(return_pb)
350     }
351 
352     /// Handle socket request
handle_socket_request( &mut self, request_pb: &ProtoStorageRequestMessage, ) -> Result<ProtoStorageReturnMessage, AconfigdError>353     fn handle_socket_request(
354         &mut self,
355         request_pb: &ProtoStorageRequestMessage,
356     ) -> Result<ProtoStorageReturnMessage, AconfigdError> {
357         match request_pb.msg {
358             Some(ProtoStorageRequestMessageMsg::NewStorageMessage(_)) => {
359                 self.handle_new_storage(request_pb.new_storage_message())
360             }
361             Some(ProtoStorageRequestMessageMsg::FlagOverrideMessage(_)) => {
362                 self.handle_flag_override(request_pb.flag_override_message())
363             }
364             Some(ProtoStorageRequestMessageMsg::OtaStagingMessage(_)) => {
365                 self.handle_ota_staging(request_pb.ota_staging_message())
366             }
367             Some(ProtoStorageRequestMessageMsg::FlagQueryMessage(_)) => {
368                 self.handle_flag_query(request_pb.flag_query_message())
369             }
370             Some(ProtoStorageRequestMessageMsg::RemoveLocalOverrideMessage(_)) => {
371                 self.handle_local_override_removal(request_pb.remove_local_override_message())
372             }
373             Some(ProtoStorageRequestMessageMsg::ResetStorageMessage(_)) => {
374                 self.handle_storage_reset()
375             }
376             Some(ProtoStorageRequestMessageMsg::ListStorageMessage(_)) => {
377                 self.handle_list_storage(request_pb.list_storage_message())
378             }
379             _ => Err(AconfigdError::InvalidSocketRequest { errmsg: String::new() }),
380         }
381     }
382 
383     /// Handle socket request from a unix stream
handle_socket_request_from_stream( &mut self, stream: &mut UnixStream, ) -> Result<(), AconfigdError>384     pub fn handle_socket_request_from_stream(
385         &mut self,
386         stream: &mut UnixStream,
387     ) -> Result<(), AconfigdError> {
388         let mut length_buffer = [0u8; 4];
389         stream
390             .read_exact(&mut length_buffer)
391             .map_err(|errmsg| AconfigdError::FailToReadFromSocket { errmsg })?;
392         let mut message_length = u32::from_be_bytes(length_buffer);
393 
394         let mut request_buffer = vec![0u8; message_length as usize];
395         stream
396             .read_exact(&mut request_buffer)
397             .map_err(|errmsg| AconfigdError::FailToReadFromSocket { errmsg })?;
398 
399         let requests: &ProtoStorageRequestMessages =
400             &protobuf::Message::parse_from_bytes(&request_buffer[..]).map_err(|errmsg| {
401                 AconfigdError::FailToParsePbFromBytes { file: "socket request".to_string(), errmsg }
402             })?;
403 
404         let mut return_msgs = ProtoStorageReturnMessages::new();
405         for request in requests.msgs.iter() {
406             let return_pb = match self.handle_socket_request(request) {
407                 Ok(return_msg) => return_msg,
408                 Err(errmsg) => {
409                     error!("failed to handle socket request: {}", errmsg);
410                     let mut return_msg = ProtoStorageReturnMessage::new();
411                     return_msg.set_error_message(format!(
412                         "failed to handle socket request: {:?}",
413                         errmsg
414                     ));
415                     return_msg
416                 }
417             };
418             return_msgs.msgs.push(return_pb);
419         }
420 
421         let bytes = protobuf::Message::write_to_bytes(&return_msgs).map_err(|errmsg| {
422             AconfigdError::FailToSerializePb { file: "socket".to_string(), errmsg }
423         })?;
424 
425         message_length = bytes.len() as u32;
426         length_buffer = message_length.to_be_bytes();
427         stream
428             .write_all(&length_buffer)
429             .map_err(|errmsg| AconfigdError::FailToWriteToSocket { errmsg })?;
430         stream.write_all(&bytes).map_err(|errmsg| AconfigdError::FailToWriteToSocket { errmsg })?;
431 
432         Ok(())
433     }
434 }
435 
436 #[cfg(test)]
437 mod tests {
438     use super::*;
439     use crate::test_utils::{has_same_content, ContainerMock, StorageRootDirMock};
440     use crate::utils::{get_files_digest, read_pb_from_file};
441     use aconfigd_protos::{
442         ProtoFlagOverride, ProtoFlagOverrideType, ProtoLocalFlagOverrides,
443         ProtoPersistStorageRecord,
444     };
445     use std::net::Shutdown;
446     use std::os::fd::{FromRawFd, IntoRawFd, RawFd};
447     use tempfile::tempfile;
448 
create_mock_aconfigd(root_dir: &StorageRootDirMock) -> Aconfigd449     fn create_mock_aconfigd(root_dir: &StorageRootDirMock) -> Aconfigd {
450         Aconfigd::new(root_dir.tmp_dir.path(), &root_dir.flags_dir.join("storage_records.pb"))
451     }
452 
add_mockup_container_storage(container: &ContainerMock, aconfigd: &mut Aconfigd)453     fn add_mockup_container_storage(container: &ContainerMock, aconfigd: &mut Aconfigd) {
454         let mut request = ProtoStorageRequestMessage::new();
455         let actual_request = request.mut_new_storage_message();
456         actual_request.set_container("mockup".to_string());
457         actual_request.set_package_map(container.package_map.display().to_string());
458         actual_request.set_flag_map(container.flag_map.display().to_string());
459         actual_request.set_flag_value(container.flag_val.display().to_string());
460         actual_request.set_flag_info(container.flag_info.display().to_string());
461         let return_msg = aconfigd.handle_socket_request(&request);
462         assert!(return_msg.is_ok());
463     }
464 
465     #[test]
test_new_storage_request()466     fn test_new_storage_request() {
467         let container = ContainerMock::new();
468         let root_dir = StorageRootDirMock::new();
469         let mut aconfigd = create_mock_aconfigd(&root_dir);
470         add_mockup_container_storage(&container, &mut aconfigd);
471 
472         let persist_package_map = root_dir.maps_dir.join("mockup.package.map");
473         assert!(persist_package_map.exists());
474         assert!(has_same_content(&container.package_map, &persist_package_map));
475         let persist_flag_map = root_dir.maps_dir.join("mockup.flag.map");
476         assert!(persist_flag_map.exists());
477         assert!(has_same_content(&container.flag_map, &persist_flag_map));
478         let persist_flag_val = root_dir.flags_dir.join("mockup.val");
479         assert!(persist_flag_val.exists());
480         assert!(has_same_content(&container.flag_val, &persist_flag_val));
481         let persist_flag_info = root_dir.flags_dir.join("mockup.info");
482         assert!(persist_flag_info.exists());
483         assert!(has_same_content(&container.flag_info, &persist_flag_info));
484         let boot_flag_val = root_dir.boot_dir.join("mockup.val");
485         assert!(boot_flag_val.exists());
486         assert!(has_same_content(&container.flag_val, &boot_flag_val));
487         let boot_flag_info = root_dir.boot_dir.join("mockup.info");
488         assert!(boot_flag_info.exists());
489         assert!(has_same_content(&container.flag_info, &boot_flag_info));
490 
491         let digest = get_files_digest(
492             &[
493                 container.package_map.as_path(),
494                 container.flag_map.as_path(),
495                 container.flag_val.as_path(),
496                 container.flag_info.as_path(),
497             ][..],
498         )
499         .unwrap();
500         let pb = read_pb_from_file::<ProtoPersistStorageRecords>(&aconfigd.persist_storage_records)
501             .unwrap();
502         assert_eq!(pb.records.len(), 1);
503         let mut entry = ProtoPersistStorageRecord::new();
504         entry.set_version(1);
505         entry.set_container("mockup".to_string());
506         entry.set_package_map(container.package_map.display().to_string());
507         entry.set_flag_map(container.flag_map.display().to_string());
508         entry.set_flag_val(container.flag_val.display().to_string());
509         entry.set_flag_info(container.flag_info.display().to_string());
510         entry.set_digest(digest);
511         assert_eq!(pb.records[0], entry);
512     }
513 
get_flag_snapshot( aconfigd: &mut Aconfigd, package: &str, flag: &str, ) -> ProtoFlagQueryReturnMessage514     fn get_flag_snapshot(
515         aconfigd: &mut Aconfigd,
516         package: &str,
517         flag: &str,
518     ) -> ProtoFlagQueryReturnMessage {
519         let mut request = ProtoStorageRequestMessage::new();
520         let actual_request = request.mut_flag_query_message();
521         actual_request.set_package_name(package.to_string());
522         actual_request.set_flag_name(flag.to_string());
523         let return_msg = aconfigd.handle_socket_request(&request);
524         assert!(return_msg.is_ok());
525         return_msg.unwrap().flag_query_message().clone()
526     }
527 
528     #[test]
test_server_on_boot_flag_override_request()529     fn test_server_on_boot_flag_override_request() {
530         let container = ContainerMock::new();
531         let root_dir = StorageRootDirMock::new();
532         let mut aconfigd = create_mock_aconfigd(&root_dir);
533         add_mockup_container_storage(&container, &mut aconfigd);
534         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
535 
536         let mut request = ProtoStorageRequestMessage::new();
537         let actual_request = request.mut_flag_override_message();
538         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
539         actual_request.set_flag_name("enabled_rw".to_string());
540         actual_request.set_flag_value("false".to_string());
541         actual_request.set_override_type(ProtoFlagOverrideType::SERVER_ON_REBOOT);
542         let return_msg = aconfigd.handle_socket_request(&request);
543         assert!(return_msg.is_ok());
544 
545         let flag =
546             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
547         assert_eq!(flag.server_flag_value(), "false");
548         assert_eq!(flag.boot_flag_value(), "true");
549         assert_eq!(flag.local_flag_value(), "");
550         assert_eq!(flag.has_server_override(), true);
551         assert_eq!(flag.has_local_override(), false);
552     }
553 
554     #[test]
test_local_on_boot_flag_override_request()555     fn test_local_on_boot_flag_override_request() {
556         let container = ContainerMock::new();
557         let root_dir = StorageRootDirMock::new();
558         let mut aconfigd = create_mock_aconfigd(&root_dir);
559         add_mockup_container_storage(&container, &mut aconfigd);
560         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
561 
562         let mut request = ProtoStorageRequestMessage::new();
563         let actual_request = request.mut_flag_override_message();
564         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
565         actual_request.set_flag_name("enabled_rw".to_string());
566         actual_request.set_flag_value("false".to_string());
567         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_ON_REBOOT);
568         let return_msg = aconfigd.handle_socket_request(&request);
569         assert!(return_msg.is_ok());
570 
571         let flag =
572             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
573         assert_eq!(flag.server_flag_value(), "");
574         assert_eq!(flag.boot_flag_value(), "true");
575         assert_eq!(flag.local_flag_value(), "false");
576         assert_eq!(flag.has_server_override(), false);
577         assert_eq!(flag.has_local_override(), true);
578     }
579 
580     #[test]
test_local_immediate_flag_override_request()581     fn test_local_immediate_flag_override_request() {
582         let container = ContainerMock::new();
583         let root_dir = StorageRootDirMock::new();
584         let mut aconfigd = create_mock_aconfigd(&root_dir);
585         add_mockup_container_storage(&container, &mut aconfigd);
586         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
587 
588         let mut request = ProtoStorageRequestMessage::new();
589         let actual_request = request.mut_flag_override_message();
590         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
591         actual_request.set_flag_name("enabled_rw".to_string());
592         actual_request.set_flag_value("false".to_string());
593         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_IMMEDIATE);
594         let return_msg = aconfigd.handle_socket_request(&request);
595         assert!(return_msg.is_ok());
596 
597         let flag =
598             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
599         assert_eq!(flag.server_flag_value(), "");
600         assert_eq!(flag.boot_flag_value(), "false");
601         assert_eq!(flag.local_flag_value(), "false");
602         assert_eq!(flag.has_server_override(), false);
603         assert_eq!(flag.has_local_override(), true);
604     }
605 
606     #[test]
test_negative_flag_override_request()607     fn test_negative_flag_override_request() {
608         let container = ContainerMock::new();
609         let root_dir = StorageRootDirMock::new();
610         let mut aconfigd = create_mock_aconfigd(&root_dir);
611         add_mockup_container_storage(&container, &mut aconfigd);
612         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
613 
614         let mut request = ProtoStorageRequestMessage::new();
615         let actual_request = request.mut_flag_override_message();
616         actual_request.set_package_name("not_exist".to_string());
617         actual_request.set_flag_name("not_exist".to_string());
618         actual_request.set_flag_value("false".to_string());
619         let return_msg = aconfigd.handle_socket_request(&request);
620         assert!(return_msg.is_err());
621         if let Err(errmsg) = return_msg {
622             assert_eq!("cannot find container for package not_exist", format!("{}", errmsg));
623         }
624     }
625 
626     #[test]
test_ota_flag_staging_request()627     fn test_ota_flag_staging_request() {
628         let root_dir = StorageRootDirMock::new();
629         let mut aconfigd = create_mock_aconfigd(&root_dir);
630 
631         let mut request = ProtoStorageRequestMessage::new();
632         let actual_request = request.mut_ota_staging_message();
633         actual_request.set_build_id("xyz.123".to_string());
634         let mut flag1 = ProtoFlagOverride::new();
635         flag1.set_package_name("package_foo".to_string());
636         flag1.set_flag_name("flag_foo".to_string());
637         flag1.set_flag_value("false".to_string());
638         actual_request.overrides.push(flag1.clone());
639         let mut flag2 = ProtoFlagOverride::new();
640         flag2.set_package_name("package_bar".to_string());
641         flag2.set_flag_name("flag_bar".to_string());
642         flag2.set_flag_value("true".to_string());
643         actual_request.overrides.push(flag2.clone());
644         let return_msg = aconfigd.handle_socket_request(&request);
645         assert!(return_msg.is_ok());
646 
647         let ota_pb_file = root_dir.flags_dir.join("ota.pb");
648         assert!(ota_pb_file.exists());
649         let ota_flags = read_pb_from_file::<ProtoOTAFlagStagingMessage>(&ota_pb_file).unwrap();
650         assert_eq!(ota_flags.build_id(), "xyz.123");
651         assert_eq!(ota_flags.overrides.len(), 2);
652         assert_eq!(ota_flags.overrides[0], flag1);
653         assert_eq!(ota_flags.overrides[1], flag2);
654     }
655 
656     #[test]
test_flag_querry_request()657     fn test_flag_querry_request() {
658         let container = ContainerMock::new();
659         let root_dir = StorageRootDirMock::new();
660         let mut aconfigd = create_mock_aconfigd(&root_dir);
661         add_mockup_container_storage(&container, &mut aconfigd);
662         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
663 
664         let mut flag =
665             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
666         assert_eq!(flag.container(), "mockup");
667         assert_eq!(flag.package_name(), "com.android.aconfig.storage.test_1");
668         assert_eq!(flag.flag_name(), "enabled_rw");
669         assert_eq!(flag.server_flag_value(), "");
670         assert_eq!(flag.boot_flag_value(), "true");
671         assert_eq!(flag.local_flag_value(), "");
672         assert_eq!(flag.default_flag_value(), "true");
673         assert_eq!(flag.is_readwrite(), true);
674         assert_eq!(flag.has_server_override(), false);
675         assert_eq!(flag.has_local_override(), false);
676 
677         let mut request = ProtoStorageRequestMessage::new();
678         let mut actual_request = request.mut_flag_override_message();
679         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
680         actual_request.set_flag_name("enabled_rw".to_string());
681         actual_request.set_flag_value("false".to_string());
682         actual_request.set_override_type(ProtoFlagOverrideType::SERVER_ON_REBOOT);
683         let mut return_msg = aconfigd.handle_socket_request(&request);
684         assert!(return_msg.is_ok());
685 
686         flag = get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
687         assert_eq!(flag.container(), "mockup");
688         assert_eq!(flag.package_name(), "com.android.aconfig.storage.test_1");
689         assert_eq!(flag.flag_name(), "enabled_rw");
690         assert_eq!(flag.server_flag_value(), "false");
691         assert_eq!(flag.boot_flag_value(), "true");
692         assert_eq!(flag.local_flag_value(), "");
693         assert_eq!(flag.default_flag_value(), "true");
694         assert_eq!(flag.is_readwrite(), true);
695         assert_eq!(flag.has_server_override(), true);
696         assert_eq!(flag.has_local_override(), false);
697 
698         request = ProtoStorageRequestMessage::new();
699         actual_request = request.mut_flag_override_message();
700         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
701         actual_request.set_flag_name("enabled_rw".to_string());
702         actual_request.set_flag_value("false".to_string());
703         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_IMMEDIATE);
704         return_msg = aconfigd.handle_socket_request(&request);
705         assert!(return_msg.is_ok());
706 
707         flag = get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
708         assert_eq!(flag.container(), "mockup");
709         assert_eq!(flag.package_name(), "com.android.aconfig.storage.test_1");
710         assert_eq!(flag.flag_name(), "enabled_rw");
711         assert_eq!(flag.server_flag_value(), "false");
712         assert_eq!(flag.boot_flag_value(), "false");
713         assert_eq!(flag.local_flag_value(), "false");
714         assert_eq!(flag.default_flag_value(), "true");
715         assert_eq!(flag.is_readwrite(), true);
716         assert_eq!(flag.has_server_override(), true);
717         assert_eq!(flag.has_local_override(), true);
718     }
719 
720     #[test]
test_negative_flag_querry_request()721     fn test_negative_flag_querry_request() {
722         let container = ContainerMock::new();
723         let root_dir = StorageRootDirMock::new();
724         let mut aconfigd = create_mock_aconfigd(&root_dir);
725         add_mockup_container_storage(&container, &mut aconfigd);
726         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
727 
728         let mut request = ProtoStorageRequestMessage::new();
729         let actual_request = request.mut_flag_query_message();
730         actual_request.set_package_name("not_exist".to_string());
731         actual_request.set_flag_name("not_exist".to_string());
732         let return_msg = aconfigd.handle_socket_request(&request);
733         assert!(return_msg.is_err());
734         if let Err(errmsg) = return_msg {
735             assert_eq!("flag not_exist.not_exist does not exist", format!("{}", errmsg));
736         }
737     }
738 
739     #[test]
test_remove_single_local_override_request()740     fn test_remove_single_local_override_request() {
741         let container = ContainerMock::new();
742         let root_dir = StorageRootDirMock::new();
743         let mut aconfigd = create_mock_aconfigd(&root_dir);
744         add_mockup_container_storage(&container, &mut aconfigd);
745         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
746 
747         let mut request = ProtoStorageRequestMessage::new();
748         let actual_request = request.mut_flag_override_message();
749         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
750         actual_request.set_flag_name("enabled_rw".to_string());
751         actual_request.set_flag_value("false".to_string());
752         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_ON_REBOOT);
753         let return_msg = aconfigd.handle_socket_request(&request);
754         assert!(return_msg.is_ok());
755 
756         request = ProtoStorageRequestMessage::new();
757         let actual_request = request.mut_flag_override_message();
758         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
759         actual_request.set_flag_name("disabled_rw".to_string());
760         actual_request.set_flag_value("true".to_string());
761         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_ON_REBOOT);
762         let return_msg = aconfigd.handle_socket_request(&request);
763         assert!(return_msg.is_ok());
764 
765         request = ProtoStorageRequestMessage::new();
766         let actual_request = request.mut_remove_local_override_message();
767         actual_request.set_remove_all(false);
768         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
769         actual_request.set_flag_name("enabled_rw".to_string());
770         let return_msg = aconfigd.handle_socket_request(&request);
771         assert!(return_msg.is_ok());
772 
773         let flag =
774             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
775         assert_eq!(flag.local_flag_value(), "");
776         assert_eq!(flag.has_local_override(), false);
777 
778         let flag =
779             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "disabled_rw");
780         assert_eq!(flag.local_flag_value(), "true");
781         assert_eq!(flag.has_local_override(), true);
782     }
783 
784     #[test]
test_remove_all_local_override_request()785     fn test_remove_all_local_override_request() {
786         let container = ContainerMock::new();
787         let root_dir = StorageRootDirMock::new();
788         let mut aconfigd = create_mock_aconfigd(&root_dir);
789         add_mockup_container_storage(&container, &mut aconfigd);
790         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
791 
792         let mut request = ProtoStorageRequestMessage::new();
793         let actual_request = request.mut_flag_override_message();
794         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
795         actual_request.set_flag_name("enabled_rw".to_string());
796         actual_request.set_flag_value("false".to_string());
797         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_ON_REBOOT);
798         let return_msg = aconfigd.handle_socket_request(&request);
799         assert!(return_msg.is_ok());
800 
801         request = ProtoStorageRequestMessage::new();
802         let actual_request = request.mut_flag_override_message();
803         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
804         actual_request.set_flag_name("disabled_rw".to_string());
805         actual_request.set_flag_value("true".to_string());
806         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_ON_REBOOT);
807         let return_msg = aconfigd.handle_socket_request(&request);
808         assert!(return_msg.is_ok());
809 
810         request = ProtoStorageRequestMessage::new();
811         let actual_request = request.mut_remove_local_override_message();
812         actual_request.set_remove_all(true);
813         actual_request.set_package_name("abc".to_string());
814         actual_request.set_flag_name("def".to_string());
815         let return_msg = aconfigd.handle_socket_request(&request);
816         assert!(return_msg.is_ok());
817 
818         let flag =
819             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
820         assert_eq!(flag.local_flag_value(), "");
821         assert_eq!(flag.has_local_override(), false);
822 
823         let flag =
824             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "disabled_rw");
825         assert_eq!(flag.local_flag_value(), "");
826         assert_eq!(flag.has_local_override(), false);
827 
828         let local_pb_file = root_dir.flags_dir.join("mockup_local_overrides.pb");
829         let pb = read_pb_from_file::<ProtoLocalFlagOverrides>(&local_pb_file).unwrap();
830         assert_eq!(pb.overrides.len(), 0);
831     }
832 
833     #[test]
test_negative_remove_local_override_request()834     fn test_negative_remove_local_override_request() {
835         let container = ContainerMock::new();
836         let root_dir = StorageRootDirMock::new();
837         let mut aconfigd = create_mock_aconfigd(&root_dir);
838         add_mockup_container_storage(&container, &mut aconfigd);
839         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
840 
841         let mut request = ProtoStorageRequestMessage::new();
842         let actual_request = request.mut_flag_override_message();
843         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
844         actual_request.set_flag_name("enabled_rw".to_string());
845         actual_request.set_flag_value("false".to_string());
846         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_ON_REBOOT);
847         let return_msg = aconfigd.handle_socket_request(&request);
848         assert!(return_msg.is_ok());
849 
850         request = ProtoStorageRequestMessage::new();
851         let actual_request = request.mut_remove_local_override_message();
852         actual_request.set_remove_all(false);
853         actual_request.set_package_name("abc".to_string());
854         actual_request.set_flag_name("def".to_string());
855         let return_msg = aconfigd.handle_socket_request(&request);
856         assert!(return_msg.is_err());
857         if let Err(errmsg) = return_msg {
858             assert_eq!("cannot find container for package abc", format!("{}", errmsg));
859         }
860     }
861 
862     #[test]
test_reset_storage_request()863     fn test_reset_storage_request() {
864         let container = ContainerMock::new();
865         let root_dir = StorageRootDirMock::new();
866         let mut aconfigd = create_mock_aconfigd(&root_dir);
867         add_mockup_container_storage(&container, &mut aconfigd);
868         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
869 
870         let mut request = ProtoStorageRequestMessage::new();
871         let actual_request = request.mut_flag_override_message();
872         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
873         actual_request.set_flag_name("enabled_rw".to_string());
874         actual_request.set_flag_value("false".to_string());
875         actual_request.set_override_type(ProtoFlagOverrideType::SERVER_ON_REBOOT);
876         let return_msg = aconfigd.handle_socket_request(&request);
877         assert!(return_msg.is_ok());
878 
879         request = ProtoStorageRequestMessage::new();
880         let actual_request = request.mut_flag_override_message();
881         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
882         actual_request.set_flag_name("disabled_rw".to_string());
883         actual_request.set_flag_value("true".to_string());
884         actual_request.set_override_type(ProtoFlagOverrideType::LOCAL_ON_REBOOT);
885         let return_msg = aconfigd.handle_socket_request(&request);
886         assert!(return_msg.is_ok());
887 
888         let mut request = ProtoStorageRequestMessage::new();
889         let _actual_request = request.mut_reset_storage_message();
890         let return_msg = aconfigd.handle_socket_request(&request);
891         assert!(return_msg.is_ok());
892 
893         let mut flag =
894             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "enabled_rw");
895         assert_eq!(flag.server_flag_value(), "");
896         assert_eq!(flag.local_flag_value(), "");
897         assert_eq!(flag.has_server_override(), false);
898         assert_eq!(flag.has_local_override(), false);
899 
900         flag =
901             get_flag_snapshot(&mut aconfigd, "com.android.aconfig.storage.test_1", "disabled_rw");
902         assert_eq!(flag.server_flag_value(), "");
903         assert_eq!(flag.local_flag_value(), "");
904         assert_eq!(flag.has_server_override(), false);
905         assert_eq!(flag.has_local_override(), false);
906     }
907 
908     #[test]
test_list_package_request()909     fn test_list_package_request() {
910         let container = ContainerMock::new();
911         let root_dir = StorageRootDirMock::new();
912         let mut aconfigd = create_mock_aconfigd(&root_dir);
913         add_mockup_container_storage(&container, &mut aconfigd);
914         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
915 
916         let mut request = ProtoStorageRequestMessage::new();
917         let actual_request = request.mut_list_storage_message();
918         actual_request.set_package_name("com.android.aconfig.storage.test_1".to_string());
919         let return_msg = aconfigd.handle_socket_request(&request);
920         assert!(return_msg.is_ok());
921 
922         let flags = return_msg.unwrap().list_storage_message().clone();
923         assert_eq!(flags.flags.len(), 3);
924 
925         let mut flag = ProtoFlagQueryReturnMessage::new();
926         flag.set_container("mockup".to_string());
927         flag.set_package_name("com.android.aconfig.storage.test_1".to_string());
928         flag.set_flag_name("disabled_rw".to_string());
929         flag.set_server_flag_value("".to_string());
930         flag.set_local_flag_value("".to_string());
931         flag.set_boot_flag_value("false".to_string());
932         flag.set_default_flag_value("false".to_string());
933         flag.set_is_readwrite(true);
934         flag.set_has_server_override(false);
935         flag.set_has_local_override(false);
936         assert_eq!(flags.flags[0], flag);
937 
938         flag.set_flag_name("enabled_ro".to_string());
939         flag.set_boot_flag_value("true".to_string());
940         flag.set_default_flag_value("true".to_string());
941         flag.set_is_readwrite(false);
942         assert_eq!(flags.flags[1], flag);
943 
944         flag.set_flag_name("enabled_rw".to_string());
945         flag.set_is_readwrite(true);
946         assert_eq!(flags.flags[2], flag);
947     }
948 
949     #[test]
test_negative_list_package_request()950     fn test_negative_list_package_request() {
951         let container = ContainerMock::new();
952         let root_dir = StorageRootDirMock::new();
953         let mut aconfigd = create_mock_aconfigd(&root_dir);
954         add_mockup_container_storage(&container, &mut aconfigd);
955         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
956 
957         let mut request = ProtoStorageRequestMessage::new();
958         let actual_request = request.mut_list_storage_message();
959         actual_request.set_package_name("not_exist".to_string());
960         let return_msg = aconfigd.handle_socket_request(&request);
961         assert!(return_msg.is_err());
962         if let Err(errmsg) = return_msg {
963             assert_eq!("cannot find container for package not_exist", format!("{}", errmsg));
964         }
965     }
966 
967     #[test]
test_list_container_request()968     fn test_list_container_request() {
969         let container = ContainerMock::new();
970         let root_dir = StorageRootDirMock::new();
971         let mut aconfigd = create_mock_aconfigd(&root_dir);
972         add_mockup_container_storage(&container, &mut aconfigd);
973         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
974 
975         let mut request = ProtoStorageRequestMessage::new();
976         let actual_request = request.mut_list_storage_message();
977         actual_request.set_container("mockup".to_string());
978         let return_msg = aconfigd.handle_socket_request(&request);
979         assert!(return_msg.is_ok());
980 
981         let flags = return_msg.unwrap().list_storage_message().clone();
982         assert_eq!(flags.flags.len(), 8);
983     }
984 
985     #[test]
test_negative_list_container_request()986     fn test_negative_list_container_request() {
987         let container = ContainerMock::new();
988         let root_dir = StorageRootDirMock::new();
989         let mut aconfigd = create_mock_aconfigd(&root_dir);
990         add_mockup_container_storage(&container, &mut aconfigd);
991         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
992 
993         let mut request = ProtoStorageRequestMessage::new();
994         let actual_request = request.mut_list_storage_message();
995         actual_request.set_container("not_exist".to_string());
996         let return_msg = aconfigd.handle_socket_request(&request);
997         assert!(return_msg.is_err());
998         if let Err(errmsg) = return_msg {
999             assert_eq!("fail to get storage files for not_exist", format!("{}", errmsg));
1000         }
1001     }
1002 
1003     #[test]
test_aconfigd_unix_stream()1004     fn test_aconfigd_unix_stream() {
1005         let container = ContainerMock::new();
1006         let root_dir = StorageRootDirMock::new();
1007         let mut aconfigd = create_mock_aconfigd(&root_dir);
1008         add_mockup_container_storage(&container, &mut aconfigd);
1009         aconfigd.storage_manager.apply_all_staged_overrides("mockup").unwrap();
1010 
1011         let mut request = ProtoStorageRequestMessage::new();
1012         let actual_request = request.mut_flag_query_message();
1013         actual_request.set_package_name("abc".to_string());
1014         actual_request.set_flag_name("def".to_string());
1015         let bytes = protobuf::Message::write_to_bytes(&request).unwrap();
1016 
1017         let (mut stream1, mut stream2) = UnixStream::pair().unwrap();
1018         let length_bytes = (bytes.len() as u32).to_be_bytes();
1019         stream1.write_all(&length_bytes).unwrap();
1020         stream1.write_all(&bytes).unwrap();
1021         stream1.shutdown(Shutdown::Write).unwrap();
1022         let result = aconfigd.handle_socket_request_from_stream(&mut stream2);
1023         assert!(result.is_ok());
1024     }
1025 
1026     #[test]
test_negative_aconfigd_unix_stream()1027     fn test_negative_aconfigd_unix_stream() {
1028         let root_dir = StorageRootDirMock::new();
1029         let mut aconfigd = create_mock_aconfigd(&root_dir);
1030 
1031         let (mut stream1, mut stream2) = UnixStream::pair().unwrap();
1032         let length_bytes = 11_u32.to_be_bytes();
1033         stream1.write_all(&length_bytes).unwrap();
1034         stream1.write_all(b"hello world").unwrap();
1035         stream1.shutdown(Shutdown::Write).unwrap();
1036         let result = aconfigd.handle_socket_request_from_stream(&mut stream2);
1037         assert!(result.is_err());
1038         if let Err(errmsg) = result {
1039             assert_eq!("fail to parse to protobuf from bytes for socket request: Error(WireError(UnexpectedWireType(EndGroup)))", format!("{}", errmsg));
1040         }
1041     }
1042 
1043     #[test]
test_initialize_platform_storage_fresh_install()1044     fn test_initialize_platform_storage_fresh_install() {
1045         let root_dir = StorageRootDirMock::new();
1046         let mut aconfigd = create_mock_aconfigd(&root_dir);
1047         aconfigd.initialize_platform_storage().unwrap();
1048         assert!(aconfigd.persist_storage_records.exists());
1049         let pb = read_pb_from_file::<ProtoPersistStorageRecords>(&aconfigd.persist_storage_records)
1050             .unwrap();
1051         assert_eq!(pb.records.len(), 3);
1052 
1053         for container in ["system", "product", "vendor"] {
1054             let aconfig_dir = PathBuf::from("/".to_string() + container + "/etc/aconfig");
1055             let default_package_map = aconfig_dir.join("package.map");
1056             let default_flag_map = aconfig_dir.join("flag.map");
1057             let default_flag_val = aconfig_dir.join("flag.val");
1058             let default_flag_info = aconfig_dir.join("flag.info");
1059 
1060             let persist_package_map =
1061                 root_dir.maps_dir.join(container.to_string() + ".package.map");
1062             let persist_flag_map = root_dir.maps_dir.join(container.to_string() + ".flag.map");
1063             let persist_flag_val = root_dir.flags_dir.join(container.to_string() + ".val");
1064             let persist_flag_info = root_dir.flags_dir.join(container.to_string() + ".info");
1065             let boot_flag_val = root_dir.boot_dir.join(container.to_string() + ".val");
1066             let boot_flag_info = root_dir.boot_dir.join(container.to_string() + ".info");
1067             let local_overrides =
1068                 root_dir.flags_dir.join(container.to_string() + "_local_overrides.pb");
1069 
1070             assert!(has_same_content(&persist_package_map, &default_package_map));
1071             assert!(has_same_content(&persist_flag_map, &default_flag_map));
1072             assert!(has_same_content(&persist_flag_val, &default_flag_val));
1073             assert!(has_same_content(&persist_flag_info, &default_flag_info));
1074             assert!(has_same_content(&boot_flag_val, &default_flag_val));
1075             assert!(has_same_content(&boot_flag_info, &default_flag_info));
1076             assert!(local_overrides.exists());
1077 
1078             let mut entry = ProtoPersistStorageRecord::new();
1079             entry.set_version(1);
1080             entry.set_container(container.to_string());
1081             entry.set_package_map(default_package_map.display().to_string());
1082             entry.set_flag_map(default_flag_map.display().to_string());
1083             entry.set_flag_val(default_flag_val.display().to_string());
1084             entry.set_flag_info(default_flag_info.display().to_string());
1085             let digest = get_files_digest(
1086                 &[
1087                     default_package_map.as_path(),
1088                     default_flag_map.as_path(),
1089                     default_flag_val.as_path(),
1090                     default_flag_info.as_path(),
1091                 ][..],
1092             )
1093             .unwrap();
1094             entry.set_digest(digest);
1095             assert!(pb.records.iter().any(|x| *x == entry));
1096         }
1097     }
1098 
1099     #[test]
test_initialize_mainline_storage()1100     fn test_initialize_mainline_storage() {
1101         let root_dir = StorageRootDirMock::new();
1102         let mut aconfigd = create_mock_aconfigd(&root_dir);
1103         aconfigd.initialize_mainline_storage().unwrap();
1104         let entries: Vec<_> = std::fs::read_dir(&root_dir.flags_dir).into_iter().collect();
1105         assert!(entries.len() > 0);
1106     }
1107 }
1108