fuchsia_fuzzctl_fdomain/
manager.rs1use anyhow::{Context as _, Result, anyhow, bail};
6use flex_client::fidl::ProtocolMarker;
7use flex_client::{self, ProxyHasDomain};
8use flex_fuchsia_fuzzer::{self as fuzz};
9use url::Url;
10use zx_status as zx;
11
12pub struct Manager {
15 proxy: fuzz::ManagerProxy,
16}
17
18impl Manager {
19 pub fn new(proxy: fuzz::ManagerProxy) -> Self {
24 Self { proxy }
25 }
26
27 pub async fn connect(&self, url: &Url) -> Result<fuzz::ControllerProxy> {
35 let dc = self.proxy.domain();
36 let (proxy, server_end) = dc.create_proxy::<fuzz::ControllerMarker>();
37 let result = self
38 .proxy
39 .connect(url.as_str(), server_end)
40 .await
41 .map_err(|e| anyhow!("{}/Connect: {}", fuzz::ManagerMarker::DEBUG_NAME, e))?;
42 if let Err(e) = result {
43 return Err(anyhow!(
44 "{}/Connect returned ZX_ERR_{}",
45 fuzz::ManagerMarker::DEBUG_NAME,
46 zx::Status::err_from_raw(e)
47 ));
48 }
49 Ok(proxy)
50 }
51
52 pub async fn get_output(
54 &self,
55 url: &Url,
56 output: fuzz::TestOutput,
57 ) -> Result<flex_client::Socket> {
58 let dc = self.proxy.domain();
59 let (rx, tx) = dc.create_stream_socket();
60 let result = self
61 .proxy
62 .get_output(url.as_str(), output, tx)
63 .await
64 .context("failed to get output")?;
65 if let Err(e) = result {
66 bail!(
67 "fuchsia.fuzzer/Manager.GetOutput returned ZX_ERR_{}",
68 zx::Status::err_from_raw(e)
69 );
70 }
71 Ok(rx)
72 }
73
74 pub async fn stop(&self, url: &Url) -> Result<bool> {
80 let result = self.proxy.stop(url.as_str()).await.context(fidl_name("Stop"))?;
81 match result {
82 Ok(()) => Ok(true),
83 Err(e) if e == zx::Status::NOT_FOUND.into_raw() => Ok(false),
84 Err(e) => {
85 bail!("fuchsia.fuzzer/Manager.Stop returned ZX_ERR_{}", zx::Status::err_from_raw(e))
86 }
87 }
88 }
89}
90
91fn fidl_name(method: &str) -> String {
92 format!("{}/{}", fuzz::ManagerMarker::DEBUG_NAME, method)
93}
94
95#[cfg(test)]
96mod tests {
97 use super::Manager;
98 use anyhow::Result;
99 use flex_fuchsia_fuzzer as fuzz;
100 use fuchsia_fuzzctl_test::{TEST_URL, Test, create_task, serve_manager};
101 use url::Url;
102
103 #[fuchsia::test]
104 async fn test_connect() -> Result<()> {
105 let test = Test::try_new()?;
106 let (proxy, server_end) = test.create_proxy::<fuzz::ManagerMarker>();
107 let _task = create_task(serve_manager(server_end, test.clone()), test.writer());
108 let manager = Manager::new(proxy);
109
110 let url = Url::parse(TEST_URL)?;
111 manager.connect(&url).await?;
112
113 let actual = test.url().borrow().as_ref().map(|url| url.to_string());
114 let expected = Some(url.to_string());
115 assert_eq!(actual, expected);
116 Ok(())
117 }
118
119 #[fuchsia::test]
120 async fn test_stop() -> Result<()> {
121 let test = Test::try_new()?;
122 let (proxy, server_end) = test.create_proxy::<fuzz::ManagerMarker>();
123 let _task = create_task(serve_manager(server_end, test.clone()), test.writer());
124 let manager = Manager::new(proxy);
125
126 let url = Url::parse(TEST_URL)?;
127 manager.stop(&url).await?;
128
129 let actual = test.url().borrow().as_ref().map(|url| url.to_string());
130 let expected = Some(url.to_string());
131 assert_eq!(actual, expected);
132 Ok(())
133 }
134}