Skip to content

Commit db2224a

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 7c5a10b commit db2224a

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
@@ -709,27 +709,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
709709
#[cfg(test)]
710710
mod tests {
711711
#![allow(clippy::undocumented_unsafe_blocks)]
712+
712713
use super::*;
713-
#[cfg(feature = "backend-mmap")]
714-
use crate::bytes::ByteValued;
715-
#[cfg(feature = "backend-mmap")]
716-
use crate::GuestAddress;
717-
#[cfg(feature = "backend-mmap")]
718714
use std::time::{Duration, Instant};
719715

720-
use vmm_sys_util::tempfile::TempFile;
721-
722-
#[cfg(feature = "backend-mmap")]
723-
type GuestMemoryMmap = crate::GuestMemoryMmap<()>;
724-
725716
#[cfg(feature = "backend-mmap")]
726-
fn make_image(size: u8) -> Vec<u8> {
727-
let mut image: Vec<u8> = Vec::with_capacity(size as usize);
728-
for i in 0..size {
729-
image.push(i);
730-
}
731-
image
732-
}
717+
use crate::mmap::tests::AnyBackend;
718+
use crate::ByteValued;
719+
use vmm_sys_util::tempfile::TempFile;
733720

734721
#[test]
735722
fn test_file_offset() {
@@ -744,19 +731,29 @@ mod tests {
744731
}
745732

746733
#[cfg(feature = "backend-mmap")]
734+
fn make_image(size: u8) -> Vec<u8> {
735+
let mut image: Vec<u8> = Vec::with_capacity(size as usize);
736+
for i in 0..size {
737+
image.push(i);
738+
}
739+
image
740+
}
741+
747742
#[test]
743+
#[cfg(feature = "backend-mmap")]
748744
fn checked_read_from() {
749745
let start_addr1 = GuestAddress(0x0);
750746
let start_addr2 = GuestAddress(0x40);
751-
let mem = GuestMemoryMmap::from_ranges(&[(start_addr1, 64), (start_addr2, 64)]).unwrap();
752-
let image = make_image(0x80);
753-
let offset = GuestAddress(0x30);
754-
let count: usize = 0x20;
755-
assert_eq!(
756-
0x20_usize,
757-
mem.read_volatile_from(offset, &mut image.as_slice(), count)
758-
.unwrap()
759-
);
747+
for mem in AnyBackend::all(&[(start_addr1, 64, None), (start_addr2, 64, None)]) {
748+
let image = make_image(0x80);
749+
let offset = GuestAddress(0x30);
750+
let count: usize = 0x20;
751+
assert_eq!(
752+
0x20_usize,
753+
mem.read_volatile_from(offset, &mut image.as_slice(), count)
754+
.unwrap()
755+
);
756+
}
760757
}
761758

762759
// Runs the provided closure in a loop, until at least `duration` time units have elapsed.
@@ -785,8 +782,8 @@ mod tests {
785782
// flips all the bits of the member with every write, while the reader checks that every byte
786783
// has the same value (and thus it did not do a non-atomic access). The test succeeds if
787784
// no mismatch is detected after performing accesses for a pre-determined amount of time.
788-
#[cfg(feature = "backend-mmap")]
789785
#[cfg(not(miri))] // This test simulates a race condition between guest and vmm
786+
#[cfg(feature = "backend-mmap")]
790787
fn non_atomic_access_helper<T>()
791788
where
792789
T: ByteValued
@@ -823,69 +820,68 @@ mod tests {
823820
// The address where we start writing/reading a Data<T> value.
824821
let data_start = GuestAddress((region_len - mem::size_of::<T>()) as u64);
825822

826-
let mem = GuestMemoryMmap::from_ranges(&[
827-
(start, region_len),
828-
(start.unchecked_add(region_len as u64), region_len),
829-
])
830-
.unwrap();
831-
832-
// Need to clone this and move it into the new thread we create.
833-
let mem2 = mem.clone();
834-
// Just some bytes.
835-
let some_bytes = [1u8, 2, 4, 16, 32, 64, 128, 255];
836-
837-
let mut data = Data {
838-
val: T::from(0u8),
839-
some_bytes,
840-
};
841-
842-
// Simple check that cross-region write/read is ok.
843-
mem.write_obj(data, data_start).unwrap();
844-
let read_data = mem.read_obj::<Data<T>>(data_start).unwrap();
845-
assert_eq!(read_data, data);
846-
847-
let t = thread::spawn(move || {
848-
let mut count: u64 = 0;
849-
850-
loop_timed(Duration::from_secs(3), || {
851-
let data = mem2.read_obj::<Data<T>>(data_start).unwrap();
852-
853-
// Every time data is written to memory by the other thread, the value of
854-
// data.val alternates between 0 and T::MAX, so the inner bytes should always
855-
// have the same value. If they don't match, it means we read a partial value,
856-
// so the access was not atomic.
857-
let bytes = data.val.into().to_le_bytes();
858-
for i in 1..mem::size_of::<T>() {
859-
if bytes[0] != bytes[i] {
860-
panic!(
861-
"val bytes don't match {:?} after {} iterations",
862-
&bytes[..mem::size_of::<T>()],
863-
count
864-
);
823+
for mem in AnyBackend::all(&[
824+
(start, region_len, None),
825+
(start.unchecked_add(region_len as u64), region_len, None),
826+
]) {
827+
// Need to clone this and move it into the new thread we create.
828+
let mem2 = mem.clone();
829+
// Just some bytes.
830+
let some_bytes = [1u8, 2, 4, 16, 32, 64, 128, 255];
831+
832+
let mut data = Data {
833+
val: T::from(0u8),
834+
some_bytes,
835+
};
836+
837+
// Simple check that cross-region write/read is ok.
838+
mem.write_obj(data, data_start).unwrap();
839+
let read_data = mem.read_obj::<Data<T>>(data_start).unwrap();
840+
assert_eq!(read_data, data);
841+
842+
let t = thread::spawn(move || {
843+
let mut count: u64 = 0;
844+
845+
loop_timed(Duration::from_secs(3), || {
846+
let data = mem2.read_obj::<Data<T>>(data_start).unwrap();
847+
848+
// Every time data is written to memory by the other thread, the value of
849+
// data.val alternates between 0 and T::MAX, so the inner bytes should always
850+
// have the same value. If they don't match, it means we read a partial value,
851+
// so the access was not atomic.
852+
let bytes = data.val.into().to_le_bytes();
853+
for i in 1..mem::size_of::<T>() {
854+
if bytes[0] != bytes[i] {
855+
panic!(
856+
"val bytes don't match {:?} after {} iterations",
857+
&bytes[..mem::size_of::<T>()],
858+
count
859+
);
860+
}
865861
}
866-
}
867-
count += 1;
862+
count += 1;
863+
});
868864
});
869-
});
870865

871-
// Write the object while flipping the bits of data.val over and over again.
872-
loop_timed(Duration::from_secs(3), || {
873-
mem.write_obj(data, data_start).unwrap();
874-
data.val = !data.val;
875-
});
866+
// Write the object while flipping the bits of data.val over and over again.
867+
loop_timed(Duration::from_secs(3), || {
868+
mem.write_obj(data, data_start).unwrap();
869+
data.val = !data.val;
870+
});
876871

877-
t.join().unwrap()
872+
t.join().unwrap()
873+
}
878874
}
879875

880-
#[cfg(feature = "backend-mmap")]
881876
#[test]
882877
#[cfg(not(miri))]
878+
#[cfg(feature = "backend-mmap")]
883879
fn test_non_atomic_access() {
884880
non_atomic_access_helper::<u16>()
885881
}
886882

887-
#[cfg(feature = "backend-mmap")]
888883
#[test]
884+
#[cfg(feature = "backend-mmap")]
889885
fn test_zero_length_accesses() {
890886
#[derive(Default, Clone, Copy)]
891887
#[repr(C)]
@@ -896,47 +892,49 @@ mod tests {
896892
unsafe impl ByteValued for ZeroSizedStruct {}
897893

898894
let addr = GuestAddress(0x1000);
899-
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
900-
let obj = ZeroSizedStruct::default();
901-
let mut image = make_image(0x80);
902-
903-
assert_eq!(mem.write(&[], addr).unwrap(), 0);
904-
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
905-
906-
assert!(mem.write_slice(&[], addr).is_ok());
907-
assert!(mem.read_slice(&mut [], addr).is_ok());
908-
909-
assert!(mem.write_obj(obj, addr).is_ok());
910-
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
911-
912-
assert_eq!(
913-
mem.read_volatile_from(addr, &mut image.as_slice(), 0)
914-
.unwrap(),
915-
0
916-
);
917-
918-
assert!(mem
919-
.read_exact_volatile_from(addr, &mut image.as_slice(), 0)
920-
.is_ok());
921-
922-
assert_eq!(
923-
mem.write_volatile_to(addr, &mut image.as_mut_slice(), 0)
924-
.unwrap(),
925-
0
926-
);
927-
928-
assert!(mem
929-
.write_all_volatile_to(addr, &mut image.as_mut_slice(), 0)
930-
.is_ok());
895+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
896+
let obj = ZeroSizedStruct::default();
897+
let mut image = make_image(0x80);
898+
899+
assert_eq!(mem.write(&[], addr).unwrap(), 0);
900+
assert_eq!(mem.read(&mut [], addr).unwrap(), 0);
901+
902+
assert!(mem.write_slice(&[], addr).is_ok());
903+
assert!(mem.read_slice(&mut [], addr).is_ok());
904+
905+
assert!(mem.write_obj(obj, addr).is_ok());
906+
assert!(mem.read_obj::<ZeroSizedStruct>(addr).is_ok());
907+
908+
assert_eq!(
909+
mem.read_volatile_from(addr, &mut image.as_slice(), 0)
910+
.unwrap(),
911+
0
912+
);
913+
914+
assert!(mem
915+
.read_exact_volatile_from(addr, &mut image.as_slice(), 0)
916+
.is_ok());
917+
918+
assert_eq!(
919+
mem.write_volatile_to(addr, &mut image.as_mut_slice(), 0)
920+
.unwrap(),
921+
0
922+
);
923+
924+
assert!(mem
925+
.write_all_volatile_to(addr, &mut image.as_mut_slice(), 0)
926+
.is_ok());
927+
}
931928
}
932929

933-
#[cfg(feature = "backend-mmap")]
934930
#[cfg(target_os = "linux")]
935931
#[test]
932+
#[cfg(feature = "backend-mmap")]
936933
fn test_guest_memory_mmap_is_hugetlbfs() {
937934
let addr = GuestAddress(0x1000);
938-
let mem = GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
939-
let r = mem.find_region(addr).unwrap();
940-
assert_eq!(r.is_hugetlbfs(), None);
935+
for mem in AnyBackend::all(&[(addr, 0x1000, None)]) {
936+
let r = mem.find_region(addr).unwrap();
937+
assert_eq!(r.is_hugetlbfs(), None);
938+
}
941939
}
942940
}

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)