network_test_realm/
lib.rs1use anyhow::{anyhow, Context as _, Result};
6use std::collections::HashMap;
7use {
8 fidl_fuchsia_component as fcomponent, fidl_fuchsia_component_decl as fdecl,
9 fidl_fuchsia_net_interfaces as fnet_interfaces,
10 fidl_fuchsia_net_interfaces_ext as fnet_interfaces_ext,
11};
12
13pub const HERMETIC_NETWORK_COLLECTION_NAME: &'static str = "enclosed-network";
15
16pub const HERMETIC_NETWORK_REALM_NAME: &'static str = "hermetic-network";
18
19pub const STUB_COLLECTION_NAME: &'static str = "stubs";
21
22pub const STUB_COMPONENT_NAME: &'static str = "test-stub";
24
25pub async fn has_hermetic_network_realm(realm_proxy: &fcomponent::RealmProxy) -> Result<bool> {
35 let child_ref = create_hermetic_network_realm_child_ref();
36 has_running_child(
37 fdecl::CollectionRef { name: HERMETIC_NETWORK_COLLECTION_NAME.to_string() },
38 &child_ref,
39 realm_proxy,
40 )
41 .await
42}
43
44pub async fn has_stub(realm_proxy: &fcomponent::RealmProxy) -> Result<bool> {
53 let child_ref = create_stub_child_ref();
54 has_running_child(
55 fdecl::CollectionRef { name: STUB_COLLECTION_NAME.to_string() },
56 &child_ref,
57 realm_proxy,
58 )
59 .await
60}
61
62async fn has_running_child(
65 collection_ref: fdecl::CollectionRef,
66 expected_child_ref: &fdecl::ChildRef,
67 realm_proxy: &fcomponent::RealmProxy,
68) -> Result<bool> {
69 let (iterator_proxy, server_end) = fidl::endpoints::create_proxy();
70 let list_children_result = realm_proxy
71 .list_children(&collection_ref, server_end)
72 .await
73 .context("failed to list_children")?;
74
75 match list_children_result {
76 Ok(()) => {
77 let children =
78 iterator_proxy.next().await.context("failed to iterate over children")?;
79
80 Ok(children.iter().any(|child| child == expected_child_ref))
81 }
82 Err(error) => match error {
83 fcomponent::Error::CollectionNotFound => Ok(false),
87 fcomponent::Error::AccessDenied
88 | fcomponent::Error::InstanceDied
89 | fcomponent::Error::InvalidArguments
90 | fcomponent::Error::InstanceAlreadyExists
92 | fcomponent::Error::InstanceAlreadyStarted
93 | fcomponent::Error::InstanceCannotResolve
94 | fcomponent::Error::InstanceCannotUnresolve
95 | fcomponent::Error::InstanceCannotStart
96 | fcomponent::Error::InstanceNotFound
97 | fcomponent::Error::Internal
98 | fcomponent::Error::ResourceNotFound
99 | fcomponent::Error::ResourceUnavailable
100 | fcomponent::Error::Unsupported
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 fnet_interfaces_ext::IncludedAddresses::OnlyAssigned,
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 }| {
149 if name == interface_name {
150 Some(id.get())
151 } else {
152 None
153 }
154 },
155 ))
156}