use std::path::PathBuf;
use std::time::{Duration, Instant};
#[test]
fn test_exponential_backoff_timing() {
let base_delay = Duration::from_millis(10);
let max_delay = Duration::from_millis(1000);
let mut delays = Vec::new();
let mut current_delay = base_delay;
for _ in 0..10 {
delays.push(current_delay);
current_delay = (current_delay * 2).min(max_delay);
}
assert_eq!(delays[0], Duration::from_millis(10));
assert_eq!(delays[1], Duration::from_millis(20));
assert_eq!(delays[2], Duration::from_millis(40));
assert_eq!(delays[3], Duration::from_millis(80));
assert_eq!(delays[4], Duration::from_millis(160));
assert_eq!(delays[5], Duration::from_millis(320));
assert_eq!(delays[6], Duration::from_millis(640));
assert_eq!(delays[7], Duration::from_millis(1000)); assert_eq!(delays[8], Duration::from_millis(1000)); assert_eq!(delays[9], Duration::from_millis(1000)); }
#[test]
fn test_exponential_backoff_total_wait_time() {
let base_delay = Duration::from_millis(10);
let max_delay = Duration::from_millis(1000);
let max_attempts = 10;
let mut total_wait = Duration::from_secs(0);
let mut current_delay = base_delay;
for _ in 0..max_attempts {
total_wait += current_delay;
current_delay = (current_delay * 2).min(max_delay);
}
assert_eq!(total_wait, Duration::from_millis(4270));
assert!(total_wait < Duration::from_secs(5));
assert!(total_wait > Duration::from_secs(4));
}
#[test]
fn test_max_attempts_limit() {
const MAX_ATTEMPTS: usize = 10;
let mut attempts = 0;
for i in 0..MAX_ATTEMPTS {
attempts = i + 1;
}
assert_eq!(attempts, MAX_ATTEMPTS);
}
#[test]
fn test_temp_dir_path_generation() {
use uuid::Uuid;
let id = Uuid::new_v4();
let temp_dir = std::env::temp_dir().join(format!("html_view_{}", id));
assert!(temp_dir.to_string_lossy().contains("html_view_"));
assert!(temp_dir.to_string_lossy().contains(&id.to_string()));
}
#[test]
fn test_temp_dir_unique_per_request() {
use uuid::Uuid;
let id1 = Uuid::new_v4();
let id2 = Uuid::new_v4();
let temp1 = std::env::temp_dir().join(format!("html_view_{}", id1));
let temp2 = std::env::temp_dir().join(format!("html_view_{}", id2));
assert_ne!(temp1, temp2);
assert_ne!(id1, id2);
}
#[test]
fn test_request_json_filename() {
use uuid::Uuid;
let id = Uuid::new_v4();
let temp_dir = std::env::temp_dir().join(format!("html_view_{}", id));
let request_file = temp_dir.join("request.json");
assert_eq!(request_file.file_name().unwrap(), "request.json");
}
#[test]
fn test_result_json_filename() {
use uuid::Uuid;
let id = Uuid::new_v4();
let temp_dir = std::env::temp_dir().join(format!("html_view_{}", id));
let result_file = temp_dir.join("result.json");
assert_eq!(result_file.file_name().unwrap(), "result.json");
}
#[test]
fn test_temp_dir_cleanup_on_drop() {
use std::fs;
use uuid::Uuid;
let id = Uuid::new_v4();
let temp_dir = std::env::temp_dir().join(format!("html_view_test_{}", id));
fs::create_dir_all(&temp_dir).unwrap();
assert!(temp_dir.exists());
{
let _guard = TestTempDirGuard {
path: temp_dir.clone(),
};
assert!(temp_dir.exists());
}
assert!(!temp_dir.exists());
struct TestTempDirGuard {
path: PathBuf,
}
impl Drop for TestTempDirGuard {
fn drop(&mut self) {
let _ = fs::remove_dir_all(&self.path);
}
}
}
#[test]
fn test_file_permissions_unix() {
#[cfg(unix)]
{
use std::fs;
use std::os::unix::fs::PermissionsExt;
use uuid::Uuid;
let id = Uuid::new_v4();
let temp_dir = std::env::temp_dir().join(format!("html_view_test_perms_{}", id));
fs::create_dir_all(&temp_dir).unwrap();
let mut perms = fs::metadata(&temp_dir).unwrap().permissions();
perms.set_mode(0o700);
fs::set_permissions(&temp_dir, perms).unwrap();
let metadata = fs::metadata(&temp_dir).unwrap();
let mode = metadata.permissions().mode() & 0o777;
assert_eq!(mode, 0o700, "Expected 0o700, got 0o{:o}", mode);
fs::remove_dir_all(&temp_dir).unwrap();
}
}
#[test]
fn test_polling_early_exit_on_success() {
let start = Instant::now();
let max_attempts = 10;
let found_on_attempt = 3;
let mut attempts = 0;
for i in 0..max_attempts {
attempts = i + 1;
if i == found_on_attempt {
break; }
std::thread::sleep(Duration::from_millis(1));
}
let elapsed = start.elapsed();
assert_eq!(attempts, found_on_attempt + 1);
assert!(elapsed < Duration::from_millis(100)); }
#[test]
fn test_backoff_never_exceeds_max_delay() {
let base_delay = Duration::from_millis(10);
let max_delay = Duration::from_millis(1000);
let mut current_delay = base_delay;
for _ in 0..100 {
current_delay = (current_delay * 2).min(max_delay);
assert!(current_delay <= max_delay);
}
assert_eq!(current_delay, max_delay);
}
#[test]
fn test_uuid_generation_uniqueness() {
use std::collections::HashSet;
use uuid::Uuid;
let mut ids = HashSet::new();
for _ in 0..1000 {
let id = Uuid::new_v4();
assert!(ids.insert(id), "UUID collision detected!");
}
assert_eq!(ids.len(), 1000);
}