#![cfg(all(feature = "websocket", not(target_arch = "wasm32")))]
use pmcp::server::transport::websocket_enhanced::*;
use pmcp::shared::TransportMessage;
use proptest::prelude::*;
use std::time::Duration;
#[cfg(test)]
mod websocket_reliability {
use super::*;
proptest! {
#[test]
fn property_connection_count_consistency(
max_connections in 1usize..100,
_actual_connections in 0usize..100
) {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let config = EnhancedWebSocketConfig {
max_connections,
..Default::default()
};
let server = EnhancedWebSocketServer::new(config);
prop_assert_eq!(server.client_count().await, 0);
prop_assert!(server.get_connected_clients().await.is_empty());
Ok(())
})?;
}
#[test]
fn property_broadcast_configuration(
enable_broadcast in any::<bool>()
) {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let config = EnhancedWebSocketConfig {
enable_broadcast,
..Default::default()
};
let server = EnhancedWebSocketServer::new(config);
let dummy_msg = TransportMessage::Notification(
pmcp::types::Notification::Progress(pmcp::types::ProgressNotification::new(
pmcp::types::ProgressToken::String("test".to_string()),
0.0,
None,
))
);
let result = server.broadcast(dummy_msg).await;
if enable_broadcast {
prop_assert!(result.is_ok());
} else {
prop_assert!(result.is_err());
}
Ok(())
})?;
}
#[test]
fn property_heartbeat_configuration(
heartbeat_secs in 1u64..300
) {
let config = EnhancedWebSocketConfig {
heartbeat_interval: Duration::from_secs(heartbeat_secs),
..Default::default()
};
prop_assert_eq!(config.heartbeat_interval.as_secs(), heartbeat_secs);
}
#[test]
fn property_connection_timeout(
timeout_secs in 1u64..600
) {
let config = EnhancedWebSocketConfig {
connection_timeout: Duration::from_secs(timeout_secs),
..Default::default()
};
prop_assert_eq!(config.connection_timeout.as_secs(), timeout_secs);
}
#[test]
fn property_max_connections_limit(
max_connections in 1usize..1000,
bind_port in 10000u16..20000
) {
let config = EnhancedWebSocketConfig {
max_connections,
bind_addr: format!("127.0.0.1:{}", bind_port).parse().unwrap(),
..Default::default()
};
prop_assert_eq!(config.max_connections, max_connections);
prop_assert!(config.max_connections > 0);
}
#[test]
fn property_frame_size_limits(
max_frame_size in prop::option::of(1024usize..100_000_000),
max_message_size in prop::option::of(1024usize..100_000_000)
) {
let _config = EnhancedWebSocketConfig {
max_frame_size,
max_message_size,
..Default::default()
};
if let Some(frame_size) = max_frame_size {
prop_assert!(frame_size >= 1024);
}
if let Some(msg_size) = max_message_size {
prop_assert!(msg_size >= 1024);
}
}
}
}
#[cfg(test)]
mod connection_pooling {
use super::*;
proptest! {
#[test]
fn property_connection_pooling(
enable_pooling in any::<bool>()
) {
let config = EnhancedWebSocketConfig {
enable_pooling,
..Default::default()
};
prop_assert_eq!(config.enable_pooling, enable_pooling);
}
#[test]
fn property_client_id_uniqueness(
num_ids in 1usize..1000
) {
use uuid::Uuid;
let mut ids = Vec::new();
for _ in 0..num_ids {
ids.push(Uuid::new_v4());
}
let mut unique_ids = ids.clone();
unique_ids.sort();
unique_ids.dedup();
prop_assert_eq!(ids.len(), unique_ids.len());
}
}
}
#[cfg(test)]
mod message_ordering {
use super::*;
proptest! {
#[test]
fn property_message_ordering(
messages in prop::collection::vec(any::<u32>(), 1..100)
) {
let received = messages.clone();
let original = messages;
for (i, msg) in original.iter().enumerate() {
if i < received.len() {
prop_assert_eq!(*msg, received[i]);
}
}
}
}
}