feat(client): expose probe send commitment through typed receipts

This commit is contained in:
Nils Andreas Svee committed 2026-10-04 19:14:06 +07:00
1 parent eebe83986a
commit a6ba335302
18 files changed
+322 -122

No files matched your search

+8 -9
View File
@@ -60,7 +60,9 @@ fn send_probe_fails_after_close() {
client.close().unwrap();
assert!(matches!(
client.send_probe(),
Err(ClientError::AlreadyClosed)
Err(irtt_client::SendProbeError::NotCommitted(
ClientError::AlreadyClosed
))
));
server.join();
}
@@ -206,9 +208,7 @@ fn close_flagged_retained_timeout_emits_late_then_closes() {
.unwrap();
assert_open_started(client.open().unwrap());
let sent = client.send_probe().unwrap();
let ClientEvent::EchoSent { sent_at, .. } = &sent[0] else {
panic!("expected EchoSent");
};
let sent_at = sent.sent_at;
assert!(matches!(
client
.poll_timeouts_at(sent_at.mono + client.probe_timeout())
@@ -426,10 +426,7 @@ fn wrong_token_close_flag_does_not_close_session() {
}]
));
assert!(!client.is_peer_closed());
assert!(matches!(
client.send_probe().unwrap().as_slice(),
[ClientEvent::EchoSent { seq: 1, .. }]
));
assert_eq!(client.send_probe().unwrap().seq, 1);
client.close().unwrap();
server.join();
}
@@ -498,7 +495,9 @@ fn close_flagged_echo_reply_emits_reply_then_closes_without_sending_close() {
assert!(matches!(
client.send_probe(),
Err(ClientError::AlreadyClosed)
Err(irtt_client::SendProbeError::NotCommitted(
ClientError::AlreadyClosed
))
));
let first = server.rx.recv_timeout(Duration::from_millis(100)).unwrap();
+3 -1
View File
@@ -101,7 +101,9 @@ fn send_probe_fails_after_no_test_completed() {
assert_no_test_completed(client.open().unwrap());
assert!(matches!(
client.send_probe(),
Err(ClientError::AlreadyCompleted)
Err(irtt_client::SendProbeError::NotCommitted(
ClientError::AlreadyCompleted
))
));
server.join();
}
@@ -26,7 +26,9 @@ fn probe_timeout_overflow_transmits_no_echo() {
assert_open_started(client.open().unwrap());
assert!(matches!(
client.send_probe(),
Err(ClientError::DurationOverflow)
Err(irtt_client::SendProbeError::NotCommitted(
ClientError::DurationOverflow
))
));
assert!(!client.has_pending_probes());
client.close().unwrap();
@@ -181,7 +183,9 @@ fn pending_full_does_not_send_packet() {
assert!(matches!(
client.send_probe(),
Err(ClientError::PendingLimitExceeded { limit: 2 })
Err(irtt_client::SendProbeError::NotCommitted(
ClientError::PendingLimitExceeded { limit: 2 }
))
));
thread::sleep(Duration::from_millis(30));
+16 -3
View File
@@ -261,10 +261,23 @@ fn a_closed_udp_peer_surfaces_a_socket_error() {
close_tx.send(()).unwrap();
task.join().unwrap();
// Refusal can arrive during send's TX drain or the following receive.
let result = client.send_probe().and_then(|_| client.recv_once());
// Either way this first Echo was accepted and must stay pending.
let (receipt, error) = match client.send_probe() {
Ok(receipt) => (receipt, client.recv_once().unwrap_err()),
Err(irtt_client::SendProbeError::AfterCommit { receipt, source }) => (receipt, *source),
Err(error) => panic!("first Echo should be accepted: {error:?}"),
};
assert_eq!(receipt.seq, 0);
assert_eq!(receipt.remote, addr);
assert!(client.has_pending_probes());
assert!(
matches!(result, Err(irtt_client::ClientError::Socket(ref error))
matches!(error, irtt_client::ClientError::Socket(ref error)
if error.kind() == std::io::ErrorKind::ConnectionRefused),
"{result:?}"
"{error:?}"
);
assert!(matches!(
client.poll_timeouts_at(receipt.sent_at.mono + client.probe_timeout())
.unwrap().as_slice(),
[ClientEvent::EchoLoss { seq: 0, sent_at, .. }] if *sent_at == receipt.sent_at
));
}