use http_handle::{Server, ShutdownSignal};
use std::fs;
use std::net::TcpListener;
use std::sync::Arc;
use std::time::Duration;
use tempfile::TempDir;
fn setup_test_directory() -> TempDir {
let temp_dir = TempDir::new().unwrap();
let root_path = temp_dir.path();
fs::write(
root_path.join("index.html"),
"<html><body>Hello, Integration Test!</body></html>",
)
.unwrap();
fs::create_dir(root_path.join("404")).unwrap();
fs::write(
root_path.join("404/index.html"),
"<html><body>404 Not Found</body></html>",
)
.unwrap();
fs::write(root_path.join("style.css"), "body { color: red; }")
.unwrap();
fs::write(
root_path.join("script.js"),
"console.log('Hello, World!');",
)
.unwrap();
temp_dir
}
fn find_available_port() -> u16 {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
listener.local_addr().unwrap().port()
}
#[test]
fn test_server_creation_and_configuration() {
let temp_dir = setup_test_directory();
let port = find_available_port();
let address = format!("127.0.0.1:{}", port);
let server =
Server::new(&address, temp_dir.path().to_str().unwrap());
assert!(format!("{:?}", server).contains(&address));
}
#[test]
fn test_shutdown_signal_functionality() {
let shutdown = ShutdownSignal::new(Duration::from_secs(1));
assert!(!shutdown.is_shutdown_requested());
assert_eq!(shutdown.active_connection_count(), 0);
shutdown.connection_started();
assert_eq!(shutdown.active_connection_count(), 1);
shutdown.connection_started();
assert_eq!(shutdown.active_connection_count(), 2);
shutdown.connection_finished();
assert_eq!(shutdown.active_connection_count(), 1);
shutdown.shutdown();
assert!(shutdown.is_shutdown_requested());
assert_eq!(shutdown.active_connection_count(), 1);
shutdown.connection_finished();
assert_eq!(shutdown.active_connection_count(), 0);
}
#[test]
fn test_shutdown_signal_wait_functionality() {
let shutdown = ShutdownSignal::new(Duration::from_millis(100));
shutdown.shutdown();
let start = std::time::Instant::now();
let graceful = shutdown.wait_for_shutdown();
let elapsed = start.elapsed();
assert!(
graceful,
"Should shut down gracefully when no connections"
);
assert!(
elapsed < Duration::from_millis(50),
"Should be nearly immediate when no connections, took: {:?}",
elapsed
);
}
#[test]
fn test_shutdown_signal_timeout() {
let shutdown = ShutdownSignal::new(Duration::from_millis(200));
shutdown.connection_started();
shutdown.shutdown();
let start = std::time::Instant::now();
let graceful = shutdown.wait_for_shutdown();
let elapsed = start.elapsed();
assert!(!graceful, "Should timeout when connections don't close");
assert!(
elapsed >= Duration::from_millis(180),
"Should wait close to timeout duration, waited: {:?}",
elapsed
);
assert!(
elapsed < Duration::from_millis(400),
"Should not wait too long past timeout, waited: {:?}",
elapsed
);
}
#[test]
fn test_shutdown_signal_default() {
let shutdown = ShutdownSignal::default();
assert!(!shutdown.is_shutdown_requested());
assert_eq!(shutdown.active_connection_count(), 0);
}
#[test]
#[ignore] fn test_server_basic_startup() {
let temp_dir = setup_test_directory();
let port = find_available_port();
let address = format!("127.0.0.1:{}", port);
let _server =
Server::new(&address, temp_dir.path().to_str().unwrap());
let shutdown =
Arc::new(ShutdownSignal::new(Duration::from_millis(100)));
assert!(shutdown.active_connection_count() == 0);
}