fuchsia_fuzzctl/
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::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!("fuchsia.fuzzer/Manager.GetOutput returned ZX_ERR_{}", zx::Status::from_raw(e));
67 }
68 Ok(rx)
69 }
70
71 pub async fn stop(&self, url: &Url) -> Result<bool> {
77 let result = self.proxy.stop(url.as_str()).await.context(fidl_name("Stop"))?;
78 match result {
79 Ok(()) => Ok(true),
80 Err(e) if e == zx::Status::NOT_FOUND.into_raw() => Ok(false),
81 Err(e) => {
82 bail!("fuchsia.fuzzer/Manager.Stop returned ZX_ERR_{}", zx::Status::from_raw(e))
83 }
84 }
85 }
86}
87
88fn fidl_name(method: &str) -> String {
89 format!("{}/{}", fuzz::ManagerMarker::DEBUG_NAME, method)
90}
91
92#[cfg(test)]
93mod tests {
94 use super::Manager;
95 use anyhow::Result;
96 use flex_fuchsia_fuzzer as fuzz;
97 use fuchsia_fuzzctl_test::{TEST_URL, Test, create_task, serve_manager};
98 use url::Url;
99
100 #[fuchsia::test]
101 async fn test_connect() -> Result<()> {
102 let test = Test::try_new()?;
103 let (proxy, server_end) = test.create_proxy::<fuzz::ManagerMarker>();
104 let _task = create_task(serve_manager(server_end, test.clone()), test.writer());
105 let manager = Manager::new(proxy);
106
107 let url = Url::parse(TEST_URL)?;
108 manager.connect(&url).await?;
109
110 let actual = test.url().borrow().as_ref().map(|url| url.to_string());
111 let expected = Some(url.to_string());
112 assert_eq!(actual, expected);
113 Ok(())
114 }
115
116 #[fuchsia::test]
117 async fn test_stop() -> Result<()> {
118 let test = Test::try_new()?;
119 let (proxy, server_end) = test.create_proxy::<fuzz::ManagerMarker>();
120 let _task = create_task(serve_manager(server_end, test.clone()), test.writer());
121 let manager = Manager::new(proxy);
122
123 let url = Url::parse(TEST_URL)?;
124 manager.stop(&url).await?;
125
126 let actual = test.url().borrow().as_ref().map(|url| url.to_string());
127 let expected = Some(url.to_string());
128 assert_eq!(actual, expected);
129 Ok(())
130 }
131}