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