fuchsia_fuzzctl_test/
manager.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::controller::serve_controller;
6use crate::test::Test;
7use crate::util::create_task;
8use anyhow::{Context as _, Result};
9use fidl::endpoints::ServerEnd;
10use futures::StreamExt;
11use {fidl_fuchsia_fuzzer as fuzz, zx_status as zx};
12
13/// Serves `fuchsia.fuzzer.Manager` on the given `server_end` of a FIDL channel.
14pub async fn serve_manager(
15    server_end: ServerEnd<fuzz::ManagerMarker>,
16    mut test: Test,
17) -> Result<()> {
18    let mut stream = server_end.into_stream();
19    let mut task = None;
20    let url = test.url();
21    let fake = test.controller();
22    let writer = test.writer().clone();
23    while let Some(request) = stream.next().await {
24        let request = request.context("fuchsia.fuzzer/Manager")?;
25        match request {
26            fuzz::ManagerRequest::Connect { fuzzer_url, controller, responder } => {
27                test.record(format!("fuchsia.fuzzer/Manager.Connect({})", fuzzer_url));
28                let stream = controller.into_stream();
29                {
30                    let mut url_mut = url.borrow_mut();
31                    *url_mut = Some(fuzzer_url);
32                }
33                responder.send(Ok(()))?;
34                task = Some(create_task(serve_controller(stream, test.clone()), &writer));
35            }
36            fuzz::ManagerRequest::GetOutput { fuzzer_url, output, socket, responder } => {
37                test.record(format!(
38                    "fuchsia.fuzzer/Manager.GetOutput({}, {:?})",
39                    fuzzer_url, output
40                ));
41                let running = {
42                    let url = url.borrow();
43                    url.clone().unwrap_or(String::default())
44                };
45                if fuzzer_url == running {
46                    let response = match fake.set_output(output, socket) {
47                        zx::Status::OK => Ok(()),
48                        status => Err(status.into_raw()),
49                    };
50                    responder.send(response)?;
51                } else {
52                    responder.send(Err(zx::Status::NOT_FOUND.into_raw()))?;
53                }
54            }
55            fuzz::ManagerRequest::Stop { fuzzer_url, responder } => {
56                test.record(format!("fuchsia.fuzzer/Manager.Stop({})", fuzzer_url));
57                let running = {
58                    let mut url_mut = url.borrow_mut();
59                    let running = url_mut.as_ref().map_or(String::default(), |url| url.to_string());
60                    *url_mut = Some(fuzzer_url.to_string());
61                    running
62                };
63                if fuzzer_url == running {
64                    task = None;
65                    responder.send(Ok(()))?;
66                } else {
67                    responder.send(Err(zx::Status::NOT_FOUND.into_raw()))?;
68                }
69            }
70        };
71    }
72    if let Some(task) = task.take() {
73        task.await;
74    }
75    Ok(())
76}