1 use super::*;
2
3 #[test]
test_source_description_unmarshal()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 {name}: err = {got:?}, want {want_error:?}"
203 );
204
205 if let Some(err) = want_error {
206 let got_err = got.err().unwrap();
207 assert_eq!(
208 err, got_err,
209 "Unmarshal {name}: err = {got_err:?}, want {err:?}",
210 );
211 } else {
212 let actual = got.unwrap();
213 assert_eq!(
214 actual, want,
215 "Unmarshal {name}: got {actual:?}, want {want:?}"
216 );
217 }
218 }
219 }
220
221 #[test]
test_source_description_roundtrip()222 fn test_source_description_roundtrip() {
223 let mut too_long_text = String::new();
224 for _ in 0..(1 << 8) {
225 too_long_text += "x";
226 }
227
228 let mut too_many_chunks = vec![];
229 for _ in 0..(1 << 5) {
230 too_many_chunks.push(SourceDescriptionChunk::default());
231 }
232
233 let tests = vec![
234 (
235 "valid",
236 SourceDescription {
237 chunks: vec![
238 SourceDescriptionChunk {
239 source: 1,
240 items: vec![SourceDescriptionItem {
241 sdes_type: SdesType::SdesCname,
242 text: Bytes::from_static(b"[email protected]"),
243 }],
244 },
245 SourceDescriptionChunk {
246 source: 2,
247 items: vec![
248 SourceDescriptionItem {
249 sdes_type: SdesType::SdesNote,
250 text: Bytes::from_static(b"some note"),
251 },
252 SourceDescriptionItem {
253 sdes_type: SdesType::SdesNote,
254 text: Bytes::from_static(b"another note"),
255 },
256 ],
257 },
258 ],
259 },
260 None,
261 ),
262 (
263 "item without type",
264 SourceDescription {
265 chunks: vec![SourceDescriptionChunk {
266 source: 1,
267 items: vec![SourceDescriptionItem {
268 sdes_type: SdesType::SdesEnd,
269 text: Bytes::from_static(b"[email protected]"),
270 }],
271 }],
272 },
273 Some(Error::SdesMissingType),
274 ),
275 (
276 "zero items",
277 SourceDescription {
278 chunks: vec![SourceDescriptionChunk {
279 source: 1,
280 items: vec![],
281 }],
282 },
283 None,
284 ),
285 (
286 "email item",
287 SourceDescription {
288 chunks: vec![SourceDescriptionChunk {
289 source: 1,
290 items: vec![SourceDescriptionItem {
291 sdes_type: SdesType::SdesEmail,
292 text: Bytes::from_static(b"[email protected]"),
293 }],
294 }],
295 },
296 None,
297 ),
298 (
299 "empty text",
300 SourceDescription {
301 chunks: vec![SourceDescriptionChunk {
302 source: 1,
303 items: vec![SourceDescriptionItem {
304 sdes_type: SdesType::SdesCname,
305 text: Bytes::from_static(b""),
306 }],
307 }],
308 },
309 None,
310 ),
311 (
312 "text too long",
313 SourceDescription {
314 chunks: vec![SourceDescriptionChunk {
315 source: 1,
316 items: vec![SourceDescriptionItem {
317 sdes_type: SdesType::SdesCname,
318 text: Bytes::copy_from_slice(too_long_text.as_bytes()),
319 }],
320 }],
321 },
322 Some(Error::SdesTextTooLong),
323 ),
324 (
325 "count overflow",
326 SourceDescription {
327 chunks: too_many_chunks,
328 },
329 Some(Error::TooManyChunks),
330 ),
331 ];
332
333 for (name, want, want_error) in tests {
334 let got = want.marshal();
335
336 assert_eq!(
337 got.is_ok(),
338 want_error.is_none(),
339 "Marshal {name}: err = {got:?}, want {want_error:?}"
340 );
341
342 if let Some(err) = want_error {
343 let got_err = got.err().unwrap();
344 assert_eq!(
345 err, got_err,
346 "Unmarshal {name} rr: err = {got_err:?}, want {err:?}",
347 );
348 } else {
349 let mut data = got.ok().unwrap();
350 let actual = SourceDescription::unmarshal(&mut data)
351 .unwrap_or_else(|_| panic!("Unmarshal {name}"));
352
353 assert_eq!(
354 actual, want,
355 "{name} round trip: got {actual:?}, want {want:?}"
356 )
357 }
358 }
359 }
360