diff options
Diffstat (limited to 'src/rust/adaptation/mod.rs')
-rw-r--r-- | src/rust/adaptation/mod.rs | 452 |
1 files changed, 7 insertions, 445 deletions
diff --git a/src/rust/adaptation/mod.rs b/src/rust/adaptation/mod.rs index a97fa53..4478ebf 100644 --- a/src/rust/adaptation/mod.rs +++ b/src/rust/adaptation/mod.rs @@ -1,4 +1,4 @@ -//! Definition of UwbClientCallback +//! HAL interface. use crate::error::UwbErr; use crate::uci::uci_hrcv; @@ -19,9 +19,7 @@ use binder::IBinder; use binder_tokio::{Tokio, TokioRuntime}; use log::{error, warn}; use rustutils::system_properties; -use std::collections::VecDeque; use std::sync::Arc; -use std::sync::Mutex as StdMutex; use tokio::runtime::Handle; use tokio::sync::{mpsc, Mutex}; use uwb_uci_packets::{ @@ -197,283 +195,19 @@ impl UwbAdaptation for UwbAdaptationImpl { } } -enum ExpectedCall { - Finalize { - expected_exit_status: bool, - }, - HalOpen { - out: Result<()>, - }, - HalClose { - out: Result<()>, - }, - CoreInitialization { - out: Result<()>, - }, - SessionInitialization { - expected_session_id: i32, - out: Result<()>, - }, - SendUciMessage { - expected_cmd: UciCommandPacket, - rsp: Option<uci_hrcv::UciResponse>, - notf: Option<uci_hrcv::UciNotification>, - out: Result<()>, - }, -} - -pub struct MockUwbAdaptation { - rsp_sender: mpsc::UnboundedSender<HalCallback>, - expected_calls: StdMutex<VecDeque<ExpectedCall>>, -} - -impl MockUwbAdaptation { - pub fn new(rsp_sender: mpsc::UnboundedSender<HalCallback>) -> Self { - Self { rsp_sender, expected_calls: StdMutex::new(VecDeque::new()) } - } - - #[allow(dead_code)] - pub fn expect_finalize(&self, expected_exit_status: bool) { - self.expected_calls - .lock() - .unwrap() - .push_back(ExpectedCall::Finalize { expected_exit_status }); - } - #[allow(dead_code)] - pub fn expect_hal_open(&self, out: Result<()>) { - self.expected_calls.lock().unwrap().push_back(ExpectedCall::HalOpen { out }); - } - #[allow(dead_code)] - pub fn expect_hal_close(&self, out: Result<()>) { - self.expected_calls.lock().unwrap().push_back(ExpectedCall::HalClose { out }); - } - #[allow(dead_code)] - pub fn expect_core_initialization(&self, out: Result<()>) { - self.expected_calls.lock().unwrap().push_back(ExpectedCall::CoreInitialization { out }); - } - #[allow(dead_code)] - pub fn expect_session_initialization(&self, expected_session_id: i32, out: Result<()>) { - self.expected_calls - .lock() - .unwrap() - .push_back(ExpectedCall::SessionInitialization { expected_session_id, out }); - } - #[allow(dead_code)] - pub fn expect_send_uci_message( - &self, - expected_cmd: UciCommandPacket, - rsp: Option<uci_hrcv::UciResponse>, - notf: Option<uci_hrcv::UciNotification>, - out: Result<()>, - ) { - self.expected_calls.lock().unwrap().push_back(ExpectedCall::SendUciMessage { - expected_cmd, - rsp, - notf, - out, - }); - } - - #[allow(dead_code)] - pub fn clear_expected_calls(&self) { - self.expected_calls.lock().unwrap().clear(); - } - - async fn send_hal_event(&self, event: UwbEvent, event_status: UwbStatus) { - self.rsp_sender.send(HalCallback::Event { event, event_status }).unwrap(); - } - - async fn send_uci_response(&self, rsp: uci_hrcv::UciResponse) { - self.rsp_sender.send(HalCallback::UciRsp(rsp)).unwrap(); - } - - async fn send_uci_notification(&self, ntf: uci_hrcv::UciNotification) { - self.rsp_sender.send(HalCallback::UciNtf(ntf)).unwrap(); - } -} - -impl Drop for MockUwbAdaptation { - fn drop(&mut self) { - assert!(self.expected_calls.lock().unwrap().is_empty()); - } -} - -#[async_trait] -impl UwbAdaptation for MockUwbAdaptation { - async fn finalize(&mut self, exit_status: bool) { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedCall::Finalize { expected_exit_status }) - if expected_exit_status == exit_status => - { - return; - } - Some(call) => { - expected_calls.push_front(call); - } - None => {} - } - warn!("unpected finalize() called"); - } - - async fn hal_open(&self) -> Result<()> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedCall::HalOpen { out }) => Some(out), - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => { - let status = if out.is_ok() { UwbStatus::OK } else { UwbStatus::FAILED }; - self.send_hal_event(UwbEvent::OPEN_CPLT, status).await; - out - } - None => { - warn!("unpected hal_open() called"); - Err(UwbErr::Undefined) - } - } - } - - async fn hal_close(&self) -> Result<()> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedCall::HalClose { out }) => Some(out), - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => { - let status = if out.is_ok() { UwbStatus::OK } else { UwbStatus::FAILED }; - self.send_hal_event(UwbEvent::CLOSE_CPLT, status).await; - out - } - None => { - warn!("unpected hal_close() called"); - Err(UwbErr::Undefined) - } - } - } - - async fn core_initialization(&self) -> Result<()> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedCall::CoreInitialization { out }) => Some(out), - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => { - let status = if out.is_ok() { UwbStatus::OK } else { UwbStatus::FAILED }; - self.send_hal_event(UwbEvent::POST_INIT_CPLT, status).await; - out - } - None => { - warn!("unpected core_initialization() called"); - Err(UwbErr::Undefined) - } - } - } - - async fn session_initialization(&self, session_id: i32) -> Result<()> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedCall::SessionInitialization { expected_session_id, out }) - if expected_session_id == session_id => - { - Some(out) - } - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => out, - None => { - warn!("unpected session_initialization() called"); - Err(UwbErr::Undefined) - } - } - } - - async fn send_uci_message(&self, cmd: UciCommandPacket) -> Result<()> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedCall::SendUciMessage { - expected_cmd, - rsp, - notf, - out, - // PDL generated packets do not implement PartialEq, so use the raw bytes for comparison. - }) if expected_cmd.clone().to_bytes() == cmd.to_bytes() => Some((rsp, notf, out)), - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some((rsp, notf, out)) => { - if let Some(notf) = notf { - self.send_uci_notification(notf).await; - } - if let Some(rsp) = rsp { - self.send_uci_response(rsp).await; - } - out - } - None => { - warn!("unpected send_uci_message() called"); - Err(UwbErr::Undefined) - } - } - } -} +#[cfg(any(test, fuzzing))] +pub mod mock_adaptation; +#[cfg(test)] +mod mock_hal; #[cfg(test)] pub mod tests { use super::*; - use android_hardware_uwb::aidl::android::hardware::uwb::IUwbClientCallback::IUwbClientCallback; - use binder::{SpIBinder, StatusCode}; + use crate::adaptation::mock_hal::MockHal; + use crate::uci::mock_uci_logger::MockUciLogger; use bytes::Bytes; use uwb_uci_packets::*; - enum ExpectedHalCall { - Open { out: BinderResult<()> }, - Close { out: BinderResult<()> }, - CoreInit { out: BinderResult<()> }, - SessionInit { expected_session_id: i32, out: BinderResult<()> }, - SendUciMessage { expected_data: Vec<u8>, out: BinderResult<i32> }, - } - use crate::uci::uci_logger::MockUciLogger; - #[cfg(test)] fn create_uwb_client_callback( rsp_sender: mpsc::UnboundedSender<HalCallback>, ) -> UwbClientCallback { @@ -481,178 +215,6 @@ pub mod tests { UwbClientCallback::new(rsp_sender, Arc::new(MockUciLogger::new())) } - pub struct MockHal { - expected_calls: StdMutex<VecDeque<ExpectedHalCall>>, - } - - impl MockHal { - pub fn new() -> Self { - Self { expected_calls: StdMutex::new(VecDeque::new()) } - } - - #[allow(dead_code)] - pub fn expect_open(&self, out: BinderResult<()>) { - self.expected_calls.lock().unwrap().push_back(ExpectedHalCall::Open { out }); - } - #[allow(dead_code)] - pub fn expect_close(&self, out: BinderResult<()>) { - self.expected_calls.lock().unwrap().push_back(ExpectedHalCall::Close { out }); - } - #[allow(dead_code)] - pub fn expect_core_init(&self, out: BinderResult<()>) { - self.expected_calls.lock().unwrap().push_back(ExpectedHalCall::CoreInit { out }); - } - #[allow(dead_code)] - pub fn expect_session_init(&self, expected_session_id: i32, out: BinderResult<()>) { - self.expected_calls - .lock() - .unwrap() - .push_back(ExpectedHalCall::SessionInit { expected_session_id, out }); - } - #[allow(dead_code)] - pub fn expect_send_uci_message(&self, expected_data: Vec<u8>, out: BinderResult<i32>) { - self.expected_calls - .lock() - .unwrap() - .push_back(ExpectedHalCall::SendUciMessage { expected_data, out }); - } - } - - impl Drop for MockHal { - fn drop(&mut self) { - assert!(self.expected_calls.lock().unwrap().is_empty()); - } - } - impl Default for MockHal { - fn default() -> Self { - Self::new() - } - } - - impl binder::Interface for MockHal {} - - impl binder::FromIBinder for MockHal { - fn try_from(_ibinder: SpIBinder) -> std::result::Result<Strong<Self>, binder::StatusCode> { - Err(binder::StatusCode::OK) - } - } - - #[async_trait] - impl<P: binder::BinderAsyncPool> IUwbChipAsync<P> for MockHal { - fn getName(&self) -> binder::BoxFuture<BinderResult<String>> { - Box::pin(std::future::ready(Ok("default".into()))) - } - - fn open<'a>( - &'a self, - _cb: &'a binder::Strong<dyn IUwbClientCallback>, - ) -> binder::BoxFuture<'a, BinderResult<()>> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedHalCall::Open { out }) => Some(out), - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => Box::pin(std::future::ready(out)), - None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))), - } - } - - fn close(&self) -> binder::BoxFuture<BinderResult<()>> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedHalCall::Close { out }) => Some(out), - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => Box::pin(std::future::ready(out)), - None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))), - } - } - - fn coreInit(&self) -> binder::BoxFuture<BinderResult<()>> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedHalCall::CoreInit { out }) => Some(out), - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => Box::pin(std::future::ready(out)), - None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))), - } - } - - fn sessionInit(&self, session_id: i32) -> binder::BoxFuture<BinderResult<()>> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedHalCall::SessionInit { expected_session_id, out }) - if expected_session_id == session_id => - { - Some(out) - } - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - - match expected_out { - Some(out) => Box::pin(std::future::ready(out)), - None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))), - } - } - - fn getSupportedAndroidUciVersion(&self) -> binder::BoxFuture<BinderResult<i32>> { - Box::pin(std::future::ready(Ok(0))) - } - - fn sendUciMessage(&self, cmd: &[u8]) -> binder::BoxFuture<BinderResult<i32>> { - let expected_out = { - let mut expected_calls = self.expected_calls.lock().unwrap(); - match expected_calls.pop_front() { - Some(ExpectedHalCall::SendUciMessage { expected_data, out }) - if expected_data == cmd => - { - Some(out) - } - Some(call) => { - expected_calls.push_front(call); - None - } - None => None, - } - }; - match expected_out { - Some(out) => Box::pin(std::future::ready(out)), - None => Box::pin(std::future::ready(Err(StatusCode::UNKNOWN_ERROR.into()))), - } - } - } - fn setup_client_callback() -> (mpsc::UnboundedReceiver<HalCallback>, UwbClientCallback) { // TODO: Remove this once we call it somewhere real. logger::init( |