mock_omaha_server_fuchsia/
lib.rs1use anyhow::Error;
6use fuchsia_async as fasync;
7use futures::stream::StreamExt as _;
8use hyper_util::rt::TokioIo;
9use std::future::Future;
10use std::net::{Ipv4Addr, SocketAddr};
11use std::sync::{Arc, Mutex};
12
13pub use mock_omaha_server::*;
14
15#[derive(Clone, Copy, Debug, Default)]
17pub struct FuchsiaExecutor;
18
19impl Executor for FuchsiaExecutor {
20 fn spawn(&self, fut: impl Future<Output = ()> + Send + 'static) {
21 fasync::Task::spawn(fut).detach();
22 }
23}
24
25pub struct FuchsiaListener {
26 addr: SocketAddr,
27 stream: fasync::net::AcceptStream,
28}
29
30impl FuchsiaListener {
31 pub fn bind(addr: &SocketAddr) -> Result<Self, std::io::Error> {
32 let listener = fasync::net::TcpListener::bind(addr)?;
33 let addr = listener.local_addr()?;
34 let stream = listener.accept_stream();
35 Ok(Self { addr, stream })
36 }
37}
38
39impl Listener for FuchsiaListener {
40 type Io = TokioIo<fuchsia_hyper::TcpStream>;
41 type Error = std::io::Error;
42
43 async fn accept(&mut self) -> Result<Self::Io, Self::Error> {
44 let (conn, _) = self.stream.next().await.ok_or_else(|| {
45 std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "stream closed")
46 })??;
47 Ok(TokioIo::new(fuchsia_hyper::TcpStream { stream: conn }))
48 }
49}
50
51pub trait OmahaServerExt {
52 fn start_and_detach(
53 arc_server: Arc<Mutex<OmahaServer>>,
54 addr: Option<SocketAddr>,
55 ) -> impl Future<Output = Result<String, Error>>;
56}
57
58impl OmahaServerExt for OmahaServer {
59 async fn start_and_detach(
60 arc_server: Arc<Mutex<OmahaServer>>,
61 addr: Option<SocketAddr>,
62 ) -> Result<String, Error> {
63 let addr = addr.unwrap_or_else(|| SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 0));
64 let listener = FuchsiaListener::bind(&addr)?;
65 let local_addr = listener.addr;
66 fasync::Task::spawn(async move {
67 let _ = OmahaServer::start(arc_server, listener, FuchsiaExecutor).await;
68 })
69 .detach();
70 Ok(format!("http://{local_addr}/"))
71 }
72}
73
74#[cfg(test)]
75mod unit_tests {
76 use super::*;
77
78 mock_omaha_server::declare_tests! {
79 test_attr: #[fasync::run_singlethreaded(test)],
80 start_server: async |server| <OmahaServer as OmahaServerExt>::start_and_detach(server, None).await,
81 new_http_client: async || fuchsia_hyper::new_client(),
82 cup_expect_panic: "mock-omaha-server was configured to expect CUP, but we received a request without it.",
83 }
84}