- 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
356 lines
9.8 KiB
Rust
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"));
|
|
}
|