use super::*;
#[test]
fn server_new_creates_empty_registries() {
let server = Server::new(ServerConfig::default());
assert!(server.sessions.is_empty());
assert!(server.services.is_none());
assert!(server.session_factory.is_none());
}
#[test]
fn server_with_services() {
let services = Arc::new(ServiceRegistry::new());
let server = Server::with_services(ServerConfig::default(), services);
assert!(server.services.is_some());
assert!(server.session_factory.is_none());
}
#[test]
fn server_with_session_factory() {
let factory: SessionFactory = Box::new(SessionState::default);
let server = Server::with_session_factory(ServerConfig::default(), factory);
assert!(server.services.is_none());
assert!(server.session_factory.is_some());
}
#[test]
fn create_session_state_uses_default_when_no_factory() {
let server = Server::new(ServerConfig::default());
let state = server.create_session_state();
let _ = state;
}
#[test]
fn create_session_state_uses_factory() {
let factory: SessionFactory = Box::new(|| {
let mut state = SessionState::default();
state.app.running = false; state
});
let server = Server::with_session_factory(ServerConfig::default(), factory);
let state = server.create_session_state();
assert!(!state.app.is_running());
}
#[test]
fn sessions_accessor() {
let server = Server::new(ServerConfig::default());
assert!(server.sessions().is_empty());
}
#[cfg(feature = "grpc")]
#[test]
fn server_with_bridges() {
struct TestBridge;
impl reovim_driver_session::bridges::ExtensionStateBridge for TestBridge {
fn kind(&self) -> &'static str {
"test-bridge"
}
fn scope(&self) -> reovim_driver_session::bridges::ExtensionScope {
reovim_driver_session::bridges::ExtensionScope::Client
}
fn snapshot(&self, _: &reovim_driver_session::ExtensionMap) -> Option<serde_json::Value> {
None
}
fn is_active(&self, _: &reovim_driver_session::ExtensionMap) -> bool {
false
}
fn on_mode_changed(
&self,
_from: &str,
_to: &str,
_: &mut reovim_driver_session::ExtensionMap,
) {
}
}
let mut registry = BridgeRegistry::new();
registry.register(TestBridge);
let server = Server::new(ServerConfig::default()).with_bridges(registry);
let _ = server;
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_until_starts_and_shuts_down() {
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>();
let (port_tx, port_rx) = tokio::sync::oneshot::channel::<u16>();
let config = ServerConfig::grpc(0); let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move {
server_clone
.run_until(
async {
shutdown_rx.await.ok();
},
Some(port_tx),
)
.await
});
let port = port_rx.await.expect("should receive port");
assert!(port > 0);
assert_eq!(server.sessions().len(), 1);
shutdown_tx.send(()).expect("should send shutdown");
let result = handle.await.expect("task should complete");
assert!(result.is_ok());
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_until_rejects_non_grpc_transport() {
let config = ServerConfig::tcp(8080);
let server = Server::new(config);
let result = server.run_until(std::future::pending::<()>(), None).await;
assert!(result.is_err());
let err = result.unwrap_err();
assert_eq!(err.kind(), std::io::ErrorKind::Unsupported);
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_until_with_factory_creates_custom_session() {
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>();
let (port_tx, port_rx) = tokio::sync::oneshot::channel::<u16>();
let factory: SessionFactory = Box::new(SessionState::default);
let config = ServerConfig::grpc(0);
let server = Arc::new(Server::with_session_factory(config, factory));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move {
server_clone
.run_until(
async {
shutdown_rx.await.ok();
},
Some(port_tx),
)
.await
});
let _port = port_rx.await.expect("should receive port");
assert_eq!(server.sessions().len(), 1);
shutdown_tx.send(()).expect("should send shutdown");
handle
.await
.expect("task should complete")
.expect("server should succeed");
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_creates_session_and_dispatches_grpc() {
let config = ServerConfig::grpc(0);
let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move { server_clone.run().await });
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
assert_eq!(server.sessions().len(), 1);
handle.abort();
let _ = handle.await;
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_tcp_transport_creates_session() {
let config = ServerConfig::default(); let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move { server_clone.run().await });
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
assert_eq!(server.sessions().len(), 1);
handle.abort();
let _ = handle.await;
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_tcp_specific_port_creates_session() {
let config = ServerConfig::tcp(0);
let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move { server_clone.run().await });
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
assert_eq!(server.sessions().len(), 1);
handle.abort();
let _ = handle.await;
}
#[cfg(all(feature = "grpc", unix))]
#[tokio::test]
async fn run_unix_socket_creates_session() {
let tmp = tempfile::tempdir().expect("should create tempdir");
let socket_path = tmp.path().join("test.sock");
let config = ServerConfig::unix_socket(&socket_path);
let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move { server_clone.run().await });
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
assert_eq!(server.sessions().len(), 1);
handle.abort();
let _ = handle.await;
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_grpc_without_shutdown_signal() {
let config = ServerConfig::grpc(0);
let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move { server_clone.run().await });
tokio::time::sleep(std::time::Duration::from_millis(300)).await;
assert_eq!(server.sessions().len(), 1);
handle.abort();
let _ = handle.await;
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_until_without_port_sender() {
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel::<()>();
let config = ServerConfig::grpc(0);
let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move {
server_clone
.run_until(
async {
shutdown_rx.await.ok();
},
None, )
.await
});
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
assert_eq!(server.sessions().len(), 1);
shutdown_tx.send(()).expect("should send shutdown");
let result = handle.await.expect("task should complete");
assert!(result.is_ok());
}
#[cfg(feature = "grpc")]
#[tokio::test]
async fn run_with_custom_session_name() {
let config = ServerConfig::grpc(0).with_session_name("my-custom-session");
let server = Arc::new(Server::new(config));
let server_clone = Arc::clone(&server);
let handle = tokio::spawn(async move { server_clone.run().await });
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
assert_eq!(server.sessions().len(), 1);
handle.abort();
let _ = handle.await;
}