Skip to content

Commit 217b29e

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 705a13e commit 217b29e

File tree

2 files changed

+111
-109
lines changed

2 files changed

+111
-109
lines changed

src/guest_memory.rs

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

737-
use vmm_sys_util::tempfile::TempFile;
738-
739734
#[cfg(feature = "backend-mmap")]
740-
type GuestMemoryMmap = crate::GuestMemoryMmap<()>;
741-
735+
use crate::mmap::tests::AnyBackend;
742736
#[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-
}
737+
use crate::ByteValued;
738+
use vmm_sys_util::tempfile::TempFile;
750739

751740
#[test]
752741
fn test_file_offset() {
@@ -761,19 +750,29 @@ mod tests {
761750
}
762751

763752
#[cfg(feature = "backend-mmap")]
753+
fn make_image(size: u8) -> Vec<u8> {
754+
let mut image: Vec<u8> = Vec::with_capacity(size as usize);
755+
for i in 0..size {
756+
image.push(i);
757+
}
758+
image
759+
}
760+
764761
#[test]
762+
#[cfg(feature = "backend-mmap")]
765763
fn checked_read_from() {
766764
let start_addr1 = GuestAddress(0x0);
767765
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-
);
766+
for mem in AnyBackend::all(&[(start_addr1, 64, None), (start_addr2, 64, None)]) {
767+
let image = make_image(0x80);
768+
let offset = GuestAddress(0x30);
769+
let count: usize = 0x20;
770+
assert_eq!(
771+
0x20_usize,
772+
mem.read_volatile_from(offset, &mut image.as_slice(), count)
773+
.unwrap()
774+
);
775+
}
777776
}
778777

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

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

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-
});
885+
// Write the object while flipping the bits of data.val over and over again.
886+
loop_timed(Duration::from_secs(3), || {
887+
mem.write_obj(data, data_start).unwrap();
888+
data.val = !data.val;
889+
});
893890

894-
t.join().unwrap()
891+
t.join().unwrap()
892+
}
895893
}
896894

897-
#[cfg(feature = "backend-mmap")]
898895
#[test]
899896
#[cfg(not(miri))]
897+
#[cfg(feature = "backend-mmap")]
900898
fn test_non_atomic_access() {
901899
non_atomic_access_helper::<u16>()
902900
}
903901

904-
#[cfg(feature = "backend-mmap")]
905902
#[test]
903+
#[cfg(feature = "backend-mmap")]
906904
fn test_zero_length_accesses() {
907905
#[derive(Default, Clone, Copy)]
908906
#[repr(C)]
@@ -913,47 +911,49 @@ mod tests {
913911
unsafe impl ByteValued for ZeroSizedStruct {}
914912

915913
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);
914+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
915+
let obj = ZeroSizedStruct::default();
916+
let mut image = make_image(0x80);
919917

920-
assert_eq!(mem.write(&[], addr).unwrap(), 0);
921-
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
918+
assert_eq!(mem.write(&[], addr).unwrap(), 0);
919+
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
922920

923-
assert!(mem.write_slice(&[], addr).is_ok());
924-
assert!(mem.read_slice(&mut [], addr).is_ok());
921+
assert!(mem.write_slice(&[], addr).is_ok());
922+
assert!(mem.read_slice(&mut [], addr).is_ok());
925923

926-
assert!(mem.write_obj(obj, addr).is_ok());
927-
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
924+
assert!(mem.write_obj(obj, addr).is_ok());
925+
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
928926

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());
927+
assert_eq!(
928+
mem.read_volatile_from(addr, &mut image.as_slice(), 0)
929+
.unwrap(),
930+
0
931+
);
938932

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

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

950-
#[cfg(feature = "backend-mmap")]
951949
#[cfg(target_os = "linux")]
952950
#[test]
951+
#[cfg(feature = "backend-mmap")]
953952
fn test_guest_memory_mmap_is_hugetlbfs() {
954953
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);
954+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
955+
let r = mem.find_region(addr).unwrap();
956+
assert_eq!(r.is_hugetlbfs(), None);
957+
}
958958
}
959959
}

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)