use std::mem;
use bincode::{deserialize, serialize};
use libc::{c_void, iovec};
use rexsgdata::{Iovec, SgData, SgList};
use serde_test::{assert_ser_tokens, Token};
fn vec_into_iovec(mut vec: Vec<u8>) -> iovec {
let len = vec.len();
let base = vec.as_mut_ptr();
mem::forget(vec);
iovec {
iov_base: base as *mut c_void,
iov_len: len,
}
}
fn create_sglist(sgvec: Vec<Vec<u8>>) -> SgList {
let vec = sgvec.into_iter().map(vec_into_iovec).collect::<Vec<_>>();
let len = vec.len();
let iov = vec.as_ptr();
mem::forget(vec);
SgList::new(iov, len)
}
#[test]
fn add_buf() {
let mut data: SgData = vec![12, 56, 34].into();
data += vec![255, 129, 99].into();
assert_eq!(data, vec![12, 56, 34, 255, 129, 99].into());
assert_eq!(
data + vec![0, 111, 222].into(),
vec![12, 56, 34, 255, 129, 99, 0, 111, 222].into()
);
}
#[test]
fn add_vec() {
let mut data: SgData = vec![vec![12, 56], vec![16, 27, 38]].into();
data += vec![255, 129].into();
assert_eq!(
data,
vec![vec![12, 56], vec![16, 27, 38], vec![255, 129]].into()
);
assert_eq!(
data + vec![0, 111].into(),
vec![vec![12, 56], vec![16, 27, 38], vec![255, 129], vec![0, 111]].into()
);
}
#[test]
fn clone_from() {
let iovec = vec![vec![0; 1024], vec![0; 1024], vec![0; 1024]];
let (base, count) = create_sglist(iovec).into_inner();
let data: SgData = vec![0xAA; 3072].into();
let sglist = unsafe { data.drain_into(base as *mut libc::iovec, count) };
let buf = serialize(&sglist).unwrap();
let sgvec: SgData = deserialize(&buf).unwrap();
let buf = serialize(&sgvec).unwrap();
let direct: SgData = deserialize(&buf).unwrap();
assert_eq!(SgData::from(vec![0xAA; 3072]), direct);
}
#[test]
fn sglist_capacity() {
let sgvec = vec![vec![0; 345], vec![0; 123], vec![0; 2000]];
let sglist = create_sglist(sgvec);
let capacity = unsafe { sglist.capacity() };
assert_eq!(capacity, 2468);
}
#[test]
fn iter_sgvec() {
let v1 = vec![12, 56, 76];
let v2 = vec![128, 255];
let data: SgData = vec![v1.clone(), v2.clone()].into();
let mut iter = data.iter();
assert_eq!(iter.next(), Some(v1.as_slice()));
assert_eq!(iter.next(), Some(v2.as_slice()));
assert_eq!(iter.next(), None);
}
#[test]
fn drain_into() {
let sgdata: SgData = vec![0, 202, 3, 4, 10, 23, 12, 134, 45, 198].into();
let iov = vec![vec![0; 5], vec![0; 2], vec![0; 3]];
let (iovec, count) = create_sglist(iov).into_inner();
let sgdata: SgData = unsafe { sgdata.drain_into(iovec as *mut iovec, count) };
assert_eq!(sgdata.size(), 3);
let mut slices = sgdata.iter();
assert_eq!(slices.next(), Some([0, 202, 3, 4, 10].as_ref()));
assert_eq!(slices.next(), Some([23, 12].as_ref()));
assert_eq!(slices.next(), Some([134, 45, 198].as_ref()));
assert_eq!(slices.next(), None);
}
#[test]
fn iter_direct() {
let v1 = vec![12, 56, 34, 255, 0];
let data: SgData = v1.clone().into();
let mut iter = data.iter();
assert_eq!(iter.next(), Some(v1.as_slice()));
assert_eq!(iter.next(), None);
}
#[test]
fn sglist_serde() {
let sgvec = vec![vec![0x45_u8; 4096]; 5];
let data: SgData = unsafe { SgData::from_sglist(create_sglist(sgvec)) };
let buf = serialize(&data).unwrap();
let data: SgData = deserialize(&buf).unwrap();
assert_eq!(data, SgData::from(vec![0x45_u8; 4096 * 5]));
}
#[test]
fn iovec_serde() {
let data: SgData = vec![vec![0x46; 4096]; 7]
.into_iter()
.map(vec_into_iovec)
.map(Iovec::from)
.collect();
let buf = serialize(&data).unwrap();
let data: SgData = deserialize(&buf).unwrap();
assert_eq!(data, SgData::from(vec![vec![0x46; 4096]; 7]));
}
#[test]
fn sgvec_serde() {
let data: SgData = vec![vec![12, 56, 76], vec![128, 255]].into();
let buf = serialize(&data).unwrap();
let data: SgData = deserialize(&buf).unwrap();
assert_eq!(data, SgData::from(vec![12, 56, 76, 128, 255]));
}
#[test]
fn mixed_serde() {
let data: SgData = unsafe {
SgData::from(vec![0xa2; 2])
+ SgData::from_sglist(create_sglist(vec![vec![12, 56, 76], vec![128, 255]]))
+ Iovec::from(vec_into_iovec(vec![0x5a; 3])).into()
};
let buf = serialize(&data).unwrap();
let data: SgData = deserialize(&buf).unwrap();
let expected = SgData::from(vec![0xa2, 0xa2, 12, 56, 76, 128, 255, 0x5a, 0x5a, 0x5a]);
assert_eq!(data, expected);
}
mod tokens {
use super::*;
#[test]
fn direct() {
let data: SgData = vec![12, 56, 34, 0, 255].into();
assert_ser_tokens(
&data,
&[
Token::Struct {
name: "SgData",
len: 1,
},
Token::Str("data"),
Token::Seq { len: Some(1) },
Token::Bytes(&[12, 56, 34, 0, 255]),
Token::SeqEnd,
Token::StructEnd,
],
);
}
#[test]
fn sglist() {
let data: SgData =
unsafe { SgData::from_sglist(create_sglist(vec![vec![12, 56, 76], vec![128, 255]])) };
assert_ser_tokens(
&data,
&[
Token::Struct {
name: "SgData",
len: 1,
},
Token::Str("data"),
Token::Seq { len: Some(2) },
Token::Bytes(&[12, 56, 76]),
Token::Bytes(&[128, 255]),
Token::SeqEnd,
Token::StructEnd,
],
);
}
#[test]
fn iovec() {
let data: SgData = vec![vec![36, 123, 234], vec![87, 187, 211, 45]]
.into_iter()
.map(vec_into_iovec)
.map(Iovec::from)
.collect();
assert_ser_tokens(
&data,
&[
Token::Struct {
name: "SgData",
len: 1,
},
Token::Str("data"),
Token::Seq { len: Some(2) },
Token::Bytes(&[36, 123, 234]),
Token::Bytes(&[87, 187, 211, 45]),
Token::SeqEnd,
Token::StructEnd,
],
);
}
#[test]
fn mixed() {
let data: SgData = unsafe {
SgData::from(vec![0xa2; 4])
+ SgData::from_sglist(create_sglist(vec![vec![12, 56, 76], vec![128, 255]]))
+ Iovec::from(vec_into_iovec(vec![0x5a; 4])).into()
};
assert_ser_tokens(
&data,
&[
Token::Struct {
name: "SgData",
len: 1,
},
Token::Str("data"),
Token::Seq { len: Some(4) },
Token::Bytes(&[0xa2; 4]),
Token::Bytes(&[12, 56, 76]),
Token::Bytes(&[128, 255]),
Token::Bytes(&[0x5a; 4]),
Token::SeqEnd,
Token::StructEnd,
],
);
}
}
mod version {
#[test]
fn version() {
assert_eq!(rexsgdata::VERSION, env!("CARGO_PKG_VERSION"));
}
}