Skip to content

Commit

Permalink
Add more integration tests
Browse files Browse the repository at this point in the history
Added tests for Vec, struct, union, enum, FamStructWrapper and
combinations of them for testing `Versionize` functionality.

Signed-off-by: Laura Loghin <[email protected]>
  • Loading branch information
lauralt authored and ioanachirca committed May 13, 2020
1 parent 3ecbf9b commit 0a1bd10
Show file tree
Hide file tree
Showing 5 changed files with 1,326 additions and 353 deletions.
2 changes: 1 addition & 1 deletion coverage_config_aarch64.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"coverage_score": 91.8, "exclude_path": "", "crate_features": ""}
{"coverage_score": 92.2, "exclude_path": "", "crate_features": ""}
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"coverage_score": 92.8, "exclude_path": "", "crate_features": ""}
{"coverage_score": 93.0, "exclude_path": "", "crate_features": ""}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,6 @@ mod tests {
format!("{:?}{}", Io(0), Io(0));
format!("{:?}{}", Serialize(str.clone()), Serialize(str.clone()));
format!("{:?}{}", Deserialize(str.clone()), Deserialize(str.clone()));
format!("{:?}{}", Semantic(str.clone()), Semantic(str.clone()));
format!("{:?}{}", Semantic(str.clone()), Semantic(str));
}
}
295 changes: 0 additions & 295 deletions src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,30 +418,8 @@ impl<T: Versionize, U: Versionize> Versionize for (T, U) {

#[cfg(test)]
mod tests {
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
use super::*;
use super::{VersionMap, Versionize, VersionizeResult};
use vmm_sys_util::generate_fam_struct_impl;

#[repr(C)]
#[derive(Default, Debug, Versionize)]
struct Message {
pub len: u32,
pub padding: u32,
pub value: u32,
#[version(start = 2, default_fn = "default_extra_value")]
pub extra_value: u16,
pub entries: __IncompleteArrayField<u32>,
}

impl Message {
fn default_extra_value(_source_version: u16) -> u16 {
321
}
}
generate_fam_struct_impl!(Message, u32, entries, u32, len, 100);

// Generate primitive tests using this macro.
macro_rules! primitive_int_test {
Expand Down Expand Up @@ -492,53 +470,6 @@ mod tests {
assert_eq!(store, restore);
}

#[repr(u32)]
#[derive(Debug, Versionize, PartialEq, Clone)]
pub enum TestState {
Zero,
One(u32, String),
#[version(start = 2, default_fn = "test_state_default_one")]
Two(u32),
#[version(start = 3, default_fn = "test_state_default_two")]
Three(u32),
}

impl Default for TestState {
fn default() -> Self {
Self::One(1, "Default".to_owned())
}
}

impl TestState {
fn test_state_default_one(
&self,
target_version: u16,
) -> Result<TestState, VersionizeError> {
match target_version {
2 => Ok(TestState::Two(2)),
1 => Ok(TestState::Zero),
i => Err(VersionizeError::Serialize(format!(
"Unknown target version: {}",
i
))),
}
}

fn test_state_default_two(
&self,
target_version: u16,
) -> Result<TestState, VersionizeError> {
match target_version {
2 => Ok(TestState::Two(2)),
1 => Ok(TestState::One(1, "Test".to_owned())),
i => Err(VersionizeError::Serialize(format!(
"Unknown target version: {}",
i
))),
}
}
}

#[derive(Debug, serde_derive::Deserialize, PartialEq, serde_derive::Serialize, Versionize)]
enum CompatibleEnum {
A,
Expand Down Expand Up @@ -642,60 +573,6 @@ mod tests {
assert_eq!(test_struct, restored_state);
}

#[test]
fn test_enum_basic() {
let mut snapshot_mem = vec![0u8; 64];
let mut vm = VersionMap::new();
vm.new_version()
.set_type_version(TestState::type_id(), 2)
.new_version()
.set_type_version(TestState::type_id(), 3);

// Test trivial case.
let state = TestState::One(1337, "a string".to_owned());
state
.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 1)
.unwrap();
let restored_state =
<TestState as Versionize>::deserialize(&mut snapshot_mem.as_slice(), &vm, 1).unwrap();
assert_eq!(state, restored_state);
}

#[test]
fn test_enum_rollback() {
let mut snapshot_mem = vec![0u8; 64];
let mut vm = VersionMap::new();
vm.new_version()
.set_type_version(TestState::type_id(), 2)
.new_version()
.set_type_version(TestState::type_id(), 3);

// Test `default_fn` for serialization of enum variants that don't exist in previous versions.
let state = TestState::Three(1337);
state
.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 2)
.unwrap();
let restored_state =
<TestState as Versionize>::deserialize(&mut snapshot_mem.as_slice(), &vm, 2).unwrap();
assert_eq!(restored_state, TestState::Two(2));

let state = TestState::Three(1337);
state
.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 1)
.unwrap();
let restored_state =
<TestState as Versionize>::deserialize(&mut snapshot_mem.as_slice(), &vm, 1).unwrap();
assert_eq!(restored_state, TestState::One(1, "Test".to_owned()));

let state = TestState::Two(1234);
state
.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 1)
.unwrap();
let restored_state =
<TestState as Versionize>::deserialize(&mut snapshot_mem.as_slice(), &vm, 1).unwrap();
assert_eq!(restored_state, TestState::Zero);
}

#[test]
fn test_ser_de_bool() {
let vm = VersionMap::new();
Expand Down Expand Up @@ -824,178 +701,6 @@ mod tests {
assert_eq!(store, restore);
}

#[test]
fn test_ser_de_vec_version() {
type MessageFamStructWrapper = FamStructWrapper<Message>;
let vm = VersionMap::new();
let mut f = MessageFamStructWrapper::new(0);
f.as_mut_fam_struct().padding = 123;
f.as_mut_fam_struct().extra_value = 321;

f.push(10).unwrap();
f.push(20).unwrap();

let mut snapshot_mem = vec![0u8; 512];
let mut store = Vec::new();
store.push(f.clone());
store.push(f.clone());

store
.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 1)
.unwrap();
let restore = <Vec<MessageFamStructWrapper> as Versionize>::deserialize(
&mut snapshot_mem.as_slice(),
&vm,
1,
)
.unwrap();
let eq = store == restore;
// This is important to test separately as we rely on the default_fn to
// override the u16 default value.
assert_eq!(321, restore[0].as_fam_struct_ref().extra_value);
assert!(eq);
}

#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
__IncompleteArrayField(::std::marker::PhantomData, [])
}
#[inline]
pub unsafe fn as_ptr(&self) -> *const T {
self as *const __IncompleteArrayField<T> as *const T
}
#[inline]
pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
self as *mut __IncompleteArrayField<T> as *mut T
}
#[inline]
pub unsafe fn as_slice(&self, len: usize) -> &[T] {
::std::slice::from_raw_parts(self.as_ptr(), len)
}
#[inline]
pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}

impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
fmt.write_str("__IncompleteArrayField")
}
}
impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
#[inline]
fn clone(&self) -> Self {
Self::new()
}
}

impl<T> Versionize for __IncompleteArrayField<T> {
#[inline]
fn serialize<W: std::io::Write>(
&self,
_writer: &mut W,
_version_map: &VersionMap,
_app_version: u16,
) -> Result<(), VersionizeError> {
Ok(())
}

#[inline]
fn deserialize<R: std::io::Read>(
_reader: &mut R,
_version_map: &VersionMap,
_app_version: u16,
) -> Result<Self, VersionizeError> {
Ok(Self::new())
}

// Not used.
fn version() -> u16 {
1
}
}

#[test]
fn test_famstruct() {
type MessageFamStructWrapper = FamStructWrapper<Message>;

let vm = VersionMap::new();
let mut f = MessageFamStructWrapper::new(0);
f.as_mut_fam_struct().padding = 123;
f.as_mut_fam_struct().extra_value = 321;

f.push(10).unwrap();
f.push(20).unwrap();

let mut snapshot_mem = vec![0u8; 64];
f.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 1)
.unwrap();
let restored_state =
MessageFamStructWrapper::deserialize(&mut snapshot_mem.as_slice(), &vm, 1).unwrap();

let original_values = f.as_slice();
let restored_values = restored_state.as_slice();

assert_eq!(
f.as_fam_struct_ref().padding,
restored_state.as_fam_struct_ref().padding
);
assert_eq!(original_values, restored_values);
assert_eq!(
f.as_fam_struct_ref().extra_value,
restored_state.as_fam_struct_ref().extra_value
);
}

#[test]
fn test_famstruct_ser_error() {
type MessageFamStructWrapper = FamStructWrapper<Message>;

let vm = VersionMap::new();
let mut f = MessageFamStructWrapper::new(0);
f.as_mut_fam_struct().padding = 123;
f.as_mut_fam_struct().extra_value = 321;

f.push(10).unwrap();
f.push(20).unwrap();

let mut snapshot_mem = vec![0u8; 16];

assert!(f
.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 1)
.is_err());
}
#[test]
fn test_famstruct_version() {
type MessageFamStructWrapper = FamStructWrapper<Message>;

let vm = VersionMap::new();
let mut f = MessageFamStructWrapper::new(0);
f.as_mut_fam_struct().padding = 123;
f.push(10).unwrap();
f.push(20).unwrap();

let mut snapshot_mem = vec![0u8; 64];
f.serialize(&mut snapshot_mem.as_mut_slice(), &vm, 1)
.unwrap();
let restored_state =
MessageFamStructWrapper::deserialize(&mut snapshot_mem.as_slice(), &vm, 1).unwrap();

let original_values = f.as_slice();
let restored_values = restored_state.as_slice();

assert_eq!(
f.as_fam_struct_ref().padding,
restored_state.as_fam_struct_ref().padding
);
assert_eq!(original_values, restored_values);
}

#[test]
fn test_vec_limit() {
// We need extra 8 bytes for vector len.
Expand Down
Loading

0 comments on commit 0a1bd10

Please sign in to comment.