mock_boot_arguments/
lib.rs
1use fuchsia_hash::Hash;
6use futures::TryStreamExt as _;
7use std::collections::HashMap;
8use std::sync::Arc;
9
10static PKGFS_BOOT_ARG_KEY: &str = "zircon.system.pkgfs.cmd";
11static PKGFS_BOOT_ARG_VALUE_PREFIX: &str = "bin/pkgsvr+";
12
13pub struct MockBootArgumentsService {
18 args: HashMap<String, Option<String>>,
19}
20
21impl MockBootArgumentsService {
22 pub fn insert_pkgfs_boot_arg(&mut self, system_image: Hash) {
24 let system_image = format!("{PKGFS_BOOT_ARG_VALUE_PREFIX}{system_image}");
25 assert_eq!(self.args.insert(PKGFS_BOOT_ARG_KEY.to_string(), Some(system_image)), None);
26 }
27
28 pub fn new(args: HashMap<String, Option<String>>) -> Self {
29 Self { args }
30 }
31
32 pub async fn handle_request_stream(
34 self: Arc<Self>,
35 mut stream: fidl_fuchsia_boot::ArgumentsRequestStream,
36 ) {
37 while let Some(event) =
38 stream.try_next().await.expect("received fuchsia.boot/Arguments request")
39 {
40 match event {
41 fidl_fuchsia_boot::ArgumentsRequest::GetString { key, responder } => {
42 if let Some(value) = self.args.get(&key) {
43 responder.send(value.as_deref()).unwrap();
44 } else {
45 panic!("unexpected fuchsia.boot/Arguments.GetString key {key:?}");
46 }
47 }
48 fidl_fuchsia_boot::ArgumentsRequest::GetStrings { keys, responder } => {
49 let mut values: Vec<Option<String>> = vec![];
50 for key in keys {
51 if let Some(value) = self.args.get(&key) {
52 values.push(value.clone());
53 } else {
54 values.push(None);
55 }
56 }
57 responder
58 .send(&values)
59 .expect("Error sending boot_arguments strings response.");
60 }
61 req => {
62 panic!("unexpected fuchsia.boot/Arguments request {req:?}");
63 }
64 }
65 }
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use fuchsia_async as fasync;
73 use maplit::hashmap;
74
75 #[test]
76 fn insert_pkgfs_boot_arg_some() {
77 let mut mock = MockBootArgumentsService::new(HashMap::new());
78 mock.insert_pkgfs_boot_arg(Hash::from([0; 32]));
79 assert_eq!(
80 mock.args,
81 hashmap! {
82 "zircon.system.pkgfs.cmd".to_string() =>
83 Some("bin/pkgsvr+0000000000000000000000000000000000000000000000000000000000000000"
84 .to_string()
85 )
86 }
87 );
88 }
89
90 #[fasync::run_singlethreaded(test)]
91 async fn get_strings_request() {
92 let mock = Arc::new(MockBootArgumentsService::new(hashmap! {
93 "some-key".to_string() => Some("some-value".to_string()),
94 "some-key-2".to_string() => Some("some-value-2".to_string())
95 }));
96 let (proxy, stream) =
97 fidl::endpoints::create_proxy_and_stream::<fidl_fuchsia_boot::ArgumentsMarker>();
98 fasync::Task::spawn(mock.handle_request_stream(stream)).detach();
99
100 let keys = &["some-key".to_string(), "missing-key".to_string(), "some-key-2".to_string()];
101 let values = proxy.get_strings(keys).await.unwrap();
102 assert_eq!(
103 values,
104 vec![Some("some-value".to_string()), None, Some("some-value-2".to_string())]
105 );
106 }
107
108 #[fasync::run_singlethreaded(test)]
109 async fn handle_request_stream() {
110 let mock = Arc::new(MockBootArgumentsService::new(
111 hashmap! {"some-key".to_string() => Some("some-value".to_string())},
112 ));
113 let (proxy, stream) =
114 fidl::endpoints::create_proxy_and_stream::<fidl_fuchsia_boot::ArgumentsMarker>();
115 fasync::Task::spawn(mock.handle_request_stream(stream)).detach();
116
117 let value = proxy.get_string("some-key").await.unwrap();
118
119 assert_eq!(value, Some("some-value".to_string()));
120 }
121}