1 use super::*; 2 3 use std::io::BufWriter; 4 5 use util::Error; 6 7 use crate::goodbye::*; 8 use crate::receiver_report::*; 9 use crate::sender_report::*; 10 11 lazy_static! { 12 // An RTCP packet from a packet dump 13 static ref REAL_PACKET:Vec<u8> = vec![ 14 // Receiver Report (offset=0) 15 // v=2, p=0, count=1, RR, len=7 16 0x81, 0xc9, 0x0, 0x7, // ssrc=0x902f9e2e 17 0x90, 0x2f, 0x9e, 0x2e, // ssrc=0xbc5e9a40 18 0xbc, 0x5e, 0x9a, 0x40, // fracLost=0, totalLost=0 19 0x0, 0x0, 0x0, 0x0, // lastSeq=0x46e1 20 0x0, 0x0, 0x46, 0xe1, // jitter=273 21 0x0, 0x0, 0x1, 0x11, // lsr=0x9f36432 22 0x9, 0xf3, 0x64, 0x32, // delay=150137 23 0x0, 0x2, 0x4a, 0x79, 24 // Source Description (offset=32) 25 // v=2, p=0, count=1, SDES, len=12 26 0x81, 0xca, 0x0, 0xc, // ssrc=0x902f9e2e 27 0x90, 0x2f, 0x9e, 0x2e, // CNAME, len=38 28 0x1, 0x26, // text="{9c00eb92-1afb-9d49-a47d-91f64eee69f5}" 29 0x7b, 0x39, 0x63, 0x30, 0x30, 0x65, 0x62, 0x39, 0x32, 0x2d, 0x31, 0x61, 0x66, 0x62, 0x2d, 30 0x39, 0x64, 0x34, 0x39, 0x2d, 0x61, 0x34, 0x37, 0x64, 0x2d, 0x39, 0x31, 0x66, 0x36, 0x34, 31 0x65, 0x65, 0x65, 0x36, 0x39, 0x66, 0x35, 0x7d, // END + padding 32 0x0, 0x0, 0x0, 0x0, 33 // Goodbye (offset=84) 34 // v=2, p=0, count=1, BYE, len=1 35 0x81, 0xcb, 0x0, 0x1, // source=0x902f9e2e 36 0x90, 0x2f, 0x9e, 0x2e, // Picture Loss Indication (offset=92) 37 0x81, 0xce, 0x0, 0x2, // sender=0x902f9e2e 38 0x90, 0x2f, 0x9e, 0x2e, // media=0x902f9e2e 39 0x90, 0x2f, 0x9e, 0x2e, // RapidResynchronizationRequest (offset=104) 40 0x85, 0xcd, 0x0, 0x2, // sender=0x902f9e2e 41 0x90, 0x2f, 0x9e, 0x2e, // media=0x902f9e2e 42 0x90, 0x2f, 0x9e, 0x2e, 43 ]; 44 } 45 46 #[test] 47 fn test_read_eof() -> Result<(), Error> { 48 let short_header = vec![ 49 0x81, 0xc9, // missing type & len 50 ]; 51 let result = unmarshal(&short_header); 52 assert!(result.is_err(), "missing type & len"); 53 54 Ok(()) 55 } 56 57 #[test] 58 fn test_bad_compound() -> Result<(), Error> { 59 let bad_compound = &REAL_PACKET[..34]; 60 let result = unmarshal(bad_compound); 61 assert!(result.is_err(), "trailing data!"); 62 63 let bad_compound = &REAL_PACKET[84..104]; 64 let packet = unmarshal(bad_compound)?; 65 let result = match packet { 66 Packet::CompoundPacket(p) => p.validate(), 67 _ => Ok(()), 68 }; 69 if let Err(got) = result { 70 let want = ERR_BAD_FIRST_PACKET.clone(); 71 assert_eq!( 72 got, want, 73 "Unmarshal(badcompound) err={}, want {}", 74 got, want 75 ); 76 } else { 77 assert!(false, "must be error"); 78 } 79 80 Ok(()) 81 } 82 83 #[test] 84 fn test_valid_compound() -> Result<(), Error> { 85 let cname = Packet::SourceDescription(SourceDescription { 86 chunks: vec![SourceDescriptionChunk { 87 source: 1234, 88 items: vec![SourceDescriptionItem { 89 sdes_type: SDESType::SDESCNAME, 90 text: "cname".to_string(), 91 }], 92 }], 93 }); 94 95 let tests = vec![ 96 ( 97 "empty", 98 CompoundPacket(vec![]), 99 Some(ERR_EMPTY_COMPOUND.clone()), 100 ), 101 ( 102 "no cname", 103 CompoundPacket(vec![Packet::SenderReport(SenderReport::default())]), 104 Some(ERR_MISSING_CNAME.clone()), 105 ), 106 ( 107 "just BYE", 108 CompoundPacket(vec![Packet::Goodbye(Goodbye::default())]), 109 Some(ERR_BAD_FIRST_PACKET.clone()), 110 ), 111 ( 112 "SDES / no cname", 113 CompoundPacket(vec![ 114 Packet::SenderReport(SenderReport::default()), 115 Packet::SourceDescription(SourceDescription::default()), 116 ]), 117 Some(ERR_MISSING_CNAME.clone()), 118 ), 119 ( 120 "just SR", 121 CompoundPacket(vec![ 122 Packet::SenderReport(SenderReport::default()), 123 cname.clone(), 124 ]), 125 None, 126 ), 127 ( 128 "multiple SRs", 129 CompoundPacket(vec![ 130 Packet::SenderReport(SenderReport::default()), 131 Packet::SenderReport(SenderReport::default()), 132 cname.clone(), 133 ]), 134 Some(ERR_PACKET_BEFORE_CNAME.clone()), 135 ), 136 ( 137 "just RR", 138 CompoundPacket(vec![ 139 Packet::ReceiverReport(ReceiverReport::default()), 140 cname.clone(), 141 ]), 142 None, 143 ), 144 ( 145 "multiple RRs", 146 CompoundPacket(vec![ 147 Packet::ReceiverReport(ReceiverReport::default()), 148 Packet::ReceiverReport(ReceiverReport::default()), 149 cname.clone(), 150 ]), 151 None, 152 ), 153 ( 154 "goodbye", 155 CompoundPacket(vec![ 156 Packet::ReceiverReport(ReceiverReport::default()), 157 cname.clone(), 158 Packet::Goodbye(Goodbye::default()), 159 ]), 160 None, 161 ), 162 ]; 163 164 for (name, compound_packet, want_error) in tests { 165 let result = compound_packet.validate(); 166 if let Some(err) = want_error { 167 if let Err(got) = result { 168 assert_eq!(got, err, "validate {} : err = {}, want {}", name, got, err); 169 } else { 170 assert!(false, "want error in test {}", name); 171 } 172 } else { 173 assert!(result.is_ok(), "must no error in test {}", name); 174 } 175 } 176 177 Ok(()) 178 } 179 180 #[test] 181 fn test_cname() -> Result<(), Error> { 182 let cname = Packet::SourceDescription(SourceDescription { 183 chunks: vec![SourceDescriptionChunk { 184 source: 1234, 185 items: vec![SourceDescriptionItem { 186 sdes_type: SDESType::SDESCNAME, 187 text: "cname".to_string(), 188 }], 189 }], 190 }); 191 192 let tests = vec![ 193 ( 194 "no cname", 195 CompoundPacket(vec![Packet::SenderReport(SenderReport::default())]), 196 Some(ERR_MISSING_CNAME.clone()), 197 "", 198 ), 199 ( 200 "SDES / no cname", 201 CompoundPacket(vec![ 202 Packet::SenderReport(SenderReport::default()), 203 Packet::SourceDescription(SourceDescription::default()), 204 ]), 205 Some(ERR_MISSING_CNAME.clone()), 206 "", 207 ), 208 ( 209 "just SR", 210 CompoundPacket(vec![ 211 Packet::SenderReport(SenderReport::default()), 212 cname.clone(), 213 ]), 214 None, 215 "cname", 216 ), 217 ( 218 "multiple SRs", 219 CompoundPacket(vec![ 220 Packet::SenderReport(SenderReport::default()), 221 Packet::SenderReport(SenderReport::default()), 222 cname.clone(), 223 ]), 224 Some(ERR_PACKET_BEFORE_CNAME.clone()), 225 "", 226 ), 227 ( 228 "just RR", 229 CompoundPacket(vec![ 230 Packet::ReceiverReport(ReceiverReport::default()), 231 cname.clone(), 232 ]), 233 None, 234 "cname", 235 ), 236 ( 237 "multiple RRs", 238 CompoundPacket(vec![ 239 Packet::ReceiverReport(ReceiverReport::default()), 240 Packet::ReceiverReport(ReceiverReport::default()), 241 cname.clone(), 242 ]), 243 None, 244 "cname", 245 ), 246 ( 247 "goodbye", 248 CompoundPacket(vec![ 249 Packet::ReceiverReport(ReceiverReport::default()), 250 cname.clone(), 251 Packet::Goodbye(Goodbye::default()), 252 ]), 253 None, 254 "cname", 255 ), 256 ]; 257 258 for (name, compound_packet, want_error, text) in tests { 259 let result = compound_packet.validate(); 260 if let Some(err) = want_error { 261 if let Err(got) = result { 262 assert_eq!(got, err, "validate {} : err = {}, want {}", name, got, err); 263 } else { 264 assert!(false, "want error in test {}", name); 265 } 266 } else { 267 assert!(result.is_ok(), "must no error in test {}", name); 268 if let Ok(cname) = compound_packet.cname() { 269 assert_eq!(cname, text, "test {} = {}, want {}", name, cname, text); 270 } else { 271 assert!(false, "want cname in test {}", name); 272 } 273 } 274 } 275 276 Ok(()) 277 } 278 279 #[test] 280 fn test_compound_packet_roundtrip() -> Result<(), Error> { 281 let cname = Packet::SourceDescription(SourceDescription { 282 chunks: vec![SourceDescriptionChunk { 283 source: 1234, 284 items: vec![SourceDescriptionItem { 285 sdes_type: SDESType::SDESCNAME, 286 text: "cname".to_string(), 287 }], 288 }], 289 }); 290 291 let tests = vec![ 292 ( 293 "goodbye", 294 CompoundPacket(vec![ 295 Packet::ReceiverReport(ReceiverReport::default()), 296 cname.clone(), 297 Packet::Goodbye(Goodbye::default()), 298 ]), 299 None, 300 ), 301 ( 302 "no cname", 303 CompoundPacket(vec![Packet::ReceiverReport(ReceiverReport::default())]), 304 Some(ERR_MISSING_CNAME.clone()), 305 ), 306 ]; 307 308 for (name, packet, marshal_error) in tests { 309 let mut data: Vec<u8> = vec![]; 310 { 311 let mut writer = BufWriter::<&mut Vec<u8>>::new(data.as_mut()); 312 let result = packet.marshal(&mut writer); 313 if let Some(err) = marshal_error { 314 if let Err(got) = result { 315 assert_eq!( 316 got, err, 317 "marshal {} header: err = {}, want {}", 318 name, got, err 319 ); 320 } else { 321 assert!(false, "want error in test {}", name); 322 } 323 continue; 324 } else { 325 assert!(result.is_ok(), "must no error in test {}", name); 326 } 327 } 328 329 let _decoded = unmarshal(&data)?; 330 331 let mut expect: Vec<u8> = vec![]; 332 { 333 let mut writer = BufWriter::<&mut Vec<u8>>::new(expect.as_mut()); 334 let _result = packet.marshal(&mut writer); 335 } 336 assert_eq!( 337 data, expect, 338 "{} header round trip: got {:?}, want {:?}", 339 name, data, expect 340 ) 341 } 342 343 Ok(()) 344 } 345