Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run
- Add new sal-net package to the workspace. - Update MONOREPO_CONVERSION_PLAN.md to reflect the addition of the sal-net package and mark it as production-ready. - Add Cargo.toml and README.md for the sal-net package.
180 lines
5.6 KiB
Rust
180 lines
5.6 KiB
Rust
use sal_net::TcpConnector;
|
|
use std::net::{IpAddr, Ipv4Addr};
|
|
use std::time::Duration;
|
|
use tokio::net::TcpListener;
|
|
|
|
#[tokio::test]
|
|
async fn test_tcp_connector_new() {
|
|
let connector = TcpConnector::new();
|
|
|
|
// Test that the connector can actually perform operations
|
|
// Use a port that should be closed to verify the connector works
|
|
let result = connector
|
|
.check_port(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 65534)
|
|
.await;
|
|
assert!(result.is_ok());
|
|
assert!(!result.unwrap()); // Port should be closed
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_tcp_connector_with_timeout() {
|
|
let timeout = Duration::from_millis(100); // Short timeout for testing
|
|
let connector = TcpConnector::with_timeout(timeout);
|
|
|
|
// Test that the custom timeout is actually used by trying to connect to a non-routable IP
|
|
// This should timeout quickly with our short timeout
|
|
let start = std::time::Instant::now();
|
|
let result = connector
|
|
.check_port(IpAddr::V4(Ipv4Addr::new(10, 255, 255, 1)), 80)
|
|
.await;
|
|
let elapsed = start.elapsed();
|
|
|
|
assert!(result.is_ok());
|
|
assert!(!result.unwrap()); // Should timeout and return false
|
|
assert!(elapsed < Duration::from_secs(2)); // Should timeout much faster than default
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_tcp_connector_default() {
|
|
let connector = TcpConnector::default();
|
|
|
|
// Test that default constructor creates a working connector
|
|
// Verify it behaves the same as TcpConnector::new()
|
|
let result = connector
|
|
.check_port(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 65534)
|
|
.await;
|
|
assert!(result.is_ok());
|
|
assert!(!result.unwrap()); // Port should be closed
|
|
|
|
// Test that it can also ping (basic functionality test)
|
|
let ping_result = connector.ping("127.0.0.1").await;
|
|
assert!(ping_result.is_ok()); // Should not error, regardless of ping success
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_check_port_open() {
|
|
// Start a test server
|
|
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
|
let addr = listener.local_addr().unwrap();
|
|
|
|
// Keep the listener alive in a background task
|
|
let _handle = tokio::spawn(async move {
|
|
loop {
|
|
if let Ok((stream, _)) = listener.accept().await {
|
|
drop(stream); // Immediately close the connection
|
|
}
|
|
}
|
|
});
|
|
|
|
// Give the server a moment to start
|
|
tokio::time::sleep(Duration::from_millis(10)).await;
|
|
|
|
let connector = TcpConnector::new();
|
|
let result = connector.check_port(addr.ip(), addr.port()).await;
|
|
|
|
assert!(result.is_ok());
|
|
assert!(result.unwrap()); // Port should be open
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_check_port_closed() {
|
|
let connector = TcpConnector::new();
|
|
|
|
// Use a port that's very unlikely to be open
|
|
let result = connector
|
|
.check_port(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 65534)
|
|
.await;
|
|
|
|
assert!(result.is_ok());
|
|
assert!(!result.unwrap()); // Port should be closed
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_check_port_timeout() {
|
|
let connector = TcpConnector::with_timeout(Duration::from_millis(1));
|
|
|
|
// Use a non-routable IP to trigger timeout
|
|
let result = connector
|
|
.check_port(IpAddr::V4(Ipv4Addr::new(10, 255, 255, 1)), 80)
|
|
.await;
|
|
|
|
assert!(result.is_ok());
|
|
assert!(!result.unwrap()); // Should timeout and return false
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_check_multiple_ports() {
|
|
// Start test servers on multiple ports
|
|
let listener1 = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
|
let addr1 = listener1.local_addr().unwrap();
|
|
let listener2 = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
|
let addr2 = listener2.local_addr().unwrap();
|
|
|
|
// Keep listeners alive
|
|
let _handle1 = tokio::spawn(async move {
|
|
loop {
|
|
if let Ok((stream, _)) = listener1.accept().await {
|
|
drop(stream);
|
|
}
|
|
}
|
|
});
|
|
let _handle2 = tokio::spawn(async move {
|
|
loop {
|
|
if let Ok((stream, _)) = listener2.accept().await {
|
|
drop(stream);
|
|
}
|
|
}
|
|
});
|
|
|
|
tokio::time::sleep(Duration::from_millis(10)).await;
|
|
|
|
let connector = TcpConnector::new();
|
|
let ports = vec![addr1.port(), addr2.port(), 65533]; // Two open, one closed
|
|
let results = connector.check_ports(addr1.ip(), &ports).await;
|
|
|
|
assert!(results.is_ok());
|
|
let results = results.unwrap();
|
|
assert_eq!(results.len(), 3);
|
|
|
|
// First two should be open, last should be closed
|
|
assert!(results[0].1); // addr1.port() should be open
|
|
assert!(results[1].1); // addr2.port() should be open
|
|
assert!(!results[2].1); // 65533 should be closed
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_ping_localhost() {
|
|
let connector = TcpConnector::new();
|
|
|
|
// Ping localhost - should work on most systems
|
|
let result = connector.ping("localhost").await;
|
|
|
|
// Note: This might fail in some environments (containers, etc.)
|
|
// so we just verify the function doesn't panic and returns a boolean result
|
|
assert!(result.is_ok());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_ping_invalid_host() {
|
|
let connector = TcpConnector::new();
|
|
|
|
// Ping an invalid hostname
|
|
let result = connector
|
|
.ping("this-host-definitely-does-not-exist-12345")
|
|
.await;
|
|
|
|
assert!(result.is_ok());
|
|
assert!(!result.unwrap()); // Should fail to ping invalid host
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_ping_timeout() {
|
|
let connector = TcpConnector::with_timeout(Duration::from_millis(1));
|
|
|
|
// Use a non-routable IP to trigger timeout
|
|
let result = connector.ping("10.255.255.1").await;
|
|
|
|
assert!(result.is_ok());
|
|
// Result could be true or false depending on system, but shouldn't panic
|
|
}
|