pollux/tests/rate_limiting.rs
Jeena 0459cb6220 feat: Implement virtual hosting for multi-domain Gemini server
- Add hostname-based request routing for multiple capsules per server
- Parse virtual host configs from TOML sections ([hostname])
- Implement per-host certificate and content isolation
- Add comprehensive virtual host testing and validation
- Update docs and examples for multi-host deployments

This enables Pollux to serve multiple Gemini domains from one instance,
providing the foundation for multi-tenant Gemini hosting.
2026-01-22 02:38:09 +00:00

80 lines
No EOL
2.9 KiB
Rust

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("--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
println!("Results: {:?}", results);
println!("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);
}