@@ -45,22 +45,6 @@ fn publisher_video_track(room: &Room) -> Result<LocalVideoTrack> {
4545 Err ( anyhow ! ( "No local video track publication found" ) )
4646}
4747
48- /// Returns the publisher's local video tracks keyed by track SID.
49- #[ cfg( feature = "__lk-e2e-test" ) ]
50- fn publisher_video_tracks ( room : & Room ) -> HashMap < TrackSid , LocalVideoTrack > {
51- room. local_participant ( )
52- . track_publications ( )
53- . into_values ( )
54- . filter_map ( |publication| {
55- let sid = publication. sid ( ) ;
56- let Some ( LocalTrack :: Video ( track) ) = publication. track ( ) else {
57- return None ;
58- } ;
59- Some ( ( sid, track) )
60- } )
61- . collect ( )
62- }
63-
6448/// Polls `publishing_layers()` until the `check` predicate returns true, or times out.
6549#[ cfg( feature = "__lk-e2e-test" ) ]
6650async fn wait_for_layers (
@@ -87,62 +71,68 @@ async fn wait_for_layers(
8771 }
8872}
8973
90- /// Waits for the publisher to expose `expected_count` local video tracks .
74+ /// Waits for the publisher's next local video track publication .
9175#[ cfg( feature = "__lk-e2e-test" ) ]
92- async fn wait_for_publisher_video_tracks (
93- room : & Room ,
94- expected_count : usize ,
76+ async fn wait_for_next_publisher_video_track (
77+ events : & mut UnboundedReceiver < RoomEvent > ,
9578 label : & str ,
9679 max_wait : Duration ,
97- ) -> Result < HashMap < TrackSid , LocalVideoTrack > > {
98- let deadline = tokio:: time:: Instant :: now ( ) + max_wait;
99- loop {
100- let tracks = publisher_video_tracks ( room) ;
101- if tracks. len ( ) == expected_count {
102- return Ok ( tracks) ;
103- }
104- if tokio:: time:: Instant :: now ( ) >= deadline {
105- return Err ( anyhow ! (
106- "dynacast test [{}]: timed out waiting for {} publisher video tracks, got {}" ,
107- label,
108- expected_count,
109- tracks. len( )
110- ) ) ;
80+ ) -> Result < ( TrackSid , LocalVideoTrack ) > {
81+ timeout ( max_wait, async {
82+ while let Some ( event) = events. recv ( ) . await {
83+ if let RoomEvent :: LocalTrackPublished {
84+ publication,
85+ track : LocalTrack :: Video ( track) ,
86+ ..
87+ } = event
88+ {
89+ return Ok ( ( publication. sid ( ) , track) ) ;
90+ }
11191 }
112- time:: sleep ( Duration :: from_millis ( 250 ) ) . await ;
113- }
92+ Err ( anyhow ! ( "dynacast test [{}]: event channel closed before video track published" , label) )
93+ } )
94+ . await
95+ . map_err ( |_| {
96+ anyhow ! ( "dynacast test [{}]: timed out waiting for publisher video track" , label)
97+ } ) ?
11498}
11599
116100/// Waits for a subscriber to observe all expected remote track publications.
117101#[ cfg( feature = "__lk-e2e-test" ) ]
118102async fn wait_for_remote_publications (
119- room : & Room ,
103+ events : & mut UnboundedReceiver < RoomEvent > ,
120104 track_sids : & [ TrackSid ] ,
121105 label : & str ,
122106 max_wait : Duration ,
123107) -> Result < HashMap < TrackSid , RemoteTrackPublication > > {
124- let deadline = tokio:: time:: Instant :: now ( ) + max_wait;
125- loop {
126- let publications: HashMap < _ , _ > = room
127- . remote_participants ( )
128- . into_values ( )
129- . flat_map ( |participant| participant. track_publications ( ) )
130- . filter ( |( sid, _) | track_sids. contains ( sid) )
131- . collect ( ) ;
132-
133- if publications. len ( ) == track_sids. len ( ) {
134- return Ok ( publications) ;
135- }
136- if tokio:: time:: Instant :: now ( ) >= deadline {
137- return Err ( anyhow ! (
138- "dynacast test [{}]: timed out waiting for remote publications, got {}/{}" ,
139- label,
140- publications. len( ) ,
141- track_sids. len( )
142- ) ) ;
108+ let mut publications: HashMap < TrackSid , RemoteTrackPublication > = HashMap :: new ( ) ;
109+ timeout ( max_wait, async {
110+ while publications. len ( ) < track_sids. len ( ) {
111+ let Some ( event) = events. recv ( ) . await else {
112+ return Err ( anyhow ! (
113+ "dynacast test [{}]: event channel closed before all remote publications observed" ,
114+ label
115+ ) ) ;
116+ } ;
117+ if let RoomEvent :: TrackPublished { publication, .. } = event {
118+ let sid = publication. sid ( ) ;
119+ if track_sids. contains ( & sid) {
120+ publications. insert ( sid, publication) ;
121+ }
122+ }
143123 }
144- time:: sleep ( Duration :: from_millis ( 250 ) ) . await ;
145- }
124+ Ok ( ( ) )
125+ } )
126+ . await
127+ . map_err ( |_| {
128+ anyhow ! (
129+ "dynacast test [{}]: timed out waiting for remote publications, got {}/{}" ,
130+ label,
131+ publications. len( ) ,
132+ track_sids. len( )
133+ )
134+ } ) ??;
135+ Ok ( publications)
146136}
147137
148138/// Subscribes to exactly one of the provided publications and waits for it to attach a track.
@@ -363,63 +353,41 @@ async fn test_dynacast_multiple_subscribers_only_publish_requested_tracks() -> R
363353
364354 let mut rooms =
365355 test_rooms_with_options ( [ pub_options, sub_options. clone ( ) , sub_options] ) . await ?;
366- let ( pub_room, _pub_events ) = rooms. remove ( 0 ) ;
367- let ( sub1_room , mut sub1_events) = rooms. remove ( 0 ) ;
368- let ( sub2_room , mut sub2_events) = rooms. remove ( 0 ) ;
356+ let ( pub_room, mut pub_events ) = rooms. remove ( 0 ) ;
357+ let ( _sub1_room , mut sub1_events) = rooms. remove ( 0 ) ;
358+ let ( _sub2_room , mut sub2_events) = rooms. remove ( 0 ) ;
369359
370360 let pub_room = Arc :: new ( pub_room) ;
371361 let mut solid_tracks = Vec :: new ( ) ;
372362 let mut track_sids: Vec < TrackSid > = Vec :: new ( ) ;
363+ let mut publisher_tracks: Vec < ( TrackSid , LocalVideoTrack ) > = Vec :: new ( ) ;
373364
374365 for ( index, luma) in [ 64 , 128 , 192 ] . into_iter ( ) . enumerate ( ) {
375366 let solid_params = SolidColorParams { width : 1280 , height : 720 , luma } ;
376367 let mut solid_track = SolidColorTrack :: new ( pub_room. clone ( ) , solid_params) ;
377368 solid_track. publish ( VideoCodec :: VP8 , true ) . await ?;
378369
379- let published_tracks = wait_for_publisher_video_tracks (
380- & pub_room,
381- index + 1 ,
370+ let ( new_sid, track) = wait_for_next_publisher_video_track (
371+ & mut pub_events,
382372 & format ! ( "publish track {}" , index + 1 ) ,
383373 Duration :: from_secs ( 15 ) ,
384374 )
385375 . await ?;
386- let Some ( new_sid) = published_tracks
387- . keys ( )
388- . find ( |sid| !track_sids. iter ( ) . any ( |published_sid| published_sid == * sid) )
389- else {
390- return Err ( anyhow ! ( "No new track SID found after publishing track {}" , index + 1 ) ) ;
391- } ;
392376 log:: info!( "dynacast multi: published track {} as {}" , index + 1 , new_sid) ;
393377 track_sids. push ( new_sid. clone ( ) ) ;
378+ publisher_tracks. push ( ( new_sid, track) ) ;
394379 solid_tracks. push ( solid_track) ;
395380 }
396381
397- let published_tracks = wait_for_publisher_video_tracks (
398- & pub_room,
399- 3 ,
400- "all published tracks" ,
401- Duration :: from_secs ( 5 ) ,
402- )
403- . await ?;
404- let publisher_tracks: Vec < _ > = track_sids
405- . iter ( )
406- . map ( |sid| {
407- let track = published_tracks
408- . get ( sid)
409- . ok_or_else ( || anyhow ! ( "Missing local video track {}" , sid) ) ?;
410- Ok ( ( sid. clone ( ) , track. clone ( ) ) )
411- } )
412- . collect :: < Result < _ > > ( ) ?;
413-
414382 let sub1_publications = wait_for_remote_publications (
415- & sub1_room ,
383+ & mut sub1_events ,
416384 & track_sids,
417385 "subscriber 1" ,
418386 Duration :: from_secs ( 15 ) ,
419387 )
420388 . await ?;
421389 let sub2_publications = wait_for_remote_publications (
422- & sub2_room ,
390+ & mut sub2_events ,
423391 & track_sids,
424392 "subscriber 2" ,
425393 Duration :: from_secs ( 15 ) ,
0 commit comments