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:
@@ -1,63 +1,156 @@
|
||||
// Service lifecycle management test script
|
||||
// This script tests complete service lifecycle scenarios
|
||||
// This script tests REAL complete service lifecycle scenarios
|
||||
|
||||
print("=== Service Lifecycle Management Test ===");
|
||||
|
||||
// Test configuration - simplified to avoid complexity issues
|
||||
let service_names = ["web-server", "background-task", "oneshot-task"];
|
||||
let service_count = 3;
|
||||
// Create service manager
|
||||
let manager = create_service_manager();
|
||||
print("✓ Service manager created");
|
||||
|
||||
// Test configuration - real services for testing
|
||||
let test_services = [
|
||||
#{
|
||||
name: "lifecycle-test-1",
|
||||
binary_path: "/bin/echo",
|
||||
args: ["Lifecycle test 1"],
|
||||
working_directory: "/tmp",
|
||||
environment: #{},
|
||||
auto_restart: false
|
||||
},
|
||||
#{
|
||||
name: "lifecycle-test-2",
|
||||
binary_path: "/bin/echo",
|
||||
args: ["Lifecycle test 2"],
|
||||
working_directory: "/tmp",
|
||||
environment: #{ "TEST_VAR": "test_value" },
|
||||
auto_restart: false
|
||||
}
|
||||
];
|
||||
|
||||
let total_tests = 0;
|
||||
let passed_tests = 0;
|
||||
|
||||
// Test 1: Service Creation
|
||||
print("\n1. Testing service creation...");
|
||||
for service_name in service_names {
|
||||
print(`\nCreating service: ${service_name}`);
|
||||
print(` ✓ Service ${service_name} created successfully`);
|
||||
// Test 1: Service Creation and Start
|
||||
print("\n1. Testing service creation and start...");
|
||||
for service_config in test_services {
|
||||
print(`\nStarting service: ${service_config.name}`);
|
||||
try {
|
||||
start(manager, service_config);
|
||||
print(` ✓ Service ${service_config.name} started successfully`);
|
||||
passed_tests += 1;
|
||||
} catch(e) {
|
||||
print(` ✗ Service ${service_config.name} start failed: ${e}`);
|
||||
}
|
||||
total_tests += 1;
|
||||
passed_tests += 1;
|
||||
}
|
||||
|
||||
// Test 2: Service Start
|
||||
print("\n2. Testing service start...");
|
||||
for service_name in service_names {
|
||||
print(`\nStarting service: ${service_name}`);
|
||||
print(` ✓ Service ${service_name} started successfully`);
|
||||
// Test 2: Service Existence Check
|
||||
print("\n2. Testing service existence checks...");
|
||||
for service_config in test_services {
|
||||
print(`\nChecking existence of: ${service_config.name}`);
|
||||
try {
|
||||
let service_exists = exists(manager, service_config.name);
|
||||
if service_exists {
|
||||
print(` ✓ Service ${service_config.name} exists: ${service_exists}`);
|
||||
passed_tests += 1;
|
||||
} else {
|
||||
print(` ✗ Service ${service_config.name} doesn't exist after start`);
|
||||
}
|
||||
} catch(e) {
|
||||
print(` ✗ Existence check failed for ${service_config.name}: ${e}`);
|
||||
}
|
||||
total_tests += 1;
|
||||
passed_tests += 1;
|
||||
}
|
||||
|
||||
// Test 3: Status Check
|
||||
print("\n3. Testing status checks...");
|
||||
for service_name in service_names {
|
||||
print(`\nChecking status of: ${service_name}`);
|
||||
print(` ✓ Service ${service_name} status: Running`);
|
||||
for service_config in test_services {
|
||||
print(`\nChecking status of: ${service_config.name}`);
|
||||
try {
|
||||
let service_status = status(manager, service_config.name);
|
||||
print(` ✓ Service ${service_config.name} status: ${service_status}`);
|
||||
passed_tests += 1;
|
||||
} catch(e) {
|
||||
print(` ✗ Status check failed for ${service_config.name}: ${e}`);
|
||||
}
|
||||
total_tests += 1;
|
||||
passed_tests += 1;
|
||||
}
|
||||
|
||||
// Test 4: Service Stop
|
||||
print("\n4. Testing service stop...");
|
||||
for service_name in service_names {
|
||||
print(`\nStopping service: ${service_name}`);
|
||||
print(` ✓ Service ${service_name} stopped successfully`);
|
||||
total_tests += 1;
|
||||
// Test 4: Service List Check
|
||||
print("\n4. Testing service list...");
|
||||
try {
|
||||
let services = list(manager);
|
||||
print(` ✓ Service list retrieved (${services.len()} services)`);
|
||||
|
||||
// Check if our test services are in the list
|
||||
for service_config in test_services {
|
||||
let found = false;
|
||||
for service in services {
|
||||
if service.contains(service_config.name) {
|
||||
found = true;
|
||||
print(` ✓ Found ${service_config.name} in list`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
print(` ⚠ ${service_config.name} not found in service list`);
|
||||
}
|
||||
}
|
||||
passed_tests += 1;
|
||||
} catch(e) {
|
||||
print(` ✗ Service list failed: ${e}`);
|
||||
}
|
||||
total_tests += 1;
|
||||
|
||||
// Test 5: Service Stop
|
||||
print("\n5. Testing service stop...");
|
||||
for service_config in test_services {
|
||||
print(`\nStopping service: ${service_config.name}`);
|
||||
try {
|
||||
stop(manager, service_config.name);
|
||||
print(` ✓ Service ${service_config.name} stopped successfully`);
|
||||
passed_tests += 1;
|
||||
} catch(e) {
|
||||
print(` ✗ Service ${service_config.name} stop failed: ${e}`);
|
||||
}
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 5: Service Removal
|
||||
print("\n5. Testing service removal...");
|
||||
for service_name in service_names {
|
||||
print(`\nRemoving service: ${service_name}`);
|
||||
print(` ✓ Service ${service_name} removed successfully`);
|
||||
// Test 6: Service Removal
|
||||
print("\n6. Testing service removal...");
|
||||
for service_config in test_services {
|
||||
print(`\nRemoving service: ${service_config.name}`);
|
||||
try {
|
||||
remove(manager, service_config.name);
|
||||
print(` ✓ Service ${service_config.name} removed successfully`);
|
||||
passed_tests += 1;
|
||||
} catch(e) {
|
||||
print(` ✗ Service ${service_config.name} removal failed: ${e}`);
|
||||
}
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 7: Cleanup Verification
|
||||
print("\n7. Testing cleanup verification...");
|
||||
for service_config in test_services {
|
||||
print(`\nVerifying removal of: ${service_config.name}`);
|
||||
try {
|
||||
let exists_after_remove = exists(manager, service_config.name);
|
||||
if !exists_after_remove {
|
||||
print(` ✓ Service ${service_config.name} correctly doesn't exist after removal`);
|
||||
passed_tests += 1;
|
||||
} else {
|
||||
print(` ✗ Service ${service_config.name} still exists after removal`);
|
||||
}
|
||||
} catch(e) {
|
||||
print(` ✗ Cleanup verification failed for ${service_config.name}: ${e}`);
|
||||
}
|
||||
total_tests += 1;
|
||||
passed_tests += 1;
|
||||
}
|
||||
|
||||
// Test Summary
|
||||
print("\n=== Lifecycle Test Summary ===");
|
||||
print(`Services tested: ${service_count}`);
|
||||
print(`Services tested: ${test_services.len()}`);
|
||||
print(`Total operations: ${total_tests}`);
|
||||
print(`Successful operations: ${passed_tests}`);
|
||||
print(`Failed operations: ${total_tests - passed_tests}`);
|
||||
@@ -79,6 +172,6 @@ print("\n=== Service Lifecycle Test Complete ===");
|
||||
total_tests: total_tests,
|
||||
passed_tests: passed_tests,
|
||||
success_rate: (passed_tests * 100) / total_tests,
|
||||
services_tested: service_count
|
||||
services_tested: test_services.len()
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
// Basic service manager functionality test script
|
||||
// This script tests the service manager through Rhai integration
|
||||
// This script tests the REAL service manager through Rhai integration
|
||||
|
||||
print("=== Service Manager Basic Functionality Test ===");
|
||||
|
||||
// Test configuration
|
||||
let test_service_name = "rhai-test-service";
|
||||
let test_binary = "echo";
|
||||
let test_binary = "/bin/echo";
|
||||
let test_args = ["Hello from Rhai service manager test"];
|
||||
|
||||
print(`Testing service: ${test_service_name}`);
|
||||
@@ -15,11 +15,11 @@ print(`Args: ${test_args}`);
|
||||
// Test results tracking
|
||||
let test_results = #{
|
||||
creation: "NOT_RUN",
|
||||
start: "NOT_RUN",
|
||||
exists_before: "NOT_RUN",
|
||||
start: "NOT_RUN",
|
||||
exists_after: "NOT_RUN",
|
||||
status: "NOT_RUN",
|
||||
exists: "NOT_RUN",
|
||||
list: "NOT_RUN",
|
||||
logs: "NOT_RUN",
|
||||
stop: "NOT_RUN",
|
||||
remove: "NOT_RUN",
|
||||
cleanup: "NOT_RUN"
|
||||
@@ -28,14 +28,11 @@ let test_results = #{
|
||||
let passed_tests = 0;
|
||||
let total_tests = 0;
|
||||
|
||||
// Note: Helper functions are defined inline to avoid scope issues
|
||||
|
||||
// Test 1: Service Manager Creation
|
||||
print("\n1. Testing service manager creation...");
|
||||
try {
|
||||
// Note: This would require the service manager to be exposed to Rhai
|
||||
// For now, we'll simulate this test
|
||||
print("✓ Service manager creation test simulated");
|
||||
let manager = create_service_manager();
|
||||
print("✓ Service manager created successfully");
|
||||
test_results["creation"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
@@ -43,10 +40,36 @@ try {
|
||||
print(`✗ Service manager creation failed: ${e}`);
|
||||
test_results["creation"] = "FAIL";
|
||||
total_tests += 1;
|
||||
// Return early if we can't create the manager
|
||||
return test_results;
|
||||
}
|
||||
|
||||
// Test 2: Service Configuration
|
||||
print("\n2. Testing service configuration...");
|
||||
// Create the service manager for all subsequent tests
|
||||
let manager = create_service_manager();
|
||||
|
||||
// Test 2: Check if service exists before creation
|
||||
print("\n2. Testing service existence check (before creation)...");
|
||||
try {
|
||||
let exists_before = exists(manager, test_service_name);
|
||||
print(`✓ Service existence check: ${exists_before}`);
|
||||
|
||||
if !exists_before {
|
||||
print("✓ Service correctly doesn't exist before creation");
|
||||
test_results["exists_before"] = "PASS";
|
||||
passed_tests += 1;
|
||||
} else {
|
||||
print("⚠ Service unexpectedly exists before creation");
|
||||
test_results["exists_before"] = "WARN";
|
||||
}
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service existence check failed: ${e}`);
|
||||
test_results["exists_before"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 3: Start the service
|
||||
print("\n3. Testing service start...");
|
||||
try {
|
||||
// Create a service configuration object
|
||||
let service_config = #{
|
||||
@@ -57,160 +80,127 @@ try {
|
||||
environment: #{},
|
||||
auto_restart: false
|
||||
};
|
||||
|
||||
print(`✓ Service config created: ${service_config.name}`);
|
||||
print(` Binary: ${service_config.binary_path}`);
|
||||
print(` Args: ${service_config.args}`);
|
||||
print(` Working dir: ${service_config.working_directory}`);
|
||||
print(` Auto restart: ${service_config.auto_restart}`);
|
||||
|
||||
start(manager, service_config);
|
||||
print("✓ Service started successfully");
|
||||
test_results["start"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service configuration failed: ${e}`);
|
||||
print(`✗ Service start failed: ${e}`);
|
||||
test_results["start"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 3: Service Status Simulation
|
||||
print("\n3. Testing service status simulation...");
|
||||
// Test 4: Check if service exists after creation
|
||||
print("\n4. Testing service existence check (after creation)...");
|
||||
try {
|
||||
// Simulate different service statuses
|
||||
let statuses = ["Running", "Stopped", "Failed", "Unknown"];
|
||||
|
||||
for status in statuses {
|
||||
print(` Simulated status: ${status}`);
|
||||
let exists_after = exists(manager, test_service_name);
|
||||
print(`✓ Service existence check: ${exists_after}`);
|
||||
|
||||
if exists_after {
|
||||
print("✓ Service correctly exists after creation");
|
||||
test_results["exists_after"] = "PASS";
|
||||
passed_tests += 1;
|
||||
} else {
|
||||
print("✗ Service doesn't exist after creation");
|
||||
test_results["exists_after"] = "FAIL";
|
||||
}
|
||||
|
||||
print("✓ Service status simulation completed");
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service existence check failed: ${e}`);
|
||||
test_results["exists_after"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 5: Check service status
|
||||
print("\n5. Testing service status...");
|
||||
try {
|
||||
let service_status = status(manager, test_service_name);
|
||||
print(`✓ Service status: ${service_status}`);
|
||||
test_results["status"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service status simulation failed: ${e}`);
|
||||
print(`✗ Service status check failed: ${e}`);
|
||||
test_results["status"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 4: Service Existence Check Simulation
|
||||
print("\n4. Testing service existence check simulation...");
|
||||
// Test 6: List services
|
||||
print("\n6. Testing service list...");
|
||||
try {
|
||||
// Simulate checking if a service exists
|
||||
let existing_service = true;
|
||||
let non_existing_service = false;
|
||||
|
||||
if existing_service {
|
||||
print("✓ Existing service check: true");
|
||||
}
|
||||
|
||||
if !non_existing_service {
|
||||
print("✓ Non-existing service check: false");
|
||||
}
|
||||
|
||||
test_results["exists"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service existence check simulation failed: ${e}`);
|
||||
test_results["exists"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
let services = list(manager);
|
||||
print(`✓ Service list retrieved (${services.len()} services)`);
|
||||
|
||||
// Test 5: Service List Simulation
|
||||
print("\n5. Testing service list simulation...");
|
||||
try {
|
||||
// Simulate listing services
|
||||
let mock_services = [
|
||||
"system-service-1",
|
||||
"user-service-2",
|
||||
test_service_name,
|
||||
"background-task"
|
||||
];
|
||||
// Check if our test service is in the list
|
||||
let found_test_service = false;
|
||||
for service in services {
|
||||
if service.contains(test_service_name) {
|
||||
found_test_service = true;
|
||||
print(` ✓ Found test service: ${service}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print(`✓ Simulated service list (${mock_services.len()} services):`);
|
||||
for service in mock_services {
|
||||
print(` - ${service}`);
|
||||
if found_test_service {
|
||||
print("✓ Test service found in service list");
|
||||
} else {
|
||||
print("⚠ Test service not found in service list");
|
||||
}
|
||||
|
||||
test_results["list"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service list simulation failed: ${e}`);
|
||||
print(`✗ Service list failed: ${e}`);
|
||||
test_results["list"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 6: Service Logs Simulation
|
||||
print("\n6. Testing service logs simulation...");
|
||||
// Test 7: Stop the service
|
||||
print("\n7. Testing service stop...");
|
||||
try {
|
||||
// Simulate retrieving service logs
|
||||
let mock_logs = [
|
||||
"[2024-01-01 10:00:00] Service started",
|
||||
"[2024-01-01 10:00:01] Processing request",
|
||||
"[2024-01-01 10:00:02] Task completed",
|
||||
"[2024-01-01 10:00:03] Service ready"
|
||||
];
|
||||
|
||||
print(`✓ Simulated logs (${mock_logs.len()} entries):`);
|
||||
for log_entry in mock_logs {
|
||||
print(` ${log_entry}`);
|
||||
}
|
||||
|
||||
test_results["logs"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service logs simulation failed: ${e}`);
|
||||
test_results["logs"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 7: Service Stop Simulation
|
||||
print("\n7. Testing service stop simulation...");
|
||||
try {
|
||||
print(`✓ Simulated stopping service: ${test_service_name}`);
|
||||
print(" Service stop command executed");
|
||||
print(" Service status changed to: Stopped");
|
||||
|
||||
stop(manager, test_service_name);
|
||||
print(`✓ Service stopped: ${test_service_name}`);
|
||||
test_results["stop"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service stop simulation failed: ${e}`);
|
||||
print(`✗ Service stop failed: ${e}`);
|
||||
test_results["stop"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 8: Service Remove Simulation
|
||||
print("\n8. Testing service remove simulation...");
|
||||
// Test 8: Remove the service
|
||||
print("\n8. Testing service remove...");
|
||||
try {
|
||||
print(`✓ Simulated removing service: ${test_service_name}`);
|
||||
print(" Service configuration deleted");
|
||||
print(" Service no longer exists");
|
||||
|
||||
remove(manager, test_service_name);
|
||||
print(`✓ Service removed: ${test_service_name}`);
|
||||
test_results["remove"] = "PASS";
|
||||
passed_tests += 1;
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Service remove simulation failed: ${e}`);
|
||||
print(`✗ Service remove failed: ${e}`);
|
||||
test_results["remove"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
||||
// Test 9: Cleanup Simulation
|
||||
print("\n9. Testing cleanup simulation...");
|
||||
// Test 9: Verify cleanup
|
||||
print("\n9. Testing cleanup verification...");
|
||||
try {
|
||||
print("✓ Cleanup simulation completed");
|
||||
print(" All test resources cleaned up");
|
||||
print(" System state restored");
|
||||
|
||||
test_results["cleanup"] = "PASS";
|
||||
passed_tests += 1;
|
||||
let exists_after_remove = exists(manager, test_service_name);
|
||||
if !exists_after_remove {
|
||||
print("✓ Service correctly doesn't exist after removal");
|
||||
test_results["cleanup"] = "PASS";
|
||||
passed_tests += 1;
|
||||
} else {
|
||||
print("✗ Service still exists after removal");
|
||||
test_results["cleanup"] = "FAIL";
|
||||
}
|
||||
total_tests += 1;
|
||||
} catch(e) {
|
||||
print(`✗ Cleanup simulation failed: ${e}`);
|
||||
print(`✗ Cleanup verification failed: ${e}`);
|
||||
test_results["cleanup"] = "FAIL";
|
||||
total_tests += 1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user