feat: Improve service manager testing and error handling
- Add comprehensive testing instructions to README. - Improve error handling in examples to prevent crashes. - Enhance launchctl error handling for production safety. - Improve zinit error handling for production safety. - Remove obsolete plan_to_fix.md file. - Update Rhai integration tests for improved robustness. - Improve service manager creation on Linux with systemd fallback.
This commit is contained in:
@@ -4,15 +4,18 @@ use std::collections::HashMap;
|
||||
#[test]
|
||||
fn test_create_service_manager() {
|
||||
// Test that the factory function creates the appropriate service manager for the platform
|
||||
let manager = create_service_manager();
|
||||
|
||||
let manager = create_service_manager().expect("Failed to create service manager");
|
||||
|
||||
// Test basic functionality - should be able to call methods without panicking
|
||||
let list_result = manager.list();
|
||||
|
||||
|
||||
// The result might be an error (if no service system is available), but it shouldn't panic
|
||||
match list_result {
|
||||
Ok(services) => {
|
||||
println!("✓ Service manager created successfully, found {} services", services.len());
|
||||
println!(
|
||||
"✓ Service manager created successfully, found {} services",
|
||||
services.len()
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✓ Service manager created, but got expected error: {}", e);
|
||||
@@ -32,7 +35,7 @@ fn test_service_config_creation() {
|
||||
environment: HashMap::new(),
|
||||
auto_restart: false,
|
||||
};
|
||||
|
||||
|
||||
assert_eq!(basic_config.name, "test-service");
|
||||
assert_eq!(basic_config.binary_path, "/usr/bin/echo");
|
||||
assert_eq!(basic_config.args.len(), 2);
|
||||
@@ -41,14 +44,14 @@ fn test_service_config_creation() {
|
||||
assert!(basic_config.working_directory.is_none());
|
||||
assert!(basic_config.environment.is_empty());
|
||||
assert!(!basic_config.auto_restart);
|
||||
|
||||
|
||||
println!("✓ Basic service config created successfully");
|
||||
|
||||
// Test config with environment variables
|
||||
let mut env = HashMap::new();
|
||||
env.insert("PATH".to_string(), "/usr/bin:/bin".to_string());
|
||||
env.insert("HOME".to_string(), "/tmp".to_string());
|
||||
|
||||
|
||||
let env_config = ServiceConfig {
|
||||
name: "env-service".to_string(),
|
||||
binary_path: "/usr/bin/env".to_string(),
|
||||
@@ -57,16 +60,22 @@ fn test_service_config_creation() {
|
||||
environment: env.clone(),
|
||||
auto_restart: true,
|
||||
};
|
||||
|
||||
|
||||
assert_eq!(env_config.name, "env-service");
|
||||
assert_eq!(env_config.binary_path, "/usr/bin/env");
|
||||
assert!(env_config.args.is_empty());
|
||||
assert_eq!(env_config.working_directory, Some("/tmp".to_string()));
|
||||
assert_eq!(env_config.environment.len(), 2);
|
||||
assert_eq!(env_config.environment.get("PATH"), Some(&"/usr/bin:/bin".to_string()));
|
||||
assert_eq!(env_config.environment.get("HOME"), Some(&"/tmp".to_string()));
|
||||
assert_eq!(
|
||||
env_config.environment.get("PATH"),
|
||||
Some(&"/usr/bin:/bin".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
env_config.environment.get("HOME"),
|
||||
Some(&"/tmp".to_string())
|
||||
);
|
||||
assert!(env_config.auto_restart);
|
||||
|
||||
|
||||
println!("✓ Environment service config created successfully");
|
||||
}
|
||||
|
||||
@@ -85,16 +94,19 @@ fn test_service_config_clone() {
|
||||
},
|
||||
auto_restart: true,
|
||||
};
|
||||
|
||||
|
||||
let cloned_config = original_config.clone();
|
||||
|
||||
|
||||
assert_eq!(original_config.name, cloned_config.name);
|
||||
assert_eq!(original_config.binary_path, cloned_config.binary_path);
|
||||
assert_eq!(original_config.args, cloned_config.args);
|
||||
assert_eq!(original_config.working_directory, cloned_config.working_directory);
|
||||
assert_eq!(
|
||||
original_config.working_directory,
|
||||
cloned_config.working_directory
|
||||
);
|
||||
assert_eq!(original_config.environment, cloned_config.environment);
|
||||
assert_eq!(original_config.auto_restart, cloned_config.auto_restart);
|
||||
|
||||
|
||||
println!("✓ Service config cloning works correctly");
|
||||
}
|
||||
|
||||
@@ -102,18 +114,24 @@ fn test_service_config_clone() {
|
||||
#[test]
|
||||
fn test_macos_service_manager() {
|
||||
use sal_service_manager::LaunchctlServiceManager;
|
||||
|
||||
|
||||
// Test creating macOS-specific service manager
|
||||
let manager = LaunchctlServiceManager::new();
|
||||
|
||||
|
||||
// Test basic functionality
|
||||
let list_result = manager.list();
|
||||
match list_result {
|
||||
Ok(services) => {
|
||||
println!("✓ macOS LaunchctlServiceManager created successfully, found {} services", services.len());
|
||||
println!(
|
||||
"✓ macOS LaunchctlServiceManager created successfully, found {} services",
|
||||
services.len()
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✓ macOS LaunchctlServiceManager created, but got expected error: {}", e);
|
||||
println!(
|
||||
"✓ macOS LaunchctlServiceManager created, but got expected error: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,18 +140,24 @@ fn test_macos_service_manager() {
|
||||
#[test]
|
||||
fn test_linux_service_manager() {
|
||||
use sal_service_manager::SystemdServiceManager;
|
||||
|
||||
|
||||
// Test creating Linux-specific service manager
|
||||
let manager = SystemdServiceManager::new();
|
||||
|
||||
|
||||
// Test basic functionality
|
||||
let list_result = manager.list();
|
||||
match list_result {
|
||||
Ok(services) => {
|
||||
println!("✓ Linux SystemdServiceManager created successfully, found {} services", services.len());
|
||||
println!(
|
||||
"✓ Linux SystemdServiceManager created successfully, found {} services",
|
||||
services.len()
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("✓ Linux SystemdServiceManager created, but got expected error: {}", e);
|
||||
println!(
|
||||
"✓ Linux SystemdServiceManager created, but got expected error: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,7 +165,7 @@ fn test_linux_service_manager() {
|
||||
#[test]
|
||||
fn test_service_status_debug() {
|
||||
use sal_service_manager::ServiceStatus;
|
||||
|
||||
|
||||
// Test that ServiceStatus can be debugged and cloned
|
||||
let statuses = vec![
|
||||
ServiceStatus::Running,
|
||||
@@ -149,22 +173,25 @@ fn test_service_status_debug() {
|
||||
ServiceStatus::Failed,
|
||||
ServiceStatus::Unknown,
|
||||
];
|
||||
|
||||
|
||||
for status in &statuses {
|
||||
let cloned = status.clone();
|
||||
let debug_str = format!("{:?}", status);
|
||||
|
||||
|
||||
assert!(!debug_str.is_empty());
|
||||
assert_eq!(status, &cloned);
|
||||
|
||||
println!("✓ ServiceStatus::{:?} debug and clone work correctly", status);
|
||||
|
||||
println!(
|
||||
"✓ ServiceStatus::{:?} debug and clone work correctly",
|
||||
status
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_service_manager_error_debug() {
|
||||
use sal_service_manager::ServiceManagerError;
|
||||
|
||||
|
||||
// Test that ServiceManagerError can be debugged and displayed
|
||||
let errors = vec![
|
||||
ServiceManagerError::ServiceNotFound("test".to_string()),
|
||||
@@ -175,14 +202,14 @@ fn test_service_manager_error_debug() {
|
||||
ServiceManagerError::LogsFailed("test".to_string(), "reason".to_string()),
|
||||
ServiceManagerError::Other("generic error".to_string()),
|
||||
];
|
||||
|
||||
|
||||
for error in &errors {
|
||||
let debug_str = format!("{:?}", error);
|
||||
let display_str = format!("{}", error);
|
||||
|
||||
|
||||
assert!(!debug_str.is_empty());
|
||||
assert!(!display_str.is_empty());
|
||||
|
||||
|
||||
println!("✓ Error debug: {:?}", error);
|
||||
println!("✓ Error display: {}", error);
|
||||
}
|
||||
@@ -191,11 +218,12 @@ fn test_service_manager_error_debug() {
|
||||
#[test]
|
||||
fn test_service_manager_trait_object() {
|
||||
// Test that we can use ServiceManager as a trait object
|
||||
let manager: Box<dyn ServiceManager> = create_service_manager();
|
||||
|
||||
let manager: Box<dyn ServiceManager> =
|
||||
create_service_manager().expect("Failed to create service manager");
|
||||
|
||||
// Test that we can call methods through the trait object
|
||||
let list_result = manager.list();
|
||||
|
||||
|
||||
match list_result {
|
||||
Ok(services) => {
|
||||
println!("✓ Trait object works, found {} services", services.len());
|
||||
@@ -204,7 +232,7 @@ fn test_service_manager_trait_object() {
|
||||
println!("✓ Trait object works, got expected error: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test exists method
|
||||
let exists_result = manager.exists("non-existent-service");
|
||||
match exists_result {
|
||||
|
Reference in New Issue
Block a user