// 01_container_operations.rhai // Tests for Nerdctl container operations // Custom assert function fn assert_true(condition, message) { if !condition { print(`ASSERTION FAILED: ${message}`); throw message; } } // Custom assert_eq function fn assert_eq(actual, expected, message) { if actual != expected { print(`ASSERTION FAILED: ${message}`); print(`Expected: "${expected}"`); print(`Actual: "${actual}"`); throw message; } } // Helper function to check if nerdctl is available fn is_nerdctl_available() { let command = run("which nerdctl"); return command.silent().execute().success; } // Helper function to check if a container exists fn container_exists(container_name) { // let command = run(`nerdctl ps -a --format "{{.Names}}" | grep -w ${container_name}`); let command = run(`nerdctl ps -a --format "{{.Names}}"`); let result = command.silent().execute(); // Check if the command was successful if !result.success { print(`Error executing 'nerdctl ps': ${result.stderr}`); return false; } // Split the output into individual lines (names) // and check if any of them is an exact match for our container name. for line in result.stdout.split('\n') { if line.trim() == container_name { return true; // Found the container } } return false; // Did not find the container } // Helper function to clean up a container if it exists fn cleanup_container(container_name) { if container_exists(container_name) { try { run(`nerdctl stop ${container_name}`); run(`nerdctl rm ${container_name}`); print(`Cleaned up container: ${container_name}`); } catch(err) { print(`Error cleaning up container ${container_name}: ${err}`); } } else { print!(`No container with name ${container_name} found. Nothing to clean up.`); } } print("=== Testing Nerdctl Container Operations ==="); // Check if nerdctl is available let nerdctl_available = is_nerdctl_available(); if !nerdctl_available { print("nerdctl is not available. Skipping Nerdctl tests."); throw err; } print("✓ nerdctl is available"); // Define test container name let container_name = "rhai_test_container"; // Clean up any existing test container cleanup_container(container_name); try { // Test creating a new Container print("Testing nerdctl_container_new()..."); let container = nerdctl_container_new(container_name); // Test Container properties print("Testing Container properties..."); assert_eq(container.name, container_name, "Container name should match"); assert_eq(container.container_id, "", "Container ID should be empty initially"); // Test setting container image print("Testing image setter..."); container.image = "alpine:latest"; assert_eq(container.image, "alpine:latest", "Container image should match"); // Test setting container config print("Testing config setter..."); let config_options = #{"key1": "value1", "key2": "value2"}; container.config = config_options; assert_eq(container.config, config_options, "Container config options should match"); // Test container_id setter and getter print("Testing container_id setter..."); container.container_id = "test-id"; assert_eq(container.container_id, "test-id", "Container ID should be 'test-id'"); // Test ports setter and getter print("Testing ports setter and getter..."); let ports_list = ["1234", "2345"]; container.ports = ports_list; assert_eq(container.ports, ports_list, "Container ports should match"); // Test volumes setter and getter print("Testing volumes setter and getter..."); let volumes_list = ["/tmp:/tmp"]; container.volumes = volumes_list; assert_eq(container.volumes, volumes_list, "Container volumes should match"); // Test env_vars setter and getter print("Testing env_vars setter and getter..."); let env_vars_map = #{"VAR1": "value1", "VAR2": "value2"}; container.env_vars = env_vars_map; assert_eq(container.env_vars, env_vars_map, "Container env_vars should match"); // Test network setter and getter print("Testing network setter and getter..."); container.network = "test-net"; assert_eq(container.network, "test-net", "Container network should match"); // Test network_aliases setter and getter print("Testing network_aliases setter and getter..."); let aliases = ["alias1", "alias2"]; container.network_aliases = aliases; assert_eq(container.network_aliases, aliases, "Container network_aliases should match"); // Test cpu_limit setter and getter print("Testing cpu_limit setter and getter..."); container.cpu_limit = "0.5"; assert_eq(container.cpu_limit, "0.5", "Container cpu_limit should match"); // Test memory_limit setter and getter print("Testing memory_limit setter and getter..."); container.memory_limit = "512m"; assert_eq(container.memory_limit, "512m", "Container memory_limit should match"); // Test memory_swap_limit setter and getter print("Testing memory_swap_limit setter and getter..."); container.memory_swap_limit = "1g"; assert_eq(container.memory_swap_limit, "1g", "Container memory_swap_limit should match"); // Test cpu_shares setter and getter print("Testing cpu_shares setter and getter..."); container.cpu_shares = "1024"; assert_eq(container.cpu_shares, "1024", "Container cpu_shares should match"); // Test restart_policy setter and getter print("Testing restart_policy setter and getter..."); container.restart_policy = "always"; assert_eq(container.restart_policy, "always", "Container restart_policy should match"); // Test detach setter and getter print("Testing detach setter and getter..."); container.detach = false; assert_eq(container.detach, false, "Container detach should be false"); container.detach = true; assert_eq(container.detach, true, "Container detach should be true"); // TODO: Test health_check setter and getter print("Testing health_check setter and getter..."); // Test snapshotter setter and getter print("Testing snapshotter setter and getter..."); container.snapshotter = "stargz"; assert_eq(container.snapshotter, "stargz", "Container snapshotter should match"); // // Test running the container // print("Testing run()..."); // let run_result = container.run(); // assert_true(run_result.success, "Container run should succeed"); // assert_true(container.container_id != "", "Container ID should not be empty after run"); // print(`✓ run(): Container started with ID: ${container.container_id}`); // // Test executing a command in the container // print("Testing exec()..."); // let exec_result = container.exec("echo 'Hello from container'"); // assert_true(exec_result.success, "Container exec should succeed"); // assert_true(exec_result.stdout.contains("Hello from container"), "Exec output should contain expected text"); // print("✓ exec(): Command executed successfully"); // // Test getting container logs // print("Testing logs()..."); // let logs_result = container.logs(); // assert_true(logs_result.success, "Container logs should succeed"); // print("✓ logs(): Logs retrieved successfully"); // // Test stopping the container // print("Testing stop()..."); // let stop_result = container.stop(); // assert_true(stop_result.success, "Container stop should succeed"); // print("✓ stop(): Container stopped successfully"); // // Test removing the container // print("Testing remove()..."); // let remove_result = container.remove(); // assert_true(remove_result.success, "Container remove should succeed"); // print("✓ remove(): Container removed successfully"); // // Clean up test directory // delete(test_dir); // print("✓ Cleanup: Test directory removed"); // print("All container operations tests completed successfully!"); } catch(err) { print(`Error: ${err}`); // Clean up in case of error cleanup_container(container_name); // Clean up test directory try { delete("rhai_test_nerdctl_volume"); } catch(e) { // Ignore errors during cleanup } throw err; }