Add tests for config error reporting and multi-vhost startup

Test that the server correctly reports missing certificate errors,
rejects invalid hostnames, fails gracefully on port conflicts, and
starts successfully with multiple virtual hosts configured.
This commit is contained in:
Jeena 2026-03-05 20:30:19 +09:00
parent 55fe47b172
commit 7de660dbb6
8 changed files with 94 additions and 392 deletions

View file

@ -33,7 +33,11 @@ fn create_tls_config(
fn print_startup_info(
config: &config::Config,
hosts: &std::collections::HashMap<String, config::HostConfig>,
quiet: bool,
) {
if quiet {
return;
}
println!("Pollux Gemini Server (Virtual Host Mode)");
println!("Configured hosts:");
for (hostname, host_config) in hosts {
@ -60,6 +64,10 @@ struct Args {
#[arg(short, long)]
config: Option<String>,
/// Suppress startup output (for testing)
#[arg(long)]
quiet: bool,
/// Processing delay for testing (in milliseconds)
#[arg(long, hide = true)]
test_processing_delay: Option<u64>,
@ -69,6 +77,12 @@ struct Args {
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
// Initialize logging with RUST_LOG support
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_writer(std::io::stderr)
.init();
// Load config
let config_path = args.config.as_deref().unwrap_or("/etc/pollux/config.toml");
if !std::path::Path::new(&config_path).exists() {
@ -79,26 +93,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut stdout = std::io::stdout();
writeln!(stderr, "Config file '{}' not found", config_path).unwrap();
writeln!(
stdout,
"Create the config file with virtual host sections like:"
)
.unwrap();
writeln!(stdout, "[example.com]").unwrap();
writeln!(stdout, "root = \"/var/gemini\"").unwrap();
writeln!(stdout, "cert = \"/etc/pollux/tls/cert.pem\"").unwrap();
writeln!(stdout, "key = \"/etc/pollux/tls/key.pem\"").unwrap();
if !args.quiet {
writeln!(
stdout,
"Create the config file with virtual host sections like:"
)
.unwrap();
writeln!(stdout, "[example.com]").unwrap();
writeln!(stdout, "root = \"/var/gemini\"").unwrap();
writeln!(stdout, "cert = \"/etc/pollux/tls/cert.pem\"").unwrap();
writeln!(stdout, "key = \"/etc/pollux/tls/key.pem\"").unwrap();
stdout.flush().unwrap();
stdout.flush().unwrap();
}
std::process::exit(1);
}
// Initialize logging with RUST_LOG support AFTER basic config checks
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_writer(std::io::stderr)
.init();
// Load and parse config
let config = match config::load_config(config_path) {
Ok(config) => config,
@ -147,11 +157,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Validate certificate files (always required for TLS)
let cert_path = Path::new(&host_config.cert);
if !cert_path.exists() {
eprintln!(
"Error: Certificate file '{}' for host '{}' does not exist",
host_config.cert, hostname
tracing::error!(
"Certificate file '{}' for host '{}' does not exist",
host_config.cert,
hostname
);
eprintln!("Generate or obtain TLS certificates for your domain");
tracing::error!("Generate or obtain TLS certificates for your domain");
std::process::exit(1);
}
if let Err(e) = std::fs::File::open(cert_path) {
@ -206,22 +217,26 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let test_processing_delay = 0;
// Print startup information
print_startup_info(&config, &config.hosts);
print_startup_info(&config, &config.hosts, args.quiet);
// Phase 3: TLS mode (always enabled)
let tls_config = create_tls_config(&config.hosts)?;
let acceptor = TlsAcceptor::from(tls_config);
println!("Starting Pollux Gemini Server with Virtual Host support...");
if !args.quiet {
println!("Starting Pollux Gemini Server with Virtual Host support...");
}
let bind_host = config.bind_host.as_deref().unwrap_or("0.0.0.0");
let port = config.port.unwrap_or(1965);
let listener = TcpListener::bind(format!("{}:{}", bind_host, port)).await?;
println!(
"Listening on {}:{} for all virtual hosts (TLS enabled)",
bind_host, port
);
if !args.quiet {
println!(
"Listening on {}:{} for all virtual hosts (TLS enabled)",
bind_host, port
);
}
loop {
let (stream, _) = listener.accept().await?;