network_test_realm/
lib.rs1use anyhow::{Context as _, Result, anyhow};
6use fidl_fuchsia_component as fcomponent;
7use fidl_fuchsia_component_decl as fdecl;
8use fidl_fuchsia_net_interfaces as fnet_interfaces;
9use fidl_fuchsia_net_interfaces_ext as fnet_interfaces_ext;
10use std::collections::HashMap;
11
12pub const HERMETIC_NETWORK_COLLECTION_NAME: &'static str = "enclosed-network";
14
15pub const HERMETIC_NETWORK_REALM_NAME: &'static str = "hermetic-network";
17
18pub const STUB_COLLECTION_NAME: &'static str = "stubs";
20
21pub const STUB_COMPONENT_NAME: &'static str = "test-stub";
23
24pub async fn has_hermetic_network_realm(realm_proxy: &fcomponent::RealmProxy) -> Result<bool> {
34 let child_ref = create_hermetic_network_realm_child_ref();
35 has_running_child(
36 fdecl::CollectionRef { name: HERMETIC_NETWORK_COLLECTION_NAME.to_string() },
37 &child_ref,
38 realm_proxy,
39 )
40 .await
41}
42
43pub async fn has_stub(realm_proxy: &fcomponent::RealmProxy) -> Result<bool> {
52 let child_ref = create_stub_child_ref();
53 has_running_child(
54 fdecl::CollectionRef { name: STUB_COLLECTION_NAME.to_string() },
55 &child_ref,
56 realm_proxy,
57 )
58 .await
59}
60
61async fn has_running_child(
64 collection_ref: fdecl::CollectionRef,
65 expected_child_ref: &fdecl::ChildRef,
66 realm_proxy: &fcomponent::RealmProxy,
67) -> Result<bool> {
68 let (iterator_proxy, server_end) = fidl::endpoints::create_proxy();
69 let list_children_result = realm_proxy
70 .list_children(&collection_ref, server_end)
71 .await
72 .context("failed to list_children")?;
73
74 match list_children_result {
75 Ok(()) => {
76 let children =
77 iterator_proxy.next().await.context("failed to iterate over children")?;
78
79 Ok(children.iter().any(|child| child == expected_child_ref))
80 }
81 Err(error) => match error {
82 fcomponent::Error::CollectionNotFound => Ok(false),
86 fcomponent::Error::AccessDenied
87 | fcomponent::Error::InstanceDied
88 | fcomponent::Error::InvalidArguments
89 | fcomponent::Error::InstanceAlreadyExists
91 | fcomponent::Error::InstanceAlreadyStarted
92 | fcomponent::Error::InstanceCannotResolve
93 | fcomponent::Error::InstanceCannotUnresolve
94 | fcomponent::Error::InstanceCannotStart
95 | fcomponent::Error::InstanceNotFound
96 | fcomponent::Error::Internal
97 | fcomponent::Error::ResourceNotFound
98 | fcomponent::Error::ResourceUnavailable
99 | fcomponent::Error::Unsupported
100 | fcomponent::Error::DependencyCycle
101 | fcomponent::ErrorUnknown!()
102 => {
103 Err(anyhow!("failed to list children: {:?}", error))
104 }
105 },
106 }
107}
108
109pub fn create_hermetic_network_realm_child_ref() -> fdecl::ChildRef {
111 fdecl::ChildRef {
112 name: HERMETIC_NETWORK_REALM_NAME.to_string(),
113 collection: Some(HERMETIC_NETWORK_COLLECTION_NAME.to_string()),
114 }
115}
116
117pub fn create_stub_child_ref() -> fdecl::ChildRef {
119 fdecl::ChildRef {
120 name: STUB_COMPONENT_NAME.to_string(),
121 collection: Some(STUB_COLLECTION_NAME.to_string()),
122 }
123}
124
125pub async fn get_interface_id<'a>(
129 interface_name: &'a str,
130 state_proxy: &'a fnet_interfaces::StateProxy,
131) -> Result<Option<u64>> {
132 let stream =
133 fnet_interfaces_ext::event_stream_from_state::<fnet_interfaces_ext::DefaultInterest>(
134 &state_proxy,
135 Default::default(),
136 )
137 .context("failed to get interface stream")?;
138 let interfaces = fnet_interfaces_ext::existing(
139 stream,
140 HashMap::<u64, fidl_fuchsia_net_interfaces_ext::PropertiesAndState<(), _>>::new(),
141 )
142 .await
143 .context("failed to get existing interfaces")?;
144 Ok(interfaces.values().find_map(
145 |fidl_fuchsia_net_interfaces_ext::PropertiesAndState {
146 properties: fidl_fuchsia_net_interfaces_ext::Properties { id, name, .. },
147 state: _,
148 }| { if name == interface_name { Some(id.get()) } else { None } },
149 ))
150}