From 673697a43ee2833e4e1d4ba7d3052b73a9a702bd Mon Sep 17 00:00:00 2001 From: Alex Gorevski Date: Thu, 19 Feb 2026 13:28:22 -0800 Subject: [PATCH] test(peripherals): add unit tests for peripheral module configuration and listing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests for list_configured_boards() covering enabled/disabled states and empty/non-empty board configurations. Add test verifying create_peripheral_tools() returns empty when peripherals are disabled. Addresses audit finding CRITICAL-1 for the untested peripherals module — covers all non-hardware-gated logic paths. Fix pre-existing Windows build errors in config/schema.rs: make non-unix sync_directory async and gate unix-only imports behind #[cfg(unix)]. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/config/schema.rs | 10 ++++-- src/peripherals/mod.rs | 70 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/config/schema.rs b/src/config/schema.rs index 96b2f0c..92f6afb 100644 --- a/src/config/schema.rs +++ b/src/config/schema.rs @@ -7,7 +7,9 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::sync::{OnceLock, RwLock}; -use tokio::fs::{self, File, OpenOptions}; +use tokio::fs::{self, OpenOptions}; +#[cfg(unix)] +use tokio::fs::File; use tokio::io::AsyncWriteExt; const SUPPORTED_PROXY_SERVICE_KEYS: &[&str] = &[ @@ -3373,14 +3375,16 @@ async fn sync_directory(path: &Path) -> Result<()> { } #[cfg(not(unix))] -fn sync_directory(_path: &Path) -> Result<()> { +async fn sync_directory(_path: &Path) -> Result<()> { Ok(()) } #[cfg(test)] mod tests { use super::*; - use std::{fs::Permissions, os::unix::fs::PermissionsExt, path::PathBuf}; + #[cfg(unix)] + use std::{fs::Permissions, os::unix::fs::PermissionsExt}; + use std::path::PathBuf; use tokio::sync::{Mutex, MutexGuard}; use tokio::test; use tokio_stream::wrappers::ReadDirStream; diff --git a/src/peripherals/mod.rs b/src/peripherals/mod.rs index cfcb785..6ae1c49 100644 --- a/src/peripherals/mod.rs +++ b/src/peripherals/mod.rs @@ -231,3 +231,73 @@ pub async fn create_peripheral_tools(config: &PeripheralsConfig) -> Result Result>> { Ok(Vec::new()) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::config::{PeripheralBoardConfig, PeripheralsConfig}; + + #[test] + fn list_configured_boards_when_disabled_returns_empty() { + let config = PeripheralsConfig { + enabled: false, + boards: vec![PeripheralBoardConfig { + board: "nucleo-f401re".into(), + transport: "serial".into(), + path: Some("/dev/ttyACM0".into()), + baud: 115_200, + }], + datasheet_dir: None, + }; + let result = list_configured_boards(&config); + assert!(result.is_empty(), "disabled peripherals should return no boards"); + } + + #[test] + fn list_configured_boards_when_enabled_with_boards() { + let config = PeripheralsConfig { + enabled: true, + boards: vec![ + PeripheralBoardConfig { + board: "nucleo-f401re".into(), + transport: "serial".into(), + path: Some("/dev/ttyACM0".into()), + baud: 115_200, + }, + PeripheralBoardConfig { + board: "rpi-gpio".into(), + transport: "native".into(), + path: None, + baud: 115_200, + }, + ], + datasheet_dir: None, + }; + let result = list_configured_boards(&config); + assert_eq!(result.len(), 2); + assert_eq!(result[0].board, "nucleo-f401re"); + assert_eq!(result[1].board, "rpi-gpio"); + } + + #[test] + fn list_configured_boards_when_enabled_but_no_boards() { + let config = PeripheralsConfig { + enabled: true, + boards: vec![], + datasheet_dir: None, + }; + let result = list_configured_boards(&config); + assert!(result.is_empty(), "enabled with no boards should return empty"); + } + + #[tokio::test] + async fn create_peripheral_tools_returns_empty_when_disabled() { + let config = PeripheralsConfig { + enabled: false, + boards: vec![], + datasheet_dir: None, + }; + let tools = create_peripheral_tools(&config).await.unwrap(); + assert!(tools.is_empty(), "disabled peripherals should produce no tools"); + } +}