docs: Add documentation for Nerdctl and RFS module tests
Some checks failed
Rhai Tests / Run Rhai Tests (push) Waiting to run
Rhai Tests / Run Rhai Tests (pull_request) Has been cancelled

- Added documentation for Nerdctl module tests, detailing test
  structure, running instructions, and individual test cases.
- Added documentation for RFS module tests, covering test
  structure, running instructions, and individual test cases.  These
  tests verify remote filesystem operations and filesystem layer
  management.
This commit is contained in:
Mahmoud Emad
2025-05-08 17:48:00 +03:00
parent 83662736c0
commit d3c645e8e6
10 changed files with 1361 additions and 0 deletions

View File

@@ -0,0 +1,176 @@
// 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() {
try {
let result = run("which nerdctl");
return result.success;
} catch(err) {
return false;
}
}
// Helper function to check if a container exists
fn container_exists(container_name) {
try {
let result = run(`nerdctl ps -a --format "{{.Names}}" | grep -w ${container_name}`);
return result.success;
} catch(err) {
return false;
}
}
// 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}`);
}
}
}
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.");
// Exit gracefully without error
return;
}
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 with_image()...");
container.with_image("alpine:latest");
assert_eq(container.image, "alpine:latest", "Container image should match");
// Test setting detach mode
print("Testing with_detach()...");
container.with_detach(true);
assert_true(container.detach, "Container detach mode should be true");
// Test setting environment variables
print("Testing with_env()...");
container.with_env("TEST_VAR", "test_value");
// Test setting multiple environment variables
print("Testing with_envs()...");
let env_map = #{
"VAR1": "value1",
"VAR2": "value2"
};
container.with_envs(env_map);
// Test setting ports
print("Testing with_port()...");
container.with_port("8080:80");
// Test setting multiple ports
print("Testing with_ports()...");
container.with_ports(["9090:90", "7070:70"]);
// Test setting volumes
print("Testing with_volume()...");
// Create a test directory for volume mounting
let test_dir = "rhai_test_nerdctl_volume";
mkdir(test_dir);
container.with_volume(`${test_dir}:/data`);
// Test setting resource limits
print("Testing with_cpu_limit() and with_memory_limit()...");
container.with_cpu_limit("0.5");
container.with_memory_limit("256m");
// 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;
}

View File

@@ -0,0 +1,168 @@
// 02_image_operations.rhai
// Tests for Nerdctl image 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() {
try {
let result = run("which nerdctl");
return result.success;
} catch(err) {
return false;
}
}
// Helper function to check if an image exists
fn image_exists(image_name) {
try {
let result = run(`nerdctl images -q ${image_name}`);
return result.success && result.stdout.trim() != "";
} catch(err) {
return false;
}
}
// Helper function to clean up an image if it exists
fn cleanup_image(image_name) {
if image_exists(image_name) {
try {
run(`nerdctl rmi ${image_name}`);
print(`Cleaned up image: ${image_name}`);
} catch(err) {
print(`Error cleaning up image ${image_name}: ${err}`);
}
}
}
print("=== Testing Nerdctl Image Operations ===");
// Check if nerdctl is available
let nerdctl_available = is_nerdctl_available();
if !nerdctl_available {
print("nerdctl is not available. Skipping Nerdctl tests.");
// Exit gracefully without error
return;
}
print("✓ nerdctl is available");
// Create a temporary directory for testing
let test_dir = "rhai_test_nerdctl";
mkdir(test_dir);
try {
// Test pulling an image
print("Testing nerdctl_image_pull()...");
// Use a small image for testing
let pull_result = nerdctl_image_pull("alpine:latest");
assert_true(pull_result.success, "Image pull should succeed");
print("✓ nerdctl_image_pull(): Image pulled successfully");
// Test listing images
print("Testing nerdctl_images()...");
let images_result = nerdctl_images();
assert_true(images_result.success, "Image listing should succeed");
assert_true(images_result.stdout.contains("alpine"), "Image list should contain alpine");
print("✓ nerdctl_images(): Images listed successfully");
// Test tagging an image
print("Testing nerdctl_image_tag()...");
let tag_result = nerdctl_image_tag("alpine:latest", "rhai_test_image:latest");
assert_true(tag_result.success, "Image tag should succeed");
print("✓ nerdctl_image_tag(): Image tagged successfully");
// Test building an image
print("Testing nerdctl_image_build()...");
// Create a simple Dockerfile
let dockerfile_content = `FROM alpine:latest
RUN echo "Hello from Dockerfile" > /hello.txt
CMD ["cat", "/hello.txt"]
`;
file_write(`${test_dir}/Dockerfile`, dockerfile_content);
// Build the image
let build_result = nerdctl_image_build("rhai_test_build:latest", test_dir);
assert_true(build_result.success, "Image build should succeed");
print("✓ nerdctl_image_build(): Image built successfully");
// Test running a container from the built image
print("Testing container from built image...");
let container_name = "rhai_test_container_from_build";
// Clean up any existing container with the same name
try {
run(`nerdctl stop ${container_name}`);
run(`nerdctl rm ${container_name}`);
} catch(e) {
// Ignore errors during cleanup
}
// Run the container
let run_result = nerdctl_run_with_name("rhai_test_build:latest", container_name);
assert_true(run_result.success, "Container run should succeed");
assert_true(run_result.stdout.contains("Hello from Dockerfile"), "Container output should contain expected text");
print("✓ Container from built image ran successfully");
// Clean up the container
let stop_result = nerdctl_stop(container_name);
assert_true(stop_result.success, "Container stop should succeed");
let remove_result = nerdctl_remove(container_name);
assert_true(remove_result.success, "Container remove should succeed");
print("✓ Cleanup: Container removed");
// Test removing images
print("Testing nerdctl_image_remove()...");
// Remove the tagged image
let remove_tag_result = nerdctl_image_remove("rhai_test_image:latest");
assert_true(remove_tag_result.success, "Image removal should succeed");
print("✓ nerdctl_image_remove(): Tagged image removed successfully");
// Remove the built image
let remove_build_result = nerdctl_image_remove("rhai_test_build:latest");
assert_true(remove_build_result.success, "Image removal should succeed");
print("✓ nerdctl_image_remove(): Built image removed successfully");
print("All image operations tests completed successfully!");
} catch(err) {
print(`Error: ${err}`);
// Clean up in case of error
try {
run("nerdctl stop rhai_test_container_from_build");
run("nerdctl rm rhai_test_container_from_build");
} catch(e) {
// Ignore errors during cleanup
}
try {
cleanup_image("rhai_test_image:latest");
cleanup_image("rhai_test_build:latest");
} catch(e) {
// Ignore errors during cleanup
}
throw err;
} finally {
// Clean up test directory
delete(test_dir);
print("✓ Cleanup: Test directory removed");
}

View File

@@ -0,0 +1,166 @@
// 03_container_builder.rhai
// Tests for Nerdctl Container Builder pattern
// 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() {
try {
let result = run("which nerdctl");
return result.success;
} catch(err) {
return false;
}
}
// Helper function to check if a container exists
fn container_exists(container_name) {
try {
let result = run(`nerdctl ps -a --format "{{.Names}}" | grep -w ${container_name}`);
return result.success;
} catch(err) {
return false;
}
}
// 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}`);
}
}
}
print("=== Testing Nerdctl Container Builder Pattern ===");
// Check if nerdctl is available
let nerdctl_available = is_nerdctl_available();
if !nerdctl_available {
print("nerdctl is not available. Skipping Nerdctl tests.");
// Exit gracefully without error
return;
}
print("✓ nerdctl is available");
// Define test container name
let container_name = "rhai_test_builder";
// Clean up any existing test container
cleanup_container(container_name);
// Create test directories
let work_dir = "rhai_test_nerdctl_work";
let config_dir = "rhai_test_nerdctl_config";
mkdir(work_dir);
mkdir(config_dir);
try {
// Test creating a container from an image with builder pattern
print("Testing nerdctl_container_from_image() with builder pattern...");
// Create a container with a rich set of options using the builder pattern
let container = nerdctl_container_from_image(container_name, "alpine:latest")
.reset() // Reset to default configuration
.with_detach(true)
.with_ports(["8080:80", "9090:90"])
.with_volumes([`${work_dir}:/data`, `${config_dir}:/config`])
.with_envs(#{
"ENV1": "value1",
"ENV2": "value2",
"TEST_MODE": "true"
})
.with_network("bridge")
.with_cpu_limit("0.5")
.with_memory_limit("256m");
// Verify container properties
assert_eq(container.name, container_name, "Container name should match");
assert_eq(container.image, "alpine:latest", "Container image should match");
assert_true(container.detach, "Container detach mode should be true");
// Run the container
print("Testing run() with builder pattern...");
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 environment variables
print("Testing environment variables...");
let env_result = container.exec("env");
assert_true(env_result.success, "Container exec should succeed");
assert_true(env_result.stdout.contains("ENV1=value1"), "Environment variable ENV1 should be set");
assert_true(env_result.stdout.contains("ENV2=value2"), "Environment variable ENV2 should be set");
assert_true(env_result.stdout.contains("TEST_MODE=true"), "Environment variable TEST_MODE should be set");
print("✓ Environment variables set correctly");
// Test volume mounts
print("Testing volume mounts...");
// Create a test file in the work directory
file_write(`${work_dir}/test.txt`, "Hello from host");
// Check if the file is accessible in the container
let volume_result = container.exec("cat /data/test.txt");
assert_true(volume_result.success, "Container exec should succeed");
assert_true(volume_result.stdout.contains("Hello from host"), "Volume mount should work correctly");
print("✓ Volume mounts working correctly");
// Test writing from container to volume
print("Testing writing from container to volume...");
let write_result = container.exec("echo 'Hello from container' > /config/container.txt");
assert_true(write_result.success, "Container exec should succeed");
// Check if the file was created on the host
let host_file_content = file_read(`${config_dir}/container.txt`);
assert_true(host_file_content.contains("Hello from container"), "Container should be able to write to volume");
print("✓ Container can write to volume");
// 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");
print("All container builder pattern tests completed successfully!");
} catch(err) {
print(`Error: ${err}`);
// Clean up in case of error
cleanup_container(container_name);
throw err;
} finally {
// Clean up test directories
delete(work_dir);
delete(config_dir);
print("✓ Cleanup: Test directories removed");
}

View File

@@ -0,0 +1,183 @@
// run_all_tests.rhai
// Runs all Nerdctl module tests
print("=== Running Nerdctl Module Tests ===");
// Custom assert function
fn assert_true(condition, message) {
if !condition {
print(`ASSERTION FAILED: ${message}`);
throw message;
}
}
// Helper function to check if nerdctl is available
fn is_nerdctl_available() {
try {
let result = run("which nerdctl");
return result.success;
} catch(e) {
return false;
}
}
// Helper function to clean up a container if it exists
fn cleanup_container(container_name) {
try {
run(`nerdctl stop ${container_name}`);
run(`nerdctl rm ${container_name}`);
} catch(e) {
// Ignore errors during cleanup
}
}
// Run each test directly
let passed = 0;
let failed = 0;
let skipped = 0;
let total = 0;
// Check if nerdctl is available
let nerdctl_available = is_nerdctl_available();
if !nerdctl_available {
print("nerdctl is not available. Skipping all Nerdctl tests.");
skipped = 3; // Skip all three tests
total = 3;
} else {
// Test 1: Container Operations
print("\n--- Running Container Operations Tests ---");
try {
// Define test container name
let container_name = "rhai_test_container";
// Clean up any existing test container
cleanup_container(container_name);
// Create a new Container
let container = nerdctl_container_new(container_name);
// Set container image
container.with_image("alpine:latest");
// Set detach mode
container.with_detach(true);
// Run the container
let run_result = container.run();
assert_true(run_result.success, "Container run should succeed");
// Execute a command in the container
let exec_result = container.exec("echo 'Hello from container'");
assert_true(exec_result.success, "Container exec should succeed");
// Clean up
container.stop();
container.remove();
print("--- Container Operations Tests completed successfully ---");
passed += 1;
} catch(err) {
print(`!!! Error in Container Operations Tests: ${err}`);
failed += 1;
// Clean up in case of error
cleanup_container("rhai_test_container");
}
total += 1;
// Test 2: Image Operations
print("\n--- Running Image Operations Tests ---");
try {
// Create a temporary directory for testing
let test_dir = "rhai_test_nerdctl";
mkdir(test_dir);
// Pull a small image for testing
let pull_result = nerdctl_image_pull("alpine:latest");
assert_true(pull_result.success, "Image pull should succeed");
// List images
let images_result = nerdctl_images();
assert_true(images_result.success, "Image listing should succeed");
// Clean up
delete(test_dir);
print("--- Image Operations Tests completed successfully ---");
passed += 1;
} catch(err) {
print(`!!! Error in Image Operations Tests: ${err}`);
failed += 1;
// Clean up in case of error
try {
delete("rhai_test_nerdctl");
} catch(e) {
// Ignore errors during cleanup
}
}
total += 1;
// Test 3: Container Builder Pattern
print("\n--- Running Container Builder Pattern Tests ---");
try {
// Define test container name
let container_name = "rhai_test_builder";
// Clean up any existing test container
cleanup_container(container_name);
// Create test directory
let work_dir = "rhai_test_nerdctl_work";
mkdir(work_dir);
// Create a container with builder pattern
let container = nerdctl_container_from_image(container_name, "alpine:latest")
.reset()
.with_detach(true)
.with_volumes([`${work_dir}:/data`]);
// Run the container
let run_result = container.run();
assert_true(run_result.success, "Container run should succeed");
// Clean up
container.stop();
container.remove();
delete(work_dir);
print("--- Container Builder Pattern Tests completed successfully ---");
passed += 1;
} catch(err) {
print(`!!! Error in Container Builder Pattern Tests: ${err}`);
failed += 1;
// Clean up in case of error
cleanup_container("rhai_test_builder");
try {
delete("rhai_test_nerdctl_work");
} catch(e) {
// Ignore errors during cleanup
}
}
total += 1;
}
print("\n=== Test Summary ===");
print(`Passed: ${passed}`);
print(`Failed: ${failed}`);
print(`Skipped: ${skipped}`);
print(`Total: ${total}`);
if failed == 0 {
if skipped > 0 {
print("\n⚠ All tests skipped or passed!");
} else {
print("\n✅ All tests passed!");
}
} else {
print("\n❌ Some tests failed!");
}
// Return the number of failed tests (0 means success)
failed;

View File

@@ -0,0 +1,152 @@
// 01_mount_operations.rhai
// Tests for RFS mount 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 rfs is available
fn is_rfs_available() {
try {
let result = run("which rfs");
return result.success;
} catch(err) {
return false;
}
}
// Helper function to clean up mounts
fn cleanup_mounts() {
try {
rfs_unmount_all();
print("All mounts cleaned up");
} catch(err) {
print(`Error cleaning up mounts: ${err}`);
}
}
print("=== Testing RFS Mount Operations ===");
// Check if rfs is available
let rfs_available = is_rfs_available();
if !rfs_available {
print("rfs is not available. Skipping RFS tests.");
// Exit gracefully without error
return;
}
print("✓ rfs is available");
// Clean up any existing mounts
cleanup_mounts();
// Create test directories
let source_dir = "rhai_test_rfs_source";
let target_dir = "rhai_test_rfs_target";
mkdir(source_dir);
mkdir(target_dir);
// Create a test file in the source directory
let test_file = `${source_dir}/test.txt`;
file_write(test_file, "Hello from RFS test");
try {
// Test mounting a local directory
print("Testing rfs_mount() with local directory...");
let options = #{
"readonly": "true"
};
let mount = rfs_mount(source_dir, target_dir, "local", options);
// Verify mount properties
assert_true(mount.id != "", "Mount ID should not be empty");
assert_eq(mount.source, source_dir, "Mount source should match");
assert_eq(mount.target, target_dir, "Mount target should match");
assert_eq(mount.fs_type, "local", "Mount type should be local");
print(`✓ rfs_mount(): Mounted ${mount.source} to ${mount.target} with ID: ${mount.id}`);
// Test listing mounts
print("Testing rfs_list_mounts()...");
let mounts = rfs_list_mounts();
assert_true(mounts.len() > 0, "There should be at least one mount");
// Find our mount in the list
let found = false;
for m in mounts {
if m.target == target_dir {
found = true;
break;
}
}
assert_true(found, "Our mount should be in the list");
print(`✓ rfs_list_mounts(): Found ${mounts.len()} mounts`);
// Test getting mount info
print("Testing rfs_get_mount_info()...");
let mount_info = rfs_get_mount_info(target_dir);
assert_eq(mount_info.target, target_dir, "Mount info target should match");
assert_eq(mount_info.source, source_dir, "Mount info source should match");
print(`✓ rfs_get_mount_info(): Got info for mount at ${mount_info.target}`);
// Verify the mounted file is accessible
let mounted_file = `${target_dir}/test.txt`;
assert_true(exist(mounted_file), "Mounted file should exist");
let mounted_content = file_read(mounted_file);
assert_eq(mounted_content, "Hello from RFS test", "Mounted file content should match");
print("✓ Mounted file is accessible and content matches");
// Test unmounting a specific mount
print("Testing rfs_unmount()...");
rfs_unmount(target_dir);
// Verify the mount is gone
try {
rfs_get_mount_info(target_dir);
assert_true(false, "Mount should not exist after unmounting");
} catch(err) {
print("✓ rfs_unmount(): Mount successfully unmounted");
}
// Mount again to test unmount_all
print("Testing mounting again for unmount_all...");
let mount2 = rfs_mount(source_dir, target_dir, "local", options);
assert_true(mount2.id != "", "Mount ID should not be empty");
// Test unmounting all mounts
print("Testing rfs_unmount_all()...");
rfs_unmount_all();
// Verify all mounts are gone
let mounts_after = rfs_list_mounts();
assert_true(mounts_after.len() == 0, "There should be no mounts after unmount_all");
print("✓ rfs_unmount_all(): All mounts successfully unmounted");
print("All mount operations tests completed successfully!");
} catch(err) {
print(`Error: ${err}`);
// Clean up in case of error
cleanup_mounts();
throw err;
} finally {
// Clean up test directories
delete(source_dir);
delete(target_dir);
print("✓ Cleanup: Test directories removed");
}

View File

@@ -0,0 +1,117 @@
// 02_filesystem_layer_operations.rhai
// Tests for RFS filesystem layer 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 rfs is available
fn is_rfs_available() {
try {
let result = run("which rfs");
return result.success;
} catch(err) {
return false;
}
}
print("=== Testing RFS Filesystem Layer Operations ===");
// Check if rfs is available
let rfs_available = is_rfs_available();
if !rfs_available {
print("rfs is not available. Skipping RFS tests.");
// Exit gracefully without error
return;
}
print("✓ rfs is available");
// Create test directories
let source_dir = "rhai_test_rfs_source";
let unpack_dir = "rhai_test_rfs_unpack";
mkdir(source_dir);
mkdir(unpack_dir);
// Create test files in the source directory
file_write(`${source_dir}/file1.txt`, "Content of file 1");
file_write(`${source_dir}/file2.txt`, "Content of file 2");
// Create a subdirectory with files
mkdir(`${source_dir}/subdir`);
file_write(`${source_dir}/subdir/file3.txt`, "Content of file 3");
// Output file for the filesystem layer
let output_file = "rhai_test_rfs_layer.fl";
try {
// Test packing a directory
print("Testing rfs_pack()...");
// Use a file store spec for testing
let store_specs = "file:path=.";
rfs_pack(source_dir, output_file, store_specs);
// Verify the output file exists
assert_true(exist(output_file), "Output file should exist");
print(`✓ rfs_pack(): Directory packed to ${output_file}`);
// Test listing contents of the filesystem layer
print("Testing rfs_list_contents()...");
let contents = rfs_list_contents(output_file);
// Verify the contents include our files
assert_true(contents.contains("file1.txt"), "Contents should include file1.txt");
assert_true(contents.contains("file2.txt"), "Contents should include file2.txt");
assert_true(contents.contains("subdir/file3.txt"), "Contents should include subdir/file3.txt");
print("✓ rfs_list_contents(): Layer contents listed successfully");
// Test verifying the filesystem layer
print("Testing rfs_verify()...");
let is_valid = rfs_verify(output_file);
assert_true(is_valid, "Filesystem layer should be valid");
print("✓ rfs_verify(): Layer verified successfully");
// Test unpacking the filesystem layer
print("Testing rfs_unpack()...");
rfs_unpack(output_file, unpack_dir);
// Verify the unpacked files exist and have the correct content
assert_true(exist(`${unpack_dir}/file1.txt`), "Unpacked file1.txt should exist");
assert_true(exist(`${unpack_dir}/file2.txt`), "Unpacked file2.txt should exist");
assert_true(exist(`${unpack_dir}/subdir/file3.txt`), "Unpacked subdir/file3.txt should exist");
let content1 = file_read(`${unpack_dir}/file1.txt`);
let content2 = file_read(`${unpack_dir}/file2.txt`);
let content3 = file_read(`${unpack_dir}/subdir/file3.txt`);
assert_eq(content1, "Content of file 1", "Content of file1.txt should match");
assert_eq(content2, "Content of file 2", "Content of file2.txt should match");
assert_eq(content3, "Content of file 3", "Content of file3.txt should match");
print("✓ rfs_unpack(): Layer unpacked successfully");
print("All filesystem layer operations tests completed successfully!");
} catch(err) {
print(`Error: ${err}`);
throw err;
} finally {
// Clean up test directories and files
delete(source_dir);
delete(unpack_dir);
delete(output_file);
print("✓ Cleanup: Test directories and files removed");
}

View File

@@ -0,0 +1,168 @@
// run_all_tests.rhai
// Runs all RFS module tests
print("=== Running RFS Module Tests ===");
// Custom assert function
fn assert_true(condition, message) {
if !condition {
print(`ASSERTION FAILED: ${message}`);
throw message;
}
}
// Helper function to check if rfs is available
fn is_rfs_available() {
try {
let result = run("which rfs");
return result.success;
} catch(e) {
return false;
}
}
// Helper function to clean up mounts
fn cleanup_mounts() {
try {
rfs_unmount_all();
} catch(e) {
// Ignore errors during cleanup
}
}
// Run each test directly
let passed = 0;
let failed = 0;
let skipped = 0;
let total = 0;
// Check if rfs is available
let rfs_available = is_rfs_available();
if !rfs_available {
print("rfs is not available. Skipping all RFS tests.");
skipped = 2; // Skip both tests
total = 2;
} else {
// Test 1: Mount Operations
print("\n--- Running Mount Operations Tests ---");
try {
// Clean up any existing mounts
cleanup_mounts();
// Create test directories
let source_dir = "rhai_test_rfs_source";
let target_dir = "rhai_test_rfs_target";
mkdir(source_dir);
mkdir(target_dir);
// Create a test file in the source directory
let test_file = `${source_dir}/test.txt`;
file_write(test_file, "Hello from RFS test");
// Mount the directory
let options = #{
"readonly": "true"
};
let mount = rfs_mount(source_dir, target_dir, "local", options);
assert_true(mount.id != "", "Mount ID should not be empty");
// List mounts
let mounts = rfs_list_mounts();
assert_true(mounts.len() > 0, "There should be at least one mount");
// Unmount
rfs_unmount(target_dir);
// Clean up
delete(source_dir);
delete(target_dir);
print("--- Mount Operations Tests completed successfully ---");
passed += 1;
} catch(err) {
print(`!!! Error in Mount Operations Tests: ${err}`);
failed += 1;
// Clean up in case of error
cleanup_mounts();
try {
delete("rhai_test_rfs_source");
delete("rhai_test_rfs_target");
} catch(e) {
// Ignore errors during cleanup
}
}
total += 1;
// Test 2: Filesystem Layer Operations
print("\n--- Running Filesystem Layer Operations Tests ---");
try {
// Create test directories
let source_dir = "rhai_test_rfs_source";
let unpack_dir = "rhai_test_rfs_unpack";
mkdir(source_dir);
mkdir(unpack_dir);
// Create test files in the source directory
file_write(`${source_dir}/file1.txt`, "Content of file 1");
// Output file for the filesystem layer
let output_file = "rhai_test_rfs_layer.fl";
// Pack the directory
let store_specs = "file:path=.";
rfs_pack(source_dir, output_file, store_specs);
// List contents
let contents = rfs_list_contents(output_file);
assert_true(contents.contains("file1.txt"), "Contents should include file1.txt");
// Verify the layer
let is_valid = rfs_verify(output_file);
assert_true(is_valid, "Filesystem layer should be valid");
// Unpack the layer
rfs_unpack(output_file, unpack_dir);
// Clean up
delete(source_dir);
delete(unpack_dir);
delete(output_file);
print("--- Filesystem Layer Operations Tests completed successfully ---");
passed += 1;
} catch(err) {
print(`!!! Error in Filesystem Layer Operations Tests: ${err}`);
failed += 1;
// Clean up in case of error
try {
delete("rhai_test_rfs_source");
delete("rhai_test_rfs_unpack");
delete("rhai_test_rfs_layer.fl");
} catch(e) {
// Ignore errors during cleanup
}
}
total += 1;
}
print("\n=== Test Summary ===");
print(`Passed: ${passed}`);
print(`Failed: ${failed}`);
print(`Skipped: ${skipped}`);
print(`Total: ${total}`);
if failed == 0 {
if skipped > 0 {
print("\n⚠ All tests skipped or passed!");
} else {
print("\n✅ All tests passed!");
}
} else {
print("\n❌ Some tests failed!");
}
// Return the number of failed tests (0 means success)
failed;