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