#[path = "../../../os-pci-discovery/src/capabilities.rs"] mod pci_capabilities; use pci_capabilities::{Capability, ConfigReader, Error, Store, walk}; struct Config { words: [u32; 64], reads: usize, fail_at: Option, } impl Config { fn two_nodes() -> Self { let mut words = [0; 64]; words[0x40 / 4] = 1 | (0x50 << 8); words[0x50 / 4] = 5; Self {words, reads: 0, fail_at: None} } } impl ConfigReader for Config { fn read_dword(&mut self, offset: u8) -> Result { self.reads += 1; if self.fail_at == Some(offset) { return Err(Error::ReadFailed); } Ok(self.words[usize::from(offset) / 4]) } } #[test] fn os_pci_discovery_capabilities_positive() { let mut config = Config::two_nodes(); let mut store = Store::<3>::new(); let chain = store.discover(&mut config, 0x40).unwrap(); assert_eq!(chain.len, 2); assert_eq!(chain.entries, [ Some(Capability {offset: 0x40, id: 1, next: 0x50}), Some(Capability {offset: 0x50, id: 5, next: 0}), None]); assert_eq!(config.reads, 2); assert_eq!(store.snapshot().chain, Some(chain)); assert_eq!(store.snapshot().published_count, 2); let empty = walk::<3>(&mut config, 0).unwrap(); assert_eq!(empty.len, 0); assert_eq!(config.reads, 2); } #[test] fn os_pci_discovery_capabilities_negative() { let mut config = Config::two_nodes(); let mut store = Store::<2>::new(); store.discover(&mut config, 0x40).unwrap(); let before = store.snapshot(); config.words[0x40 / 4] = 1 | (0x40 << 8); assert_eq!(store.discover(&mut config, 0x40), Err(Error::Cycle)); assert_eq!(store.snapshot(), before); assert_eq!(store.discover(&mut config, 0x41), Err(Error::InvalidPointer)); assert_eq!(store.discover(&mut config, 0x3c), Err(Error::InvalidPointer)); assert_eq!(store.snapshot(), before); config.words[0x40 / 4] = 1 | (0x50 << 8); config.words[0x50 / 4] = 5 | (0x60 << 8); assert_eq!(store.discover(&mut config, 0x40), Err(Error::Full)); assert_eq!(store.snapshot(), before); config.words[0x50 / 4] = 5; config.fail_at = Some(0x50); assert_eq!(store.discover(&mut config, 0x40), Err(Error::ReadFailed)); assert_eq!(store.snapshot(), before); }