feat: Add zinit_client package to workspace
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run

- Add `zinit_client` package to the workspace, enabling its use
  in the SAL monorepo.  This allows for better organization and
  dependency management.
- Update `MONOREPO_CONVERSION_PLAN.md` to reflect the addition
  of `zinit_client` and its status.  This ensures the conversion
  plan stays up-to-date.
- Move `src/zinit_client/` directory to `zinit_client/` for better
   organization.  This improves the overall structure of the
   project.
- Update references to `zinit_client` to use the new path.  This
  ensures the codebase correctly links to the `zinit_client`
  package.
This commit is contained in:
Mahmoud-Emad
2025-06-22 10:59:19 +03:00
parent 74217364fa
commit 511729c477
17 changed files with 2681 additions and 455 deletions

View File

@@ -0,0 +1,127 @@
// Basic Zinit operations test script
// This script tests fundamental zinit client operations
// Configuration
let socket_paths = [
"/var/run/zinit.sock",
"/tmp/zinit.sock",
"/run/zinit.sock",
"./zinit.sock"
];
// Find available socket
let socket_path = "";
for path in socket_paths {
try {
let test_services = zinit_list(path);
socket_path = path;
print(`✓ Found working Zinit socket at: ${path}`);
break;
} catch(e) {
// Continue to next path
}
}
if socket_path == "" {
print("⚠ No working Zinit socket found. Skipping tests.");
return;
}
print("=== Basic Zinit Operations Test ===");
// Test 1: List services
print("\n1. Testing service listing...");
try {
let services = zinit_list(socket_path);
print(`✓ Successfully listed ${services.len()} services`);
if services.len() > 0 {
print(" Sample services:");
let count = 0;
for name in services.keys() {
if count >= 3 { break; }
let state = services[name];
print(` ${name}: ${state}`);
count += 1;
}
} else {
print(" No services currently managed by Zinit");
}
} catch(e) {
print(`✗ Service listing failed: ${e}`);
}
// Test 2: Service status (if services exist)
print("\n2. Testing service status...");
try {
let services = zinit_list(socket_path);
if services.len() > 0 {
let service_names = services.keys();
let first_service = service_names[0];
try {
let status = zinit_status(socket_path, first_service);
print(`✓ Status for '${first_service}':`);
print(` Name: ${status.name}`);
print(` PID: ${status.pid}`);
print(` State: ${status.state}`);
print(` Target: ${status.target}`);
if status.after.len() > 0 {
print(" Dependencies:");
for dep in status.after.keys() {
let dep_state = status.after[dep];
print(` ${dep}: ${dep_state}`);
}
}
} catch(e) {
print(`⚠ Status check failed for '${first_service}': ${e}`);
}
} else {
print(" No services available for status testing");
}
} catch(e) {
print(`✗ Service status test failed: ${e}`);
}
// Test 3: Logs functionality
print("\n3. Testing logs functionality...");
try {
let all_logs = zinit_logs_all(socket_path);
print(`✓ Retrieved ${all_logs.len()} log entries`);
if all_logs.len() > 0 {
print(" Recent log entries:");
let count = 0;
for log_entry in all_logs {
if count >= 3 { break; }
print(` ${log_entry}`);
count += 1;
}
} else {
print(" No log entries available");
}
} catch(e) {
print(`⚠ Logs retrieval failed: ${e}`);
}
// Test 4: Filtered logs
print("\n4. Testing filtered logs...");
try {
let filtered_logs = zinit_logs(socket_path, "zinit");
print(`✓ Retrieved ${filtered_logs.len()} filtered log entries`);
} catch(e) {
print(`⚠ Filtered logs retrieval failed: ${e}`);
}
// Test 5: Error handling with invalid service
print("\n5. Testing error handling...");
let invalid_service = "non-existent-service-12345";
try {
let status = zinit_status(socket_path, invalid_service);
print(`⚠ Unexpected success for non-existent service: ${status}`);
} catch(e) {
print(`✓ Correctly failed for non-existent service: ${e}`);
}
print("\n=== Basic Operations Test Complete ===");

View File

@@ -0,0 +1,149 @@
// Service lifecycle management test script
// This script tests creating, managing, and deleting services
// Configuration
let socket_paths = [
"/var/run/zinit.sock",
"/tmp/zinit.sock",
"/run/zinit.sock",
"./zinit.sock"
];
// Find available socket
let socket_path = "";
for path in socket_paths {
try {
let test_services = zinit_list(path);
socket_path = path;
print(`✓ Found working Zinit socket at: ${path}`);
break;
} catch(e) {
// Continue to next path
}
}
if socket_path == "" {
print("⚠ No working Zinit socket found. Skipping tests.");
return;
}
print("=== Service Lifecycle Test ===");
let service_name = "rhai-lifecycle-test";
let exec_command = "echo 'Hello from Rhai lifecycle test'";
let oneshot = true;
// Clean up any existing service first
print("\n0. Cleaning up any existing test service...");
try {
zinit_stop(socket_path, service_name);
zinit_forget(socket_path, service_name);
zinit_delete_service(socket_path, service_name);
print("✓ Cleanup completed");
} catch(e) {
print(" (Cleanup errors are expected if service doesn't exist)");
}
// Test 1: Service creation
print("\n1. Testing service creation...");
try {
let create_result = zinit_create_service(socket_path, service_name, exec_command, oneshot);
print(`✓ Service created: ${create_result}`);
} catch(e) {
print(`✗ Service creation failed: ${e}`);
print("⚠ Remaining tests will be skipped");
return;
}
// Test 2: Service monitoring
print("\n2. Testing service monitoring...");
try {
let monitor_result = zinit_monitor(socket_path, service_name);
print(`✓ Service monitoring started: ${monitor_result}`);
} catch(e) {
print(`⚠ Service monitoring failed: ${e}`);
}
// Test 3: Service start
print("\n3. Testing service start...");
try {
let start_result = zinit_start(socket_path, service_name);
print(`✓ Service started: ${start_result}`);
// Wait a moment for the service to run
print(" Waiting for service to execute...");
// Note: Rhai doesn't have sleep, so we'll just continue
} catch(e) {
print(`⚠ Service start failed: ${e}`);
}
// Test 4: Service status check
print("\n4. Testing service status...");
try {
let status = zinit_status(socket_path, service_name);
print(`✓ Service status retrieved:`);
print(` Name: ${status.name}`);
print(` PID: ${status.pid}`);
print(` State: ${status.state}`);
print(` Target: ${status.target}`);
} catch(e) {
print(`⚠ Service status check failed: ${e}`);
}
// Test 5: Service configuration retrieval
print("\n5. Testing service configuration retrieval...");
try {
let config = zinit_get_service(socket_path, service_name);
print(`✓ Service configuration retrieved: ${type_of(config)}`);
print(` Config: ${config}`);
} catch(e) {
print(`⚠ Service configuration retrieval failed: ${e}`);
}
// Test 6: Service restart
print("\n6. Testing service restart...");
try {
let restart_result = zinit_restart(socket_path, service_name);
print(`✓ Service restarted: ${restart_result}`);
} catch(e) {
print(`⚠ Service restart failed: ${e}`);
}
// Test 7: Service stop
print("\n7. Testing service stop...");
try {
let stop_result = zinit_stop(socket_path, service_name);
print(`✓ Service stopped: ${stop_result}`);
} catch(e) {
print(`⚠ Service stop failed: ${e}`);
}
// Test 8: Service forget (stop monitoring)
print("\n8. Testing service forget...");
try {
let forget_result = zinit_forget(socket_path, service_name);
print(`✓ Service forgotten: ${forget_result}`);
} catch(e) {
print(`⚠ Service forget failed: ${e}`);
}
// Test 9: Service deletion
print("\n9. Testing service deletion...");
try {
let delete_result = zinit_delete_service(socket_path, service_name);
print(`✓ Service deleted: ${delete_result}`);
} catch(e) {
print(`⚠ Service deletion failed: ${e}`);
}
// Test 10: Verify service is gone
print("\n10. Verifying service deletion...");
try {
let status = zinit_status(socket_path, service_name);
print(`⚠ Service still exists after deletion: ${status}`);
} catch(e) {
print(`✓ Service correctly removed: ${e}`);
}
print("\n=== Service Lifecycle Test Complete ===");

View File

@@ -0,0 +1,200 @@
// Signal management and kill functionality test script
// This script tests sending signals to services
// Configuration
let socket_paths = [
"/var/run/zinit.sock",
"/tmp/zinit.sock",
"/run/zinit.sock",
"./zinit.sock"
];
// Find available socket
let socket_path = "";
for path in socket_paths {
try {
let test_services = zinit_list(path);
socket_path = path;
print(`✓ Found working Zinit socket at: ${path}`);
break;
} catch(e) {
// Continue to next path
}
}
if socket_path == "" {
print("⚠ No working Zinit socket found. Skipping tests.");
return;
}
print("=== Signal Management Test ===");
let service_name = "rhai-signal-test";
let exec_command = "sleep 30"; // Long-running command for signal testing
let oneshot = false; // Not oneshot so it keeps running
// Clean up any existing service first
print("\n0. Cleaning up any existing test service...");
try {
zinit_stop(socket_path, service_name);
zinit_forget(socket_path, service_name);
zinit_delete_service(socket_path, service_name);
print("✓ Cleanup completed");
} catch(e) {
print(" (Cleanup errors are expected if service doesn't exist)");
}
// Test 1: Create long-running service for signal testing
print("\n1. Creating long-running service for signal testing...");
try {
let create_result = zinit_create_service(socket_path, service_name, exec_command, oneshot);
print(`✓ Long-running service created: ${create_result}`);
} catch(e) {
print(`✗ Service creation failed: ${e}`);
print("⚠ Signal tests will be skipped");
return;
}
// Test 2: Start the service
print("\n2. Starting the service...");
try {
let monitor_result = zinit_monitor(socket_path, service_name);
let start_result = zinit_start(socket_path, service_name);
print(`✓ Service started: ${start_result}`);
// Check if it's running
try {
let status = zinit_status(socket_path, service_name);
print(` Service state: ${status.state}`);
print(` Service PID: ${status.pid}`);
} catch(e) {
print(` Status check failed: ${e}`);
}
} catch(e) {
print(`⚠ Service start failed: ${e}`);
// Clean up and exit
try {
zinit_delete_service(socket_path, service_name);
} catch(cleanup_e) {
// Ignore cleanup errors
}
return;
}
// Test 3: Send TERM signal
print("\n3. Testing TERM signal...");
try {
let kill_result = zinit_kill(socket_path, service_name, "TERM");
print(`✓ TERM signal sent: ${kill_result}`);
// Check status after signal
try {
let status = zinit_status(socket_path, service_name);
print(` Service state after TERM: ${status.state}`);
print(` Service PID after TERM: ${status.pid}`);
} catch(e) {
print(` Status check after TERM failed: ${e}`);
}
} catch(e) {
print(`⚠ TERM signal failed: ${e}`);
}
// Test 4: Restart service for more signal testing
print("\n4. Restarting service for additional signal tests...");
try {
let restart_result = zinit_restart(socket_path, service_name);
print(`✓ Service restarted: ${restart_result}`);
// Check if it's running again
try {
let status = zinit_status(socket_path, service_name);
print(` Service state after restart: ${status.state}`);
print(` Service PID after restart: ${status.pid}`);
} catch(e) {
print(` Status check after restart failed: ${e}`);
}
} catch(e) {
print(`⚠ Service restart failed: ${e}`);
}
// Test 5: Send HUP signal
print("\n5. Testing HUP signal...");
try {
let kill_result = zinit_kill(socket_path, service_name, "HUP");
print(`✓ HUP signal sent: ${kill_result}`);
// Check status after signal
try {
let status = zinit_status(socket_path, service_name);
print(` Service state after HUP: ${status.state}`);
print(` Service PID after HUP: ${status.pid}`);
} catch(e) {
print(` Status check after HUP failed: ${e}`);
}
} catch(e) {
print(`⚠ HUP signal failed: ${e}`);
}
// Test 6: Send USR1 signal
print("\n6. Testing USR1 signal...");
try {
let kill_result = zinit_kill(socket_path, service_name, "USR1");
print(`✓ USR1 signal sent: ${kill_result}`);
// Check status after signal
try {
let status = zinit_status(socket_path, service_name);
print(` Service state after USR1: ${status.state}`);
print(` Service PID after USR1: ${status.pid}`);
} catch(e) {
print(` Status check after USR1 failed: ${e}`);
}
} catch(e) {
print(`⚠ USR1 signal failed: ${e}`);
}
// Test 7: Send KILL signal (forceful termination)
print("\n7. Testing KILL signal (forceful termination)...");
try {
let kill_result = zinit_kill(socket_path, service_name, "KILL");
print(`✓ KILL signal sent: ${kill_result}`);
// Check status after signal
try {
let status = zinit_status(socket_path, service_name);
print(` Service state after KILL: ${status.state}`);
print(` Service PID after KILL: ${status.pid}`);
} catch(e) {
print(` Status check after KILL failed: ${e}`);
}
} catch(e) {
print(`⚠ KILL signal failed: ${e}`);
}
// Test 8: Test invalid signal
print("\n8. Testing invalid signal handling...");
try {
let kill_result = zinit_kill(socket_path, service_name, "INVALID");
print(`⚠ Invalid signal unexpectedly succeeded: ${kill_result}`);
} catch(e) {
print(`✓ Invalid signal correctly rejected: ${e}`);
}
// Cleanup
print("\n9. Cleaning up test service...");
try {
zinit_stop(socket_path, service_name);
zinit_forget(socket_path, service_name);
let delete_result = zinit_delete_service(socket_path, service_name);
print(`✓ Test service cleaned up: ${delete_result}`);
} catch(e) {
print(`⚠ Cleanup failed: ${e}`);
}
print("\n=== Signal Management Test Complete ===");

View File

@@ -0,0 +1,316 @@
// Real-world scenarios test script
// This script tests practical zinit usage scenarios
// Configuration
let socket_paths = [
"/var/run/zinit.sock",
"/tmp/zinit.sock",
"/run/zinit.sock",
"./zinit.sock"
];
// Find available socket
let socket_path = "";
for path in socket_paths {
try {
let test_services = zinit_list(path);
socket_path = path;
print(`✓ Found working Zinit socket at: ${path}`);
break;
} catch(e) {
// Continue to next path
}
}
if socket_path == "" {
print("⚠ No working Zinit socket found. Skipping tests.");
return;
}
print("=== Real-World Scenarios Test ===");
// Scenario 1: Web server simulation
print("\n=== Scenario 1: Web Server Simulation ===");
let web_service = "rhai-web-server";
let web_command = "python3 -m http.server 8080";
let web_oneshot = false;
// Clean up first
try {
zinit_stop(socket_path, web_service);
zinit_forget(socket_path, web_service);
zinit_delete_service(socket_path, web_service);
} catch(e) {
// Ignore cleanup errors
}
print("1. Creating web server service...");
try {
let create_result = zinit_create_service(socket_path, web_service, web_command, web_oneshot);
print(`✓ Web server service created: ${create_result}`);
print("2. Starting web server...");
zinit_monitor(socket_path, web_service);
let start_result = zinit_start(socket_path, web_service);
print(`✓ Web server started: ${start_result}`);
print("3. Checking web server status...");
let status = zinit_status(socket_path, web_service);
print(` State: ${status.state}, PID: ${status.pid}`);
print("4. Gracefully stopping web server...");
let stop_result = zinit_stop(socket_path, web_service);
print(`✓ Web server stopped: ${stop_result}`);
print("5. Cleaning up web server...");
zinit_forget(socket_path, web_service);
zinit_delete_service(socket_path, web_service);
print("✓ Web server cleaned up");
} catch(e) {
print(`⚠ Web server scenario failed: ${e}`);
// Cleanup on failure
try {
zinit_stop(socket_path, web_service);
zinit_forget(socket_path, web_service);
zinit_delete_service(socket_path, web_service);
} catch(cleanup_e) {
// Ignore cleanup errors
}
}
// Scenario 2: Batch job processing
print("\n=== Scenario 2: Batch Job Processing ===");
let batch_service = "rhai-batch-job";
let batch_command = "echo 'Processing batch job...' && sleep 2 && echo 'Batch job completed'";
let batch_oneshot = true;
// Clean up first
try {
zinit_stop(socket_path, batch_service);
zinit_forget(socket_path, batch_service);
zinit_delete_service(socket_path, batch_service);
} catch(e) {
// Ignore cleanup errors
}
print("1. Creating batch job service...");
try {
let create_result = zinit_create_service(socket_path, batch_service, batch_command, batch_oneshot);
print(`✓ Batch job service created: ${create_result}`);
print("2. Starting batch job...");
zinit_monitor(socket_path, batch_service);
let start_result = zinit_start(socket_path, batch_service);
print(`✓ Batch job started: ${start_result}`);
print("3. Monitoring batch job progress...");
let status = zinit_status(socket_path, batch_service);
print(` Initial state: ${status.state}, PID: ${status.pid}`);
// Since it's a oneshot job, it should complete automatically
print("4. Checking final status...");
try {
let final_status = zinit_status(socket_path, batch_service);
print(` Final state: ${final_status.state}, PID: ${final_status.pid}`);
} catch(e) {
print(` Status check: ${e}`);
}
print("5. Cleaning up batch job...");
zinit_forget(socket_path, batch_service);
zinit_delete_service(socket_path, batch_service);
print("✓ Batch job cleaned up");
} catch(e) {
print(`⚠ Batch job scenario failed: ${e}`);
// Cleanup on failure
try {
zinit_stop(socket_path, batch_service);
zinit_forget(socket_path, batch_service);
zinit_delete_service(socket_path, batch_service);
} catch(cleanup_e) {
// Ignore cleanup errors
}
}
// Scenario 3: Service dependency simulation
print("\n=== Scenario 3: Service Dependency Simulation ===");
let db_service = "rhai-mock-db";
let app_service = "rhai-mock-app";
let db_command = "echo 'Database started' && sleep 10";
let app_command = "echo 'Application started' && sleep 5";
// Clean up first
for service in [db_service, app_service] {
try {
zinit_stop(socket_path, service);
zinit_forget(socket_path, service);
zinit_delete_service(socket_path, service);
} catch(e) {
// Ignore cleanup errors
}
}
print("1. Creating database service...");
try {
let db_create = zinit_create_service(socket_path, db_service, db_command, false);
print(`✓ Database service created: ${db_create}`);
print("2. Creating application service...");
let app_create = zinit_create_service(socket_path, app_service, app_command, false);
print(`✓ Application service created: ${app_create}`);
print("3. Starting database first...");
zinit_monitor(socket_path, db_service);
let db_start = zinit_start(socket_path, db_service);
print(`✓ Database started: ${db_start}`);
print("4. Checking database status...");
let db_status = zinit_status(socket_path, db_service);
print(` Database state: ${db_status.state}, PID: ${db_status.pid}`);
print("5. Starting application...");
zinit_monitor(socket_path, app_service);
let app_start = zinit_start(socket_path, app_service);
print(`✓ Application started: ${app_start}`);
print("6. Checking application status...");
let app_status = zinit_status(socket_path, app_service);
print(` Application state: ${app_status.state}, PID: ${app_status.pid}`);
print("7. Stopping services in reverse order...");
zinit_stop(socket_path, app_service);
print(" Application stopped");
zinit_stop(socket_path, db_service);
print(" Database stopped");
print("8. Cleaning up services...");
for service in [app_service, db_service] {
zinit_forget(socket_path, service);
zinit_delete_service(socket_path, service);
}
print("✓ Services cleaned up");
} catch(e) {
print(`⚠ Service dependency scenario failed: ${e}`);
// Cleanup on failure
for service in [app_service, db_service] {
try {
zinit_stop(socket_path, service);
zinit_forget(socket_path, service);
zinit_delete_service(socket_path, service);
} catch(cleanup_e) {
// Ignore cleanup errors
}
}
}
// Scenario 4: Log monitoring and analysis
print("\n=== Scenario 4: Log Monitoring and Analysis ===");
print("1. Analyzing current system logs...");
try {
let all_logs = zinit_logs_all(socket_path);
print(`✓ Retrieved ${all_logs.len()} total log entries`);
if all_logs.len() > 0 {
print("2. Analyzing log patterns...");
let error_count = 0;
let warning_count = 0;
let info_count = 0;
for log_entry in all_logs {
let log_lower = log_entry.to_lower();
if log_lower.contains("error") {
error_count += 1;
} else if log_lower.contains("warn") {
warning_count += 1;
} else {
info_count += 1;
}
}
print(` Error entries: ${error_count}`);
print(` Warning entries: ${warning_count}`);
print(` Info entries: ${info_count}`);
print("3. Testing filtered log retrieval...");
let zinit_logs = zinit_logs(socket_path, "zinit");
print(`✓ Retrieved ${zinit_logs.len()} zinit-specific log entries`);
if zinit_logs.len() > 0 {
print(" Recent zinit logs:");
let count = 0;
for log_entry in zinit_logs {
if count >= 2 { break; }
print(` ${log_entry}`);
count += 1;
}
}
} else {
print(" No logs available for analysis");
}
} catch(e) {
print(`⚠ Log monitoring scenario failed: ${e}`);
}
// Scenario 5: Error recovery simulation
print("\n=== Scenario 5: Error Recovery Simulation ===");
let failing_service = "rhai-failing-service";
let failing_command = "exit 1"; // Command that always fails
// Clean up first
try {
zinit_stop(socket_path, failing_service);
zinit_forget(socket_path, failing_service);
zinit_delete_service(socket_path, failing_service);
} catch(e) {
// Ignore cleanup errors
}
print("1. Creating service that will fail...");
try {
let create_result = zinit_create_service(socket_path, failing_service, failing_command, true);
print(`✓ Failing service created: ${create_result}`);
print("2. Starting failing service...");
zinit_monitor(socket_path, failing_service);
let start_result = zinit_start(socket_path, failing_service);
print(`✓ Failing service started: ${start_result}`);
print("3. Checking service status after failure...");
try {
let status = zinit_status(socket_path, failing_service);
print(` Service state: ${status.state}, PID: ${status.pid}`);
} catch(e) {
print(` Status check: ${e}`);
}
print("4. Attempting restart...");
try {
let restart_result = zinit_restart(socket_path, failing_service);
print(`✓ Restart attempted: ${restart_result}`);
} catch(e) {
print(` Restart failed as expected: ${e}`);
}
print("5. Cleaning up failing service...");
zinit_forget(socket_path, failing_service);
zinit_delete_service(socket_path, failing_service);
print("✓ Failing service cleaned up");
} catch(e) {
print(`⚠ Error recovery scenario failed: ${e}`);
// Cleanup on failure
try {
zinit_stop(socket_path, failing_service);
zinit_forget(socket_path, failing_service);
zinit_delete_service(socket_path, failing_service);
} catch(cleanup_e) {
// Ignore cleanup errors
}
}
print("\n=== Real-World Scenarios Test Complete ===");
print("✓ All scenarios tested successfully");

View File

@@ -0,0 +1,290 @@
// Zinit Client Rhai Test Runner
// This script runs all zinit client Rhai tests
print("=== Zinit Client Rhai Test Suite ===");
print("Running comprehensive tests for sal-zinit-client Rhai integration");
print("");
// Configuration
let socket_paths = [
"/var/run/zinit.sock",
"/tmp/zinit.sock",
"/run/zinit.sock",
"./zinit.sock"
];
// Find available socket
let socket_path = "";
for path in socket_paths {
try {
let test_services = zinit_list(path);
socket_path = path;
print(`✓ Found working Zinit socket at: ${path}`);
break;
} catch(e) {
// Continue to next path
}
}
if socket_path == "" {
print("⚠ No working Zinit socket found.");
print(" Please ensure Zinit is running and accessible at one of these paths:");
for path in socket_paths {
print(` ${path}`);
}
print("");
print(" To start Zinit for testing:");
print(" sudo zinit --socket /tmp/zinit.sock");
print("");
print("⚠ All tests will be skipped.");
return;
}
print("");
print("=== Test Environment Information ===");
try {
let services = zinit_list(socket_path);
print(`Current services managed by Zinit: ${services.len()}`);
if services.len() > 0 {
print("Existing services:");
for name in services.keys() {
let state = services[name];
print(` ${name}: ${state}`);
}
}
} catch(e) {
print(`Error getting service list: ${e}`);
}
print("");
print("=== Running Test Suite ===");
// Test results tracking
let test_results = #{};
let total_tests = 0;
let passed_tests = 0;
let failed_tests = 0;
// Test 1: Basic Operations
print("\n--- Test 1: Basic Operations ---");
total_tests += 1;
try {
// Test basic listing
let services = zinit_list(socket_path);
print(`✓ Service listing: ${services.len()} services`);
// Test logs
let logs = zinit_logs_all(socket_path);
print(`✓ Log retrieval: ${logs.len()} entries`);
// Test filtered logs
let filtered_logs = zinit_logs(socket_path, "zinit");
print(`✓ Filtered logs: ${filtered_logs.len()} entries`);
test_results.basic_operations = "PASSED";
passed_tests += 1;
print("✓ Basic Operations: PASSED");
} catch(e) {
test_results.basic_operations = `FAILED: ${e}`;
failed_tests += 1;
print(`✗ Basic Operations: FAILED - ${e}`);
}
// Test 2: Service Creation and Management
print("\n--- Test 2: Service Creation and Management ---");
total_tests += 1;
let test_service = "rhai-test-runner-service";
try {
// Clean up first
try {
zinit_stop(socket_path, test_service);
zinit_forget(socket_path, test_service);
zinit_delete_service(socket_path, test_service);
} catch(e) {
// Ignore cleanup errors
}
// Create service
let create_result = zinit_create_service(socket_path, test_service, "echo 'Test service'", true);
print(`✓ Service creation: ${create_result}`);
// Monitor service
let monitor_result = zinit_monitor(socket_path, test_service);
print(`✓ Service monitoring: ${monitor_result}`);
// Start service
let start_result = zinit_start(socket_path, test_service);
print(`✓ Service start: ${start_result}`);
// Get status
let status = zinit_status(socket_path, test_service);
print(`✓ Service status: ${status.state}`);
// Stop service
let stop_result = zinit_stop(socket_path, test_service);
print(`✓ Service stop: ${stop_result}`);
// Forget service
let forget_result = zinit_forget(socket_path, test_service);
print(`✓ Service forget: ${forget_result}`);
// Delete service
let delete_result = zinit_delete_service(socket_path, test_service);
print(`✓ Service deletion: ${delete_result}`);
test_results.service_management = "PASSED";
passed_tests += 1;
print("✓ Service Management: PASSED");
} catch(e) {
test_results.service_management = `FAILED: ${e}`;
failed_tests += 1;
print(`✗ Service Management: FAILED - ${e}`);
// Cleanup on failure
try {
zinit_stop(socket_path, test_service);
zinit_forget(socket_path, test_service);
zinit_delete_service(socket_path, test_service);
} catch(cleanup_e) {
// Ignore cleanup errors
}
}
// Test 3: Signal Handling
print("\n--- Test 3: Signal Handling ---");
total_tests += 1;
let signal_service = "rhai-signal-test-service";
try {
// Clean up first
try {
zinit_stop(socket_path, signal_service);
zinit_forget(socket_path, signal_service);
zinit_delete_service(socket_path, signal_service);
} catch(e) {
// Ignore cleanup errors
}
// Create long-running service
let create_result = zinit_create_service(socket_path, signal_service, "sleep 10", false);
print(`✓ Signal test service created: ${create_result}`);
// Start service
zinit_monitor(socket_path, signal_service);
let start_result = zinit_start(socket_path, signal_service);
print(`✓ Signal test service started: ${start_result}`);
// Send TERM signal
let kill_result = zinit_kill(socket_path, signal_service, "TERM");
print(`✓ TERM signal sent: ${kill_result}`);
// Check status after signal
try {
let status = zinit_status(socket_path, signal_service);
print(`✓ Status after signal: ${status.state}`);
} catch(e) {
print(` Status check: ${e}`);
}
// Cleanup
zinit_stop(socket_path, signal_service);
zinit_forget(socket_path, signal_service);
zinit_delete_service(socket_path, signal_service);
test_results.signal_handling = "PASSED";
passed_tests += 1;
print("✓ Signal Handling: PASSED");
} catch(e) {
test_results.signal_handling = `FAILED: ${e}`;
failed_tests += 1;
print(`✗ Signal Handling: FAILED - ${e}`);
// Cleanup on failure
try {
zinit_stop(socket_path, signal_service);
zinit_forget(socket_path, signal_service);
zinit_delete_service(socket_path, signal_service);
} catch(cleanup_e) {
// Ignore cleanup errors
}
}
// Test 4: Error Handling
print("\n--- Test 4: Error Handling ---");
total_tests += 1;
try {
// Test with non-existent service
try {
let status = zinit_status(socket_path, "non-existent-service-12345");
print("⚠ Unexpected success for non-existent service");
test_results.error_handling = "FAILED: Should have failed for non-existent service";
failed_tests += 1;
} catch(e) {
print(`✓ Correctly failed for non-existent service: ${e}`);
test_results.error_handling = "PASSED";
passed_tests += 1;
print("✓ Error Handling: PASSED");
}
} catch(e) {
test_results.error_handling = `FAILED: ${e}`;
failed_tests += 1;
print(`✗ Error Handling: FAILED - ${e}`);
}
// Test 5: Configuration Retrieval
print("\n--- Test 5: Configuration Retrieval ---");
total_tests += 1;
try {
let services = zinit_list(socket_path);
if services.len() > 0 {
let service_names = services.keys();
let first_service = service_names[0];
try {
let config = zinit_get_service(socket_path, first_service);
print(`✓ Configuration retrieved for '${first_service}': ${type_of(config)}`);
test_results.config_retrieval = "PASSED";
passed_tests += 1;
print("✓ Configuration Retrieval: PASSED");
} catch(e) {
print(`⚠ Configuration retrieval failed: ${e}`);
test_results.config_retrieval = `FAILED: ${e}`;
failed_tests += 1;
print("✗ Configuration Retrieval: FAILED");
}
} else {
print("⚠ No services available for configuration test");
test_results.config_retrieval = "SKIPPED: No services available";
print("⚠ Configuration Retrieval: SKIPPED");
}
} catch(e) {
test_results.config_retrieval = `FAILED: ${e}`;
failed_tests += 1;
print(`✗ Configuration Retrieval: FAILED - ${e}`);
}
// Test Summary
print("\n=== Test Summary ===");
print(`Total tests: ${total_tests}`);
print(`Passed: ${passed_tests}`);
print(`Failed: ${failed_tests}`);
print(`Success rate: ${(passed_tests * 100 / total_tests).round()}%`);
print("\nDetailed Results:");
for test_name in test_results.keys() {
let result = test_results[test_name];
print(` ${test_name}: ${result}`);
}
if failed_tests == 0 {
print("\n🎉 All tests passed! Zinit client Rhai integration is working correctly.");
} else {
print(`\n⚠ ${failed_tests} test(s) failed. Please check the errors above.`);
}
print("\n=== Zinit Client Rhai Test Suite Complete ===");