fn last_known_validated_path_should_update_on_path_response()

in quic/s2n-quic-transport/src/path/manager/tests.rs [1719:1862]


fn last_known_validated_path_should_update_on_path_response() {
    // Setup:
    let mut publisher = Publisher::snapshot();
    let zero_conn_id = connection::PeerId::try_from_bytes(&[0]).unwrap();
    let first_conn_id = connection::PeerId::try_from_bytes(&[1]).unwrap();
    let second_conn_id = connection::PeerId::try_from_bytes(&[2]).unwrap();

    // path zero
    let zero_path_id = path_id(0);
    let mut zero_path = helper_path(zero_conn_id);
    zero_path.on_handshake_packet();

    let mut random_generator = random::testing::Generator(123);
    let mut peer_id_registry =
        ConnectionIdMapper::new(&mut random_generator, endpoint::Type::Server)
            .create_server_peer_id_registry(
                InternalConnectionIdGenerator::new().generate_id(),
                zero_path.peer_connection_id,
                true,
            );
    assert!(peer_id_registry
        .on_new_connection_id(&first_conn_id, 1, 0, &TEST_TOKEN_1)
        .is_ok());

    assert!(peer_id_registry
        .on_new_connection_id(&second_conn_id, 2, 0, &TEST_TOKEN_2)
        .is_ok());

    let mut manager = Manager::new(zero_path, peer_id_registry);

    assert!(!manager[zero_path_id].is_challenge_pending());
    assert!(manager[zero_path_id].is_validated());
    assert_eq!(manager.active_path_id(), zero_path_id);

    // Trigger Setup 1:
    let first_path_id = path_id(1);
    let mut first_path = helper_path(first_conn_id);
    let now = NoopClock {}.get_time();
    let challenge_expiration = Duration::from_millis(10_000);
    let first_expected_data = [0; 8];
    let challenge = challenge::Challenge::new(challenge_expiration, first_expected_data);
    first_path.set_challenge(challenge);
    manager.paths.push(first_path);
    assert!(manager
        .update_active_path(
            first_path_id,
            &mut random::testing::Generator(123),
            &mut publisher
        )
        .is_ok());

    // Expectation Setup 1:
    assert_eq!(manager.active_path_id(), first_path_id);
    // first
    assert!(manager[first_path_id].is_challenge_pending());
    assert!(!manager[first_path_id].is_validated());
    // last_known_active_validated_path
    assert_eq!(
        manager.last_known_active_validated_path.unwrap(),
        zero_path_id.as_u8()
    );

    // Trigger Setup 2:
    let second_path_id = path_id(2);
    let second_expected_data = [1; 8];
    let challenge = challenge::Challenge::new(challenge_expiration, second_expected_data);
    let mut second_path = helper_path(second_conn_id);
    second_path.set_challenge(challenge);
    let mut frame_buffer = OutgoingFrameBuffer::new();
    let mut context = MockWriteContext::new(
        now,
        &mut frame_buffer,
        transmission::Constraint::None,
        transmission::Mode::Normal,
        endpoint::Type::Client,
    );
    second_path.on_transmit(&mut context); // send challenge and arm timer

    manager.paths.push(second_path);
    assert!(manager
        .update_active_path(
            second_path_id,
            &mut random::testing::Generator(123),
            &mut publisher,
        )
        .is_ok());

    // Expectation Setup 2:
    assert_eq!(manager.active_path_id(), second_path_id);
    // second
    assert!(manager[second_path_id].is_challenge_pending());
    assert!(!manager[second_path_id].is_validated());
    // first
    assert!(manager[first_path_id].is_challenge_pending());
    assert!(!manager[first_path_id].is_validated());
    // last_known_active_validated_path
    assert_eq!(
        manager.last_known_active_validated_path.unwrap(),
        zero_path_id.as_u8()
    );

    // Trigger 1:
    // - path response for path 1
    let frame = s2n_quic_core::frame::PathResponse {
        data: &first_expected_data,
    };
    let amplification_outcome = manager.on_path_response(&frame, &mut publisher);
    // Expectation 1:
    assert!(amplification_outcome.is_inactivate_path_unblocked());
    assert_eq!(manager.active_path_id(), second_path_id);
    // second
    assert!(manager[second_path_id].is_challenge_pending());
    assert!(!manager[second_path_id].is_validated());
    // first
    assert!(!manager[first_path_id].is_challenge_pending());
    assert!(manager[first_path_id].is_validated());
    // last_known_active_validated_path
    assert_eq!(
        manager.last_known_active_validated_path.unwrap(),
        first_path_id.as_u8()
    );

    // Trigger 2:
    // - timeout for path 2 challenge
    let amplification_outcome = manager
        .on_timeout(
            now + challenge_expiration + Duration::from_millis(100),
            &mut random::testing::Generator(123),
            &mut publisher,
        )
        .unwrap();

    // Expectation 2:
    assert!(amplification_outcome.is_active_path_unblocked());
    assert_eq!(manager.active_path_id(), first_path_id);
    // second
    assert!(!manager[second_path_id].is_challenge_pending());
    assert!(!manager[second_path_id].is_validated());
    // first
    assert!(!manager[first_path_id].is_challenge_pending());
    assert!(manager[first_path_id].is_validated());
    // last_known_active_validated_path
    assert_eq!(manager.last_known_active_validated_path, None);
}