use bssh::executor::ParallelExecutor;
use bssh::node::Node;
use std::path::PathBuf;
use tempfile::TempDir;
#[tokio::test]
async fn test_upload_nonexistent_file() {
let nodes = vec![Node::new("localhost".to_string(), 22, "user".to_string())];
let executor = ParallelExecutor::new(nodes, 1, None);
let nonexistent_file = PathBuf::from("/this/file/does/not/exist.txt");
let results = executor
.upload_file(&nonexistent_file, "/tmp/destination.txt")
.await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 1);
assert!(!results[0].is_success());
}
#[tokio::test]
async fn test_download_to_invalid_directory() {
let nodes = vec![Node::new("localhost".to_string(), 22, "user".to_string())];
let executor = ParallelExecutor::new(nodes, 1, None);
let invalid_dir = PathBuf::from("/this/directory/does/not/exist");
let results = executor.download_file("/etc/passwd", &invalid_dir).await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 1);
assert!(!results[0].is_success());
}
#[tokio::test]
async fn test_connection_to_invalid_host() {
let nodes = vec![Node::new(
"this.host.does.not.exist.invalid".to_string(),
22,
"user".to_string(),
)];
let executor = ParallelExecutor::new(nodes, 1, None);
let results = executor.execute("echo test").await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 1);
assert!(!results[0].is_success());
}
#[tokio::test]
async fn test_connection_to_invalid_port() {
let nodes = vec![
Node::new("localhost".to_string(), 59999, "user".to_string()), ];
let executor = ParallelExecutor::new(nodes, 1, None);
let results = executor.execute("echo test").await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 1);
assert!(!results[0].is_success());
}
#[tokio::test]
async fn test_invalid_ssh_key_path() {
let nodes = vec![Node::new("localhost".to_string(), 22, "user".to_string())];
let executor =
ParallelExecutor::new(nodes, 1, Some("/this/key/does/not/exist.pem".to_string()));
let results = executor.execute("echo test").await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 1);
assert!(!results[0].is_success());
}
#[tokio::test]
async fn test_parallel_execution_with_mixed_results() {
let nodes = vec![
Node::new(
"localhost".to_string(),
22,
std::env::var("USER").unwrap_or_else(|_| "user".to_string()),
),
Node::new("invalid.host.example".to_string(), 22, "user".to_string()),
Node::new("another.invalid.host".to_string(), 22, "user".to_string()),
];
let executor = ParallelExecutor::new(nodes, 3, None);
let results = executor.execute("echo test").await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 3);
let failures = results.iter().filter(|r| !r.is_success()).count();
assert!(failures >= 2);
}
#[tokio::test]
async fn test_upload_with_permission_denied() {
let nodes = vec![Node::new(
"localhost".to_string(),
22,
std::env::var("USER").unwrap_or_else(|_| "user".to_string()),
)];
let executor = ParallelExecutor::new(nodes, 1, None);
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.txt");
std::fs::write(&test_file, "test content").unwrap();
let results = executor
.upload_file(&test_file, "/test_file_should_not_be_created.txt")
.await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 1);
}
#[tokio::test]
async fn test_download_nonexistent_remote_file() {
let nodes = vec![Node::new(
"localhost".to_string(),
22,
std::env::var("USER").unwrap_or_else(|_| "user".to_string()),
)];
let executor = ParallelExecutor::new(nodes, 1, None);
let temp_dir = TempDir::new().unwrap();
let results = executor
.download_file("/this/remote/file/does/not/exist.txt", temp_dir.path())
.await;
assert!(results.is_ok());
let results = results.unwrap();
assert_eq!(results.len(), 1);
if !results[0].is_success() {
assert!(!results[0].is_success());
}
}
#[tokio::test]
async fn test_glob_pattern_with_no_matches() {
let temp_dir = TempDir::new().unwrap();
std::fs::write(temp_dir.path().join("test.txt"), "content").unwrap();
let nodes = vec![Node::new("localhost".to_string(), 22, "user".to_string())];
let executor = ParallelExecutor::new(nodes, 1, None);
let pattern = temp_dir.path().join("*.pdf");
let results = executor.upload_file(&pattern, "/tmp/").await;
assert!(results.is_ok());
}