#[path = "../../../os-virtio-features/src/lib.rs"] mod virtio_features; use virtio_features::{Error, Negotiator, Phase, VERSION_1}; const OPTIONAL: u64 = 1 << 5; const EXTRA: u64 = 1 << 28; #[test] fn os_virtio_features_positive() { let mut model = Negotiator::new(); let generation = model.observe_reset(0).unwrap(); model.acknowledge(generation, 1).unwrap(); model.driver(generation, 3).unwrap(); let offered = VERSION_1 | OPTIONAL | EXTRA | 1 << 60; model.propose(generation, offered, VERSION_1 | OPTIONAL | EXTRA, VERSION_1 | OPTIONAL | EXTRA, VERSION_1, &[(EXTRA, OPTIONAL)]).unwrap(); assert_eq!(model.snapshot().phase, Phase::Proposed); model.observe_features_ok(generation, 0xb).unwrap(); model.observe_driver_ok(generation, 0xf).unwrap(); assert_eq!(model.snapshot().phase, Phase::DriverOk); let later = model.observe_reset(0).unwrap(); assert!(later.0 > generation.0); assert_eq!(model.snapshot().accepted, 0); assert_eq!(model.acknowledge(generation, 1), Err(Error::StaleGeneration)); model.release(later).unwrap(); assert_eq!(model.snapshot().phase, Phase::Idle); } #[test] fn os_virtio_features_negative() { let mut model = Negotiator::new(); assert_eq!(model.observe_reset(1), Err(Error::ResetNotObserved)); let generation = model.observe_reset(0).unwrap(); assert_eq!(model.release(generation), Ok(())); let generation = model.observe_reset(0).unwrap(); assert_eq!(model.driver(generation, 3), Err(Error::WrongPhase)); assert_eq!(model.acknowledge(generation, 3), Err(Error::DeviceRejected)); model.acknowledge(generation, 1).unwrap(); model.driver(generation, 3).unwrap(); let before = model.snapshot(); assert_eq!(model.propose(generation, VERSION_1, VERSION_1 | OPTIONAL, VERSION_1 | OPTIONAL, VERSION_1, &[]), Err(Error::UnsupportedFeature)); assert_eq!(model.propose(generation, VERSION_1 | OPTIONAL, VERSION_1 | OPTIONAL, VERSION_1, VERSION_1, &[]), Err(Error::UnsupportedFeature)); assert_eq!(model.propose(generation, VERSION_1 | OPTIONAL, OPTIONAL, VERSION_1 | OPTIONAL, VERSION_1, &[]), Err(Error::MissingRequired)); assert_eq!(model.propose(generation, VERSION_1 | OPTIONAL | EXTRA, VERSION_1 | EXTRA, VERSION_1 | OPTIONAL | EXTRA, VERSION_1, &[(EXTRA, OPTIONAL)]), Err(Error::MissingDependency)); assert_eq!(model.snapshot(), before); model.propose(generation, VERSION_1 | OPTIONAL, VERSION_1, VERSION_1, VERSION_1, &[]).unwrap(); let proposed = model.snapshot(); assert_eq!(model.release(generation), Err(Error::StillActive)); assert_eq!(model.propose(generation, VERSION_1, VERSION_1, VERSION_1, VERSION_1, &[]), Err(Error::WrongPhase)); assert_eq!(model.snapshot(), proposed); assert_eq!(model.observe_features_ok(generation, 3), Err(Error::DeviceRejected)); assert_eq!(model.snapshot().phase, Phase::Failed); assert_eq!(model.release(generation), Err(Error::StillActive)); let next = model.observe_reset(0).unwrap(); model.release(next).unwrap(); }