fn can_send_multiple_chunks()

in quic/s2n-quic-transport/src/stream/send_stream/tests.rs [2656:2763]


fn can_send_multiple_chunks() {
    let max_send_buffer_size = 3000;
    for sizes in [&[10, 10, 10][..], &[500, 500, 500], &[1000, 1000, 1000][..]] {
        for finish in [false, true] {
            for flush in [false, true] {
                for with_context in [false, true] {
                    let test_env_config = TestEnvironmentConfig {
                        max_send_buffer_size,
                        stream_id: StreamId::initial(
                            endpoint::Type::Client,
                            StreamType::Unidirectional,
                        ),
                        local_endpoint_type: endpoint::Type::Client,
                        ..Default::default()
                    };
                    let mut test_env = setup_stream_test_env_with_config(test_env_config);
                    let mut expected_buffer_size = max_send_buffer_size;

                    dbg!(sizes);
                    dbg!(finish);
                    dbg!(flush);
                    dbg!(with_context);

                    let mut chunks = gen_pattern_test_chunks(VarInt::from_u8(0), sizes);

                    let mut request = ops::Request::default();
                    request.send(&mut chunks);

                    if finish {
                        request.finish();
                    }

                    if flush {
                        request.flush();
                    }

                    let mut expected_consumed_bytes = 0;
                    let mut expected_consumed_chunks = 0;
                    for size in sizes.iter().cloned() {
                        expected_consumed_bytes += size;
                        expected_consumed_chunks += 1;
                        if let Some(size) = expected_buffer_size.checked_sub(size) {
                            expected_buffer_size = size;
                        } else {
                            expected_buffer_size = 0;
                            break;
                        }
                    }
                    let consumed_all = expected_consumed_chunks == sizes.len();

                    // finishing the buffer should end the availability
                    if finish {
                        expected_buffer_size = 0;
                    }

                    let will_wake = with_context && (!consumed_all || flush);

                    assert_eq!(
                        test_env.run_request(&mut request, with_context),
                        Ok(ops::Response {
                            tx: Some(ops::tx::Response {
                                bytes: ops::Bytes {
                                    available: expected_buffer_size,
                                    consumed: expected_consumed_bytes,
                                },
                                chunks: ops::Chunks {
                                    available: expected_buffer_size,
                                    consumed: expected_consumed_chunks,
                                },
                                status: if consumed_all && finish {
                                    ops::Status::Finishing
                                } else {
                                    ops::Status::Open
                                },
                                will_wake,
                            }),
                            rx: None,
                        }),
                    );

                    execute_instructions(
                        &mut test_env,
                        &[Instruction::CheckInterests(stream_interests(&["tx"]))],
                    );

                    let mut offset = 0;
                    let mut idx = 0;
                    while let Some(mut frame) = test_env.transmit() {
                        if let Frame::Stream(stream) = frame.as_frame() {
                            offset += stream.data.len();
                            test_env.ack_packet(pn(idx), ExpectWakeup(None));
                            idx += 1;
                        } else {
                            panic!("invalid frame");
                        }
                    }

                    assert_eq!(expected_consumed_bytes, offset);

                    execute_instructions(
                        &mut test_env,
                        &[Instruction::CheckInterests(stream_interests(&[]))],
                    );
                }
            }
        }
    }
}