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