bt_fidl_mocks/
hci.rs

1// Copyright 2024 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::expect::{expect_call, Status};
6use anyhow::Error;
7use fidl_fuchsia_hardware_bluetooth::{
8    HciTransportMarker, HciTransportProxy, HciTransportRequest, HciTransportRequestStream,
9    SentPacket,
10};
11use zx::MonotonicDuration;
12
13/// Provides a simple mock implementation of `fuchsia.hardware.bluetooth/HciTransport`.
14pub struct HciTransportMock {
15    stream: HciTransportRequestStream,
16    timeout: MonotonicDuration,
17}
18
19impl HciTransportMock {
20    pub fn new(timeout: MonotonicDuration) -> Result<(HciTransportProxy, HciTransportMock), Error> {
21        let (proxy, stream) = fidl::endpoints::create_proxy_and_stream::<HciTransportMarker>();
22        Ok((proxy, HciTransportMock { stream, timeout }))
23    }
24
25    pub fn from_stream(
26        stream: HciTransportRequestStream,
27        timeout: MonotonicDuration,
28    ) -> HciTransportMock {
29        HciTransportMock { stream, timeout }
30    }
31
32    pub async fn expect_send(&mut self, packet: SentPacket) -> Result<(), Error> {
33        expect_call(&mut self.stream, self.timeout, move |req| match req {
34            HciTransportRequest::Send_ { payload, responder } => {
35                let _ = responder.send()?;
36                if payload != packet {
37                    return Ok(Status::Pending);
38                }
39                Ok(Status::Satisfied(()))
40            }
41            _ => Ok(Status::Pending),
42        })
43        .await
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use crate::timeout_duration;
51    use futures::join;
52
53    #[fuchsia_async::run_until_stalled(test)]
54    async fn test_expect_send() {
55        let (proxy, mut mock) =
56            HciTransportMock::new(timeout_duration()).expect("failed to create mock");
57        let send_fut = proxy.send_(&SentPacket::Command(vec![0x03]));
58        let expect_fut = mock.expect_send(SentPacket::Command(vec![0x03]));
59
60        let (send_result, expect_result) = join!(send_fut, expect_fut);
61        let _ = send_result.expect("send request failed");
62        let _ = expect_result.expect("expectation not satisfied");
63    }
64}