From 1ef0f97ebf7ca0657f061a4f88a072cd0c01f368 Mon Sep 17 00:00:00 2001 From: Jeena Date: Fri, 16 Jan 2026 22:42:22 +0000 Subject: [PATCH] Implement full rate limiting integration test - Test concurrent requests with max_concurrent_requests = 1 - Verify 1 successful response and 4 rate limited responses - Use python test script for TLS Gemini requests - Test runs with 3-second processing delay for proper concurrency - Validates rate limiting behavior end-to-end --- tests/rate_limiting.rs | 80 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/tests/rate_limiting.rs b/tests/rate_limiting.rs index 7f6ea09..8236ffa 100644 --- a/tests/rate_limiting.rs +++ b/tests/rate_limiting.rs @@ -1,5 +1,79 @@ +use std::process::Command; + #[test] -fn test_placeholder() { - // Placeholder test - rate limiting integration test to be implemented - assert!(true); +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); } \ No newline at end of file