policy_testing_common/
lib.rs1use std::pin::pin;
6
7use fidl_fuchsia_net_interfaces as fnet_interfaces;
8use futures::future::{FutureExt as _, LocalBoxFuture};
9use netstack_testing_common::realms::{
10 KnownServiceProvider, Manager, ManagerConfig, Netstack, TestSandboxExt,
11};
12use netstack_testing_common::{
13 interfaces, wait_for_component_stopped, ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT,
14};
15
16#[derive(Default)]
17pub struct NetcfgOwnedDeviceArgs {
18 pub use_out_of_stack_dhcp_client: bool,
20 pub use_socket_proxy: bool,
22 pub extra_known_service_providers: Vec<KnownServiceProvider>,
24}
25
26pub async fn with_netcfg_owned_device<
32 M: Manager,
33 N: Netstack,
34 F: for<'a> FnOnce(
35 u64,
36 &'a netemul::TestNetwork<'a>,
37 &'a fnet_interfaces::StateProxy,
38 &'a netemul::TestRealm<'a>,
39 &'a netemul::TestSandbox,
40 ) -> LocalBoxFuture<'a, ()>,
41>(
42 name: &str,
43 manager_config: ManagerConfig,
44 additional_args: NetcfgOwnedDeviceArgs,
45 after_interface_up: F,
46) -> String {
47 let NetcfgOwnedDeviceArgs {
48 use_out_of_stack_dhcp_client,
49 use_socket_proxy,
50 extra_known_service_providers,
51 } = additional_args;
52 let sandbox = netemul::TestSandbox::new().expect("create sandbox");
53 let realm = sandbox
54 .create_netstack_realm_with::<N, _, _>(
55 name,
56 [
57 KnownServiceProvider::Manager {
58 agent: M::MANAGEMENT_AGENT,
59 use_dhcp_server: false,
60 use_out_of_stack_dhcp_client,
61 use_socket_proxy,
62 config: manager_config,
63 },
64 KnownServiceProvider::DnsResolver,
65 KnownServiceProvider::FakeClock,
66 ]
67 .into_iter()
68 .chain(extra_known_service_providers)
69 .chain(
72 use_out_of_stack_dhcp_client
73 .then_some(KnownServiceProvider::DhcpClient)
74 .into_iter(),
75 )
76 .chain(use_socket_proxy.then_some(KnownServiceProvider::SocketProxy).into_iter()),
77 )
78 .expect("create netstack realm");
79
80 let network = sandbox.create_network(name).await.expect("create network");
82 let endpoint = network.create_endpoint(name).await.expect("create endpoint");
83 endpoint.set_link_up(true).await.expect("set link up");
84 let endpoint_mount_path = netemul::devfs_device_path("ep");
85 let endpoint_mount_path = endpoint_mount_path.as_path();
86 realm.add_virtual_device(&endpoint, endpoint_mount_path).await.unwrap_or_else(|e| {
87 panic!("add virtual device {}: {:?}", endpoint_mount_path.display(), e)
88 });
89
90 let interface_state = realm
92 .connect_to_protocol::<fnet_interfaces::StateMarker>()
93 .expect("connect to fuchsia.net.interfaces/State service");
94 let wait_for_netmgr =
95 wait_for_component_stopped(&realm, M::MANAGEMENT_AGENT.get_component_name(), None).fuse();
96 let mut wait_for_netmgr = pin!(wait_for_netmgr);
97 let (if_id, if_name): (u64, String) = interfaces::wait_for_non_loopback_interface_up(
98 &interface_state,
99 &mut wait_for_netmgr,
100 None,
101 ASYNC_EVENT_POSITIVE_CHECK_TIMEOUT,
102 )
103 .await
104 .expect("wait for non loopback interface");
105
106 after_interface_up(if_id, &network, &interface_state, &realm, &sandbox).await;
107
108 realm.shutdown().await.expect("failed to shutdown realm");
115
116 if_name
117}