From c3d1a446c4af7b0aa67110dcd5165592f71520b7 Mon Sep 17 00:00:00 2001 From: Henri Date: Tue, 15 Apr 2025 14:40:35 +0200 Subject: [PATCH] Fix failing device tests --- .github/workflows/rust.yml | 2 + Cargo.toml | 1 + src/sync_stream.rs | 20 ------- src/tests/attribute_set.rs | 7 +-- src/tests/mod.rs | 86 ------------------------------ tests/common/mod.rs | 86 ++++++++++++++++++++++++++++++ {src/tests => tests}/compensate.rs | 8 ++- tests/device.rs | 25 +++++++++ 8 files changed, 124 insertions(+), 111 deletions(-) create mode 100644 tests/common/mod.rs rename {src/tests => tests}/compensate.rs (91%) create mode 100644 tests/device.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index bf979f46..7192356d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -26,6 +26,8 @@ jobs: run: cargo test --verbose - name: Doc run: cargo doc --all-features + - name: Run device tests + run: sudo -E env "PATH=$PATH" cargo test --tests --features device-test cross-linux: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 902be789..fc0f185e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ rust-version = "1.64" serde = ["dep:serde"] tokio = ["dep:tokio"] stream-trait = ["tokio", "futures-core"] +device-test = [] [dependencies] libc = { version = "0.2.121", features = ["extra_traits"]} diff --git a/src/sync_stream.rs b/src/sync_stream.rs index eaa18721..c3605f43 100644 --- a/src/sync_stream.rs +++ b/src/sync_stream.rs @@ -889,7 +889,6 @@ pub use tokio_stream::EventStream; #[cfg(test)] mod tests { use super::*; - use crate::tests::{get_test_device, key_event}; fn result_events_iter( events: &[input_event], @@ -957,23 +956,4 @@ mod tests { assert_eq!(next(), (Err(false), None)); assert_eq!(next(), (Err(false), None)); } - - #[test] - pub fn test_get_key_state() -> Result<(), Box> { - let (input, mut output) = get_test_device()?; - - output.emit(&[key_event(KeyCode::KEY_DOT, 1)])?; - - assert_eq!(1, input.get_key_state()?.iter().count()); - assert!(input - .get_key_state()? - .iter() - .all(|e| e.code() == KeyCode::KEY_DOT.code())); - - output.emit(&[key_event(KeyCode::KEY_DOT, 0)])?; - - assert_eq!(0, input.get_key_state()?.iter().count()); - - Ok(()) - } } diff --git a/src/tests/attribute_set.rs b/src/tests/attribute_set.rs index 178a864d..c9de6ad6 100644 --- a/src/tests/attribute_set.rs +++ b/src/tests/attribute_set.rs @@ -1,11 +1,12 @@ -use crate::tests::get_test_device; use crate::{AttributeSet, KeyCode}; #[test] pub fn test_iteration_keys() -> std::io::Result<()> { - let (input, _) = get_test_device()?; + let mut keys: AttributeSet = AttributeSet::new(); - let keys = input.supported_keys().unwrap(); + for code in 1..59 { + keys.insert(KeyCode::new(code)); + } assert_eq!(58, keys.iter().count()); diff --git a/src/tests/mod.rs b/src/tests/mod.rs index b6059054..d7a2659c 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,87 +1 @@ mod attribute_set; -mod compensate; - -use crate::uinput::VirtualDevice; -use crate::{AttributeSet, BusType, Device, EventType, InputEvent, InputId, KeyCode, SwitchCode}; -use std::path::PathBuf; -use std::thread; -use std::time::Duration; - -pub fn key_click(key: KeyCode) -> Vec { - vec![key_event(key, 1), key_event(key, 0)] -} - -pub fn key_event(key: KeyCode, key_state: i32) -> InputEvent { - InputEvent::new(EventType::KEY.0, key.code(), key_state) -} - -pub fn get_test_device() -> std::io::Result<(Device, VirtualDevice)> { - let (name, output) = get_device()?; - - let mut input = Device::open(&name)?; - - input.grab()?; - - Ok((input, output)) -} - -pub fn get_device() -> std::io::Result<(PathBuf, VirtualDevice)> { - let mut keys: AttributeSet = AttributeSet::new(); - for code in 1..59 { - let key = KeyCode::new(code); - let name = format!("{:?}", key); - if name.starts_with("KEY_") { - keys.insert(key); - } - } - - let mut sw: AttributeSet = AttributeSet::new(); - - sw.insert(SwitchCode::SW_LID); - sw.insert(SwitchCode::SW_TABLET_MODE); - - let mut device = VirtualDevice::builder()? - .input_id(InputId::new(BusType::BUS_USB, 0x1234, 0x5678, 0x111)) - .name("test device") - .with_keys(&keys)? - .with_switches(&sw)? - .build()?; - - // Fetch name. - let d: Vec = device - .enumerate_dev_nodes_blocking()? - .map(|p| p.unwrap()) - .collect(); - - thread::sleep(Duration::from_millis(100)); // To avoid permission denied. - - Ok((d.first().unwrap().clone(), device)) -} - -pub fn final_dot_state(start_state: i32, events: impl Iterator) -> i32 { - events.fold(start_state, |state, ev| { - if ev.event_type() == EventType::KEY && ev.code() == KeyCode::KEY_DOT.code() { - if ev.value() == 0 { - 0 - } else { - 1 - } - } else { - state - } - }) -} - -pub fn final_event_state(key: KeyCode, events: &Vec) -> Option { - events.iter().fold(None, |state, ev| { - if ev.event_type() == EventType::KEY && ev.code() == key.code() { - if ev.value() == 0 { - Some(0) - } else { - Some(1) - } - } else { - state - } - }) -} diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 00000000..d01385bd --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,86 @@ +#![allow(dead_code)] + +use evdev::uinput::VirtualDevice; +use evdev::{AttributeSet, BusType, Device, EventType, InputEvent, InputId, KeyCode, SwitchCode}; +use std::path::PathBuf; +use std::thread; +use std::time::Duration; + +pub fn key_click(key: KeyCode) -> Vec { + vec![key_event(key, 1), key_event(key, 0)] +} + +pub fn key_event(key: KeyCode, key_state: i32) -> InputEvent { + InputEvent::new(EventType::KEY.0, key.code(), key_state) +} + +pub fn get_test_device() -> std::io::Result<(Device, VirtualDevice)> { + let (name, output) = get_device()?; + + let mut input = Device::open(&name)?; + + input.grab()?; + + Ok((input, output)) +} + +pub fn get_device() -> std::io::Result<(PathBuf, VirtualDevice)> { + let mut keys: AttributeSet = AttributeSet::new(); + for code in 1..59 { + let key = KeyCode::new(code); + let name = format!("{:?}", key); + if name.starts_with("KEY_") { + keys.insert(key); + } + } + + let mut sw: AttributeSet = AttributeSet::new(); + + sw.insert(SwitchCode::SW_LID); + sw.insert(SwitchCode::SW_TABLET_MODE); + + let mut device = VirtualDevice::builder()? + .input_id(InputId::new(BusType::BUS_USB, 0x1234, 0x5678, 0x111)) + .name("test device") + .with_keys(&keys)? + .with_switches(&sw)? + .build()?; + + // Fetch name. + let d: Vec = device + .enumerate_dev_nodes_blocking()? + .map(|p| p.unwrap()) + .collect(); + + thread::sleep(Duration::from_millis(100)); // To avoid permission denied. + + Ok((d.first().unwrap().clone(), device)) +} + +pub fn final_dot_state(start_state: i32, events: impl Iterator) -> i32 { + events.fold(start_state, |state, ev| { + if ev.event_type() == EventType::KEY && ev.code() == KeyCode::KEY_DOT.code() { + if ev.value() == 0 { + 0 + } else { + 1 + } + } else { + state + } + }) +} + +pub fn final_event_state(key: KeyCode, events: &Vec) -> Option { + events.iter().fold(None, |state, ev| { + if ev.event_type() == EventType::KEY && ev.code() == key.code() { + if ev.value() == 0 { + Some(0) + } else { + Some(1) + } + } else { + state + } + }) +} diff --git a/src/tests/compensate.rs b/tests/compensate.rs similarity index 91% rename from src/tests/compensate.rs rename to tests/compensate.rs index be130f4a..51b58cd3 100644 --- a/src/tests/compensate.rs +++ b/tests/compensate.rs @@ -1,5 +1,9 @@ -use crate::tests::{final_dot_state, final_event_state, get_test_device, key_click, key_event}; -use crate::{EventType, InputEvent, KeyCode, SwitchCode}; +#![cfg(feature = "device-test")] + +mod common; + +use common::{final_dot_state, final_event_state, get_test_device, key_click, key_event}; +use evdev::{EventType, InputEvent, KeyCode, SwitchCode}; #[test] pub fn test_compensate_keys() -> std::io::Result<()> { diff --git a/tests/device.rs b/tests/device.rs new file mode 100644 index 00000000..8ce21602 --- /dev/null +++ b/tests/device.rs @@ -0,0 +1,25 @@ +#![cfg(feature = "device-test")] + +mod common; + +use common::{get_test_device, key_event}; +use evdev::KeyCode; + +#[test] +pub fn test_get_key_state() -> Result<(), Box> { + let (input, mut output) = get_test_device()?; + + output.emit(&[key_event(KeyCode::KEY_DOT, 1)])?; + + assert_eq!(1, input.get_key_state()?.iter().count()); + assert!(input + .get_key_state()? + .iter() + .all(|e| e.code() == KeyCode::KEY_DOT.code())); + + output.emit(&[key_event(KeyCode::KEY_DOT, 0)])?; + + assert_eq!(0, input.get_key_state()?.iter().count()); + + Ok(()) +}