feat: Add sal-net package to workspace
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run
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.
This commit is contained in:
285
net/tests/ssh_tests.rs
Normal file
285
net/tests/ssh_tests.rs
Normal file
@@ -0,0 +1,285 @@
|
||||
use sal_net::SshConnectionBuilder;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_new() {
|
||||
// Test that builder creates a functional connection with defaults
|
||||
let connection = SshConnectionBuilder::new().build();
|
||||
|
||||
// Test that the connection can actually attempt operations
|
||||
// Use an invalid host to verify the connection object works but fails as expected
|
||||
let result = connection.execute("echo test").await;
|
||||
|
||||
// Should fail because no host is configured, but the connection object should work
|
||||
match result {
|
||||
Ok((exit_code, _)) => assert!(exit_code != 0), // Should fail due to missing host
|
||||
Err(_) => {} // Error is expected when no host is configured
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_host_functionality() {
|
||||
// Test that setting a host actually affects connection behavior
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("nonexistent-host-12345.invalid")
|
||||
.user("testuser")
|
||||
.timeout(Duration::from_millis(100))
|
||||
.build();
|
||||
|
||||
// This should fail because the host doesn't exist
|
||||
let result = connection.execute("echo test").await;
|
||||
match result {
|
||||
Ok((exit_code, _)) => assert!(exit_code != 0), // Should fail
|
||||
Err(_) => {} // Error is expected for invalid hosts
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_port_functionality() {
|
||||
// Test that setting a custom port affects connection behavior
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("127.0.0.1")
|
||||
.port(12345) // Non-standard SSH port that should be closed
|
||||
.user("testuser")
|
||||
.timeout(Duration::from_millis(100))
|
||||
.build();
|
||||
|
||||
// This should fail because port 12345 is not running SSH
|
||||
let result = connection.ping().await;
|
||||
match result {
|
||||
Ok(success) => assert!(!success), // Should fail to connect
|
||||
Err(_) => {} // Error is expected for closed ports
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_user_functionality() {
|
||||
// Test that setting a user affects connection behavior
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("127.0.0.1")
|
||||
.user("nonexistent-user-12345")
|
||||
.timeout(Duration::from_millis(100))
|
||||
.build();
|
||||
|
||||
// This should fail because the user doesn't exist
|
||||
let result = connection.execute("whoami").await;
|
||||
match result {
|
||||
Ok((exit_code, _)) => assert!(exit_code != 0), // Should fail
|
||||
Err(_) => {} // Error is expected for invalid users
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_identity_file() {
|
||||
// Test that setting an identity file affects connection behavior
|
||||
let path = PathBuf::from("/nonexistent/path/to/key");
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("127.0.0.1")
|
||||
.user("testuser")
|
||||
.identity_file(path)
|
||||
.timeout(Duration::from_millis(100))
|
||||
.build();
|
||||
|
||||
// Test that connection with identity file attempts operations but fails as expected
|
||||
let result = connection.ping().await;
|
||||
|
||||
// Should fail due to invalid key file or authentication, but connection should work
|
||||
match result {
|
||||
Ok(success) => assert!(!success), // Should fail due to invalid key or auth
|
||||
Err(_) => {} // Error is expected for invalid key file
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_timeout_functionality() {
|
||||
// Test that timeout setting actually affects connection behavior
|
||||
let short_timeout = Duration::from_secs(1); // More reasonable timeout
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("10.255.255.1") // Non-routable IP to trigger timeout
|
||||
.timeout(short_timeout)
|
||||
.build();
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let result = connection.ping().await;
|
||||
let elapsed = start.elapsed();
|
||||
|
||||
// Should timeout reasonably quickly (within 10 seconds)
|
||||
assert!(elapsed < Duration::from_secs(10));
|
||||
match result {
|
||||
Ok(success) => assert!(!success), // Should timeout/fail
|
||||
Err(_) => {} // Error is expected for timeouts
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_chaining() {
|
||||
// Test that method chaining works and produces a functional connection
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("invalid-host-12345.test")
|
||||
.port(2222)
|
||||
.user("testuser")
|
||||
.timeout(Duration::from_millis(100))
|
||||
.build();
|
||||
|
||||
// Test that the chained configuration actually works
|
||||
let result = connection.ping().await;
|
||||
match result {
|
||||
Ok(success) => assert!(!success), // Should fail to connect to invalid host
|
||||
Err(_) => {} // Error is expected for invalid hosts
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_execute_invalid_host() {
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("this-host-definitely-does-not-exist-12345")
|
||||
.user("testuser")
|
||||
.timeout(Duration::from_secs(1))
|
||||
.build();
|
||||
|
||||
let result = connection.execute("echo 'test'").await;
|
||||
|
||||
// Should fail because host doesn't exist
|
||||
// Note: This test depends on SSH client being available
|
||||
match result {
|
||||
Ok((exit_code, _output)) => {
|
||||
// SSH might return various exit codes for connection failures
|
||||
assert!(exit_code != 0); // Should not succeed
|
||||
}
|
||||
Err(_) => {
|
||||
// Error is also acceptable (SSH client might not be available)
|
||||
// This is expected behavior for invalid hosts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_execute_localhost_no_auth() {
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("localhost")
|
||||
.user("nonexistentuser12345")
|
||||
.timeout(Duration::from_secs(1))
|
||||
.build();
|
||||
|
||||
let result = connection.execute("echo 'test'").await;
|
||||
|
||||
// Should fail due to authentication/user issues
|
||||
match result {
|
||||
Ok((exit_code, _output)) => {
|
||||
// SSH should fail with non-zero exit code
|
||||
assert!(exit_code != 0);
|
||||
}
|
||||
Err(_) => {
|
||||
// Error is also acceptable (SSH client might not be available)
|
||||
// This is expected behavior for authentication failures
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_ping_invalid_host() {
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("this-host-definitely-does-not-exist-12345")
|
||||
.user("testuser")
|
||||
.timeout(Duration::from_secs(1))
|
||||
.build();
|
||||
|
||||
let result = connection.ping().await;
|
||||
|
||||
match result {
|
||||
Ok(success) => {
|
||||
assert!(!success); // Should not succeed
|
||||
}
|
||||
Err(_) => {
|
||||
// Error is also acceptable for invalid hosts
|
||||
// This is expected behavior
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_ping_localhost_no_auth() {
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("localhost")
|
||||
.user("nonexistentuser12345")
|
||||
.timeout(Duration::from_secs(1))
|
||||
.build();
|
||||
|
||||
let result = connection.ping().await;
|
||||
|
||||
match result {
|
||||
Ok(success) => {
|
||||
// Should fail due to authentication issues
|
||||
assert!(!success);
|
||||
}
|
||||
Err(_) => {
|
||||
// Error is also acceptable for authentication failures
|
||||
// This is expected behavior
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_default_values() {
|
||||
// Test that builder creates connection with reasonable defaults
|
||||
let connection = SshConnectionBuilder::new().build();
|
||||
|
||||
// Test that default connection can attempt operations but fails gracefully
|
||||
let result = connection.ping().await;
|
||||
|
||||
// Should fail because no host is configured, but should handle it gracefully
|
||||
match result {
|
||||
Ok(success) => assert!(!success), // Should fail due to missing host
|
||||
Err(_) => {} // Error is expected when no host is configured
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ssh_connection_builder_full_config() {
|
||||
// Test builder with all options set
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("nonexistent-host-12345.invalid")
|
||||
.port(2222)
|
||||
.user("testuser")
|
||||
.identity_file(PathBuf::from("/nonexistent/path/to/key"))
|
||||
.timeout(Duration::from_millis(100))
|
||||
.build();
|
||||
|
||||
// Test that fully configured connection attempts operations but fails as expected
|
||||
let result = connection.ping().await;
|
||||
|
||||
// Should fail because host doesn't exist, but all configuration should be applied
|
||||
match result {
|
||||
Ok(success) => assert!(!success), // Should fail due to invalid host
|
||||
Err(_) => {} // Error is expected for invalid host
|
||||
}
|
||||
}
|
||||
|
||||
// Integration test that requires actual SSH setup
|
||||
// This test is disabled by default as it requires SSH server and keys
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test_ssh_execute_real_connection() {
|
||||
// This test would require:
|
||||
// 1. SSH server running on localhost
|
||||
// 2. Valid SSH keys set up
|
||||
// 3. User account configured
|
||||
|
||||
let connection = SshConnectionBuilder::new()
|
||||
.host("localhost")
|
||||
.user("testuser") // Replace with actual user
|
||||
.build();
|
||||
|
||||
let result = connection.execute("echo 'Hello from SSH'").await;
|
||||
|
||||
match result {
|
||||
Ok((exit_code, output)) => {
|
||||
assert_eq!(exit_code, 0);
|
||||
assert!(output.contains("Hello from SSH"));
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("SSH execution failed: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user