Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions crates/hodeishield-api/tests/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,17 +585,18 @@ fn a_503_with_retry_after_longer_than_max_wait_does_not_retry() {

#[test]
fn a_connection_error_is_retried() {
// Bind to port 0 to get an ephemeral port, then drop the listener to free it.
// The next connection attempt to that port will be refused.
// Keep the listener bound for the whole test so no other test can take the port. It never
// accepts, so every attempt connects (the kernel completes the handshake) and then gets no
// answer: a timeout, which is retried like a refused connection.
let listener = std::net::TcpListener::bind(("127.0.0.1", 0)).expect("bind");
let port = listener.local_addr().expect("addr").port();
drop(listener);

let url = format!("http://127.0.0.1:{port}");
let retry_count = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0));
let counted = std::sync::Arc::clone(&retry_count);

let result = Client::builder(url.parse().expect("url"), SecretString::from("hsk_example"))
.timeout(Duration::from_millis(200))
.transient_retries(2, Duration::from_millis(1))
.retry_observer(move |_event| {
counted.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
Expand All @@ -608,6 +609,7 @@ fn a_connection_error_is_retried() {
assert!(matches!(result.expect_err("error"), Error::Transport(_)));
let retries = retry_count.load(std::sync::atomic::Ordering::SeqCst);
assert_eq!(retries, 2, "should have retried exactly 2 times");
drop(listener);
}

#[test]
Expand Down
Loading