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);
}