Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run
- Add sal-virt package to the workspace members - Update MONOREPO_CONVERSION_PLAN.md to reflect the completion of sal-process and sal-virt packages - Update src/lib.rs to include sal-virt - Update src/postgresclient to use sal-virt instead of local virt module - Update tests to use sal-virt
354 lines
12 KiB
Rust
354 lines
12 KiB
Rust
use sal_virt::rfs::{MountType, RfsBuilder, RfsError, StoreSpec};
|
|
|
|
/// Tests RFS builder creation and property validation
|
|
///
|
|
/// This test verifies that:
|
|
/// - Builders are created with correct initial state
|
|
/// - Properties are accessible and correct
|
|
/// - Initial state is properly set
|
|
///
|
|
/// No external dependencies required - tests pure Rust logic
|
|
#[test]
|
|
fn test_rfs_builder_creation_and_properties() {
|
|
let builder = RfsBuilder::new("/source/path", "/target/path", MountType::Local);
|
|
|
|
// Validate builder properties are correctly set
|
|
assert_eq!(builder.source(), "/source/path");
|
|
assert_eq!(builder.target(), "/target/path");
|
|
assert!(matches!(builder.mount_type(), MountType::Local));
|
|
assert!(builder.options().is_empty());
|
|
assert!(!builder.debug());
|
|
}
|
|
|
|
/// Tests mount type behavior and string conversion
|
|
///
|
|
/// This test verifies that:
|
|
/// - Each mount type is properly stored and accessible
|
|
/// - Mount types convert to correct string representations
|
|
/// - Custom mount types preserve their values
|
|
/// - Builders correctly store mount type information
|
|
#[test]
|
|
fn test_mount_type_behavior_and_serialization() {
|
|
// Test each mount type's specific behavior
|
|
let test_cases = vec![
|
|
(MountType::Local, "local", "/local/source", "/local/target"),
|
|
(
|
|
MountType::SSH,
|
|
"ssh",
|
|
"user@host:/remote/path",
|
|
"/ssh/target",
|
|
),
|
|
(MountType::S3, "s3", "s3://bucket/key", "/s3/target"),
|
|
(
|
|
MountType::WebDAV,
|
|
"webdav",
|
|
"https://webdav.example.com/path",
|
|
"/webdav/target",
|
|
),
|
|
(
|
|
MountType::Custom("fuse".to_string()),
|
|
"fuse",
|
|
"fuse://source",
|
|
"/fuse/target",
|
|
),
|
|
];
|
|
|
|
for (mount_type, expected_str, source, target) in test_cases {
|
|
// Test string representation
|
|
assert_eq!(mount_type.to_string(), expected_str);
|
|
|
|
// Test that mount type affects builder behavior correctly
|
|
let builder = RfsBuilder::new(source, target, mount_type.clone());
|
|
assert_eq!(builder.source(), source);
|
|
assert_eq!(builder.target(), target);
|
|
|
|
// Verify mount type is stored correctly
|
|
match (&mount_type, builder.mount_type()) {
|
|
(MountType::Local, MountType::Local) => {}
|
|
(MountType::SSH, MountType::SSH) => {}
|
|
(MountType::S3, MountType::S3) => {}
|
|
(MountType::WebDAV, MountType::WebDAV) => {}
|
|
(MountType::Custom(expected), MountType::Custom(actual)) => {
|
|
assert_eq!(expected, actual);
|
|
}
|
|
_ => assert!(
|
|
false,
|
|
"Mount type mismatch: expected {:?}, got {:?}",
|
|
mount_type,
|
|
builder.mount_type()
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Tests RFS builder option handling and method chaining
|
|
///
|
|
/// This test verifies that:
|
|
/// - Options are properly stored and accessible
|
|
/// - Method chaining works correctly
|
|
/// - Multiple options can be added
|
|
/// - Option values are preserved correctly
|
|
#[test]
|
|
fn test_rfs_builder_option_handling() {
|
|
let builder = RfsBuilder::new("/source", "/target", MountType::Local)
|
|
.with_option("read_only", "true")
|
|
.with_option("uid", "1000")
|
|
.with_option("gid", "1000");
|
|
|
|
// Verify options are stored correctly
|
|
assert_eq!(builder.options().len(), 3);
|
|
assert_eq!(
|
|
builder.options().get("read_only"),
|
|
Some(&"true".to_string())
|
|
);
|
|
assert_eq!(builder.options().get("uid"), Some(&"1000".to_string()));
|
|
assert_eq!(builder.options().get("gid"), Some(&"1000".to_string()));
|
|
|
|
// Verify other properties are preserved
|
|
assert_eq!(builder.source(), "/source");
|
|
assert_eq!(builder.target(), "/target");
|
|
assert!(matches!(builder.mount_type(), MountType::Local));
|
|
}
|
|
|
|
/// Tests StoreSpec creation and string serialization
|
|
///
|
|
/// This test verifies that:
|
|
/// - StoreSpec objects are created with correct type
|
|
/// - Options are properly stored and accessible
|
|
/// - String serialization works correctly
|
|
/// - Method chaining preserves all data
|
|
#[test]
|
|
fn test_store_spec_creation_and_serialization() {
|
|
// Test file store specification
|
|
let file_spec = StoreSpec::new("file").with_option("path", "/path/to/store");
|
|
assert_eq!(file_spec.spec_type, "file");
|
|
assert_eq!(file_spec.options.len(), 1);
|
|
assert_eq!(
|
|
file_spec.options.get("path"),
|
|
Some(&"/path/to/store".to_string())
|
|
);
|
|
assert_eq!(file_spec.to_string(), "file:path=/path/to/store");
|
|
|
|
// Test S3 store specification with multiple options
|
|
let s3_spec = StoreSpec::new("s3")
|
|
.with_option("bucket", "my-bucket")
|
|
.with_option("region", "us-east-1");
|
|
assert_eq!(s3_spec.spec_type, "s3");
|
|
assert_eq!(s3_spec.options.len(), 2);
|
|
assert_eq!(
|
|
s3_spec.options.get("bucket"),
|
|
Some(&"my-bucket".to_string())
|
|
);
|
|
assert_eq!(
|
|
s3_spec.options.get("region"),
|
|
Some(&"us-east-1".to_string())
|
|
);
|
|
|
|
// String representation should contain both options (order may vary)
|
|
let s3_string = s3_spec.to_string();
|
|
assert!(s3_string.starts_with("s3:"));
|
|
assert!(s3_string.contains("bucket=my-bucket"));
|
|
assert!(s3_string.contains("region=us-east-1"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_rfs_error_types() {
|
|
// Test that our error types work correctly
|
|
let error = RfsError::CommandFailed("Test error".to_string());
|
|
assert!(matches!(error, RfsError::CommandFailed(_)));
|
|
|
|
let error_msg = format!("{}", error);
|
|
assert!(error_msg.contains("Test error"));
|
|
}
|
|
|
|
/// Tests MountType string conversion and round-trip behavior
|
|
///
|
|
/// This test verifies that:
|
|
/// - MountType to_string() produces correct values
|
|
/// - MountType from_string() correctly parses values
|
|
/// - Round-trip conversion preserves data
|
|
/// - Debug formatting works without panicking
|
|
#[test]
|
|
fn test_mount_type_string_conversion() {
|
|
// Test standard mount types
|
|
let test_cases = vec![
|
|
(MountType::Local, "local"),
|
|
(MountType::SSH, "ssh"),
|
|
(MountType::S3, "s3"),
|
|
(MountType::WebDAV, "webdav"),
|
|
];
|
|
|
|
for (mount_type, expected_string) in test_cases {
|
|
// Test to_string conversion
|
|
assert_eq!(mount_type.to_string(), expected_string);
|
|
|
|
// Test round-trip conversion
|
|
let parsed = MountType::from_string(expected_string);
|
|
assert_eq!(format!("{:?}", mount_type), format!("{:?}", parsed));
|
|
|
|
// Test debug formatting doesn't panic
|
|
let debug_str = format!("{:?}", mount_type);
|
|
assert!(!debug_str.is_empty());
|
|
}
|
|
|
|
// Test custom mount type
|
|
let custom = MountType::Custom("myfs".to_string());
|
|
assert_eq!(custom.to_string(), "myfs");
|
|
let parsed_custom = MountType::from_string("myfs");
|
|
if let MountType::Custom(value) = parsed_custom {
|
|
assert_eq!(value, "myfs");
|
|
} else {
|
|
assert!(false, "Expected Custom mount type, got {:?}", parsed_custom);
|
|
}
|
|
}
|
|
|
|
/// Tests PackBuilder creation and configuration
|
|
///
|
|
/// This test verifies that:
|
|
/// - PackBuilder is created with correct initial state
|
|
/// - Store specifications are properly stored
|
|
/// - Debug mode can be set and retrieved
|
|
/// - Method chaining works correctly
|
|
#[test]
|
|
fn test_pack_builder_creation_and_configuration() {
|
|
use sal_virt::rfs::PackBuilder;
|
|
|
|
// Test creating a pack builder with store specs
|
|
let specs = vec![
|
|
StoreSpec::new("file").with_option("path", "/tmp/store"),
|
|
StoreSpec::new("s3").with_option("bucket", "test-bucket"),
|
|
];
|
|
|
|
let builder = PackBuilder::new("/source/dir", "/output/file")
|
|
.with_store_specs(specs.clone())
|
|
.with_debug(true);
|
|
|
|
// Verify builder properties
|
|
assert_eq!(builder.directory(), "/source/dir");
|
|
assert_eq!(builder.output(), "/output/file");
|
|
assert_eq!(builder.store_specs().len(), 2);
|
|
assert!(builder.debug());
|
|
|
|
// Verify store specs are correctly stored
|
|
assert_eq!(builder.store_specs()[0].spec_type, "file");
|
|
assert_eq!(builder.store_specs()[1].spec_type, "s3");
|
|
assert_eq!(
|
|
builder.store_specs()[0].options.get("path"),
|
|
Some(&"/tmp/store".to_string())
|
|
);
|
|
assert_eq!(
|
|
builder.store_specs()[1].options.get("bucket"),
|
|
Some(&"test-bucket".to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_rfs_functions_availability() {
|
|
// Test that RFS functions are available (even if they fail due to missing RFS binary)
|
|
use sal_virt::rfs::{list_mounts, unmount_all};
|
|
|
|
// These functions should exist and be callable
|
|
// They will likely fail in test environment due to missing RFS binary, but that's expected
|
|
let list_result = list_mounts();
|
|
let unmount_result = unmount_all();
|
|
|
|
// We expect these to fail in test environment, so we just check they're callable
|
|
match list_result {
|
|
Ok(_) => println!("RFS is available - list_mounts succeeded"),
|
|
Err(RfsError::CommandFailed(_)) => {
|
|
println!("RFS not available - expected in test environment")
|
|
}
|
|
Err(e) => println!("RFS error (expected): {:?}", e),
|
|
}
|
|
|
|
match unmount_result {
|
|
Ok(_) => println!("RFS is available - unmount_all succeeded"),
|
|
Err(RfsError::CommandFailed(_)) => {
|
|
println!("RFS not available - expected in test environment")
|
|
}
|
|
Err(e) => println!("RFS error (expected): {:?}", e),
|
|
}
|
|
|
|
// Test passes if functions are callable and return proper Result types
|
|
}
|
|
|
|
#[test]
|
|
fn test_pack_operations_availability() {
|
|
// Test that pack operations are available
|
|
use sal_virt::rfs::{list_contents, pack_directory, unpack, verify};
|
|
|
|
let specs = vec![StoreSpec::new("file").with_option("path", "/tmp/test")];
|
|
|
|
// These functions should exist and be callable
|
|
let pack_result = pack_directory("/nonexistent", "/tmp/test.pack", &specs);
|
|
let unpack_result = unpack("/tmp/test.pack", "/tmp/unpack");
|
|
let list_result = list_contents("/tmp/test.pack");
|
|
let verify_result = verify("/tmp/test.pack");
|
|
|
|
// We expect these to fail in test environment, so we just check they're callable
|
|
match pack_result {
|
|
Ok(_) => println!("RFS pack succeeded"),
|
|
Err(_) => println!("RFS pack failed (expected in test environment)"),
|
|
}
|
|
|
|
match unpack_result {
|
|
Ok(_) => println!("RFS unpack succeeded"),
|
|
Err(_) => println!("RFS unpack failed (expected in test environment)"),
|
|
}
|
|
|
|
match list_result {
|
|
Ok(_) => println!("RFS list_contents succeeded"),
|
|
Err(_) => println!("RFS list_contents failed (expected in test environment)"),
|
|
}
|
|
|
|
match verify_result {
|
|
Ok(_) => println!("RFS verify succeeded"),
|
|
Err(_) => println!("RFS verify failed (expected in test environment)"),
|
|
}
|
|
|
|
// Test passes if all pack operations are callable and return proper Result types
|
|
}
|
|
|
|
/// Tests RFS builder debug mode and advanced chaining
|
|
///
|
|
/// This test verifies that:
|
|
/// - Debug mode can be set and retrieved
|
|
/// - Builder chaining preserves all properties
|
|
/// - Multiple options can be added in sequence
|
|
/// - Builder state is immutable (each call returns new instance)
|
|
#[test]
|
|
fn test_rfs_builder_debug_and_chaining() {
|
|
let base_builder = RfsBuilder::new("/src", "/dst", MountType::SSH);
|
|
|
|
// Test debug mode
|
|
let debug_builder = base_builder.clone().with_debug(true);
|
|
assert!(debug_builder.debug());
|
|
assert!(!base_builder.debug()); // Original should be unchanged
|
|
|
|
// Test complex chaining
|
|
let complex_builder = base_builder
|
|
.with_option("port", "2222")
|
|
.with_option("user", "testuser")
|
|
.with_debug(true)
|
|
.with_option("timeout", "30");
|
|
|
|
// Verify all properties are preserved
|
|
assert_eq!(complex_builder.source(), "/src");
|
|
assert_eq!(complex_builder.target(), "/dst");
|
|
assert!(matches!(complex_builder.mount_type(), MountType::SSH));
|
|
assert!(complex_builder.debug());
|
|
assert_eq!(complex_builder.options().len(), 3);
|
|
assert_eq!(
|
|
complex_builder.options().get("port"),
|
|
Some(&"2222".to_string())
|
|
);
|
|
assert_eq!(
|
|
complex_builder.options().get("user"),
|
|
Some(&"testuser".to_string())
|
|
);
|
|
assert_eq!(
|
|
complex_builder.options().get("timeout"),
|
|
Some(&"30".to_string())
|
|
);
|
|
}
|