Skip to content

Commit 585bee7

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 5db97ea commit 585bee7

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
@@ -608,27 +608,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
608608
#[cfg(test)]
609609
mod tests {
610610
#![allow(clippy::undocumented_unsafe_blocks)]
611+
611612
use super::*;
612-
#[cfg(feature = "backend-mmap")]
613-
use crate::bytes::ByteValued;
614-
#[cfg(feature = "backend-mmap")]
615-
use crate::GuestAddress;
616-
#[cfg(feature = "backend-mmap")]
617613
use std::time::{Duration, Instant};
618614

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

633620
#[test]
634621
fn test_file_offset() {
@@ -643,19 +630,29 @@ mod tests {
643630
}
644631

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

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

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

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

776-
t.join().unwrap()
771+
t.join().unwrap()
772+
}
777773
}
778774

779-
#[cfg(feature = "backend-mmap")]
780775
#[test]
781776
#[cfg(not(miri))]
777+
#[cfg(feature = "backend-mmap")]
782778
fn test_non_atomic_access() {
783779
non_atomic_access_helper::<u16>()
784780
}
785781

786-
#[cfg(feature = "backend-mmap")]
787782
#[test]
783+
#[cfg(feature = "backend-mmap")]
788784
fn test_zero_length_accesses() {
789785
#[derive(Default, Clone, Copy)]
790786
#[repr(C)]
@@ -795,47 +791,49 @@ mod tests {
795791
unsafe impl ByteValued for ZeroSizedStruct {}
796792

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

832-
#[cfg(feature = "backend-mmap")]
833829
#[cfg(target_os = "linux")]
834830
#[test]
831+
#[cfg(feature = "backend-mmap")]
835832
fn test_guest_memory_mmap_is_hugetlbfs() {
836833
let addr = GuestAddress(0x1000);
837-
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
838-
let r = mem.find_region(addr).unwrap();
839-
assert_eq!(r.is_hugetlbfs(), None);
834+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
835+
let r = mem.find_region(addr).unwrap();
836+
assert_eq!(r.is_hugetlbfs(), None);
837+
}
840838
}
841839
}

src/mmap/mod.rs

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

217217
#[cfg(test)]
218-
mod tests {
218+
pub(crate) mod tests {
219219
#![allow(clippy::undocumented_unsafe_blocks)]
220220
extern crate vmm_sys_util;
221221

@@ -234,13 +234,13 @@ mod tests {
234234
macro_rules! any_backend {
235235
($($(#[$attr:meta])* $backend: ident[$region: path]), *) => {
236236
#[derive(Debug)]
237-
enum AnyRegion {
237+
pub enum AnyRegion {
238238
$(
239239
$(#[$attr])* $backend($region)
240240
),*
241241
}
242242

243-
type AnyBackend = $crate::GuestRegionCollection<AnyRegion>;
243+
pub type AnyBackend = $crate::GuestRegionCollection<AnyRegion>;
244244

245245
impl $crate::GuestMemoryRegion for AnyRegion {
246246
type B = ();
@@ -367,7 +367,9 @@ mod tests {
367367
transpose(striped)
368368
}
369369

370-
fn all(regions: &[(GuestAddress, usize, Option<FileOffset>)]) -> Vec<AnyBackend> {
370+
pub(crate) fn all(
371+
regions: &[(GuestAddress, usize, Option<FileOffset>)],
372+
) -> Vec<AnyBackend> {
371373
let striped = regions
372374
.iter()
373375
.map(|(addr, size, file)| AnyRegion::all(*addr, *size, file))

0 commit comments

Comments
 (0)