From 181abe47f0b1b97bb5d865d9d2edc97173ccdab4 Mon Sep 17 00:00:00 2001 From: Christian Meusel Date: Fri, 26 Jul 2024 21:34:40 +0200 Subject: [PATCH] Add some more test cases for MODALIAS parsing This includes throwing some random data at parse_modalias at each test run with help of quickcheck. --- Cargo.toml | 2 ++ src/posix/enumerate.rs | 58 +++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7883456e..995c4957 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,8 @@ envconfig = "0.10.0" # 6.6.0) Until then we are tricking the dependency resolver into using a # compatible version by adding it as a direct dependency here. 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 } rustversion = "1.0.16" diff --git a/src/posix/enumerate.rs b/src/posix/enumerate.rs index 4b39dc85..44c44a33 100644 --- a/src/posix/enumerate.rs +++ b/src/posix/enumerate.rs @@ -690,16 +690,56 @@ cfg_if! { } } -#[cfg(all(target_os = "linux", not(target_env = "musl"), feature = "libudev"))] -#[test] -fn parser_modalias() { - const MODALIAS: &str = "usb:v303Ap1001d0101dcEFdsc02dp01ic02isc02ip00in0C"; +#[cfg(all( + test, + target_os = "linux", + not(target_env = "musl"), + feature = "libudev" +))] +mod test { + use super::*; + + use quickcheck_macros::quickcheck; + + #[quickcheck] + fn quickcheck_parse_modalias_does_not_panic_from_random_data(modalias: String) -> bool { + let _ = parse_modalias(&modalias); + true + } + + #[test] + fn parse_modalias_canonical() { + const MODALIAS: &str = "usb:v303Ap1001d0101dcEFdsc02dp01ic02isc02ip00in0C"; - let port_info = parse_modalias(MODALIAS).expect("parse failed"); + let port_info = parse_modalias(MODALIAS).expect("parse failed"); - assert_eq!(port_info.vid, 0x303A, "vendor parse invalid"); - assert_eq!(port_info.pid, 0x1001, "product parse invalid"); + assert_eq!(port_info.vid, 0x303A, "vendor parse invalid"); + assert_eq!(port_info.pid, 0x1001, "product parse invalid"); - #[cfg(feature = "usbportinfo-interface")] - assert_eq!(port_info.interface, Some(0x0C), "interface parse invalid"); + #[cfg(feature = "usbportinfo-interface")] + assert_eq!(port_info.interface, Some(0x0C), "interface parse invalid"); + } + + #[test] + fn parse_modalias_corner_cases() { + assert!(parse_modalias("").is_none()); + assert!(parse_modalias("usb").is_none()); + assert!(parse_modalias("usb:").is_none()); + assert!(parse_modalias("usb:vdcdc").is_none()); + assert!(parse_modalias("usb:pdcdc").is_none()); + + // Just vendor and product IDs. + let info = parse_modalias("usb:vdcdcpabcd").unwrap(); + assert_eq!(info.vid, 0xdcdc); + assert_eq!(info.pid, 0xabcd); + #[cfg(feature = "usbportinfo-interface")] + assert!(info.interface.is_none()); + + // Vendor and product ID plus an interface number. + let info = parse_modalias("usb:v1234p5678indc").unwrap(); + assert_eq!(info.vid, 0x1234); + assert_eq!(info.pid, 0x5678); + #[cfg(feature = "usbportinfo-interface")] + assert_eq!(info.interface, Some(0xdc)); + } }