test: make the JMAP connection-refused check pass on Windows

Windows retries a refused loopback connection for about two seconds,
longer than the shared 200 ms timeout, so the closed-port request timed
out instead of failing to connect. Windows also words the refusal in the
system language, so the check for the English word "refused" failed on
non-English Windows.

Give the closed-port request its own client with a 10 s timeout, and check
that the message carries the root cause and that the cause is an io::Error
of kind ConnectionRefused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Piero NovielloandClaude Opus 5.5 committed 2026-11-04 08:38:06 +01:00
1 parent b6fa4aae9b
commit 963235b0bc
1 file changed
+26 -7
+26 -7
View File
@@ -1199,18 +1199,37 @@ pub(crate) mod tests {
));
held.abort();
// Nothing listens on a port that was just released.
// Nothing listens on a port that was just released. Windows retries a
// refused connection for about two seconds before reporting it, longer
// than the 200 ms timeout above, so this request gets its own client.
let closed = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let closed_url = format!("http://{}/jmap/", closed.local_addr().unwrap());
drop(closed);
let error = http.post(&closed_url).send().await.unwrap_err();
let error = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(10))
.build()
.unwrap()
.post(&closed_url)
.send()
.await
.unwrap_err();
let failure = transport_failure(&error);
assert!(
failure.starts_with(&format!("could not connect ({closed_url}): ")),
"{failure}"
// The OS words the refusal in the system language, so check that the
// message carries the root cause and that the cause is a refusal,
// rather than looking for the English word.
let mut cause: &(dyn std::error::Error + 'static) = &error;
while let Some(source) = cause.source() {
cause = source;
}
assert_eq!(
failure,
format!("could not connect ({closed_url}): {cause}")
);
assert!(
failure.to_ascii_lowercase().contains("refused"),
assert_eq!(
cause
.downcast_ref::<std::io::Error>()
.map(std::io::Error::kind),
Some(std::io::ErrorKind::ConnectionRefused),
"{failure}"
);
}