Skip to content

Commit 4ab3783

Browse files
committed
refactor(test): use new text fixtures in guest_memory.rs
There are a lot of backend-mmap dependent tests in guest_memory.rs, so have them also use the new capabilities to run with all supported backends. Signed-off-by: Patrick Roy <[email protected]>
1 parent c6f5a63 commit 4ab3783

File tree

2 files changed

+117
-117
lines changed

2 files changed

+117
-117
lines changed

src/guest_memory.rs

Lines changed: 111 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -606,27 +606,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
606606
#[cfg(test)]
607607
mod tests {
608608
#![allow(clippy::undocumented_unsafe_blocks)]
609+
609610
use super::*;
610-
#[cfg(feature = "backend-mmap")]
611-
use crate::bytes::ByteValued;
612-
#[cfg(feature = "backend-mmap")]
613-
use crate::GuestAddress;
614-
#[cfg(feature = "backend-mmap")]
615611
use std::time::{Duration, Instant};
616612

617-
use vmm_sys_util::tempfile::TempFile;
618-
619-
#[cfg(feature = "backend-mmap")]
620-
type GuestMemoryMmap = crate::GuestMemoryMmap<()>;
621-
622613
#[cfg(feature = "backend-mmap")]
623-
fn make_image(size: u8) -> Vec<u8> {
624-
let mut image: Vec<u8> = Vec::with_capacity(size as usize);
625-
for i in 0..size {
626-
image.push(i);
627-
}
628-
image
629-
}
614+
use crate::mmap::tests::AnyBackend;
615+
use crate::ByteValued;
616+
use vmm_sys_util::tempfile::TempFile;
630617

631618
#[test]
632619
fn test_file_offset() {
@@ -641,19 +628,29 @@ mod tests {
641628
}
642629

643630
#[cfg(feature = "backend-mmap")]
631+
fn make_image(size: u8) -> Vec<u8> {
632+
let mut image: Vec<u8> = Vec::with_capacity(size as usize);
633+
for i in 0..size {
634+
image.push(i);
635+
}
636+
image
637+
}
638+
644639
#[test]
640+
#[cfg(feature = "backend-mmap")]
645641
fn checked_read_from() {
646642
let start_addr1 = GuestAddress(0x0);
647643
let start_addr2 = GuestAddress(0x40);
648-
let mem = GuestMemoryMmap::from_ranges(&[(start_addr1, 64), (start_addr2, 64)]).unwrap();
649-
let image = make_image(0x80);
650-
let offset = GuestAddress(0x30);
651-
let count: usize = 0x20;
652-
assert_eq!(
653-
0x20_usize,
654-
mem.read_volatile_from(offset, &mut image.as_slice(), count)
655-
.unwrap()
656-
);
644+
for mem in AnyBackend::all(&[(start_addr1, 64, None), (start_addr2, 64, None)]) {
645+
let image = make_image(0x80);
646+
let offset = GuestAddress(0x30);
647+
let count: usize = 0x20;
648+
assert_eq!(
649+
0x20_usize,
650+
mem.read_volatile_from(offset, &mut image.as_slice(), count)
651+
.unwrap()
652+
);
653+
}
657654
}
658655

659656
// Runs the provided closure in a loop, until at least `duration` time units have elapsed.
@@ -682,8 +679,8 @@ mod tests {
682679
// flips all the bits of the member with every write, while the reader checks that every byte
683680
// has the same value (and thus it did not do a non-atomic access). The test succeeds if
684681
// no mismatch is detected after performing accesses for a pre-determined amount of time.
685-
#[cfg(feature = "backend-mmap")]
686682
#[cfg(not(miri))] // This test simulates a race condition between guest and vmm
683+
#[cfg(feature = "backend-mmap")]
687684
fn non_atomic_access_helper<T>()
688685
where
689686
T: ByteValued
@@ -720,69 +717,68 @@ mod tests {
720717
// The address where we start writing/reading a Data<T> value.
721718
let data_start = GuestAddress((region_len - mem::size_of::<T>()) as u64);
722719

723-
let mem = GuestMemoryMmap::from_ranges(&[
724-
(start, region_len),
725-
(start.unchecked_add(region_len as u64), region_len),
726-
])
727-
.unwrap();
728-
729-
// Need to clone this and move it into the new thread we create.
730-
let mem2 = mem.clone();
731-
// Just some bytes.
732-
let some_bytes = [1u8, 2, 4, 16, 32, 64, 128, 255];
733-
734-
let mut data = Data {
735-
val: T::from(0u8),
736-
some_bytes,
737-
};
738-
739-
// Simple check that cross-region write/read is ok.
740-
mem.write_obj(data, data_start).unwrap();
741-
let read_data = mem.read_obj::<Data<T>>(data_start).unwrap();
742-
assert_eq!(read_data, data);
743-
744-
let t = thread::spawn(move || {
745-
let mut count: u64 = 0;
746-
747-
loop_timed(Duration::from_secs(3), || {
748-
let data = mem2.read_obj::<Data<T>>(data_start).unwrap();
749-
750-
// Every time data is written to memory by the other thread, the value of
751-
// data.val alternates between 0 and T::MAX, so the inner bytes should always
752-
// have the same value. If they don't match, it means we read a partial value,
753-
// so the access was not atomic.
754-
let bytes = data.val.into().to_le_bytes();
755-
for i in 1..mem::size_of::<T>() {
756-
if bytes[0] != bytes[i] {
757-
panic!(
758-
"val bytes don't match {:?} after {} iterations",
759-
&bytes[..mem::size_of::<T>()],
760-
count
761-
);
720+
for mem in AnyBackend::all(&[
721+
(start, region_len, None),
722+
(start.unchecked_add(region_len as u64), region_len, None),
723+
]) {
724+
// Need to clone this and move it into the new thread we create.
725+
let mem2 = mem.clone();
726+
// Just some bytes.
727+
let some_bytes = [1u8, 2, 4, 16, 32, 64, 128, 255];
728+
729+
let mut data = Data {
730+
val: T::from(0u8),
731+
some_bytes,
732+
};
733+
734+
// Simple check that cross-region write/read is ok.
735+
mem.write_obj(data, data_start).unwrap();
736+
let read_data = mem.read_obj::<Data<T>>(data_start).unwrap();
737+
assert_eq!(read_data, data);
738+
739+
let t = thread::spawn(move || {
740+
let mut count: u64 = 0;
741+
742+
loop_timed(Duration::from_secs(3), || {
743+
let data = mem2.read_obj::<Data<T>>(data_start).unwrap();
744+
745+
// Every time data is written to memory by the other thread, the value of
746+
// data.val alternates between 0 and T::MAX, so the inner bytes should always
747+
// have the same value. If they don't match, it means we read a partial value,
748+
// so the access was not atomic.
749+
let bytes = data.val.into().to_le_bytes();
750+
for i in 1..mem::size_of::<T>() {
751+
if bytes[0] != bytes[i] {
752+
panic!(
753+
"val bytes don't match {:?} after {} iterations",
754+
&bytes[..mem::size_of::<T>()],
755+
count
756+
);
757+
}
762758
}
763-
}
764-
count += 1;
759+
count += 1;
760+
});
765761
});
766-
});
767762

768-
// Write the object while flipping the bits of data.val over and over again.
769-
loop_timed(Duration::from_secs(3), || {
770-
mem.write_obj(data, data_start).unwrap();
771-
data.val = !data.val;
772-
});
763+
// Write the object while flipping the bits of data.val over and over again.
764+
loop_timed(Duration::from_secs(3), || {
765+
mem.write_obj(data, data_start).unwrap();
766+
data.val = !data.val;
767+
});
773768

774-
t.join().unwrap()
769+
t.join().unwrap()
770+
}
775771
}
776772

777-
#[cfg(feature = "backend-mmap")]
778773
#[test]
779774
#[cfg(not(miri))]
775+
#[cfg(feature = "backend-mmap")]
780776
fn test_non_atomic_access() {
781777
non_atomic_access_helper::<u16>()
782778
}
783779

784-
#[cfg(feature = "backend-mmap")]
785780
#[test]
781+
#[cfg(feature = "backend-mmap")]
786782
fn test_zero_length_accesses() {
787783
#[derive(Default, Clone, Copy)]
788784
#[repr(C)]
@@ -793,47 +789,49 @@ mod tests {
793789
unsafe impl ByteValued for ZeroSizedStruct {}
794790

795791
let addr = GuestAddress(0x1000);
796-
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
797-
let obj = ZeroSizedStruct::default();
798-
let mut image = make_image(0x80);
799-
800-
assert_eq!(mem.write(&[], addr).unwrap(), 0);
801-
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
802-
803-
assert!(mem.write_slice(&[], addr).is_ok());
804-
assert!(mem.read_slice(&mut [], addr).is_ok());
805-
806-
assert!(mem.write_obj(obj, addr).is_ok());
807-
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
808-
809-
assert_eq!(
810-
mem.read_volatile_from(addr, &mut image.as_slice(), 0)
811-
.unwrap(),
812-
0
813-
);
814-
815-
assert!(mem
816-
.read_exact_volatile_from(addr, &mut image.as_slice(), 0)
817-
.is_ok());
818-
819-
assert_eq!(
820-
mem.write_volatile_to(addr, &mut image.as_mut_slice(), 0)
821-
.unwrap(),
822-
0
823-
);
824-
825-
assert!(mem
826-
.write_all_volatile_to(addr, &mut image.as_mut_slice(), 0)
827-
.is_ok());
792+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
793+
let obj = ZeroSizedStruct::default();
794+
let mut image = make_image(0x80);
795+
796+
assert_eq!(mem.write(&[], addr).unwrap(), 0);
797+
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
798+
799+
assert!(mem.write_slice(&[], addr).is_ok());
800+
assert!(mem.read_slice(&mut [], addr).is_ok());
801+
802+
assert!(mem.write_obj(obj, addr).is_ok());
803+
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
804+
805+
assert_eq!(
806+
mem.read_volatile_from(addr, &mut image.as_slice(), 0)
807+
.unwrap(),
808+
0
809+
);
810+
811+
assert!(mem
812+
.read_exact_volatile_from(addr, &mut image.as_slice(), 0)
813+
.is_ok());
814+
815+
assert_eq!(
816+
mem.write_volatile_to(addr, &mut image.as_mut_slice(), 0)
817+
.unwrap(),
818+
0
819+
);
820+
821+
assert!(mem
822+
.write_all_volatile_to(addr, &mut image.as_mut_slice(), 0)
823+
.is_ok());
824+
}
828825
}
829826

830-
#[cfg(feature = "backend-mmap")]
831827
#[cfg(target_os = "linux")]
832828
#[test]
829+
#[cfg(feature = "backend-mmap")]
833830
fn test_guest_memory_mmap_is_hugetlbfs() {
834831
let addr = GuestAddress(0x1000);
835-
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
836-
let r = mem.find_region(addr).unwrap();
837-
assert_eq!(r.is_hugetlbfs(), None);
832+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
833+
let r = mem.find_region(addr).unwrap();
834+
assert_eq!(r.is_hugetlbfs(), None);
835+
}
838836
}
839837
}

src/mmap.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl<B: NewBitmap> GuestMemoryMmap<B> {
242242
}
243243

244244
#[cfg(test)]
245-
mod tests {
245+
pub(crate) mod tests {
246246
#![allow(clippy::undocumented_unsafe_blocks)]
247247
extern crate vmm_sys_util;
248248

@@ -262,13 +262,13 @@ mod tests {
262262
macro_rules! any_backend {
263263
($($(#[$attr:meta])* $backend: ident[$region: path]), *) => {
264264
#[derive(Debug)]
265-
enum AnyRegion {
265+
pub enum AnyRegion {
266266
$(
267267
$(#[$attr])* $backend($region)
268268
),*
269269
}
270270

271-
type AnyBackend = $crate::GuestRegionCollection<AnyRegion>;
271+
pub type AnyBackend = $crate::GuestRegionCollection<AnyRegion>;
272272

273273
impl $crate::GuestMemoryRegion for AnyRegion {
274274
type B = ();
@@ -395,7 +395,9 @@ mod tests {
395395
transpose(striped)
396396
}
397397

398-
fn all(regions: &[(GuestAddress, usize, Option<FileOffset>)]) -> Vec<AnyBackend> {
398+
pub(crate) fn all(
399+
regions: &[(GuestAddress, usize, Option<FileOffset>)],
400+
) -> Vec<AnyBackend> {
399401
let striped = regions
400402
.iter()
401403
.map(|(addr, size, file)| AnyRegion::all(*addr, *size, file))

0 commit comments

Comments
 (0)