From ebff8ce455ea1054db127b5b556bed992f9c18ad Mon Sep 17 00:00:00 2001 From: link2xt Date: Fri, 24 Jul 2026 16:44:50 +0000 Subject: [PATCH 1/3] test: assert that run_connection_attempts tries all candidates --- src/net.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/net.rs b/src/net.rs index 01cf1c03c6..d7ba947909 100644 --- a/src/net.rs +++ b/src/net.rs @@ -209,6 +209,9 @@ where } } None => { + // We should never return an error with connection attempts left to try. + debug_assert!(futures.next().is_none()); + // Out of connection attempts. // // Break out of the loop and return error. From f9dbc23336d85dfe85b46768ab4e22948b18f7a6 Mon Sep 17 00:00:00 2001 From: link2xt Date: Fri, 24 Jul 2026 18:18:39 +0000 Subject: [PATCH 2/3] test: add basic tests for run_connection_attempts --- src/net.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/net.rs b/src/net.rs index d7ba947909..c50135251a 100644 --- a/src/net.rs +++ b/src/net.rs @@ -264,3 +264,43 @@ pub(crate) async fn connect_tcp( .map(connect_tcp_inner); run_connection_attempts(connection_futures).await } + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_run_connection_attempts() { + let futures: Vec> + Send>>> = + vec![Box::pin(async { Ok(1) }), Box::pin(async { Ok(2) })]; + assert_eq!( + run_connection_attempts(futures.into_iter()).await.unwrap(), + 1 + ); + + let futures: Vec> + Send>>> = vec![ + Box::pin(async { Err(format_err!("fail")) }), + Box::pin(async { Ok(2) }), + ]; + assert_eq!( + run_connection_attempts(futures.into_iter()).await.unwrap(), + 2 + ); + + let futures: Vec> + Send>>> = vec![ + Box::pin(async { Err(format_err!("fail")) }), + Box::pin(async { Err(format_err!("fail")) }), + Box::pin(async { Err(format_err!("fail")) }), + Box::pin(async { Err(format_err!("fail")) }), + Box::pin(async { Err(format_err!("fail")) }), + Box::pin(async { Err(format_err!("last")) }), + ]; + assert!( + run_connection_attempts(futures.into_iter()) + .await + .unwrap_err() + .to_string() + .contains("last"), + ); + } +} From 22837e57f93756d1fcc5893b284d1e605a8823ed Mon Sep 17 00:00:00 2001 From: link2xt Date: Fri, 24 Jul 2026 19:48:48 +0000 Subject: [PATCH 3/3] docs: update run_connection_attempts comment to say that it returns all errors --- src/net.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/net.rs b/src/net.rs index c50135251a..37685d72ea 100644 --- a/src/net.rs +++ b/src/net.rs @@ -157,7 +157,8 @@ pub(crate) async fn connect_tls_inner( /// and runs them until one of them succeeds /// or all of them fail. /// -/// If all connection attempts fail, returns the first error. +/// If all connection attempts fail, returns an error +/// that includes the reasons for all failures. /// /// This functions starts with one connection attempt and maintains /// up to five parallel connection attempts if connecting takes time.