use surge_ping::{
Client, Config, ICMP, PingIdentifier, PingSequence, SurgeError,
};
use std::net::IpAddr;
use std::time::Duration;
#[tokio::test]
async fn test_client_creation() {
let config = Config::default();
assert!(Client::new(&config).is_ok());
}
#[tokio::test]
async fn test_client_creation_ipv6() {
let config = Config::builder().kind(ICMP::V6).build();
assert!(Client::new(&config).is_ok());
}
#[tokio::test]
async fn test_pinger_creation() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let host = "127.0.0.1".parse().unwrap();
let pinger = client.pinger(host, PingIdentifier(42)).await;
assert_eq!(pinger.host, host);
assert_eq!(pinger.ident, Some(PingIdentifier(42)));
}
#[tokio::test]
async fn test_pinger_timeout() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let mut pinger = client
.pinger("127.0.0.1".parse().unwrap(), PingIdentifier(100))
.await;
let _ = pinger.timeout(Duration::from_millis(100));
}
#[tokio::test]
async fn test_ping_localhost() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let mut pinger = client
.pinger("127.0.0.1".parse().unwrap(), PingIdentifier(200))
.await;
pinger.timeout(Duration::from_secs(1));
let payload = vec![0; 8];
match pinger.ping(PingSequence(0), &payload).await {
Ok((packet, duration)) => {
assert!(duration.as_millis() < 10000, "Ping should complete quickly");
let _ = packet;
}
Err(SurgeError::Timeout { .. }) => {
}
Err(e) => {
panic!("Unexpected error: {:?}", e);
}
}
}
#[tokio::test]
async fn test_ping_localhost_ipv6() {
let config = Config::builder().kind(ICMP::V6).build();
let client = Client::new(&config).unwrap();
let mut pinger = client
.pinger("::1".parse().unwrap(), PingIdentifier(201))
.await;
pinger.timeout(Duration::from_secs(1));
let payload = vec![0; 8];
match pinger.ping(PingSequence(0), &payload).await {
Ok((packet, duration)) => {
assert!(duration.as_millis() < 10000);
let _ = packet;
}
Err(SurgeError::Timeout { .. }) => {
}
Err(e) => {
panic!("Unexpected error: {:?}", e);
}
}
}
#[tokio::test]
async fn test_ping_multiple_sequences() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let mut pinger = client
.pinger("127.0.0.1".parse().unwrap(), PingIdentifier(300))
.await;
pinger.timeout(Duration::from_secs(1));
let payload = vec![0; 8];
let mut successful_pings = 0;
for seq in 0..3 {
match pinger.ping(PingSequence(seq), &payload).await {
Ok(_) => successful_pings += 1,
Err(SurgeError::Timeout { .. }) => {
}
Err(e) => {
panic!("Unexpected error on seq {}: {:?}", seq, e);
}
}
}
let _ = successful_pings;
}
#[tokio::test]
async fn test_multiple_pingers_same_client() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let pinger1 = client
.pinger("127.0.0.1".parse::<IpAddr>().unwrap(), PingIdentifier(400))
.await;
let pinger2 = client
.pinger("127.0.0.1".parse::<IpAddr>().unwrap(), PingIdentifier(401))
.await;
assert_eq!(pinger1.host, "127.0.0.1".parse::<IpAddr>().unwrap());
assert_eq!(pinger2.host, "127.0.0.1".parse::<IpAddr>().unwrap());
assert_eq!(pinger1.ident, Some(PingIdentifier(400)));
assert_eq!(pinger2.ident, Some(PingIdentifier(401)));
}
#[tokio::test]
async fn test_ping_with_different_payload_sizes() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let mut pinger = client
.pinger("127.0.0.1".parse().unwrap(), PingIdentifier(500))
.await;
pinger.timeout(Duration::from_secs(1));
let sizes = [4, 8, 16, 32, 64];
for size in sizes {
let payload = vec![0u8; size];
match pinger
.ping(PingSequence(size as u16), &payload)
.await
{
Ok(_) => {
}
Err(SurgeError::Timeout { .. }) => {
}
Err(e) => {
panic!("Unexpected error with payload size {}: {:?}", size, e);
}
}
}
}
#[tokio::test]
async fn test_config_builder_with_ttl() {
let config = Config::builder().ttl(64).build();
let client = Client::new(&config);
match client {
Ok(_) => {}
Err(e) => {
println!("Client creation failed (expected on some systems): {:?}", e);
}
}
}
#[tokio::test]
async fn test_identical_requests_error() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let mut pinger = client
.pinger("127.0.0.1".parse().unwrap(), PingIdentifier(600))
.await;
pinger.timeout(Duration::from_secs(2));
let payload = vec![0; 8];
let first_ping = pinger.ping(PingSequence(0), &payload);
let _ = first_ping.await;
}
#[test]
fn test_ping_identifier_and_sequence() {
let ident = PingIdentifier(42);
let seq = PingSequence(10);
assert_eq!(ident.0, 42);
assert_eq!(seq.0, 10);
}
#[tokio::test]
async fn test_client_clone() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let _client_clone = client.clone();
}
#[tokio::test]
async fn test_get_socket() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let socket = client.get_socket();
let local_addr = socket.local_addr();
assert!(local_addr.is_ok());
}
#[tokio::test]
async fn test_ping_unreachable_host() {
let config = Config::default();
let client = Client::new(&config).unwrap();
let mut pinger = client
.pinger("192.0.2.1".parse().unwrap(), PingIdentifier(700))
.await;
pinger.timeout(Duration::from_secs(1));
let payload = vec![0; 8];
match pinger.ping(PingSequence(0), &payload).await {
Ok(_) => {
}
Err(SurgeError::Timeout { .. }) => {
}
Err(e) => {
println!("Error pinging unreachable host: {:?}", e);
}
}
}