Skip to content
This repository has been archived by the owner on Nov 6, 2024. It is now read-only.

Commit

Permalink
fam_wrappers: implement PartialEq
Browse files Browse the repository at this point in the history
Implementing PartialEq as helpful for testing. Since the
FamStructWrapper type implementation of PartialEq requires the type
T to implement PartialEq, it is necessary here to compare the
other fields of the type T except entries. entries will be compare
within FamStructWrapper's PartialEq.

Signed-off-by: wllenyj <wllenyj@linux.alibaba.com>
  • Loading branch information
wllenyj authored and jiangliu committed Dec 16, 2021
1 parent 47d4a91 commit 21b0c73
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"coverage_score": 66.3,
"coverage_score": 67.5,
"exclude_path": "",
"crate_features": "fam-wrappers"
}
27 changes: 27 additions & 0 deletions src/arm64/fam_wrappers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ const ARM64_REGS_MAX: usize = 500;
// Implement the FamStruct trait for kvm_reg_list.
generate_fam_struct_impl!(kvm_reg_list, u64, reg, u64, n, ARM64_REGS_MAX);

// Implement the PartialEq trait for kvm_reg_list.
impl PartialEq for kvm_reg_list {
fn eq(&self, other: &kvm_reg_list) -> bool {
// No need to call entries's eq, FamStructWrapper's PartialEq will do it for you
self.n == other.n
}
}

/// Wrapper over the `kvm_reg_list` structure.
///
/// The `kvm_reg_list` structure contains a flexible array member. For details check the
Expand All @@ -20,3 +28,22 @@ generate_fam_struct_impl!(kvm_reg_list, u64, reg, u64, n, ARM64_REGS_MAX);
/// the array elements, this type is implemented using
/// [FamStructWrapper](../vmm_sys_util/fam/struct.FamStructWrapper.html).
pub type RegList = FamStructWrapper<kvm_reg_list>;

#[cfg(test)]
mod tests {
use super::RegList;

#[test]
fn test_reg_list_eq() {
let mut wrapper = RegList::new(1).unwrap();
assert_eq!(wrapper.as_slice().len(), 1);

let mut wrapper2 = wrapper.clone();
assert!(wrapper == wrapper2);

wrapper.as_mut_slice()[0] = 1;
assert!(wrapper != wrapper2);
wrapper2.as_mut_slice()[0] = 1;
assert!(wrapper == wrapper2);
}
}
85 changes: 85 additions & 0 deletions src/x86/fam_wrappers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ generate_fam_struct_impl!(
KVM_MAX_CPUID_ENTRIES
);

// Implement the PartialEq trait for kvm_cpuid2.
//
// Note:
// This PartialEq implementation should not be used directly, instead FamStructWrapper
// should be used. FamStructWrapper<T> provides us with an PartialEq implementation,
// and it will determine the entire contents of the entries array. But requires
// type T to implement `Default + FamStruct + PartialEq`, so we implement PartialEq here
// and only need to determine the header field.
impl PartialEq for kvm_cpuid2 {
fn eq(&self, other: &kvm_cpuid2) -> bool {
// No need to call entries's eq, FamStructWrapper's PartialEq will do it for you
self.nent == other.nent && self.padding == other.padding
}
}

/// Wrapper over the `kvm_cpuid2` structure.
///
/// The `kvm_cpuid2` structure contains a flexible array member. For details check the
Expand All @@ -42,6 +57,14 @@ generate_fam_struct_impl!(
KVM_MAX_MSR_ENTRIES
);

// Implement the PartialEq trait for kvm_msrs.
impl PartialEq for kvm_msrs {
fn eq(&self, other: &kvm_msrs) -> bool {
// No need to call entries's eq, FamStructWrapper's PartialEq will do it for you
self.nmsrs == other.nmsrs && self.pad == other.pad
}
}

/// Wrapper over the `kvm_msrs` structure.
///
/// The `kvm_msrs` structure contains a flexible array member. For details check the
Expand All @@ -54,6 +77,14 @@ pub type Msrs = FamStructWrapper<kvm_msrs>;
// Implement the FamStruct trait for kvm_msr_list.
generate_fam_struct_impl!(kvm_msr_list, u32, indices, u32, nmsrs, KVM_MAX_MSR_ENTRIES);

// Implement the PartialEq trait for kvm_msr_list.
impl PartialEq for kvm_msr_list {
fn eq(&self, other: &kvm_msr_list) -> bool {
// No need to call entries's eq, FamStructWrapper's PartialEq will do it for you
self.nmsrs == other.nmsrs
}
}

/// Wrapper over the `kvm_msr_list` structure.
///
/// The `kvm_msr_list` structure contains a flexible array member. For details check the
Expand All @@ -62,3 +93,57 @@ generate_fam_struct_impl!(kvm_msr_list, u32, indices, u32, nmsrs, KVM_MAX_MSR_EN
/// the array elements, this type is implemented using
/// [FamStructWrapper](../vmm_sys_util/fam/struct.FamStructWrapper.html).
pub type MsrList = FamStructWrapper<kvm_msr_list>;

#[cfg(test)]
mod tests {
use super::{CpuId, MsrList, Msrs};
use x86::bindings::kvm_cpuid_entry2;

#[test]
fn test_cpuid_eq() {
let entries = &[kvm_cpuid_entry2::default(); 2];
let mut wrapper = CpuId::from_entries(entries).unwrap();
assert_eq!(wrapper.as_slice().len(), 2);

let mut wrapper2 = wrapper.clone();
assert!(wrapper == wrapper2);

wrapper.as_mut_slice()[1].index = 1;
assert!(wrapper != wrapper2);
wrapper2.as_mut_slice()[1].index = 1;
assert!(wrapper == wrapper2);
}
#[test]
fn test_msrs_eq() {
let mut wrapper = Msrs::new(2).unwrap();
assert_eq!(wrapper.as_slice().len(), 2);

let mut wrapper2 = wrapper.clone();
assert!(wrapper == wrapper2);

wrapper.as_mut_fam_struct().pad = 1;
assert!(wrapper != wrapper2);
wrapper2.as_mut_fam_struct().pad = 1;
assert!(wrapper == wrapper2);

wrapper.as_mut_slice()[1].data = 1;
assert!(wrapper != wrapper2);
assert!(wrapper.as_slice() != wrapper2.as_slice());
wrapper2.as_mut_slice()[1].data = 1;
assert!(wrapper == wrapper2);
assert!(wrapper.as_slice() == wrapper2.as_slice());
}
#[test]
fn test_msrs_list_eq() {
let mut wrapper = MsrList::new(1).unwrap();
assert_eq!(wrapper.as_slice().len(), 1);

let mut wrapper2 = wrapper.clone();
assert!(wrapper == wrapper2);

wrapper.as_mut_slice()[0] = 1;
assert!(wrapper != wrapper2);
wrapper2.as_mut_slice()[0] = 1;
assert!(wrapper == wrapper2);
}
}

0 comments on commit 21b0c73

Please sign in to comment.