#[path = "../../../os-device-registry/src/lib.rs"] mod device_registry; use device_registry::{DeviceKey, DeviceKind, Error, ResourceError, ResourceKind, ResourceRange, ResourceRegistry, Transport}; const BLOCK: DeviceKey = DeviceKey { transport: Transport::Mmio, location: 0x0a00_3e00 }; const NETWORK: DeviceKey = DeviceKey { transport: Transport::Mmio, location: 0x0a00_3c00 }; const BLOCK_RESOURCES: [ResourceRange; 3] = [ ResourceRange { kind: ResourceKind::Mmio, start: 0x0a00_3000, length: 0x1000 }, ResourceRange { kind: ResourceKind::Irq, start: 48, length: 1 }, ResourceRange { kind: ResourceKind::Dma, start: 0x4400_0000, length: 0x4000 }, ]; const NETWORK_RESOURCES: [ResourceRange; 3] = [ ResourceRange { kind: ResourceKind::Mmio, start: 0x0a00_4000, length: 0x1000 }, ResourceRange { kind: ResourceKind::Irq, start: 49, length: 1 }, ResourceRange { kind: ResourceKind::Dma, start: 0x4400_4000, length: 0x4000 }, ]; #[test] fn os_device_registry_resources_positive() { let mut registry = ResourceRegistry::<2, 6>::new(); let block = registry.attach(BLOCK, DeviceKind::Block, &BLOCK_RESOURCES).unwrap(); let network = registry.attach(NETWORK, DeviceKind::Network, &NETWORK_RESOURCES).unwrap(); assert_eq!((registry.device_count(), registry.claim_count()), (2, 6)); assert_eq!(registry.get(block).unwrap().key, BLOCK); assert_eq!(registry.get(network).unwrap().key, NETWORK); let snapshot = registry.snapshot(); assert_eq!(snapshot.claims.iter().flatten().filter(|claim| claim.owner == block).count(), 3); assert_eq!(snapshot.claims.iter().flatten().filter(|claim| claim.owner == network).count(), 3); assert_eq!(registry.detach(block).unwrap().key, BLOCK); assert_eq!((registry.device_count(), registry.claim_count()), (1, 3)); let fresh = registry.attach(BLOCK, DeviceKind::Block, &BLOCK_RESOURCES).unwrap(); assert_eq!(fresh.slot(), block.slot()); assert_eq!(fresh.generation(), block.generation() + 1); assert_eq!(registry.get(block), Err(ResourceError::Device(Error::StaleHandle))); assert_eq!((registry.device_count(), registry.claim_count()), (2, 6)); assert_eq!(registry.get(network).unwrap().key, NETWORK); } #[test] fn os_device_registry_resources_negative() { let mut registry = ResourceRegistry::<2, 6>::new(); let block = registry.attach(BLOCK, DeviceKind::Block, &BLOCK_RESOURCES).unwrap(); let before = registry.snapshot(); let overlapping_bar = [ ResourceRange { kind: ResourceKind::Mmio, start: 0x0a00_3800, length: 0x1000 }, NETWORK_RESOURCES[1], NETWORK_RESOURCES[2], ]; assert_eq!(registry.attach(NETWORK, DeviceKind::Network, &overlapping_bar), Err(ResourceError::Conflict)); assert_eq!(registry.snapshot(), before); assert_eq!(registry.get(block).unwrap().key, BLOCK); assert_eq!(registry.attach(NETWORK, DeviceKind::Network, &[]), Err(ResourceError::EmptyResources)); assert_eq!(registry.snapshot(), before); let invalid = [ResourceRange { kind: ResourceKind::Mmio, start: u64::MAX, length: 2 }]; assert_eq!(registry.attach(NETWORK, DeviceKind::Network, &invalid), Err(ResourceError::InvalidRange)); assert_eq!(registry.snapshot(), before); let overlapping_request = [NETWORK_RESOURCES[0], ResourceRange { kind: ResourceKind::Mmio, start: 0x0a00_4800, length: 0x1000 }]; assert_eq!(registry.attach(NETWORK, DeviceKind::Network, &overlapping_request), Err(ResourceError::Conflict)); assert_eq!(registry.snapshot(), before); let network = registry.attach(NETWORK, DeviceKind::Network, &NETWORK_RESOURCES).unwrap(); assert_eq!((registry.device_count(), registry.claim_count()), (2, 6)); let full = registry.snapshot(); assert_eq!(registry.detach(block).unwrap().key, BLOCK); let after_detach = registry.snapshot(); assert_eq!(registry.detach(block), Err(ResourceError::Device(Error::StaleHandle))); assert_eq!(registry.snapshot(), after_detach); assert_eq!(registry.get(network).unwrap().key, NETWORK); assert_ne!(registry.snapshot(), full); }