pollux/tests/virtual_host_config.rs
Jeena 55fe47b172 Replace custom logging with tracing crate and RUST_LOG env var
- Remove custom logging module and init_logging function
- Update main.rs to use tracing_subscriber with EnvFilter
- Remove log_level from global config structure
- Update documentation and tests to use RUST_LOG
- Format long lines in config.rs and test files for better readability
2026-01-22 05:25:46 +00:00

356 lines
9.8 KiB
Rust

mod common;
#[test]
fn test_single_host_config() {
let temp_dir = tempfile::TempDir::new().unwrap();
let config_path = temp_dir.path().join("config.toml");
let port = 1967 + (std::process::id() % 1000) as u16;
// Create content directory and certificates
let content_dir = temp_dir.path().join("content");
std::fs::create_dir(&content_dir).unwrap();
// Generate test certificates
use std::process::Command;
let cert_path = temp_dir.path().join("cert.pem");
let key_path = temp_dir.path().join("key.pem");
let cert_result = Command::new("openssl")
.args(&[
"req",
"-x509",
"-newkey",
"rsa:2048",
"-keyout",
&key_path.to_string_lossy(),
"-out",
&cert_path.to_string_lossy(),
"-days",
"1",
"-nodes",
"-subj",
"/CN=example.com",
])
.output();
if cert_result.is_err() {
panic!("Failed to generate test certificates for config test");
}
let config_content = format!(
r#"
bind_host = "127.0.0.1"
port = {}
["example.com"]
root = "{}"
cert = "{}"
key = "{}"
"#,
port,
content_dir.display(),
cert_path.display(),
key_path.display()
);
std::fs::write(&config_path, config_content).unwrap();
let mut server_process = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg(&config_path)
.spawn()
.unwrap();
std::thread::sleep(std::time::Duration::from_millis(500));
assert!(
server_process.try_wait().unwrap().is_none(),
"Server should start with valid single host config"
);
server_process.kill().unwrap();
}
#[test]
fn test_multiple_hosts_config() {
let temp_dir = common::setup_test_environment();
let config_path = temp_dir.path().join("config.toml");
let config_content = format!(
r#"
[site1.com]
root = "{}"
cert = "{}"
key = "{}"
[site2.org]
root = "{}"
cert = "{}"
key = "{}"
bind_host = "127.0.0.1"
port = 1965
"#,
temp_dir.path().join("site1").display(),
temp_dir.path().join("site1_cert.pem").display(),
temp_dir.path().join("site1_key.pem").display(),
temp_dir.path().join("site2").display(),
temp_dir.path().join("site2_cert.pem").display(),
temp_dir.path().join("site2_key.pem").display()
);
std::fs::write(&config_path, config_content).unwrap();
// Create additional directories and generate certificates
std::fs::create_dir(temp_dir.path().join("site1")).unwrap();
std::fs::create_dir(temp_dir.path().join("site2")).unwrap();
// Generate certificates for each host
use std::process::Command;
// Site 1 certificate
let cert_result1 = Command::new("openssl")
.args(&[
"req",
"-x509",
"-newkey",
"rsa:2048",
"-keyout",
&temp_dir.path().join("site1_key.pem").to_string_lossy(),
"-out",
&temp_dir.path().join("site1_cert.pem").to_string_lossy(),
"-days",
"1",
"-nodes",
"-subj",
"/CN=site1.com",
])
.output();
// Site 2 certificate
let cert_result2 = Command::new("openssl")
.args(&[
"req",
"-x509",
"-newkey",
"rsa:2048",
"-keyout",
&temp_dir.path().join("site2_key.pem").to_string_lossy(),
"-out",
&temp_dir.path().join("site2_cert.pem").to_string_lossy(),
"-days",
"1",
"-nodes",
"-subj",
"/CN=site2.org",
])
.output();
if cert_result1.is_err() || cert_result2.is_err() {
panic!("Failed to generate test certificates for multiple hosts test");
}
// Test server starts successfully with multiple host config
let port = 1968 + (std::process::id() % 1000) as u16;
let config_content = format!(
r#"
bind_host = "127.0.0.1"
port = {}
["site1.com"]
root = "{}"
cert = "{}"
key = "{}"
["site2.org"]
root = "{}"
cert = "{}"
key = "{}"
"#,
port,
temp_dir.path().join("site1").display(),
temp_dir.path().join("site1_cert.pem").display(),
temp_dir.path().join("site1_key.pem").display(),
temp_dir.path().join("site2").display(),
temp_dir.path().join("site2_cert.pem").display(),
temp_dir.path().join("site2_key.pem").display()
);
std::fs::write(&config_path, config_content).unwrap();
let mut server_process = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg(&config_path)
.spawn()
.unwrap();
std::thread::sleep(std::time::Duration::from_millis(500));
assert!(
server_process.try_wait().unwrap().is_none(),
"Server should start with valid multiple host config"
);
server_process.kill().unwrap();
}
#[test]
fn test_missing_required_fields_in_host_config() {
let temp_dir = common::setup_test_environment();
let config_path = temp_dir.path().join("config.toml");
let config_content = r#"
bind_host = "127.0.0.1"
port = 1965
["example.com"]
root = "/tmp/content"
# missing cert and key
"#;
std::fs::write(&config_path, config_content).unwrap();
let output = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg(&config_path)
.output()
.unwrap();
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(stderr.contains("Missing required field") || stderr.contains("missing field"));
}
#[test]
fn test_invalid_hostname_config() {
let temp_dir = common::setup_test_environment();
let config_path = temp_dir.path().join("config.toml");
let config_content = format!(
r#"
["invalid"]
root = "{}"
cert = "{}"
key = "{}"
"#,
temp_dir.path().join("content").display(),
temp_dir.path().join("cert.pem").display(),
temp_dir.path().join("key.pem").display()
);
std::fs::write(&config_path, config_content).unwrap();
let output = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg(&config_path)
.output()
.unwrap();
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(stderr.contains("Invalid hostname"));
}
#[test]
fn test_no_hosts_config() {
let temp_dir = common::setup_test_environment();
let config_path = temp_dir.path().join("config.toml");
let config_content = r#"
bind_host = "127.0.0.1"
port = 1965
# No host sections
"#;
std::fs::write(&config_path, config_content).unwrap();
let output = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg(&config_path)
.output()
.unwrap();
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(stderr.contains("No host configurations found"));
}
#[test]
fn test_duplicate_hostname_config() {
let temp_dir = common::setup_test_environment();
let config_path = temp_dir.path().join("config.toml");
let config_content = format!(
r#"
[example.com]
root = "{}"
cert = "{}"
key = "{}"
[example.com]
root = "{}"
cert = "{}"
key = "{}"
"#,
temp_dir.path().join("path1").display(),
temp_dir.path().join("cert1.pem").display(),
temp_dir.path().join("key1.pem").display(),
temp_dir.path().join("path2").display(),
temp_dir.path().join("cert2.pem").display(),
temp_dir.path().join("key2.pem").display()
);
std::fs::write(&config_path, config_content).unwrap();
// Create the directories and certs
std::fs::create_dir(temp_dir.path().join("path1")).unwrap();
std::fs::create_dir(temp_dir.path().join("path2")).unwrap();
std::fs::write(temp_dir.path().join("cert1.pem"), "cert1").unwrap();
std::fs::write(temp_dir.path().join("key1.pem"), "key1").unwrap();
std::fs::write(temp_dir.path().join("cert2.pem"), "cert2").unwrap();
std::fs::write(temp_dir.path().join("key2.pem"), "key2").unwrap();
let output = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg(&config_path)
.output()
.unwrap();
// Duplicate table headers are not allowed in TOML, so this should fail
assert!(!output.status.success());
}
#[test]
fn test_host_with_port_override() {
let temp_dir = common::setup_test_environment();
let config_path = temp_dir.path().join("config.toml");
// Test server starts successfully
let port = 1969 + (std::process::id() % 1000) as u16;
let config_content = format!(
r#"
bind_host = "127.0.0.1"
port = {}
["example.com"]
root = "{}"
cert = "{}"
key = "{}"
port = 1970 # Override global port
"#,
port,
temp_dir.path().join("content").display(),
temp_dir.path().join("cert.pem").display(),
temp_dir.path().join("key.pem").display()
);
std::fs::write(&config_path, config_content).unwrap();
let mut server_process = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg(&config_path)
.spawn()
.unwrap();
std::thread::sleep(std::time::Duration::from_millis(500));
assert!(
server_process.try_wait().unwrap().is_none(),
"Server should start with host port override"
);
server_process.kill().unwrap();
}
#[test]
fn test_config_file_not_found() {
let output = std::process::Command::new(env!("CARGO_BIN_EXE_pollux"))
.arg("--config")
.arg("nonexistent.toml")
.output()
.unwrap();
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(stderr.contains("Config file 'nonexistent.toml' not found"));
}