fn send_data_blocked_frame_when_blocked_by_connection_flow_limits()

in quic/s2n-quic-transport/src/stream/manager/tests.rs [1080:1207]


fn send_data_blocked_frame_when_blocked_by_connection_flow_limits() {
    let mut manager = create_stream_manager(endpoint::Type::Server);

    // Consume all window
    let current_window =
        manager.with_outgoing_connection_flow_controller(|ctrl| ctrl.total_window());
    assert_eq!(
        current_window,
        manager
            .with_outgoing_connection_flow_controller(|ctrl| ctrl.acquire_window(current_window))
    );

    // No DATA_BLOCKED is sent, since the window has been fully consumed, but not exceeded
    assert_eq!(
        transmission::Interest::None,
        manager.get_transmission_interest()
    );

    // Try acquiring one more byte to exceed the window
    assert_eq!(
        VarInt::from_u32(0),
        manager.with_outgoing_connection_flow_controller(
            |ctrl| ctrl.acquire_window(VarInt::from_u32(1))
        )
    );

    assert_eq!(
        transmission::Interest::NewData,
        manager.get_transmission_interest()
    );

    let mut frame_buffer = OutgoingFrameBuffer::new();
    let mut write_context = MockWriteContext::new(
        time::now(),
        &mut frame_buffer,
        transmission::Constraint::None,
        transmission::Mode::Normal,
        endpoint::Type::Server,
    );
    let packet_number = write_context.packet_number();
    assert!(manager.on_transmit(&mut write_context).is_ok());

    let expected_frame = Frame::DataBlocked(DataBlocked {
        data_limit: current_window,
    });

    assert_eq!(
        expected_frame,
        write_context.frame_buffer.pop_front().unwrap().as_frame()
    );
    write_context.frame_buffer.clear();

    assert_eq!(
        transmission::Interest::None,
        manager.get_transmission_interest()
    );

    manager.on_packet_loss(&PacketNumberRange::new(packet_number, packet_number));

    assert_eq!(
        transmission::Interest::LostData,
        manager.get_transmission_interest()
    );

    let packet_number = write_context.packet_number();
    assert!(manager.on_transmit(&mut write_context).is_ok());
    write_context.frame_buffer.clear();

    manager.on_packet_ack(&PacketNumberRange::new(packet_number, packet_number));

    assert_eq!(
        transmission::Interest::None,
        manager.get_transmission_interest()
    );

    let expected_transmission_backoff = 4;
    let expected_next_data_blocked_time =
        write_context.current_time + DEFAULT_SYNC_PERIOD * expected_transmission_backoff;
    assert_eq!(
        Some(expected_next_data_blocked_time),
        manager.next_expiration()
    );

    manager.on_timeout(expected_next_data_blocked_time);

    // Another DATA_BLOCKED frame should be sent
    assert_eq!(
        transmission::Interest::NewData,
        manager.get_transmission_interest()
    );

    // We get more credit from the peer so we should no longer send DATA_BLOCKED
    assert!(manager
        .on_max_data(MaxData {
            maximum_data: current_window + 1
        })
        .is_ok());

    assert_eq!(
        transmission::Interest::None,
        manager.get_transmission_interest()
    );

    // Exceed the window again
    assert_eq!(
        VarInt::from_u32(1),
        manager.with_outgoing_connection_flow_controller(
            |ctrl| ctrl.acquire_window(VarInt::from_u32(2))
        )
    );

    // Another DATA_BLOCKED frame should be sent with the updated MAX_DATA value
    assert_eq!(
        transmission::Interest::NewData,
        manager.get_transmission_interest()
    );

    assert!(manager.on_transmit(&mut write_context).is_ok());

    let expected_frame = Frame::DataBlocked(DataBlocked {
        data_limit: current_window + 1,
    });

    assert_eq!(
        expected_frame,
        write_context.frame_buffer.pop_front().unwrap().as_frame()
    );
}