1 use super::*; 2 3 #[test] 4 fn test_source_description_unmarshal() { 5 let tests = vec![ 6 ( 7 "nil", 8 Bytes::from_static(&[]), 9 SourceDescription::default(), 10 Some(Error::PacketTooShort), 11 ), 12 ( 13 "no chunks", 14 Bytes::from_static(&[ 15 // v=2, p=0, count=1, SDES, len=8 16 0x80, 0xca, 0x00, 0x04, 17 ]), 18 SourceDescription::default(), 19 None, 20 ), 21 ( 22 "missing type", 23 Bytes::from_static(&[ 24 // v=2, p=0, count=1, SDES, len=8 25 0x81, 0xca, 0x00, 0x08, // ssrc=0x00000000 26 0x00, 0x00, 0x00, 0x00, 27 ]), 28 SourceDescription::default(), 29 Some(Error::PacketTooShort), 30 ), 31 ( 32 "bad cname length", 33 Bytes::from_static(&[ 34 // v=2, p=0, count=1, SDES, len=10 35 0x81, 0xca, 0x00, 0x0a, // ssrc=0x00000000 36 0x00, 0x00, 0x00, 0x00, // CNAME, len = 1 37 0x01, 0x01, 38 ]), 39 SourceDescription::default(), 40 Some(Error::PacketTooShort), 41 ), 42 ( 43 "short cname", 44 Bytes::from_static(&[ 45 // v=2, p=0, count=1, SDES, len=9 46 0x81, 0xca, 0x00, 0x09, // ssrc=0x00000000 47 0x00, 0x00, 0x00, 0x00, // CNAME, Missing length 48 0x01, 49 ]), 50 SourceDescription::default(), 51 Some(Error::PacketTooShort), 52 ), 53 ( 54 "no end", 55 Bytes::from_static(&[ 56 // v=2, p=0, count=1, SDES, len=11 57 0x81, 0xca, 0x00, 0x0b, // ssrc=0x00000000 58 0x00, 0x00, 0x00, 0x00, // CNAME, len=1, content=A 59 0x01, 0x02, 0x41, 60 // Missing END 61 ]), 62 SourceDescription::default(), 63 Some(Error::PacketTooShort), 64 ), 65 ( 66 "bad octet count", 67 Bytes::from_static(&[ 68 // v=2, p=0, count=1, SDES, len=10 69 0x81, 0xca, 0x00, 0x0a, // ssrc=0x00000000 70 0x00, 0x00, 0x00, 0x00, // CNAME, len=1 71 0x01, 0x01, 72 ]), 73 SourceDescription::default(), 74 Some(Error::PacketTooShort), 75 ), 76 ( 77 "zero item chunk", 78 Bytes::from_static(&[ 79 // v=2, p=0, count=1, SDES, len=12 80 0x81, 0xca, 0x00, 0x0c, // ssrc=0x01020304 81 0x01, 0x02, 0x03, 0x04, // END + padding 82 0x00, 0x00, 0x00, 0x00, 83 ]), 84 SourceDescription { 85 chunks: vec![SourceDescriptionChunk { 86 source: 0x01020304, 87 items: vec![], 88 }], 89 }, 90 None, 91 ), 92 ( 93 "wrong type", 94 Bytes::from_static(&[ 95 // v=2, p=0, count=1, SR, len=12 96 0x81, 0xc8, 0x00, 0x0c, // ssrc=0x01020304 97 0x01, 0x02, 0x03, 0x04, // END + padding 98 0x00, 0x00, 0x00, 0x00, 99 ]), 100 SourceDescription::default(), 101 Some(Error::WrongType), 102 ), 103 ( 104 "bad count in header", 105 Bytes::from_static(&[ 106 // v=2, p=0, count=1, SDES, len=12 107 0x81, 0xca, 0x00, 0x0c, 108 ]), 109 SourceDescription::default(), 110 Some(Error::InvalidHeader), 111 ), 112 ( 113 "empty string", 114 Bytes::from_static(&[ 115 // v=2, p=0, count=1, SDES, len=12 116 0x81, 0xca, 0x00, 0x0c, // ssrc=0x01020304 117 0x01, 0x02, 0x03, 0x04, // CNAME, len=0 118 0x01, 0x00, // END + padding 119 0x00, 0x00, 120 ]), 121 SourceDescription { 122 chunks: vec![SourceDescriptionChunk { 123 source: 0x01020304, 124 items: vec![SourceDescriptionItem { 125 sdes_type: SdesType::SdesCname, 126 text: Bytes::from_static(b""), 127 }], 128 }], 129 }, 130 None, 131 ), 132 ( 133 "two items", 134 Bytes::from_static(&[ 135 // v=2, p=0, count=1, SDES, len=16 136 0x81, 0xca, 0x00, 0x10, // ssrc=0x10000000 137 0x10, 0x00, 0x00, 0x00, // CNAME, len=1, content=A 138 0x01, 0x01, 0x41, // PHONE, len=1, content=B 139 0x04, 0x01, 0x42, // END + padding 140 0x00, 0x00, 141 ]), 142 SourceDescription { 143 chunks: vec![SourceDescriptionChunk { 144 source: 0x10000000, 145 items: vec![ 146 SourceDescriptionItem { 147 sdes_type: SdesType::SdesCname, 148 text: Bytes::from_static(b"A"), 149 }, 150 SourceDescriptionItem { 151 sdes_type: SdesType::SdesPhone, 152 text: Bytes::from_static(b"B"), 153 }, 154 ], 155 }], 156 }, 157 None, 158 ), 159 ( 160 "two chunks", 161 Bytes::from_static(&[ 162 // v=2, p=0, count=2, SDES, len=24 163 0x82, 0xca, 0x00, 0x18, // ssrc=0x01020304 164 0x01, 0x02, 0x03, 0x04, 165 // Chunk 1 166 // CNAME, len=1, content=A 167 0x01, 0x01, 0x41, // END 168 0x00, // Chunk 2 169 // SSRC 0x05060708 170 0x05, 0x06, 0x07, 0x08, // CNAME, len=3, content=BCD 171 0x01, 0x03, 0x42, 0x43, 0x44, // END 172 0x00, 0x00, 0x00, 173 ]), 174 SourceDescription { 175 chunks: vec![ 176 SourceDescriptionChunk { 177 source: 0x01020304, 178 items: vec![SourceDescriptionItem { 179 sdes_type: SdesType::SdesCname, 180 text: Bytes::from_static(b"A"), 181 }], 182 }, 183 SourceDescriptionChunk { 184 source: 0x05060708, 185 items: vec![SourceDescriptionItem { 186 sdes_type: SdesType::SdesCname, 187 text: Bytes::from_static(b"BCD"), 188 }], 189 }, 190 ], 191 }, 192 None, 193 ), 194 ]; 195 196 for (name, mut data, want, want_error) in tests { 197 let got = SourceDescription::unmarshal(&mut data); 198 199 assert_eq!( 200 got.is_err(), 201 want_error.is_some(), 202 "Unmarshal {}: err = {:?}, want {:?}", 203 name, 204 got, 205 want_error 206 ); 207 208 if let Some(err) = want_error { 209 let got_err = got.err().unwrap(); 210 assert_eq!( 211 err, got_err, 212 "Unmarshal {}: err = {:?}, want {:?}", 213 name, got_err, err, 214 ); 215 } else { 216 let actual = got.unwrap(); 217 assert_eq!( 218 actual, want, 219 "Unmarshal {}: got {:?}, want {:?}", 220 name, actual, want 221 ); 222 } 223 } 224 } 225 226 #[test] 227 fn test_source_description_roundtrip() { 228 let mut too_long_text = String::new(); 229 for _ in 0..(1 << 8) { 230 too_long_text += "x"; 231 } 232 233 let mut too_many_chunks = vec![]; 234 for _ in 0..(1 << 5) { 235 too_many_chunks.push(SourceDescriptionChunk::default()); 236 } 237 238 let tests = vec![ 239 ( 240 "valid", 241 SourceDescription { 242 chunks: vec![ 243 SourceDescriptionChunk { 244 source: 1, 245 items: vec![SourceDescriptionItem { 246 sdes_type: SdesType::SdesCname, 247 text: Bytes::from_static(b"[email protected]"), 248 }], 249 }, 250 SourceDescriptionChunk { 251 source: 2, 252 items: vec![ 253 SourceDescriptionItem { 254 sdes_type: SdesType::SdesNote, 255 text: Bytes::from_static(b"some note"), 256 }, 257 SourceDescriptionItem { 258 sdes_type: SdesType::SdesNote, 259 text: Bytes::from_static(b"another note"), 260 }, 261 ], 262 }, 263 ], 264 }, 265 None, 266 ), 267 ( 268 "item without type", 269 SourceDescription { 270 chunks: vec![SourceDescriptionChunk { 271 source: 1, 272 items: vec![SourceDescriptionItem { 273 sdes_type: SdesType::SdesEnd, 274 text: Bytes::from_static(b"[email protected]"), 275 }], 276 }], 277 }, 278 Some(Error::SdesMissingType), 279 ), 280 ( 281 "zero items", 282 SourceDescription { 283 chunks: vec![SourceDescriptionChunk { 284 source: 1, 285 items: vec![], 286 }], 287 }, 288 None, 289 ), 290 ( 291 "email item", 292 SourceDescription { 293 chunks: vec![SourceDescriptionChunk { 294 source: 1, 295 items: vec![SourceDescriptionItem { 296 sdes_type: SdesType::SdesEmail, 297 text: Bytes::from_static(b"[email protected]"), 298 }], 299 }], 300 }, 301 None, 302 ), 303 ( 304 "empty text", 305 SourceDescription { 306 chunks: vec![SourceDescriptionChunk { 307 source: 1, 308 items: vec![SourceDescriptionItem { 309 sdes_type: SdesType::SdesCname, 310 text: Bytes::from_static(b""), 311 }], 312 }], 313 }, 314 None, 315 ), 316 ( 317 "text too long", 318 SourceDescription { 319 chunks: vec![SourceDescriptionChunk { 320 source: 1, 321 items: vec![SourceDescriptionItem { 322 sdes_type: SdesType::SdesCname, 323 text: Bytes::copy_from_slice(too_long_text.as_bytes()), 324 }], 325 }], 326 }, 327 Some(Error::SdesTextTooLong), 328 ), 329 ( 330 "count overflow", 331 SourceDescription { 332 chunks: too_many_chunks, 333 }, 334 Some(Error::TooManyChunks), 335 ), 336 ]; 337 338 for (name, want, want_error) in tests { 339 let got = want.marshal(); 340 341 assert_eq!( 342 got.is_ok(), 343 want_error.is_none(), 344 "Marshal {}: err = {:?}, want {:?}", 345 name, 346 got, 347 want_error 348 ); 349 350 if let Some(err) = want_error { 351 let got_err = got.err().unwrap(); 352 assert_eq!( 353 err, got_err, 354 "Unmarshal {} rr: err = {:?}, want {:?}", 355 name, got_err, err, 356 ); 357 } else { 358 let mut data = got.ok().unwrap(); 359 let actual = SourceDescription::unmarshal(&mut data) 360 .unwrap_or_else(|_| panic!("Unmarshal {}", name)); 361 362 assert_eq!( 363 actual, want, 364 "{} round trip: got {:?}, want {:?}", 365 name, actual, want 366 ) 367 } 368 } 369 } 370