use rstest::rstest;
use serial_test::serial;
use std::sync::{Arc, Mutex};
use torc::client::apis::configuration::Configuration;
use torc::client::utils::send_with_retries;
#[derive(Debug)]
struct MockError {
message: String,
}
impl std::fmt::Display for MockError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for MockError {}
#[rstest]
#[serial]
#[ignore] fn test_with_retries_success_on_first_try() {
let config = Configuration::default();
let result = send_with_retries(
&config,
|| Ok::<String, MockError>("success".to_string()),
1, );
assert!(result.is_ok());
assert_eq!(result.unwrap(), "success");
}
#[rstest]
#[serial]
#[ignore] fn test_with_retries_non_network_error_fails_immediately() {
let config = Configuration::default();
let result = send_with_retries(
&config,
|| {
Err::<String, MockError>(MockError {
message: "database error".to_string(),
})
},
1, );
assert!(result.is_err());
assert_eq!(result.unwrap_err().message, "database error");
}
#[rstest]
#[serial]
#[ignore] fn test_with_retries_network_error_detection() {
let config = Configuration::default();
let call_count = Arc::new(Mutex::new(0));
let call_count_clone = Arc::clone(&call_count);
let result = send_with_retries(
&config,
move || {
let mut count = call_count_clone.lock().unwrap();
*count += 1;
if *count == 1 {
Err(MockError {
message: "connection timeout error".to_string(),
})
} else {
Ok("recovered".to_string())
}
},
1, );
let final_count = *call_count.lock().unwrap();
assert!(
final_count >= 1,
"Expected at least 1 call, got {}",
final_count
);
if result.is_err() {
assert!(result.unwrap_err().message.contains("connection"));
}
}
#[rstest]
#[serial]
#[ignore] fn test_with_retries_different_network_error_types() {
let config = Configuration::default();
let network_error_types = vec![
"connection refused",
"network timeout",
"dns resolution failed",
"host unreachable",
"network is down",
];
for error_msg in network_error_types {
let result = send_with_retries(
&config,
|| {
Err::<String, MockError>(MockError {
message: error_msg.to_string(),
})
},
1, );
assert!(result.is_err());
}
}
#[rstest]
#[serial]
#[ignore] fn test_with_retries_can_be_called_from_external_module() {
let config = Configuration::default();
let result =
torc::client::send_with_retries(&config, || Ok::<&str, MockError>("accessible"), 1);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "accessible");
}
#[rstest]
#[case(0)] #[case(1)] #[case(5)] #[serial]
#[ignore] fn test_with_retries_different_timeouts(#[case] timeout_minutes: u64) {
let config = Configuration::default();
let result = send_with_retries(
&config,
|| Ok::<String, MockError>("timeout_test".to_string()),
timeout_minutes,
);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "timeout_test");
}
#[rstest]
#[serial]
#[ignore] fn test_with_retries_closure_capture() {
let config = Configuration::default();
let captured_value = "captured_data";
let result = send_with_retries(
&config,
|| Ok::<String, MockError>(format!("processed: {}", captured_value)),
1,
);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "processed: captured_data");
}