mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-20 11:56:03 +00:00
Add test case for status code retries (#15617)
When migrating from the `reqwest_retry` crate, we want to ensure that the status codes we retry stay the same. This also helps us to intentionally migrate to a different list later, by enumerating the list of status codes that are retried.
This commit is contained in:
parent
19e19d5795
commit
d5bcc0535a
1 changed files with 71 additions and 3 deletions
|
|
@ -964,7 +964,7 @@ pub fn is_transient_network_error(err: &(dyn Error + 'static)) -> bool {
|
||||||
let mut has_known_error = false;
|
let mut has_known_error = false;
|
||||||
// IO Errors or reqwest errors may be nested through custom IO errors or stream processing
|
// IO Errors or reqwest errors may be nested through custom IO errors or stream processing
|
||||||
// crates
|
// crates
|
||||||
let mut current_source = err.source();
|
let mut current_source = Some(err);
|
||||||
while let Some(source) = current_source {
|
while let Some(source) = current_source {
|
||||||
if let Some(reqwest_err) = source.downcast_ref::<WrappedReqwestError>() {
|
if let Some(reqwest_err) = source.downcast_ref::<WrappedReqwestError>() {
|
||||||
has_known_error = true;
|
has_known_error = true;
|
||||||
|
|
@ -1075,10 +1075,11 @@ pub fn retries_from_env() -> Result<u32, RetryParsingError> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use insta::assert_debug_snapshot;
|
||||||
use reqwest::{Client, Method};
|
use reqwest::{Client, Method};
|
||||||
use wiremock::matchers::method;
|
use wiremock::matchers::{method, path};
|
||||||
use wiremock::{Mock, MockServer, ResponseTemplate};
|
use wiremock::{Mock, MockServer, ResponseTemplate};
|
||||||
|
|
||||||
use crate::base_client::request_into_redirect;
|
use crate::base_client::request_into_redirect;
|
||||||
|
|
@ -1271,4 +1272,71 @@ mod tests {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enumerate which status codes we are retrying.
|
||||||
|
#[tokio::test]
|
||||||
|
async fn retried_status_codes() -> Result<()> {
|
||||||
|
let server = MockServer::start().await;
|
||||||
|
let client = Client::default();
|
||||||
|
let middleware_client = ClientWithMiddleware::default();
|
||||||
|
let mut retried = Vec::new();
|
||||||
|
for status in 100..599 {
|
||||||
|
// Test all standard status codes and and example for a non-RFC code used in the wild.
|
||||||
|
if StatusCode::from_u16(status)?.canonical_reason().is_none() && status != 420 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mock::given(path(format!("/{status}")))
|
||||||
|
.respond_with(ResponseTemplate::new(status))
|
||||||
|
.mount(&server)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let response = middleware_client
|
||||||
|
.get(format!("{}/{}", server.uri(), status))
|
||||||
|
.send()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let middleware_retry =
|
||||||
|
DefaultRetryableStrategy.handle(&response) == Some(Retryable::Transient);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.get(format!("{}/{}", server.uri(), status))
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let uv_retry = match response.error_for_status() {
|
||||||
|
Ok(_) => false,
|
||||||
|
Err(err) => is_transient_network_error(&err),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure we're retrying the same status code as the reqwest_retry crate. We may choose
|
||||||
|
// to deviate from this later.
|
||||||
|
assert_eq!(middleware_retry, uv_retry);
|
||||||
|
if uv_retry {
|
||||||
|
retried.push(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_debug_snapshot!(retried, @r"
|
||||||
|
[
|
||||||
|
100,
|
||||||
|
102,
|
||||||
|
408,
|
||||||
|
429,
|
||||||
|
500,
|
||||||
|
501,
|
||||||
|
502,
|
||||||
|
503,
|
||||||
|
504,
|
||||||
|
505,
|
||||||
|
506,
|
||||||
|
507,
|
||||||
|
508,
|
||||||
|
510,
|
||||||
|
511,
|
||||||
|
]
|
||||||
|
");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue