From 51507aaaad15dd10dd8d918d3dc7adb123b5341d Mon Sep 17 00:00:00 2001 From: Caleb Bourg Date: Thu, 27 Oct 2022 18:44:07 -0700 Subject: [PATCH] add integration tests for protocol errors --- esp32-wroom-rp/src/protocol.rs | 2 + esp32-wroom-rp/src/spi.rs | 5 +- host-tests/tests/spi.rs | 129 ++++++++++++++++++++++++++++++++- 3 files changed, 133 insertions(+), 3 deletions(-) diff --git a/esp32-wroom-rp/src/protocol.rs b/esp32-wroom-rp/src/protocol.rs index 579de4e..b89cd95 100644 --- a/esp32-wroom-rp/src/protocol.rs +++ b/esp32-wroom-rp/src/protocol.rs @@ -239,6 +239,8 @@ pub(crate) struct NinaProtocolHandler<'a, B, C> { pub control_pins: &'a mut C, } +// TODO: look at Nina Firmware code to understand conditions +// that lead to NinaProtocolVersionMismatch #[derive(Debug, PartialEq)] pub enum ProtocolError { NinaProtocolVersionMismatch, diff --git a/esp32-wroom-rp/src/spi.rs b/esp32-wroom-rp/src/spi.rs index 1cddcba..b2f30d8 100644 --- a/esp32-wroom-rp/src/spi.rs +++ b/esp32-wroom-rp/src/spi.rs @@ -15,6 +15,9 @@ use embedded_hal::blocking::spi::Transfer; use core::convert::Infallible; +// FIXME: remove before commit +//use defmt_rtt as _; + // TODO: this should eventually move into NinaCommandHandler #[repr(u8)] #[derive(Debug)] @@ -199,8 +202,6 @@ where for byte in buf { let write_buf = &mut [byte]; - // FIXME: temporary for test writing debugging - defmt::debug!("0x{:02x}, ", write_buf[0]); self.bus.transfer(write_buf).ok(); } diff --git a/host-tests/tests/spi.rs b/host-tests/tests/spi.rs index 1557348..6beeddb 100644 --- a/host-tests/tests/spi.rs +++ b/host-tests/tests/spi.rs @@ -1,5 +1,4 @@ use embedded_hal_mock::delay::MockNoop; -use embedded_hal_mock::pin::{Mock as PinMock, State as PinState, Transaction as PinTransaction}; use embedded_hal_mock::spi; use esp32_wroom_rp::gpio::EspControlInterface; @@ -31,6 +30,134 @@ impl EspControlInterface for EspControlMock { } } +#[test] +fn too_many_parameters_error() { + let spi_expectations = vec![ + // send_cmd() + spi::Transaction::transfer(vec![0xe0], vec![0x0]), + spi::Transaction::transfer(vec![0x37], vec![0x0]), + spi::Transaction::transfer(vec![0x0], vec![0x0]), + spi::Transaction::transfer(vec![0xee], vec![0x0]), + // wait_response_cmd() + spi::Transaction::transfer(vec![0xff], vec![0xe0]), + spi::Transaction::transfer(vec![0xff], vec![0xb7]), + spi::Transaction::transfer(vec![0xff], vec![0x1]), + // test relies on max number of parameters being 8. This will probably change + // as we understand more. + spi::Transaction::transfer(vec![0xff], vec![0x9]), + ]; + let mut spi = spi::Mock::new(&spi_expectations); + + let mut delay = MockNoop::new(); + + let mut pins = EspControlMock {}; + + let mut wifi = Wifi::init(&mut spi, &mut pins, &mut delay).ok().unwrap(); + let f = wifi.firmware_version(); + + assert_eq!( + f.unwrap_err(), + esp32_wroom_rp::Error::Protocol(esp32_wroom_rp::protocol::ProtocolError::TooManyParameters) + ); + + spi.done(); +} + +#[test] +fn invalid_number_of_parameters_error() { + let spi_expectations = vec![ + // send_cmd() + spi::Transaction::transfer(vec![0xe0], vec![0x0]), + spi::Transaction::transfer(vec![0x37], vec![0x0]), + spi::Transaction::transfer(vec![0x0], vec![0x0]), + spi::Transaction::transfer(vec![0xee], vec![0x0]), + // wait_response_cmd() + spi::Transaction::transfer(vec![0xff], vec![0xe0]), + spi::Transaction::transfer(vec![0xff], vec![0xb7]), + spi::Transaction::transfer(vec![0xff], vec![0x0]), + ]; + let mut spi = spi::Mock::new(&spi_expectations); + + let mut delay = MockNoop::new(); + + let mut pins = EspControlMock {}; + + let mut wifi = Wifi::init(&mut spi, &mut pins, &mut delay).ok().unwrap(); + let f = wifi.firmware_version(); + + assert_eq!( + f.unwrap_err(), + esp32_wroom_rp::Error::Protocol( + esp32_wroom_rp::protocol::ProtocolError::InvalidNumberOfParameters + ) + ); + + spi.done(); +} + +#[test] +fn invalid_command_induces_invalid_command_error() { + let spi_expectations = vec![ + // send_cmd() + spi::Transaction::transfer(vec![0xe0], vec![0x0]), + spi::Transaction::transfer(vec![0x37], vec![0x0]), + spi::Transaction::transfer(vec![0x0], vec![0x0]), + spi::Transaction::transfer(vec![0xee], vec![0x0]), + // wait_response_cmd() + spi::Transaction::transfer(vec![0xff], vec![0xe0]), + spi::Transaction::transfer(vec![0xff], vec![0x0]), + ]; + let mut spi = spi::Mock::new(&spi_expectations); + + let mut delay = MockNoop::new(); + + let mut pins = EspControlMock {}; + + let mut wifi = Wifi::init(&mut spi, &mut pins, &mut delay).ok().unwrap(); + let f = wifi.firmware_version(); + + assert_eq!( + f.unwrap_err(), + esp32_wroom_rp::Error::Protocol(esp32_wroom_rp::protocol::ProtocolError::InvalidCommand) + ); + + spi.done(); +} + +#[test] +fn timeout_induces_communication_timeout_error() { + let mut spi_expectations = vec![ + // send_cmd() + spi::Transaction::transfer(vec![0xe0], vec![0x0]), + spi::Transaction::transfer(vec![0x37], vec![0x0]), + spi::Transaction::transfer(vec![0x0], vec![0x0]), + spi::Transaction::transfer(vec![0xee], vec![0x0]), + ]; + + // simulate reading 1000 bytes which will exhaust the retry limit. + for _ in 0..1000 { + spi_expectations.push(spi::Transaction::transfer(vec![0xff], vec![0x0])) + } + + let mut spi = spi::Mock::new(&spi_expectations); + + let mut delay = MockNoop::new(); + + let mut pins = EspControlMock {}; + + let mut wifi = Wifi::init(&mut spi, &mut pins, &mut delay).ok().unwrap(); + let f = wifi.firmware_version(); + + assert_eq!( + f.unwrap_err(), + esp32_wroom_rp::Error::Protocol( + esp32_wroom_rp::protocol::ProtocolError::CommunicationTimeout + ) + ); + + spi.done(); +} + #[test] fn invalid_command_induces_nina_protocol_version_mismatch_error() { let spi_expectations = vec![