fn on_packet_ack_rate_sample()

in quic/s2n-quic-core/src/recovery/bandwidth/estimator/tests.rs [252:384]


fn on_packet_ack_rate_sample() {
    let mut publisher = event::testing::Publisher::snapshot();
    let mut publisher = PathPublisher::new(&mut publisher, path::Id::test_id());
    let t0 = NoopClock.get_time() + Duration::from_secs(60);
    let t1 = t0 + Duration::from_secs(1);
    let t2 = t0 + Duration::from_secs(2);
    let mut bw_estimator = Estimator::default();

    // Send three packets. In between each send, other packets were acknowledged, lost or had ECN CE,
    // and thus the delivered_bytes amount, lost_bytes amount, and ecn ce count is increased.
    let packet_1 = bw_estimator.on_packet_sent(0, 100, Some(false), t0);
    bw_estimator.delivered_bytes = 100000;
    bw_estimator.lost_bytes = 100;
    bw_estimator.ecn_ce_count = 5;
    let packet_2 = bw_estimator.on_packet_sent(1500, 100, Some(true), t1);
    bw_estimator.delivered_bytes = 200000;
    bw_estimator.lost_bytes = 150;
    bw_estimator.ecn_ce_count = 15;
    let packet_3 = bw_estimator.on_packet_sent(3000, 100, Some(false), t2);

    let now = t0 + Duration::from_secs(10);
    let delivered_bytes = bw_estimator.delivered_bytes;
    bw_estimator.on_ack(1500, t0, packet_1, now, &mut publisher);

    assert_eq!(bw_estimator.delivered_bytes, delivered_bytes + 1500);
    assert_eq!(bw_estimator.delivered_time, Some(now));

    // Rate sample is updated since this is the first packet delivered
    assert_eq!(
        packet_1.delivered_bytes,
        bw_estimator.rate_sample.prior_delivered_bytes
    );
    assert_eq!(
        packet_1.lost_bytes,
        bw_estimator.rate_sample.prior_lost_bytes
    );
    assert_eq!(
        packet_1.is_app_limited,
        bw_estimator.rate_sample.is_app_limited
    );
    assert_eq!(
        packet_1.bytes_in_flight,
        bw_estimator.rate_sample.bytes_in_flight
    );
    assert_eq!(Some(t0), bw_estimator.first_sent_time);
    assert_eq!(now - t0, bw_estimator.rate_sample.interval);

    // Delivered bytes, lost bytes, and ECN CE counts reflect the total lifetime counts,
    // since there was no prior delivered packets
    assert_eq!(
        bw_estimator.delivered_bytes,
        bw_estimator.rate_sample.delivered_bytes
    );
    assert_eq!(bw_estimator.lost_bytes, bw_estimator.rate_sample.lost_bytes);
    assert_eq!(
        bw_estimator.ecn_ce_count,
        bw_estimator.rate_sample.ecn_ce_count
    );

    // Ack a newer packet
    let now = now + Duration::from_secs(1);
    let delivered_bytes = bw_estimator.delivered_bytes;
    bw_estimator.on_ack(1500, t2, packet_3, now, &mut publisher);

    assert_eq!(bw_estimator.delivered_bytes, delivered_bytes + 1500);
    assert_eq!(bw_estimator.delivered_time, Some(now));

    // Rate sample is updated since this packet is newer (has a higher delivered_bytes)
    assert!(packet_3.delivered_bytes > packet_1.delivered_bytes);
    assert_eq!(
        packet_3.delivered_bytes,
        bw_estimator.rate_sample.prior_delivered_bytes
    );
    assert_eq!(
        packet_3.lost_bytes,
        bw_estimator.rate_sample.prior_lost_bytes
    );
    assert_eq!(
        packet_3.is_app_limited,
        bw_estimator.rate_sample.is_app_limited
    );
    assert_eq!(
        packet_3.bytes_in_flight,
        bw_estimator.rate_sample.bytes_in_flight
    );
    assert_eq!(Some(t2), bw_estimator.first_sent_time);
    assert_eq!(now - t0, bw_estimator.rate_sample.interval);

    // Now the delivered_bytes in the rate sample should reflect the current lifetime delivered bytes (200000 + 1500 + 1500)
    // minus the delivered bytes value at the time this packet was transmitted (200000)
    assert_eq!(3000, bw_estimator.rate_sample.delivered_bytes);
    // Lost bytes and ECN CE count are 0 since no additional loss or ECN CE was received since this packet was transmitted
    assert_eq!(0, bw_estimator.rate_sample.lost_bytes);
    assert_eq!(0, bw_estimator.rate_sample.ecn_ce_count);

    // Ack an older packet
    let now = now + Duration::from_secs(1);
    let delivered_bytes = bw_estimator.delivered_bytes;
    bw_estimator.on_ack(1500, t1, packet_2, now, &mut publisher);

    assert_eq!(bw_estimator.delivered_bytes, delivered_bytes + 1500);
    assert_eq!(bw_estimator.delivered_time, Some(now));

    //= https://tools.ietf.org/id/draft-cheng-iccrg-delivery-rate-estimation-02#3.3
    //= type=test
    //# UpdateRateSample() is invoked multiple times when a stretched ACK acknowledges
    //# multiple data packets. In this case we use the information from the most recently
    //# sent packet, i.e., the packet with the highest "P.delivered" value.

    // Rate sample is not updated since this packet is older than the current sample
    assert_eq!(
        packet_3.delivered_bytes,
        bw_estimator.rate_sample.prior_delivered_bytes
    );
    assert_eq!(
        packet_3.lost_bytes,
        bw_estimator.rate_sample.prior_lost_bytes
    );
    assert_eq!(
        packet_3.is_app_limited,
        bw_estimator.rate_sample.is_app_limited
    );
    assert_eq!(
        packet_3.bytes_in_flight,
        bw_estimator.rate_sample.bytes_in_flight
    );
    assert_eq!(Some(t2), bw_estimator.first_sent_time);

    // Delivered bytes is increased to include packet 2, as it is within the sampling interval
    assert_eq!(4500, bw_estimator.rate_sample.delivered_bytes);
    assert_eq!(0, bw_estimator.rate_sample.lost_bytes);
    assert_eq!(0, bw_estimator.rate_sample.ecn_ce_count);
}