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