Skip to content
File

Blob: firmware/vendor/str0m/tests/data-channel-direct.rs

rust129 lines
1use std::net::Ipv4Addr;
2use std::time::{Duration, Instant};
3 
4use str0m::channel::ChannelConfig;
5use str0m::{Candidate, Event, RtcConfig, RtcError};
6use tracing::info_span;
7 
8mod common;
9use common::{Peer, TestRtc, init_crypto_default, init_log, progress};
10 
11#[test]
12pub fn data_channel_direct() -> Result<(), RtcError> {
13 init_log();
14 init_crypto_default();
15 
16 let mut l = TestRtc::new(Peer::Left);
17 
18 let rtc_r = RtcConfig::new().set_ice_lite(true).build(Instant::now());
19 let mut r = TestRtc::new_with_rtc(info_span!("R"), rtc_r);
20 
21 let host1 = Candidate::host((Ipv4Addr::new(1, 1, 1, 1), 1000).into(), "udp")?;
22 let host2 = Candidate::host((Ipv4Addr::new(2, 2, 2, 2), 2000).into(), "udp")?;
23 l.add_local_candidate(host1.clone()).unwrap();
24 l.add_remote_candidate(host2.clone());
25 r.add_local_candidate(host2).unwrap();
26 r.add_remote_candidate(host1);
27 
28 let finger_l = l.direct_api().local_dtls_fingerprint().clone();
29 let finger_r = r.direct_api().local_dtls_fingerprint().clone();
30 
31 l.direct_api().set_remote_fingerprint(finger_r);
32 r.direct_api().set_remote_fingerprint(finger_l);
33 
34 let creds_l = l.direct_api().local_ice_credentials();
35 let creds_r = r.direct_api().local_ice_credentials();
36 
37 l.direct_api().set_remote_ice_credentials(creds_r);
38 r.direct_api().set_remote_ice_credentials(creds_l);
39 
40 l.direct_api().set_ice_controlling(true);
41 r.direct_api().set_ice_controlling(false);
42 
43 l.direct_api().start_dtls(true).unwrap();
44 r.direct_api().start_dtls(false).unwrap();
45 
46 l.direct_api().start_sctp(true);
47 r.direct_api().start_sctp(false);
48 
49 let config = ChannelConfig {
50 negotiated: Some(1),
51 label: "my-chan".into(),
52 ..Default::default()
53 };
54 let cid = l.direct_api().create_data_channel(config.clone());
55 r.direct_api().create_data_channel(config);
56 
57 loop {
58 if l.is_connected() || r.is_connected() {
59 break;
60 }
61 progress(&mut l, &mut r)?;
62 }
63 
64 let max = l.last.max(r.last);
65 l.last = max;
66 r.last = max;
67 
68 loop {
69 if let Some(mut chan) = l.channel(cid) {
70 chan.write(false, "Hello world! ".as_bytes())
71 .expect("to write string");
72 }
73 
74 progress(&mut l, &mut r)?;
75 
76 if l.duration() > Duration::from_secs(10) {
77 break;
78 }
79 }
80 
81 l.direct_api().close_data_channel(cid);
82 
83 loop {
84 progress(&mut l, &mut r)?;
85 
86 if l.duration() > Duration::from_secs(12) {
87 break;
88 }
89 }
90 
91 assert!(
92 l.events
93 .iter()
94 .any(|(_, event)| event == &Event::ChannelOpen(cid, "my-chan".into()))
95 );
96 assert!(r.events.len() > 120);
97 assert!(
98 l.events
99 .iter()
100 .any(|(_, event)| event == &Event::ChannelClose(cid))
101 );
102 
103 // Assert that ChannelOpen happens quickly after IceConnectionStateChange(Completed)
104 let ice_completed_time = l
105 .events
106 .iter()
107 .find_map(|(t, e)| match e {
108 Event::IceConnectionStateChange(str0m::IceConnectionState::Completed) => Some(*t),
109 _ => None,
110 })
111 .expect("IceConnectionStateChange(Completed) event");
112 let channel_open_time = l
113 .events
114 .iter()
115 .find_map(|(t, e)| match e {
116 Event::ChannelOpen(_, _) => Some(*t),
117 _ => None,
118 })
119 .expect("ChannelOpen event");
120 let channel_open_delay = channel_open_time.duration_since(ice_completed_time);
121 assert!(
122 channel_open_delay < Duration::from_millis(250),
123 "ChannelOpen should happen within 250ms of ICE completing, but took {:?}",
124 channel_open_delay
125 );
126 
127 Ok(())
128}