1 use super::*;
2
3 use std::time::UNIX_EPOCH;
4
5 #[test]
test_candidate_priority() -> Result<()>6 fn test_candidate_priority() -> Result<()> {
7 let tests = vec![
8 (
9 CandidateBase {
10 candidate_type: CandidateType::Host,
11 component: AtomicU16::new(COMPONENT_RTP),
12 ..Default::default()
13 },
14 2130706431,
15 ),
16 (
17 CandidateBase {
18 candidate_type: CandidateType::Host,
19 component: AtomicU16::new(COMPONENT_RTP),
20 network_type: AtomicU8::new(NetworkType::Tcp4 as u8),
21 tcp_type: TcpType::Active,
22 ..Default::default()
23 },
24 2128609279,
25 ),
26 (
27 CandidateBase {
28 candidate_type: CandidateType::Host,
29 component: AtomicU16::new(COMPONENT_RTP),
30 network_type: AtomicU8::new(NetworkType::Tcp4 as u8),
31 tcp_type: TcpType::Passive,
32 ..Default::default()
33 },
34 2124414975,
35 ),
36 (
37 CandidateBase {
38 candidate_type: CandidateType::Host,
39 component: AtomicU16::new(COMPONENT_RTP),
40 network_type: AtomicU8::new(NetworkType::Tcp4 as u8),
41 tcp_type: TcpType::SimultaneousOpen,
42 ..Default::default()
43 },
44 2120220671,
45 ),
46 (
47 CandidateBase {
48 candidate_type: CandidateType::PeerReflexive,
49 component: AtomicU16::new(COMPONENT_RTP),
50 ..Default::default()
51 },
52 1862270975,
53 ),
54 (
55 CandidateBase {
56 candidate_type: CandidateType::PeerReflexive,
57 component: AtomicU16::new(COMPONENT_RTP),
58 network_type: AtomicU8::new(NetworkType::Tcp6 as u8),
59 tcp_type: TcpType::SimultaneousOpen,
60 ..Default::default()
61 },
62 1860173823,
63 ),
64 (
65 CandidateBase {
66 candidate_type: CandidateType::PeerReflexive,
67 component: AtomicU16::new(COMPONENT_RTP),
68 network_type: AtomicU8::new(NetworkType::Tcp6 as u8),
69 tcp_type: TcpType::Active,
70 ..Default::default()
71 },
72 1855979519,
73 ),
74 (
75 CandidateBase {
76 candidate_type: CandidateType::PeerReflexive,
77 component: AtomicU16::new(COMPONENT_RTP),
78 network_type: AtomicU8::new(NetworkType::Tcp6 as u8),
79 tcp_type: TcpType::Passive,
80 ..Default::default()
81 },
82 1851785215,
83 ),
84 (
85 CandidateBase {
86 candidate_type: CandidateType::ServerReflexive,
87 component: AtomicU16::new(COMPONENT_RTP),
88 ..Default::default()
89 },
90 1694498815,
91 ),
92 (
93 CandidateBase {
94 candidate_type: CandidateType::Relay,
95 component: AtomicU16::new(COMPONENT_RTP),
96 ..Default::default()
97 },
98 16777215,
99 ),
100 ];
101
102 for (candidate, want) in tests {
103 let got = candidate.priority();
104 assert_eq!(
105 got, want,
106 "Candidate({candidate}).Priority() = {got}, want {want}"
107 );
108 }
109
110 Ok(())
111 }
112
113 #[test]
test_candidate_last_sent() -> Result<()>114 fn test_candidate_last_sent() -> Result<()> {
115 let candidate = CandidateBase::default();
116 assert_eq!(candidate.last_sent(), UNIX_EPOCH);
117
118 let now = SystemTime::now();
119 let d = now.duration_since(UNIX_EPOCH)?;
120 candidate.set_last_sent(d);
121 assert_eq!(candidate.last_sent(), now);
122
123 Ok(())
124 }
125
126 #[test]
test_candidate_last_received() -> Result<()>127 fn test_candidate_last_received() -> Result<()> {
128 let candidate = CandidateBase::default();
129 assert_eq!(candidate.last_received(), UNIX_EPOCH);
130
131 let now = SystemTime::now();
132 let d = now.duration_since(UNIX_EPOCH)?;
133 candidate.set_last_received(d);
134 assert_eq!(candidate.last_received(), now);
135
136 Ok(())
137 }
138
139 #[test]
test_candidate_foundation() -> Result<()>140 fn test_candidate_foundation() -> Result<()> {
141 // All fields are the same
142 assert_eq!(
143 (CandidateBase {
144 candidate_type: CandidateType::Host,
145 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
146 address: "A".to_owned(),
147 ..Default::default()
148 })
149 .foundation(),
150 (CandidateBase {
151 candidate_type: CandidateType::Host,
152 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
153 address: "A".to_owned(),
154 ..Default::default()
155 })
156 .foundation()
157 );
158
159 // Different Address
160 assert_ne!(
161 (CandidateBase {
162 candidate_type: CandidateType::Host,
163 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
164 address: "A".to_owned(),
165 ..Default::default()
166 })
167 .foundation(),
168 (CandidateBase {
169 candidate_type: CandidateType::Host,
170 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
171 address: "B".to_owned(),
172 ..Default::default()
173 })
174 .foundation(),
175 );
176
177 // Different networkType
178 assert_ne!(
179 (CandidateBase {
180 candidate_type: CandidateType::Host,
181 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
182 address: "A".to_owned(),
183 ..Default::default()
184 })
185 .foundation(),
186 (CandidateBase {
187 candidate_type: CandidateType::Host,
188 network_type: AtomicU8::new(NetworkType::Udp6 as u8),
189 address: "A".to_owned(),
190 ..Default::default()
191 })
192 .foundation(),
193 );
194
195 // Different candidateType
196 assert_ne!(
197 (CandidateBase {
198 candidate_type: CandidateType::Host,
199 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
200 address: "A".to_owned(),
201 ..Default::default()
202 })
203 .foundation(),
204 (CandidateBase {
205 candidate_type: CandidateType::PeerReflexive,
206 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
207 address: "A".to_owned(),
208 ..Default::default()
209 })
210 .foundation(),
211 );
212
213 // Port has no effect
214 assert_eq!(
215 (CandidateBase {
216 candidate_type: CandidateType::Host,
217 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
218 address: "A".to_owned(),
219 port: 8080,
220 ..Default::default()
221 })
222 .foundation(),
223 (CandidateBase {
224 candidate_type: CandidateType::Host,
225 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
226 address: "A".to_owned(),
227 port: 80,
228 ..Default::default()
229 })
230 .foundation()
231 );
232
233 Ok(())
234 }
235
236 #[test]
test_candidate_pair_state_serialization()237 fn test_candidate_pair_state_serialization() {
238 let tests = vec![
239 (CandidatePairState::Unspecified, "\"unspecified\""),
240 (CandidatePairState::Waiting, "\"waiting\""),
241 (CandidatePairState::InProgress, "\"in-progress\""),
242 (CandidatePairState::Failed, "\"failed\""),
243 (CandidatePairState::Succeeded, "\"succeeded\""),
244 ];
245
246 for (candidate_pair_state, expected_string) in tests {
247 assert_eq!(
248 expected_string.to_string(),
249 serde_json::to_string(&candidate_pair_state).unwrap()
250 );
251 }
252 }
253
254 #[test]
test_candidate_pair_state_to_string()255 fn test_candidate_pair_state_to_string() {
256 let tests = vec![
257 (CandidatePairState::Unspecified, "unspecified"),
258 (CandidatePairState::Waiting, "waiting"),
259 (CandidatePairState::InProgress, "in-progress"),
260 (CandidatePairState::Failed, "failed"),
261 (CandidatePairState::Succeeded, "succeeded"),
262 ];
263
264 for (candidate_pair_state, expected_string) in tests {
265 assert_eq!(candidate_pair_state.to_string(), expected_string);
266 }
267 }
268
269 #[test]
test_candidate_type_serialization()270 fn test_candidate_type_serialization() {
271 let tests = vec![
272 (CandidateType::Unspecified, "\"unspecified\""),
273 (CandidateType::Host, "\"host\""),
274 (CandidateType::ServerReflexive, "\"srflx\""),
275 (CandidateType::PeerReflexive, "\"prflx\""),
276 (CandidateType::Relay, "\"relay\""),
277 ];
278
279 for (candidate_type, expected_string) in tests {
280 assert_eq!(
281 serde_json::to_string(&candidate_type).unwrap(),
282 expected_string.to_string()
283 );
284 }
285 }
286
287 #[test]
test_candidate_type_to_string()288 fn test_candidate_type_to_string() {
289 let tests = vec![
290 (CandidateType::Unspecified, "Unknown candidate type"),
291 (CandidateType::Host, "host"),
292 (CandidateType::ServerReflexive, "srflx"),
293 (CandidateType::PeerReflexive, "prflx"),
294 (CandidateType::Relay, "relay"),
295 ];
296
297 for (candidate_type, expected_string) in tests {
298 assert_eq!(candidate_type.to_string(), expected_string);
299 }
300 }
301
302 #[test]
test_candidate_marshal() -> Result<()>303 fn test_candidate_marshal() -> Result<()> {
304 let tests = vec![
305 (
306 Some(CandidateBase{
307 network_type: AtomicU8::new(NetworkType::Udp6 as u8),
308 candidate_type: CandidateType::Host,
309 address: "fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a".to_owned(),
310 port: 53987,
311 priority_override: 500,
312 foundation_override: "750".to_owned(),
313 ..Default::default()
314 }),
315 "750 1 udp 500 fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a 53987 typ host",
316 ),
317 (
318 Some(CandidateBase{
319 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
320 candidate_type: CandidateType::Host,
321 address: "10.0.75.1".to_owned(),
322 port: 53634,
323 ..Default::default()
324 }),
325 "4273957277 1 udp 2130706431 10.0.75.1 53634 typ host",
326 ),
327 (
328 Some(CandidateBase{
329 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
330 candidate_type: CandidateType::ServerReflexive,
331 address: "191.228.238.68".to_owned(),
332 port: 53991,
333 related_address: Some(CandidateRelatedAddress{
334 address: "192.168.0.274".to_owned(),
335 port:53991
336 }),
337 ..Default::default()
338 }),
339 "647372371 1 udp 1694498815 191.228.238.68 53991 typ srflx raddr 192.168.0.274 rport 53991",
340 ),
341 (
342 Some(CandidateBase{
343 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
344 candidate_type: CandidateType::Relay,
345 address: "50.0.0.1".to_owned(),
346 port: 5000,
347 related_address: Some(
348 CandidateRelatedAddress{
349 address: "192.168.0.1".to_owned(),
350 port:5001}
351 ),
352 ..Default::default()
353 }),
354 "848194626 1 udp 16777215 50.0.0.1 5000 typ relay raddr 192.168.0.1 rport 5001",
355 ),
356 (
357 Some(CandidateBase{
358 network_type: AtomicU8::new(NetworkType::Tcp4 as u8),
359 candidate_type: CandidateType::Host,
360 address: "192.168.0.196".to_owned(),
361 port: 0,
362 tcp_type: TcpType::Active,
363 ..Default::default()
364 }),
365 "1052353102 1 tcp 2128609279 192.168.0.196 0 typ host tcptype active",
366 ),
367 (
368 Some(CandidateBase{
369 network_type: AtomicU8::new(NetworkType::Udp4 as u8),
370 candidate_type: CandidateType::Host,
371 address: "e2494022-4d9a-4c1e-a750-cc48d4f8d6ee.local".to_owned(),
372 port: 60542,
373 ..Default::default()
374 }),
375 "1380287402 1 udp 2130706431 e2494022-4d9a-4c1e-a750-cc48d4f8d6ee.local 60542 typ host",
376 ),
377 // Invalid candidates
378 (None, ""),
379 (None, "1938809241"),
380 (None, "1986380506 99999999 udp 2122063615 10.0.75.1 53634 typ host generation 0 network-id 2"),
381 (None, "1986380506 1 udp 99999999999 10.0.75.1 53634 typ host"),
382 (None, "4207374051 1 udp 1685790463 191.228.238.68 99999999 typ srflx raddr 192.168.0.278 rport 53991 generation 0 network-id 3"),
383 (None, "4207374051 1 udp 1685790463 191.228.238.68 53991 typ srflx raddr"),
384 (None, "4207374051 1 udp 1685790463 191.228.238.68 53991 typ srflx raddr 192.168.0.278 rport 99999999 generation 0 network-id 3"),
385 (None, "4207374051 INVALID udp 2130706431 10.0.75.1 53634 typ host"),
386 (None, "4207374051 1 udp INVALID 10.0.75.1 53634 typ host"),
387 (None, "4207374051 INVALID udp 2130706431 10.0.75.1 INVALID typ host"),
388 (None, "4207374051 1 udp 2130706431 10.0.75.1 53634 typ INVALID"),
389 ];
390
391 for (candidate, marshaled) in tests {
392 let actual_candidate = unmarshal_candidate(marshaled);
393 if let Some(candidate) = candidate {
394 if let Ok(actual_candidate) = actual_candidate {
395 assert!(
396 candidate.equal(&actual_candidate),
397 "{} vs {}",
398 candidate.marshal(),
399 marshaled
400 );
401 assert_eq!(marshaled, actual_candidate.marshal());
402 } else {
403 panic!("expected ok");
404 }
405 } else {
406 assert!(actual_candidate.is_err(), "expected error");
407 }
408 }
409
410 Ok(())
411 }
412