@@ -10411,3 +10411,83 @@ fn configuration_values_are_limited_to_max_varint() {
1041110411 // do not panic because of too large values that we try to encode via varint.
1041210412 assert_eq ! ( pipe. handshake( ) , Err ( Error :: InvalidTransportParam ) ) ;
1041310413}
10414+
10415+ /// Tests that incremental streams are scheduled round-robin when sending.
10416+ ///
10417+ /// When multiple incremental streams have data queued, each call to send()
10418+ /// should emit data from the next stream in rotation, not always from the
10419+ /// same stream.
10420+ #[ test]
10421+ fn incremental_stream_round_robin ( ) {
10422+ let mut config = Config :: new ( PROTOCOL_VERSION ) . unwrap ( ) ;
10423+ config
10424+ . load_cert_chain_from_pem_file ( "examples/cert.crt" )
10425+ . unwrap ( ) ;
10426+ config
10427+ . load_priv_key_from_pem_file ( "examples/cert.key" )
10428+ . unwrap ( ) ;
10429+ config
10430+ . set_application_protos ( & [ b"proto1" , b"proto2" ] )
10431+ . unwrap ( ) ;
10432+ // Set high limits so we can send data on multiple streams
10433+ config. set_initial_max_data ( 100000 ) ;
10434+ config. set_initial_max_stream_data_bidi_local ( 10000 ) ;
10435+ config. set_initial_max_stream_data_bidi_remote ( 10000 ) ;
10436+ config. set_initial_max_streams_bidi ( 10 ) ;
10437+ config. verify_peer ( false ) ;
10438+
10439+ let mut pipe = test_utils:: Pipe :: with_config ( & mut config) . unwrap ( ) ;
10440+ assert_eq ! ( pipe. handshake( ) , Ok ( ( ) ) ) ;
10441+
10442+ // Queue data on three streams. All streams are incremental by default.
10443+ // Use 2500 bytes so each stream needs ~2 packets to send all data.
10444+ let data = vec ! [ 0u8 ; 2500 ] ;
10445+ assert_eq ! ( pipe. client. stream_send( 4 , & data, false ) , Ok ( 2500 ) ) ;
10446+ assert_eq ! ( pipe. client. stream_send( 8 , & data, false ) , Ok ( 2500 ) ) ;
10447+ assert_eq ! ( pipe. client. stream_send( 12 , & data, false ) , Ok ( 2500 ) ) ;
10448+
10449+ // Track which streams get data sent in each packet
10450+ let mut send_order = Vec :: new ( ) ;
10451+
10452+ // Send packets one at a time
10453+ let mut buf = [ 0 ; 1350 ] ;
10454+ let mut recv_buf = [ 0 ; 1350 ] ;
10455+
10456+ // Send multiple packets and track which stream's data is sent
10457+ for _ in 0 ..10 {
10458+ let result = pipe. client . send ( & mut buf) ;
10459+ if result. is_err ( ) {
10460+ break ;
10461+ }
10462+ let ( len, _) = result. unwrap ( ) ;
10463+ if len == 0 {
10464+ break ;
10465+ }
10466+
10467+ // Process packet on server
10468+ let info = RecvInfo {
10469+ to : test_utils:: Pipe :: server_addr ( ) ,
10470+ from : test_utils:: Pipe :: client_addr ( ) ,
10471+ } ;
10472+ pipe. server . recv ( & mut buf[ ..len] , info) . unwrap ( ) ;
10473+
10474+ // Check which streams received data in THIS packet by consuming data.
10475+ // This ensures readable() only shows streams with new data next time.
10476+ for stream_id in pipe. server . readable ( ) {
10477+ send_order. push ( stream_id) ;
10478+ // Drain the data so the stream is no longer readable
10479+ while pipe. server . stream_recv ( stream_id, & mut recv_buf) . is_ok ( ) { }
10480+ }
10481+ }
10482+
10483+ // With round-robin, streams are cycled after sending:
10484+ // - Stream 4 sends (lowest sequence), cycled to back -> queue: [8, 12, 4]
10485+ // - Stream 8 sends, cycled to back -> queue: [12, 4, 8]
10486+ // - Stream 12 sends, cycled to back -> queue: [4, 8, 12]
10487+ // Pattern repeats until all data is sent (3 rounds for 2500 bytes each).
10488+ assert_eq ! (
10489+ send_order,
10490+ vec![ 4 , 8 , 12 , 4 , 8 , 12 , 4 , 8 , 12 ] ,
10491+ "Expected round-robin ordering: streams interleave across packets"
10492+ ) ;
10493+ }
0 commit comments