devices: i8042: add read_and_write unit test
@@ -6,6 +6,8 @@ use sys_util::EventFd;
use BusDevice;
+const RESET_CMD: u8 = 0xfe;
+
/// A i8042 PS/2 controller that emulates just enough to shutdown the machine.
pub struct I8042Device {
reset_evt: EventFd,
@@ -28,10 +30,44 @@ impl BusDevice for I8042Device {
}
fn write(&mut self, offset: u64, data: &[u8]) {
- if data.len() == 1 && data[0] == 0xfe && offset == 0 {
+ if data.len() == 1 && data[0] == RESET_CMD && offset == 0 {
if let Err(e) = self.reset_evt.write(1) {
error!("failed to trigger i8042 reset event: {:?}", e);
}
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn i8042_read_and_write() {
+ let reset_evt = EventFd::new().unwrap();
+ let mut i8042 = I8042Device::new(reset_evt.try_clone().unwrap());
+
+ // check if reading in a 2-length array doesn't have side effects
+ let mut data = [1, 2];
+ i8042.read(0, &mut data);
+ assert_eq!(data, [1, 2]);
+ i8042.read(1, &mut data);
+ assert_eq!(data, [1, 2]);
+
+ // check if reset works
+ // write 1 to the reset event fd, so that read doesn't block in case the event fd
+ // counter doesn't change (for 0 it blocks)
+ assert!(reset_evt.write(1).is_ok());
+ let mut data = [RESET_CMD];
+ i8042.write(0, &mut data);
+ assert_eq!(reset_evt.read(), Ok(2));
+
+ // check if reading with offset 1 doesn't have side effects
+ i8042.read(1, &mut data);
+ assert_eq!(data[0], RESET_CMD);
+
+ // check if reading in a 1-length array with offset 0 returns [0]
+ i8042.read(0, &mut data);
+ assert_eq!(data[0], 0);
+ }
+}
