use super::*;
use crate::goodbye::Goodbye;
use crate::payload_feedbacks::picture_loss_indication::PictureLossIndication;
const REAL_PACKET: [u8; 116] = [
0x81, 0xc9, 0x0, 0x7, 0x90, 0x2f, 0x9e, 0x2e, 0xbc, 0x5e, 0x9a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0xe1, 0x0, 0x0, 0x1, 0x11, 0x9, 0xf3, 0x64, 0x32, 0x0, 0x2, 0x4a, 0x79, 0x81, 0xca, 0x0, 0xc, 0x90, 0x2f, 0x9e, 0x2e, 0x1, 0x26, 0x7b, 0x39, 0x63, 0x30, 0x30, 0x65, 0x62, 0x39, 0x32, 0x2d, 0x31, 0x61, 0x66, 0x62, 0x2d, 0x39,
0x64, 0x34, 0x39, 0x2d, 0x61, 0x34, 0x37, 0x64, 0x2d, 0x39, 0x31, 0x66, 0x36, 0x34, 0x65, 0x65,
0x65, 0x36, 0x39, 0x66, 0x35, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x81, 0xcb, 0x0, 0x1, 0x90, 0x2f, 0x9e, 0x2e, 0x81, 0xce, 0x0, 0x2, 0x90, 0x2f, 0x9e, 0x2e, 0x90, 0x2f, 0x9e, 0x2e, 0x85, 0xcd, 0x0, 0x2, 0x90, 0x2f, 0x9e, 0x2e, 0x90, 0x2f, 0x9e, 0x2e, ];
#[test]
fn test_read_eof() {
let mut short_header = Bytes::from_static(&[
0x81, 0xc9, ]);
let result = unmarshal(&mut short_header);
assert!(result.is_err(), "missing type & len");
}
#[test]
fn test_bad_compound() {
let mut bad_compound = Bytes::copy_from_slice(&REAL_PACKET[..34]);
let result = unmarshal(&mut bad_compound);
assert!(result.is_err(), "trailing data!");
let mut bad_compound = Bytes::copy_from_slice(&REAL_PACKET[84..104]);
let p = unmarshal(&mut bad_compound).expect("Error unmarshalling packet");
let compound = p.as_any().downcast_ref::<CompoundPacket>().unwrap();
match compound.validate() {
Ok(_) => panic!("validation should return an error"),
Err(err) => {
let a = Error::BadFirstPacket;
assert!(
Error::BadFirstPacket.equal(&err),
"Unmarshal(badcompound) err={:?}, want {:?}",
err,
a,
);
}
};
let compound_len = compound.0.len();
assert_eq!(
compound_len, 2,
"Unmarshal(badcompound) len={}, want {}",
compound_len, 2
);
if let None = compound.0[0].as_any().downcast_ref::<Goodbye>() {
panic!("Unmarshal(badcompound), want Goodbye")
}
if let None = compound.0[1]
.as_any()
.downcast_ref::<PictureLossIndication>()
{
panic!("Unmarshal(badcompound), want PictureLossIndication")
}
}
#[test]
fn test_valid_packet() {
let cname = SourceDescription {
chunks: vec![SourceDescriptionChunk {
source: 1234,
items: vec![SourceDescriptionItem {
sdes_type: SdesType::SdesCname,
text: Bytes::from_static(b"cname"),
}],
}],
};
let tests: Vec<(&str, CompoundPacket, Option<Error>)> = vec![
(
"no cname",
CompoundPacket(vec![Box::new(SenderReport::default())]),
Some(Error::MissingCname),
),
(
"SDES / no cname",
CompoundPacket(vec![
Box::new(SenderReport::default()),
Box::new(SourceDescription::default()),
]),
Some(Error::MissingCname),
),
(
"just SR",
CompoundPacket(vec![
Box::new(SenderReport::default()),
Box::new(cname.to_owned()),
]),
None,
),
(
"multiple SRs",
CompoundPacket(vec![
Box::new(SenderReport::default()),
Box::new(SenderReport::default()),
Box::new(cname.clone()),
]),
Some(Error::PacketBeforeCname),
),
(
"just RR",
CompoundPacket(vec![
Box::new(ReceiverReport::default()),
Box::new(cname.clone()),
]),
None,
),
(
"multiple RRs",
CompoundPacket(vec![
Box::new(ReceiverReport::default()),
Box::new(cname.clone()),
Box::new(ReceiverReport::default()),
]),
None,
),
(
"goodbye",
CompoundPacket(vec![
Box::new(ReceiverReport::default()),
Box::new(cname.clone()),
Box::new(Goodbye::default()),
]),
None,
),
];
for (name, packet, error) in tests {
let result = packet.validate();
assert_eq!(result.is_ok(), error.is_none());
if let (Some(err), Err(got)) = (error, result) {
assert!(
err.equal(&got),
"Valid({}) = {:?}, want {:?}",
name,
got,
err
);
}
}
}
#[test]
fn test_cname() {
let cname = SourceDescription {
chunks: vec![SourceDescriptionChunk {
source: 1234,
items: vec![SourceDescriptionItem {
sdes_type: SdesType::SdesCname,
text: Bytes::from_static(b"cname"),
}],
}],
};
let tests: Vec<(&str, CompoundPacket, Option<Error>, &str)> = vec![
(
"no cname",
CompoundPacket(vec![Box::new(SenderReport::default())]),
Some(Error::MissingCname),
"",
),
(
"SDES / no cname",
CompoundPacket(vec![
Box::new(SenderReport::default()),
Box::new(SourceDescription::default()),
]),
Some(Error::MissingCname),
"",
),
(
"just SR",
CompoundPacket(vec![
Box::new(SenderReport::default()),
Box::new(cname.clone()),
]),
None,
"cname",
),
(
"multiple SRs",
CompoundPacket(vec![
Box::new(SenderReport::default()),
Box::new(SenderReport::default()),
Box::new(cname.clone()),
]),
Some(Error::PacketBeforeCname),
"",
),
(
"just RR",
CompoundPacket(vec![
Box::new(ReceiverReport::default()),
Box::new(cname.clone()),
]),
None,
"cname",
),
(
"multiple RRs",
CompoundPacket(vec![
Box::new(ReceiverReport::default()),
Box::new(ReceiverReport::default()),
Box::new(cname.clone()),
]),
None,
"cname",
),
(
"goodbye",
CompoundPacket(vec![
Box::new(ReceiverReport::default()),
Box::new(cname.clone()),
Box::new(Goodbye::default()),
]),
None,
"cname",
),
];
for (name, compound_packet, want_error, text) in tests {
let err = compound_packet.validate();
assert_eq!(err.is_err(), want_error.is_some());
if let (Some(want), Err(err)) = (&want_error, err) {
assert!(
want.equal(&err),
"Valid({}) = {:?}, want {:?}",
name,
err,
want
);
}
let name_result = compound_packet.cname();
assert_eq!(name_result.is_err(), want_error.is_some());
match name_result {
Ok(e) => {
assert_eq!(e, text, "CNAME({}) = {:?}, want {}", name, e, text,);
}
Err(err) => {
if let Some(want) = &want_error {
assert!(
want.equal(&err),
"CNAME({}) = {:?}, want {:?}",
name,
err,
want
);
}
}
}
}
}
#[test]
fn test_compound_packet_roundtrip() {
let cname = SourceDescription {
chunks: vec![SourceDescriptionChunk {
source: 1234,
items: vec![SourceDescriptionItem {
sdes_type: SdesType::SdesCname,
text: Bytes::from_static(b"cname"),
}],
}],
};
let tests = vec![
(
"goodbye",
CompoundPacket(vec![
Box::new(ReceiverReport::default()),
Box::new(cname.clone()),
Box::new(Goodbye {
sources: vec![1234],
..Default::default()
}),
]),
None,
),
(
"no cname",
CompoundPacket(vec![Box::new(ReceiverReport::default())]),
Some(Error::MissingCname),
),
];
for (name, packet, marshal_error) in tests {
let result = packet.marshal();
if let Some(err) = marshal_error {
if let Err(got) = result {
assert!(
err.equal(&got),
"marshal {} header: err = {}, want {}",
name,
got,
err
);
} else {
assert!(false, "want error in test {}", name);
}
continue;
} else {
assert!(result.is_ok(), "must no error in test {}", name);
}
let data1 = result.unwrap();
let c = CompoundPacket::unmarshal(&mut data1.clone())
.expect(format!("unmarshal {} error", name).as_str());
let data2 = c
.marshal()
.expect(format!("marshal {} error", name).as_str());
assert_eq!(
data1, data2,
"Unmarshal(Marshal({:?})) = {:?}, want {:?}",
name, data1, data2
)
}
}