Skip to content

Commit 0f2e831

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 4b94bcc commit 0f2e831

File tree

2 files changed

+111
-111
lines changed

2 files changed

+111
-111
lines changed

src/guest_memory.rs

Lines changed: 105 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -726,27 +726,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
726726
#[cfg(test)]
727727
mod tests {
728728
#![allow(clippy::undocumented_unsafe_blocks)]
729+
729730
use super::*;
730-
#[cfg(feature = "backend-mmap")]
731-
use crate::bytes::ByteValued;
732-
#[cfg(feature = "backend-mmap")]
733-
use crate::GuestAddress;
734-
#[cfg(feature = "backend-mmap")]
735731
use std::time::{Duration, Instant};
736732

737-
use vmm_sys_util::tempfile::TempFile;
738-
739-
#[cfg(feature = "backend-mmap")]
740-
type GuestMemoryMmap = crate::GuestMemoryMmap<()>;
741-
742733
#[cfg(feature = "backend-mmap")]
743-
fn make_image(size: u8) -> Vec<u8> {
744-
let mut image: Vec<u8> = Vec::with_capacity(size as usize);
745-
for i in 0..size {
746-
image.push(i);
747-
}
748-
image
749-
}
734+
use crate::mmap::tests::AnyBackend;
735+
use crate::ByteValued;
736+
use vmm_sys_util::tempfile::TempFile;
750737

751738
#[test]
752739
fn test_file_offset() {
@@ -761,19 +748,29 @@ mod tests {
761748
}
762749

763750
#[cfg(feature = "backend-mmap")]
751+
fn make_image(size: u8) -> Vec<u8> {
752+
let mut image: Vec<u8> = Vec::with_capacity(size as usize);
753+
for i in 0..size {
754+
image.push(i);
755+
}
756+
image
757+
}
758+
764759
#[test]
760+
#[cfg(feature = "backend-mmap")]
765761
fn checked_read_from() {
766762
let start_addr1 = GuestAddress(0x0);
767763
let start_addr2 = GuestAddress(0x40);
768-
let mem = GuestMemoryMmap::from_ranges(&[(start_addr1, 64), (start_addr2, 64)]).unwrap();
769-
let image = make_image(0x80);
770-
let offset = GuestAddress(0x30);
771-
let count: usize = 0x20;
772-
assert_eq!(
773-
0x20_usize,
774-
mem.read_volatile_from(offset, &mut image.as_slice(), count)
775-
.unwrap()
776-
);
764+
for mem in AnyBackend::all(&[(start_addr1, 64, None), (start_addr2, 64, None)]) {
765+
let image = make_image(0x80);
766+
let offset = GuestAddress(0x30);
767+
let count: usize = 0x20;
768+
assert_eq!(
769+
0x20_usize,
770+
mem.read_volatile_from(offset, &mut image.as_slice(), count)
771+
.unwrap()
772+
);
773+
}
777774
}
778775

779776
// Runs the provided closure in a loop, until at least `duration` time units have elapsed.
@@ -802,8 +799,8 @@ mod tests {
802799
// flips all the bits of the member with every write, while the reader checks that every byte
803800
// has the same value (and thus it did not do a non-atomic access). The test succeeds if
804801
// no mismatch is detected after performing accesses for a pre-determined amount of time.
805-
#[cfg(feature = "backend-mmap")]
806802
#[cfg(not(miri))] // This test simulates a race condition between guest and vmm
803+
#[cfg(feature = "backend-mmap")]
807804
fn non_atomic_access_helper<T>()
808805
where
809806
T: ByteValued
@@ -840,69 +837,68 @@ mod tests {
840837
// The address where we start writing/reading a Data<T> value.
841838
let data_start = GuestAddress((region_len - mem::size_of::<T>()) as u64);
842839

843-
let mem = GuestMemoryMmap::from_ranges(&[
844-
(start, region_len),
845-
(start.unchecked_add(region_len as u64), region_len),
846-
])
847-
.unwrap();
848-
849-
// Need to clone this and move it into the new thread we create.
850-
let mem2 = mem.clone();
851-
// Just some bytes.
852-
let some_bytes = [1u8, 2, 4, 16, 32, 64, 128, 255];
853-
854-
let mut data = Data {
855-
val: T::from(0u8),
856-
some_bytes,
857-
};
858-
859-
// Simple check that cross-region write/read is ok.
860-
mem.write_obj(data, data_start).unwrap();
861-
let read_data = mem.read_obj::<Data<T>>(data_start).unwrap();
862-
assert_eq!(read_data, data);
863-
864-
let t = thread::spawn(move || {
865-
let mut count: u64 = 0;
866-
867-
loop_timed(Duration::from_secs(3), || {
868-
let data = mem2.read_obj::<Data<T>>(data_start).unwrap();
869-
870-
// Every time data is written to memory by the other thread, the value of
871-
// data.val alternates between 0 and T::MAX, so the inner bytes should always
872-
// have the same value. If they don't match, it means we read a partial value,
873-
// so the access was not atomic.
874-
let bytes = data.val.into().to_le_bytes();
875-
for i in 1..mem::size_of::<T>() {
876-
if bytes[0] != bytes[i] {
877-
panic!(
878-
"val bytes don't match {:?} after {} iterations",
879-
&bytes[..mem::size_of::<T>()],
880-
count
881-
);
840+
for mem in AnyBackend::all(&[
841+
(start, region_len, None),
842+
(start.unchecked_add(region_len as u64), region_len, None),
843+
]) {
844+
// Need to clone this and move it into the new thread we create.
845+
let mem2 = mem.clone();
846+
// Just some bytes.
847+
let some_bytes = [1u8, 2, 4, 16, 32, 64, 128, 255];
848+
849+
let mut data = Data {
850+
val: T::from(0u8),
851+
some_bytes,
852+
};
853+
854+
// Simple check that cross-region write/read is ok.
855+
mem.write_obj(data, data_start).unwrap();
856+
let read_data = mem.read_obj::<Data<T>>(data_start).unwrap();
857+
assert_eq!(read_data, data);
858+
859+
let t = thread::spawn(move || {
860+
let mut count: u64 = 0;
861+
862+
loop_timed(Duration::from_secs(3), || {
863+
let data = mem2.read_obj::<Data<T>>(data_start).unwrap();
864+
865+
// Every time data is written to memory by the other thread, the value of
866+
// data.val alternates between 0 and T::MAX, so the inner bytes should always
867+
// have the same value. If they don't match, it means we read a partial value,
868+
// so the access was not atomic.
869+
let bytes = data.val.into().to_le_bytes();
870+
for i in 1..mem::size_of::<T>() {
871+
if bytes[0] != bytes[i] {
872+
panic!(
873+
"val bytes don't match {:?} after {} iterations",
874+
&bytes[..mem::size_of::<T>()],
875+
count
876+
);
877+
}
882878
}
883-
}
884-
count += 1;
879+
count += 1;
880+
});
885881
});
886-
});
887882

888-
// Write the object while flipping the bits of data.val over and over again.
889-
loop_timed(Duration::from_secs(3), || {
890-
mem.write_obj(data, data_start).unwrap();
891-
data.val = !data.val;
892-
});
883+
// Write the object while flipping the bits of data.val over and over again.
884+
loop_timed(Duration::from_secs(3), || {
885+
mem.write_obj(data, data_start).unwrap();
886+
data.val = !data.val;
887+
});
893888

894-
t.join().unwrap()
889+
t.join().unwrap()
890+
}
895891
}
896892

897-
#[cfg(feature = "backend-mmap")]
898893
#[test]
899894
#[cfg(not(miri))]
895+
#[cfg(feature = "backend-mmap")]
900896
fn test_non_atomic_access() {
901897
non_atomic_access_helper::<u16>()
902898
}
903899

904-
#[cfg(feature = "backend-mmap")]
905900
#[test]
901+
#[cfg(feature = "backend-mmap")]
906902
fn test_zero_length_accesses() {
907903
#[derive(Default, Clone, Copy)]
908904
#[repr(C)]
@@ -913,47 +909,49 @@ mod tests {
913909
unsafe impl ByteValued for ZeroSizedStruct {}
914910

915911
let addr = GuestAddress(0x1000);
916-
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
917-
let obj = ZeroSizedStruct::default();
918-
let mut image = make_image(0x80);
912+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
913+
let obj = ZeroSizedStruct::default();
914+
let mut image = make_image(0x80);
919915

920-
assert_eq!(mem.write(&[], addr).unwrap(), 0);
921-
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
916+
assert_eq!(mem.write(&[], addr).unwrap(), 0);
917+
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
922918

923-
assert!(mem.write_slice(&[], addr).is_ok());
924-
assert!(mem.read_slice(&mut [], addr).is_ok());
919+
assert!(mem.write_slice(&[], addr).is_ok());
920+
assert!(mem.read_slice(&mut [], addr).is_ok());
925921

926-
assert!(mem.write_obj(obj, addr).is_ok());
927-
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
922+
assert!(mem.write_obj(obj, addr).is_ok());
923+
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
928924

929-
assert_eq!(
930-
mem.read_volatile_from(addr, &mut image.as_slice(), 0)
931-
.unwrap(),
932-
0
933-
);
934-
935-
assert!(mem
936-
.read_exact_volatile_from(addr, &mut image.as_slice(), 0)
937-
.is_ok());
925+
assert_eq!(
926+
mem.read_volatile_from(addr, &mut image.as_slice(), 0)
927+
.unwrap(),
928+
0
929+
);
938930

939-
assert_eq!(
940-
mem.write_volatile_to(addr, &mut image.as_mut_slice(), 0)
941-
.unwrap(),
942-
0
943-
);
931+
assert!(mem
932+
.read_exact_volatile_from(addr, &mut image.as_slice(), 0)
933+
.is_ok());
944934

945-
assert!(mem
946-
.write_all_volatile_to(addr, &mut image.as_mut_slice(), 0)
947-
.is_ok());
935+
assert_eq!(
936+
mem.write_volatile_to(addr, &mut image.as_mut_slice(), 0)
937+
.unwrap(),
938+
0
939+
);
940+
941+
assert!(mem
942+
.write_all_volatile_to(addr, &mut image.as_mut_slice(), 0)
943+
.is_ok());
944+
}
948945
}
949946

950-
#[cfg(feature = "backend-mmap")]
951947
#[cfg(target_os = "linux")]
952948
#[test]
949+
#[cfg(feature = "backend-mmap")]
953950
fn test_guest_memory_mmap_is_hugetlbfs() {
954951
let addr = GuestAddress(0x1000);
955-
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
956-
let r = mem.find_region(addr).unwrap();
957-
assert_eq!(r.is_hugetlbfs(), None);
952+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
953+
let r = mem.find_region(addr).unwrap();
954+
assert_eq!(r.is_hugetlbfs(), None);
955+
}
958956
}
959957
}

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

@@ -236,13 +236,13 @@ mod tests {
236236
macro_rules! any_backend {
237237
($($(#[$attr:meta])* $backend: ident[$region: path]), *) => {
238238
#[derive(Debug)]
239-
enum AnyRegion {
239+
pub enum AnyRegion {
240240
$(
241241
$(#[$attr])* $backend($region)
242242
),*
243243
}
244244

245-
type AnyBackend = $crate::GuestRegionCollection<AnyRegion>;
245+
pub type AnyBackend = $crate::GuestRegionCollection<AnyRegion>;
246246

247247
impl $crate::GuestMemoryRegion for AnyRegion {
248248
type B = ();
@@ -369,7 +369,9 @@ mod tests {
369369
transpose(striped)
370370
}
371371

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

0 commit comments

Comments
 (0)