mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-05 21:15:45 +00:00
devices: serial: Make the serial unit tests pass
Some refactoring has taken place since the unit tests were written: The read/write in BusDevice now take a base address and the interrupt handling code has changed necessitating the need for a new TestInterrupt struct. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
9e372a8e48
commit
224f77500c
@ -173,13 +173,13 @@ mod tests {
|
|||||||
|
|
||||||
struct ConstantDevice;
|
struct ConstantDevice;
|
||||||
impl BusDevice for ConstantDevice {
|
impl BusDevice for ConstantDevice {
|
||||||
fn read(&mut self, offset: u64, data: &mut [u8]) {
|
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
|
||||||
for (i, v) in data.iter_mut().enumerate() {
|
for (i, v) in data.iter_mut().enumerate() {
|
||||||
*v = (offset as u8) + (i as u8);
|
*v = (offset as u8) + (i as u8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, offset: u64, data: &[u8]) {
|
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
|
||||||
for (i, v) in data.iter().enumerate() {
|
for (i, v) in data.iter().enumerate() {
|
||||||
assert_eq!(*v, (offset as u8) + (i as u8))
|
assert_eq!(*v, (offset as u8) + (i as u8))
|
||||||
}
|
}
|
||||||
|
@ -233,6 +233,23 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use vmm_sys_util::EventFd;
|
||||||
|
|
||||||
|
struct TestInterrupt {
|
||||||
|
event_fd: EventFd,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Interrupt for TestInterrupt {
|
||||||
|
fn deliver(&self) -> result::Result<(), std::io::Error> {
|
||||||
|
self.event_fd.write(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestInterrupt {
|
||||||
|
fn new(event_fd: EventFd) -> Self {
|
||||||
|
TestInterrupt { event_fd }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct SharedBuffer {
|
struct SharedBuffer {
|
||||||
@ -258,15 +275,17 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serial_output() {
|
fn serial_output() {
|
||||||
let intr_evt = EventFd::new().unwrap();
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
let serial_out = SharedBuffer::new();
|
let serial_out = SharedBuffer::new();
|
||||||
|
let mut serial = Serial::new_out(
|
||||||
|
Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
|
||||||
|
Box::new(serial_out.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
let mut serial = Serial::new_out(intr_evt, Box::new(serial_out.clone()));
|
serial.write(0, DATA as u64, &['x' as u8, 'y' as u8]);
|
||||||
|
serial.write(0, DATA as u64, &['a' as u8]);
|
||||||
serial.write(DATA as u64, &['x' as u8, 'y' as u8]);
|
serial.write(0, DATA as u64, &['b' as u8]);
|
||||||
serial.write(DATA as u64, &['a' as u8]);
|
serial.write(0, DATA as u64, &['c' as u8]);
|
||||||
serial.write(DATA as u64, &['b' as u8]);
|
|
||||||
serial.write(DATA as u64, &['c' as u8]);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
serial_out.buf.lock().unwrap().as_slice(),
|
serial_out.buf.lock().unwrap().as_slice(),
|
||||||
&['a' as u8, 'b' as u8, 'c' as u8]
|
&['a' as u8, 'b' as u8, 'c' as u8]
|
||||||
@ -275,16 +294,17 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serial_input() {
|
fn serial_input() {
|
||||||
let intr_evt = EventFd::new().unwrap();
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
let serial_out = SharedBuffer::new();
|
let serial_out = SharedBuffer::new();
|
||||||
|
let mut serial = Serial::new_out(
|
||||||
let mut serial =
|
Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())),
|
||||||
Serial::new_out(intr_evt.try_clone().unwrap(), Box::new(serial_out.clone()));
|
Box::new(serial_out.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
|
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
|
||||||
// counter doesn't change (for 0 it blocks)
|
// counter doesn't change (for 0 it blocks)
|
||||||
assert!(intr_evt.write(1).is_ok());
|
assert!(intr_evt.write(1).is_ok());
|
||||||
serial.write(IER as u64, &[IER_RECV_BIT]);
|
serial.write(0, IER as u64, &[IER_RECV_BIT]);
|
||||||
serial
|
serial
|
||||||
.queue_input_bytes(&['a' as u8, 'b' as u8, 'c' as u8])
|
.queue_input_bytes(&['a' as u8, 'b' as u8, 'c' as u8])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -293,90 +313,97 @@ mod tests {
|
|||||||
|
|
||||||
// check if reading in a 2-length array doesn't have side effects
|
// check if reading in a 2-length array doesn't have side effects
|
||||||
let mut data = [0u8, 0u8];
|
let mut data = [0u8, 0u8];
|
||||||
serial.read(DATA as u64, &mut data[..]);
|
serial.read(0, DATA as u64, &mut data[..]);
|
||||||
assert_eq!(data, [0u8, 0u8]);
|
assert_eq!(data, [0u8, 0u8]);
|
||||||
|
|
||||||
let mut data = [0u8];
|
let mut data = [0u8];
|
||||||
serial.read(LSR as u64, &mut data[..]);
|
serial.read(0, LSR as u64, &mut data[..]);
|
||||||
assert_ne!(data[0] & LSR_DATA_BIT, 0);
|
assert_ne!(data[0] & LSR_DATA_BIT, 0);
|
||||||
serial.read(DATA as u64, &mut data[..]);
|
serial.read(0, DATA as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 'a' as u8);
|
assert_eq!(data[0], 'a' as u8);
|
||||||
serial.read(DATA as u64, &mut data[..]);
|
serial.read(0, DATA as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 'b' as u8);
|
assert_eq!(data[0], 'b' as u8);
|
||||||
serial.read(DATA as u64, &mut data[..]);
|
serial.read(0, DATA as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 'c' as u8);
|
assert_eq!(data[0], 'c' as u8);
|
||||||
|
|
||||||
// check if reading from the largest u8 offset returns 0
|
// check if reading from the largest u8 offset returns 0
|
||||||
serial.read(0xff, &mut data[..]);
|
serial.read(0, 0xff, &mut data[..]);
|
||||||
assert_eq!(data[0], 0);
|
assert_eq!(data[0], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serial_thr() {
|
fn serial_thr() {
|
||||||
let intr_evt = EventFd::new().unwrap();
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
let mut serial = Serial::new_sink(intr_evt.try_clone().unwrap());
|
let mut serial =
|
||||||
|
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
|
||||||
|
|
||||||
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
|
// write 1 to the interrupt event fd, so that read doesn't block in case the event fd
|
||||||
// counter doesn't change (for 0 it blocks)
|
// counter doesn't change (for 0 it blocks)
|
||||||
assert!(intr_evt.write(1).is_ok());
|
assert!(intr_evt.write(1).is_ok());
|
||||||
serial.write(IER as u64, &[IER_THR_BIT]);
|
serial.write(0, IER as u64, &[IER_THR_BIT]);
|
||||||
serial.write(DATA as u64, &['a' as u8]);
|
serial.write(0, DATA as u64, &['a' as u8]);
|
||||||
|
|
||||||
assert_eq!(intr_evt.read().unwrap(), 2);
|
assert_eq!(intr_evt.read().unwrap(), 2);
|
||||||
let mut data = [0u8];
|
let mut data = [0u8];
|
||||||
serial.read(IER as u64, &mut data[..]);
|
serial.read(0, IER as u64, &mut data[..]);
|
||||||
assert_eq!(data[0] & IER_FIFO_BITS, IER_THR_BIT);
|
assert_eq!(data[0] & IER_FIFO_BITS, IER_THR_BIT);
|
||||||
serial.read(IIR as u64, &mut data[..]);
|
serial.read(0, IIR as u64, &mut data[..]);
|
||||||
assert_ne!(data[0] & IIR_THR_BIT, 0);
|
assert_ne!(data[0] & IIR_THR_BIT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serial_dlab() {
|
fn serial_dlab() {
|
||||||
let mut serial = Serial::new_sink(EventFd::new().unwrap());
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
|
let mut serial =
|
||||||
|
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
|
||||||
|
|
||||||
serial.write(LCR as u64, &[LCR_DLAB_BIT as u8]);
|
serial.write(0, LCR as u64, &[LCR_DLAB_BIT as u8]);
|
||||||
serial.write(DLAB_LOW as u64, &[0x12 as u8]);
|
serial.write(0, DLAB_LOW as u64, &[0x12 as u8]);
|
||||||
serial.write(DLAB_HIGH as u64, &[0x34 as u8]);
|
serial.write(0, DLAB_HIGH as u64, &[0x34 as u8]);
|
||||||
|
|
||||||
let mut data = [0u8];
|
let mut data = [0u8];
|
||||||
serial.read(LCR as u64, &mut data[..]);
|
serial.read(0, LCR as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], LCR_DLAB_BIT as u8);
|
assert_eq!(data[0], LCR_DLAB_BIT as u8);
|
||||||
serial.read(DLAB_LOW as u64, &mut data[..]);
|
serial.read(0, DLAB_LOW as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 0x12);
|
assert_eq!(data[0], 0x12);
|
||||||
serial.read(DLAB_HIGH as u64, &mut data[..]);
|
serial.read(0, DLAB_HIGH as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 0x34);
|
assert_eq!(data[0], 0x34);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serial_modem() {
|
fn serial_modem() {
|
||||||
let mut serial = Serial::new_sink(EventFd::new().unwrap());
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
|
let mut serial =
|
||||||
|
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
|
||||||
|
|
||||||
serial.write(MCR as u64, &[MCR_LOOP_BIT as u8]);
|
serial.write(0, MCR as u64, &[MCR_LOOP_BIT as u8]);
|
||||||
serial.write(DATA as u64, &['a' as u8]);
|
serial.write(0, DATA as u64, &['a' as u8]);
|
||||||
serial.write(DATA as u64, &['b' as u8]);
|
serial.write(0, DATA as u64, &['b' as u8]);
|
||||||
serial.write(DATA as u64, &['c' as u8]);
|
serial.write(0, DATA as u64, &['c' as u8]);
|
||||||
|
|
||||||
let mut data = [0u8];
|
let mut data = [0u8];
|
||||||
serial.read(MSR as u64, &mut data[..]);
|
serial.read(0, MSR as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], DEFAULT_MODEM_STATUS as u8);
|
assert_eq!(data[0], DEFAULT_MODEM_STATUS as u8);
|
||||||
serial.read(MCR as u64, &mut data[..]);
|
serial.read(0, MCR as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], MCR_LOOP_BIT as u8);
|
assert_eq!(data[0], MCR_LOOP_BIT as u8);
|
||||||
serial.read(DATA as u64, &mut data[..]);
|
serial.read(0, DATA as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 'a' as u8);
|
assert_eq!(data[0], 'a' as u8);
|
||||||
serial.read(DATA as u64, &mut data[..]);
|
serial.read(0, DATA as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 'b' as u8);
|
assert_eq!(data[0], 'b' as u8);
|
||||||
serial.read(DATA as u64, &mut data[..]);
|
serial.read(0, DATA as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 'c' as u8);
|
assert_eq!(data[0], 'c' as u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serial_scratch() {
|
fn serial_scratch() {
|
||||||
let mut serial = Serial::new_sink(EventFd::new().unwrap());
|
let intr_evt = EventFd::new(0).unwrap();
|
||||||
|
let mut serial =
|
||||||
|
Serial::new_sink(Box::new(TestInterrupt::new(intr_evt.try_clone().unwrap())));
|
||||||
|
|
||||||
serial.write(SCR as u64, &[0x12 as u8]);
|
serial.write(0, SCR as u64, &[0x12 as u8]);
|
||||||
|
|
||||||
let mut data = [0u8];
|
let mut data = [0u8];
|
||||||
serial.read(SCR as u64, &mut data[..]);
|
serial.read(0, SCR as u64, &mut data[..]);
|
||||||
assert_eq!(data[0], 0x12 as u8);
|
assert_eq!(data[0], 0x12 as u8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user