From f7b2bc8ab7916ba065f7d60531952466ee5ab3d3 Mon Sep 17 00:00:00 2001 From: Christian Meusel Date: Fri, 30 Aug 2024 21:17:15 +0200 Subject: [PATCH] Add hardware tests for setting baud rates --- Cargo.toml | 1 + tests/test_baudrate.rs | 191 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 tests/test_baudrate.rs diff --git a/Cargo.toml b/Cargo.toml index 59570331..9b222508 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ os_str_bytes = ">=6.0, <6.6.0" quickcheck = "1.0.3" quickcheck_macros = "1.0.0" rstest = { version = "0.12.0", default-features = false } +rstest_reuse = "0.6.0" rustversion = "1.0.16" [features] diff --git a/tests/test_baudrate.rs b/tests/test_baudrate.rs new file mode 100644 index 00000000..4e33b25a --- /dev/null +++ b/tests/test_baudrate.rs @@ -0,0 +1,191 @@ +mod config; + +use config::{hw_config, HardwareConfig}; +use rstest::rstest; +use rstest_reuse::{self, apply, template}; +use serialport::SerialPort; +use std::ops::Range; + +const RESET_BAUD_RATE: u32 = 300; + +/// Returs an acceptance interval for the actual baud rate returned from the device after setting +/// the supplied value. For example, the CP2102 driver on Linux returns the baud rate actually +/// configured a the device rather than the the value set. +fn accepted_actual_baud_for(baud: u32) -> Range { + let delta = baud / 200; + baud.checked_sub(delta).unwrap()..baud.checked_add(delta).unwrap() +} + +fn check_baud_rate(port: &dyn SerialPort, baud: u32) { + let accepted = accepted_actual_baud_for(baud); + let actual = port.baud_rate().unwrap(); + assert!(accepted.contains(&actual)); +} + +#[template] +#[rstest] +#[case(9600)] +#[case(57600)] +#[case(115200)] +fn standard_baud_rates(#[case] baud: u32) {} + +#[template] +#[rstest] +#[case(1000)] +#[case(42000)] +#[case(100000)] +fn non_standard_baud_rates(#[case] baud: u32) {} + +/// Test cases for setting the baud rate via [`SerialPortBuilder`]. +mod builder { + use super::*; + + #[apply(standard_baud_rates)] + #[cfg_attr(feature = "ignore-hardware-tests", ignore)] + fn test_standard_baud_rate(hw_config: HardwareConfig, #[case] baud: u32) { + let port = serialport::new(hw_config.port_1, RESET_BAUD_RATE) + .baud_rate(baud) + .open() + .unwrap(); + check_baud_rate(port.as_ref(), baud); + } + + #[apply(non_standard_baud_rates)] + #[cfg_attr( + any( + feature = "ignore-hardware-tests", + not(all(target_os = "linux", target_env = "musl")), + ), + ignore + )] + fn test_non_standard_baud_rate_fails_where_not_supported( + hw_config: HardwareConfig, + #[case] baud: u32, + ) { + let res = serialport::new(hw_config.port_1, RESET_BAUD_RATE) + .baud_rate(baud) + .open(); + assert!(res.is_err()); + } + + #[apply(non_standard_baud_rates)] + #[cfg_attr( + any( + feature = "ignore-hardware-tests", + all(target_os = "linux", target_env = "musl"), + ), + ignore + )] + fn test_non_standard_baud_rate_succeeds_where_supported( + hw_config: HardwareConfig, + #[case] baud: u32, + ) { + let port = serialport::new(hw_config.port_1, RESET_BAUD_RATE) + .baud_rate(baud) + .open() + .unwrap(); + check_baud_rate(port.as_ref(), baud); + } +} + +/// Test cases for setting the baud rate via [`serialport::new`]. +mod new { + use super::*; + + #[apply(standard_baud_rates)] + #[cfg_attr(feature = "ignore-hardware-tests", ignore)] + fn test_standard_baud_rate(hw_config: HardwareConfig, #[case] baud: u32) { + let port = serialport::new(hw_config.port_1, baud).open().unwrap(); + check_baud_rate(port.as_ref(), baud); + } + + #[apply(non_standard_baud_rates)] + #[cfg_attr( + any( + feature = "ignore-hardware-tests", + not(all(target_os = "linux", target_env = "musl")), + ), + ignore + )] + fn test_non_standard_baud_rate_fails_where_not_supported( + hw_config: HardwareConfig, + #[case] baud: u32, + ) { + assert!(serialport::new(hw_config.port_1, baud).open().is_err()); + } + + #[apply(non_standard_baud_rates)] + #[cfg_attr( + any( + feature = "ignore-hardware-tests", + all(target_os = "linux", target_env = "musl"), + ), + ignore + )] + fn test_non_standard_baud_rate_succeeds_where_supported( + hw_config: HardwareConfig, + #[case] baud: u32, + ) { + let port = serialport::new(hw_config.port_1, baud).open().unwrap(); + check_baud_rate(port.as_ref(), baud); + } +} + +/// Test cases for setting the baud rate via [`SerialPort::set_baud`]. +mod set_baud { + use super::*; + + #[apply(standard_baud_rates)] + #[cfg_attr(feature = "ignore-hardware-tests", ignore)] + fn test_standard_baud_rate(hw_config: HardwareConfig, #[case] baud: u32) { + let mut port = serialport::new(hw_config.port_1, RESET_BAUD_RATE) + .open() + .unwrap(); + check_baud_rate(port.as_ref(), RESET_BAUD_RATE); + + port.set_baud_rate(baud).unwrap(); + check_baud_rate(port.as_ref(), baud); + } + + #[apply(non_standard_baud_rates)] + #[cfg_attr( + any( + feature = "ignore-hardware-tests", + not(all(target_os = "linux", target_env = "musl")), + ), + ignore + )] + fn test_non_standard_baud_rate_fails_where_not_supported( + hw_config: HardwareConfig, + #[case] baud: u32, + ) { + let mut port = serialport::new(hw_config.port_1, RESET_BAUD_RATE) + .open() + .unwrap(); + check_baud_rate(port.as_ref(), RESET_BAUD_RATE); + + assert!(port.set_baud_rate(baud).is_err()); + check_baud_rate(port.as_ref(), RESET_BAUD_RATE); + } + + #[apply(non_standard_baud_rates)] + #[cfg_attr( + any( + feature = "ignore-hardware-tests", + all(target_os = "linux", target_env = "musl"), + ), + ignore + )] + fn test_non_standard_baud_rate_succeeds_where_supported( + hw_config: HardwareConfig, + #[case] baud: u32, + ) { + let mut port = serialport::new(hw_config.port_1, RESET_BAUD_RATE) + .open() + .unwrap(); + check_baud_rate(port.as_ref(), RESET_BAUD_RATE); + + port.set_baud_rate(baud).unwrap(); + check_baud_rate(port.as_ref(), baud); + } +}