use std::process::Command; #[test] fn test_rate_limiting_with_concurrent_requests() { // Create temp config with max_concurrent_requests = 1 let temp_dir = std::env::temp_dir(); let config_path = temp_dir.join("pollux_test_config.toml"); std::fs::write(&config_path, r#" root = "/tmp" cert = "tmp/cert.pem" key = "tmp/key.pem" hostname = "localhost" bind_host = "127.0.0.1" port = 1965 max_concurrent_requests = 1 "#).unwrap(); // Create a test file in /tmp std::fs::write("/tmp/test.gmi", "# Test Gemini file").unwrap(); // Start server with 3-second delay let mut server = Command::new(env!("CARGO_BIN_EXE_pollux")) .arg("--config") .arg(&config_path) .arg("--test-processing-delay") .arg("3") .spawn() .unwrap(); // Give server time to start std::thread::sleep(std::time::Duration::from_secs(2)); // Send 5 concurrent requests using the python test script let mut handles = vec![]; for _ in 0..5 { let handle = std::thread::spawn(|| { Command::new("python3") .arg("tmp/test_rate_limit_python.py") .arg("--limit") .arg("1") .arg("--host") .arg("127.0.0.1") .arg("--port") .arg("1965") .arg("--timeout") .arg("10") .arg("--url") .arg("gemini://localhost/test.gmi") .output() .unwrap() }); handles.push(handle); } // Collect results let mut success_count = 0; let mut rate_limited_count = 0; for handle in handles { let output = handle.join().unwrap(); let stdout = String::from_utf8(output.stdout).unwrap(); if stdout.contains("20 ") { success_count += 1; } if stdout.contains("41 Server unavailable") { rate_limited_count += 1; } } // Cleanup let _ = server.kill(); // Clean up temp files let _ = std::fs::remove_file(&config_path); let _ = std::fs::remove_file("/tmp/test.gmi"); // Verify: 1 success, 4 rate limited assert_eq!(success_count, 1); assert_eq!(rate_limited_count, 4); }