component_debug/cli/
destroy.rs
1use crate::cli::format::format_destroy_error;
6use crate::lifecycle::destroy_instance_in_collection;
7use crate::query::get_cml_moniker_from_query;
8use anyhow::{format_err, Result};
9use fidl_fuchsia_sys2 as fsys;
10
11pub async fn destroy_cmd<W: std::io::Write>(
12 query: String,
13 lifecycle_controller: fsys::LifecycleControllerProxy,
14 realm_query: fsys::RealmQueryProxy,
15 mut writer: W,
16) -> Result<()> {
17 let moniker = get_cml_moniker_from_query(&query, &realm_query).await?;
18
19 writeln!(writer, "Moniker: {}", moniker)?;
20 writeln!(writer, "Destroying component instance...")?;
21
22 let parent = moniker
23 .parent()
24 .ok_or_else(|| format_err!("Error: {} does not reference a dynamic instance", moniker))?;
25 let leaf = moniker
26 .leaf()
27 .ok_or_else(|| format_err!("Error: {} does not reference a dynamic instance", moniker))?;
28 let child_name = leaf.name();
29 let collection = leaf
30 .collection()
31 .ok_or_else(|| format_err!("Error: {} does not reference a dynamic instance", moniker))?;
32
33 destroy_instance_in_collection(&lifecycle_controller, &parent, collection, child_name)
34 .await
35 .map_err(|e| format_destroy_error(&moniker, e))?;
36
37 writeln!(writer, "Destroyed component instance!")?;
38 Ok(())
39}
40
41#[cfg(test)]
42mod test {
43 use super::*;
44 use crate::test_utils::serve_realm_query_instances;
45 use fidl::endpoints::create_proxy_and_stream;
46 use futures::TryStreamExt;
47 use moniker::Moniker;
48
49 fn setup_fake_lifecycle_controller(
50 expected_moniker: &'static str,
51 expected_collection: &'static str,
52 expected_name: &'static str,
53 ) -> fsys::LifecycleControllerProxy {
54 let (lifecycle_controller, mut stream) =
55 create_proxy_and_stream::<fsys::LifecycleControllerMarker>();
56 fuchsia_async::Task::local(async move {
57 let req = stream.try_next().await.unwrap().unwrap();
58 match req {
59 fsys::LifecycleControllerRequest::DestroyInstance {
60 parent_moniker,
61 child,
62 responder,
63 } => {
64 assert_eq!(
65 Moniker::parse_str(expected_moniker),
66 Moniker::parse_str(&parent_moniker)
67 );
68 assert_eq!(expected_collection, child.collection.unwrap());
69 assert_eq!(expected_name, child.name);
70 responder.send(Ok(())).unwrap();
71 }
72 _ => panic!("Unexpected Lifecycle Controller request"),
73 }
74 })
75 .detach();
76 lifecycle_controller
77 }
78
79 #[fuchsia_async::run_singlethreaded(test)]
80 async fn test_success() -> Result<()> {
81 let mut output = Vec::new();
82 let lifecycle_controller =
83 setup_fake_lifecycle_controller("/core", "ffx-laboratory", "test");
84 let realm_query = serve_realm_query_instances(vec![fsys::Instance {
85 moniker: Some("/core/ffx-laboratory:test".to_string()),
86 url: Some("fuchsia-pkg://fuchsia.com/test#meta/test.cml".to_string()),
87 instance_id: None,
88 resolved_info: None,
89 ..Default::default()
90 }]);
91 let response =
92 destroy_cmd("test".to_string(), lifecycle_controller, realm_query, &mut output).await;
93 response.unwrap();
94 Ok(())
95 }
96}