mod common; #[test] fn test_rate_limiting_with_concurrent_requests() { let temp_dir = common::setup_test_environment(); let port = 1967 + (std::process::id() % 1000) as u16; // Create config with rate limiting enabled let config_path = temp_dir.path().join("config.toml"); // Use existing content directory and cert files from setup_test_environment let root_dir = temp_dir.path().join("content"); let cert_path = temp_dir.path().join("cert.pem"); let key_path = temp_dir.path().join("key.pem"); let config_content = format!( r#" bind_host = "127.0.0.1" port = {} max_concurrent_requests = 1 ["localhost"] root = "{}" cert = "{}" key = "{}" "#, port, root_dir.display(), cert_path.display(), key_path.display() ); std::fs::write(&config_path, config_content).unwrap(); // Start server binary with test delay to simulate processing time let mut server_process = std::process::Command::new(env!("CARGO_BIN_EXE_pollux")) .arg("--config") .arg(&config_path) .arg("--quiet") .arg("--test-processing-delay") .arg("3") // 3 second delay per request .spawn() .expect("Failed to start server"); // Wait for server to start std::thread::sleep(std::time::Duration::from_millis(500)); // Spawn 5 concurrent client processes let mut handles = vec![]; for _ in 0..5 { let url = format!("gemini://localhost/test.gmi"); let handle = std::thread::spawn(move || { std::process::Command::new("python3") .arg("tests/gemini_test_client.py") .arg(url) .env("GEMINI_PORT", &port.to_string()) .env("RATE_LIMIT_TEST", "true") .output() }); handles.push(handle); } // Collect results let mut results = vec![]; for handle in handles { let output = handle.join().unwrap().unwrap(); let status = String::from_utf8(output.stdout).unwrap(); results.push(status.trim().to_string()); } // Kill server let _ = server_process.kill(); // Analyze results let success_count = results.iter().filter(|r| r.starts_with("20")).count(); let rate_limited_count = results.iter().filter(|r| r.starts_with("41")).count(); // Debug output tracing::debug!("Test results: {:?}", results); tracing::debug!( "Success: {}, Rate limited: {}", success_count, rate_limited_count ); // Strict validation - rate limiting must work deterministically with delay assert_eq!( success_count, 1, "Expected exactly 1 successful request with limit=1, got {}. Results: {:?}", success_count, results ); assert_eq!( rate_limited_count, 4, "Expected exactly 4 rate limited requests with limit=1, got {}. Results: {:?}", rate_limited_count, results ); // Verify all requests received valid responses assert_eq!( success_count + rate_limited_count, 5, "All 5 requests should receive responses. Results: {:?}", results ); }