Skip to content
This repository was archived by the owner on Dec 20, 2021. It is now read-only.

Commit a91898f

Browse files
Samuel Ortizandreeaflorescu
authored andcommitted
fam: Add a unit test for the vfio_irq_set wrapper
Compare the FAM wrapper generated set with a vec_with_array one. Signed-off-by: Samuel Ortiz <[email protected]>
1 parent 735588f commit a91898f

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ fam-wrappers = ["vmm-sys-util"]
1515

1616
[dependencies]
1717
vmm-sys-util = { version = ">=0.2.0", optional = true }
18+
19+
[dev-dependencies]
20+
byteorder = ">=1.2.1"

src/fam_wrappers.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,95 @@ generate_fam_struct_impl!(vfio_irq_set, u8, data, u32, count, MSIX_MAX_VECTORS);
1919
/// elements, this type is implemented using
2020
/// [FamStructWrapper](../vmm_sys_util/fam/struct.FamStructWrapper.html).
2121
pub type IrqSet = FamStructWrapper<vfio_irq_set>;
22+
23+
#[cfg(test)]
24+
mod tests {
25+
extern crate byteorder;
26+
27+
use super::*;
28+
use byteorder::{ByteOrder, LittleEndian};
29+
use std::mem;
30+
31+
fn vec_with_size_in_bytes<T: Default>(size_in_bytes: usize) -> Vec<T> {
32+
let rounded_size = (size_in_bytes + mem::size_of::<T>() - 1) / mem::size_of::<T>();
33+
let mut v = Vec::with_capacity(rounded_size);
34+
for _ in 0..rounded_size {
35+
v.push(T::default())
36+
}
37+
v
38+
}
39+
40+
fn vec_with_array_field<T: Default, F>(count: usize) -> Vec<T> {
41+
let element_space = count * mem::size_of::<F>();
42+
let vec_size_bytes = mem::size_of::<T>() + element_space;
43+
vec_with_size_in_bytes(vec_size_bytes)
44+
}
45+
46+
// Opinionated PartialEq implementation for vfio_irq_set.
47+
impl PartialEq for vfio_irq_set {
48+
fn eq(&self, other: &Self) -> bool {
49+
if self.argsz != other.argsz
50+
|| self.flags != other.flags
51+
|| self.index != other.index
52+
|| self.start != other.start
53+
|| self.count != other.count
54+
{
55+
return false;
56+
}
57+
true
58+
}
59+
}
60+
61+
#[test]
62+
fn irqset_fam_test() {
63+
let event_fds: Vec<u32> = vec![0, 1, 2, 3, 4, 5];
64+
65+
// Build a FAM wrapper for this vfio_irq_set.
66+
let mut irq_set_wrapper = IrqSet::new(event_fds.len() * mem::size_of::<u32>());
67+
let mut irq_set_fam = irq_set_wrapper.as_mut_fam_struct();
68+
69+
let fds_fam = irq_set_fam.as_mut_slice();
70+
for (index, event_fd) in event_fds.iter().enumerate() {
71+
let fds_offset = index * mem::size_of::<u32>();
72+
let fd = &mut fds_fam[fds_offset..fds_offset + mem::size_of::<u32>()];
73+
LittleEndian::write_u32(fd, *event_fd);
74+
}
75+
76+
irq_set_fam.argsz = mem::size_of::<vfio_irq_set>() as u32
77+
+ (event_fds.len() * mem::size_of::<u32>()) as u32;
78+
irq_set_fam.flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
79+
irq_set_fam.index = 1;
80+
irq_set_fam.start = 0;
81+
irq_set_fam.count = event_fds.len() as u32;
82+
83+
// Build the same vfio_irq_set structure with the vec_with_array routines
84+
let mut irq_set_vec = vec_with_array_field::<vfio_irq_set, u32>(event_fds.len());
85+
irq_set_vec[0].argsz = mem::size_of::<vfio_irq_set>() as u32
86+
+ (event_fds.len() * mem::size_of::<u32>()) as u32;
87+
irq_set_vec[0].flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
88+
irq_set_vec[0].index = 1;
89+
irq_set_vec[0].start = 0;
90+
irq_set_vec[0].count = event_fds.len() as u32;
91+
92+
let fds_vec = unsafe {
93+
irq_set_vec[0]
94+
.data
95+
.as_mut_slice(event_fds.len() * mem::size_of::<u32>())
96+
};
97+
for (index, event_fd) in event_fds.iter().enumerate() {
98+
let fds_offset = index * mem::size_of::<u32>();
99+
let fd = &mut fds_vec[fds_offset..fds_offset + mem::size_of::<u32>()];
100+
LittleEndian::write_u32(fd, *event_fd);
101+
}
102+
103+
// Both sets should be identical.
104+
assert_eq!(
105+
irq_set_vec
106+
.iter()
107+
.zip(irq_set_wrapper.into_raw().iter())
108+
.filter(|&(a, b)| a == b)
109+
.count(),
110+
irq_set_vec.len()
111+
);
112+
}
113+
}

0 commit comments

Comments
 (0)