component_debug/cli/
create.rs
1use crate::cli::format::format_create_error;
6use crate::lifecycle::create_instance_in_collection;
7use anyhow::{format_err, Result};
8use fuchsia_url::AbsoluteComponentUrl;
9use moniker::Moniker;
10use {fidl_fuchsia_component_decl as fdecl, fidl_fuchsia_sys2 as fsys};
11
12pub async fn create_cmd<W: std::io::Write>(
13 url: AbsoluteComponentUrl,
14 moniker: Moniker,
15 config_overrides: Vec<fdecl::ConfigOverride>,
16 lifecycle_controller: fsys::LifecycleControllerProxy,
17 mut writer: W,
18) -> Result<()> {
19 let parent = moniker
20 .parent()
21 .ok_or_else(|| format_err!("Error: {} does not reference a dynamic instance", moniker))?;
22 let leaf = moniker
23 .leaf()
24 .ok_or_else(|| format_err!("Error: {} does not reference a dynamic instance", moniker))?;
25 let child_name = leaf.name();
26 let collection = leaf
27 .collection()
28 .ok_or_else(|| format_err!("Error: {} does not reference a dynamic instance", moniker))?;
29
30 writeln!(writer, "URL: {}", url)?;
31 writeln!(writer, "Moniker: {}", moniker)?;
32 writeln!(writer, "Creating component instance...")?;
33
34 create_instance_in_collection(
35 &lifecycle_controller,
36 &parent,
37 collection,
38 child_name,
39 &url,
40 config_overrides,
41 None,
42 )
43 .await
44 .map_err(|e| format_create_error(&moniker, &parent, collection, e))?;
45
46 writeln!(writer, "Created component instance!")?;
47 Ok(())
48}
49
50#[cfg(test)]
51mod test {
52 use super::*;
53 use fidl::endpoints::create_proxy_and_stream;
54 use futures::TryStreamExt;
55
56 fn setup_fake_lifecycle_controller(
57 expected_moniker: &'static str,
58 expected_collection: &'static str,
59 expected_name: &'static str,
60 expected_url: &'static str,
61 ) -> fsys::LifecycleControllerProxy {
62 let (lifecycle_controller, mut stream) =
63 create_proxy_and_stream::<fsys::LifecycleControllerMarker>();
64 fuchsia_async::Task::local(async move {
65 let req = stream.try_next().await.unwrap().unwrap();
66 match req {
67 fsys::LifecycleControllerRequest::CreateInstance {
68 parent_moniker,
69 collection,
70 decl,
71 responder,
72 ..
73 } => {
74 assert_eq!(
75 Moniker::parse_str(expected_moniker),
76 Moniker::parse_str(&parent_moniker)
77 );
78 assert_eq!(expected_collection, collection.name);
79 assert_eq!(expected_name, decl.name.unwrap());
80 assert_eq!(expected_url, decl.url.unwrap());
81 responder.send(Ok(())).unwrap();
82 }
83 _ => panic!("Unexpected Lifecycle Controller request"),
84 }
85 })
86 .detach();
87 lifecycle_controller
88 }
89
90 #[fuchsia_async::run_singlethreaded(test)]
91 async fn test_success() -> Result<()> {
92 let mut output = Vec::new();
93 let lifecycle_controller = setup_fake_lifecycle_controller(
94 "core",
95 "ffx-laboratory",
96 "test",
97 "fuchsia-pkg://fuchsia.com/test#meta/test.cm",
98 );
99 let response = create_cmd(
100 "fuchsia-pkg://fuchsia.com/test#meta/test.cm".try_into().unwrap(),
101 "core/ffx-laboratory:test".try_into().unwrap(),
102 vec![],
103 lifecycle_controller,
104 &mut output,
105 )
106 .await;
107 response.unwrap();
108 Ok(())
109 }
110}