mirror of
https://github.com/rustfs/rustfs.git
synced 2026-01-17 09:40:32 +00:00
Merge pull request #430 from rustfs/feat/improve-madmin-module-tests
feat: improve madmin module test coverage - Add comprehensive test ca…
This commit is contained in:
@@ -186,3 +186,501 @@ pub struct MemInfo {
|
||||
pub fn get_mem_info(_addr: &str) -> MemInfo {
|
||||
MemInfo::default()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json;
|
||||
|
||||
#[test]
|
||||
fn test_node_common_creation() {
|
||||
let node = NodeCommon::default();
|
||||
assert!(node.addr.is_empty(), "Default addr should be empty");
|
||||
assert!(node.error.is_none(), "Default error should be None");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_common_with_values() {
|
||||
let node = NodeCommon {
|
||||
addr: "127.0.0.1:9000".to_string(),
|
||||
error: Some("Connection failed".to_string()),
|
||||
};
|
||||
assert_eq!(node.addr, "127.0.0.1:9000");
|
||||
assert_eq!(node.error.unwrap(), "Connection failed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_common_serialization() {
|
||||
let node = NodeCommon {
|
||||
addr: "localhost:8080".to_string(),
|
||||
error: None,
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&node).unwrap();
|
||||
assert!(json.contains("localhost:8080"));
|
||||
assert!(!json.contains("error"), "None error should be skipped in serialization");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_common_deserialization() {
|
||||
let json = r#"{"addr":"test.example.com:9000","error":"Test error"}"#;
|
||||
let node: NodeCommon = serde_json::from_str(json).unwrap();
|
||||
|
||||
assert_eq!(node.addr, "test.example.com:9000");
|
||||
assert_eq!(node.error.unwrap(), "Test error");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cpu_default() {
|
||||
let cpu = Cpu::default();
|
||||
assert!(cpu.vendor_id.is_empty());
|
||||
assert!(cpu.family.is_empty());
|
||||
assert!(cpu.model.is_empty());
|
||||
assert_eq!(cpu.stepping, 0);
|
||||
assert_eq!(cpu.mhz, 0.0);
|
||||
assert_eq!(cpu.cache_size, 0);
|
||||
assert!(cpu.flags.is_empty());
|
||||
assert_eq!(cpu.cores, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cpu_with_values() {
|
||||
let cpu = Cpu {
|
||||
vendor_id: "GenuineIntel".to_string(),
|
||||
family: "6".to_string(),
|
||||
model: "142".to_string(),
|
||||
stepping: 12,
|
||||
physical_id: "0".to_string(),
|
||||
model_name: "Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz".to_string(),
|
||||
mhz: 1800.0,
|
||||
cache_size: 8192,
|
||||
flags: vec!["fpu".to_string(), "vme".to_string(), "de".to_string()],
|
||||
microcode: "0xf0".to_string(),
|
||||
cores: 4,
|
||||
};
|
||||
|
||||
assert_eq!(cpu.vendor_id, "GenuineIntel");
|
||||
assert_eq!(cpu.cores, 4);
|
||||
assert_eq!(cpu.flags.len(), 3);
|
||||
assert!(cpu.flags.contains(&"fpu".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cpu_serialization() {
|
||||
let cpu = Cpu {
|
||||
vendor_id: "AMD".to_string(),
|
||||
model_name: "AMD Ryzen 7".to_string(),
|
||||
cores: 8,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&cpu).unwrap();
|
||||
assert!(json.contains("AMD"));
|
||||
assert!(json.contains("AMD Ryzen 7"));
|
||||
assert!(json.contains("8"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cpu_freq_stats_default() {
|
||||
let stats = CpuFreqStats::default();
|
||||
assert!(stats.name.is_empty());
|
||||
assert!(stats.cpuinfo_current_frequency.is_none());
|
||||
assert!(stats.available_governors.is_empty());
|
||||
assert!(stats.driver.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cpus_structure() {
|
||||
let cpus = Cpus {
|
||||
node_common: NodeCommon {
|
||||
addr: "node1".to_string(),
|
||||
error: None,
|
||||
},
|
||||
cpus: vec![Cpu {
|
||||
vendor_id: "Intel".to_string(),
|
||||
cores: 4,
|
||||
..Default::default()
|
||||
}],
|
||||
cpu_freq_stats: vec![CpuFreqStats {
|
||||
name: "cpu0".to_string(),
|
||||
cpuinfo_current_frequency: Some(2400),
|
||||
..Default::default()
|
||||
}],
|
||||
};
|
||||
|
||||
assert_eq!(cpus.node_common.addr, "node1");
|
||||
assert_eq!(cpus.cpus.len(), 1);
|
||||
assert_eq!(cpus.cpu_freq_stats.len(), 1);
|
||||
assert_eq!(cpus.cpus[0].cores, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_cpus_function() {
|
||||
let cpus = get_cpus();
|
||||
assert!(cpus.node_common.addr.is_empty());
|
||||
assert!(cpus.cpus.is_empty());
|
||||
assert!(cpus.cpu_freq_stats.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partition_default() {
|
||||
let partition = Partition::default();
|
||||
assert!(partition.error.is_empty());
|
||||
assert!(partition.device.is_empty());
|
||||
assert_eq!(partition.space_total, 0);
|
||||
assert_eq!(partition.space_free, 0);
|
||||
assert_eq!(partition.inode_total, 0);
|
||||
assert_eq!(partition.inode_free, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partition_with_values() {
|
||||
let partition = Partition {
|
||||
error: "".to_string(),
|
||||
device: "/dev/sda1".to_string(),
|
||||
model: "Samsung SSD".to_string(),
|
||||
revision: "1.0".to_string(),
|
||||
mountpoint: "/".to_string(),
|
||||
fs_type: "ext4".to_string(),
|
||||
mount_options: "rw,relatime".to_string(),
|
||||
space_total: 1000000000,
|
||||
space_free: 500000000,
|
||||
inode_total: 1000000,
|
||||
inode_free: 800000,
|
||||
};
|
||||
|
||||
assert_eq!(partition.device, "/dev/sda1");
|
||||
assert_eq!(partition.fs_type, "ext4");
|
||||
assert_eq!(partition.space_total, 1000000000);
|
||||
assert_eq!(partition.space_free, 500000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partitions_structure() {
|
||||
let partitions = Partitions {
|
||||
node_common: NodeCommon {
|
||||
addr: "storage-node".to_string(),
|
||||
error: None,
|
||||
},
|
||||
partitions: vec![
|
||||
Partition {
|
||||
device: "/dev/sda1".to_string(),
|
||||
mountpoint: "/".to_string(),
|
||||
space_total: 1000000,
|
||||
space_free: 500000,
|
||||
..Default::default()
|
||||
},
|
||||
Partition {
|
||||
device: "/dev/sdb1".to_string(),
|
||||
mountpoint: "/data".to_string(),
|
||||
space_total: 2000000,
|
||||
space_free: 1500000,
|
||||
..Default::default()
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
assert_eq!(partitions.partitions.len(), 2);
|
||||
assert_eq!(partitions.partitions[0].device, "/dev/sda1");
|
||||
assert_eq!(partitions.partitions[1].mountpoint, "/data");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_partitions_function() {
|
||||
let partitions = get_partitions();
|
||||
assert!(partitions.node_common.addr.is_empty());
|
||||
assert!(partitions.partitions.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_os_info_default() {
|
||||
let os_info = OsInfo::default();
|
||||
assert!(os_info.node_common.addr.is_empty());
|
||||
assert!(os_info.node_common.error.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_os_info_function() {
|
||||
let os_info = get_os_info();
|
||||
assert!(os_info.node_common.addr.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_proc_info_default() {
|
||||
let proc_info = ProcInfo::default();
|
||||
assert_eq!(proc_info.pid, 0);
|
||||
assert!(!proc_info.is_background);
|
||||
assert_eq!(proc_info.cpu_percent, 0.0);
|
||||
assert!(proc_info.children_pids.is_empty());
|
||||
assert!(proc_info.cmd_line.is_empty());
|
||||
assert_eq!(proc_info.num_connections, 0);
|
||||
assert!(!proc_info.is_running);
|
||||
assert_eq!(proc_info.mem_percent, 0.0);
|
||||
assert!(proc_info.name.is_empty());
|
||||
assert_eq!(proc_info.nice, 0);
|
||||
assert_eq!(proc_info.num_fds, 0);
|
||||
assert_eq!(proc_info.num_threads, 0);
|
||||
assert_eq!(proc_info.ppid, 0);
|
||||
assert!(proc_info.status.is_empty());
|
||||
assert_eq!(proc_info.tgid, 0);
|
||||
assert!(proc_info.uids.is_empty());
|
||||
assert!(proc_info.username.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_proc_info_with_values() {
|
||||
let proc_info = ProcInfo {
|
||||
node_common: NodeCommon {
|
||||
addr: "worker-node".to_string(),
|
||||
error: None,
|
||||
},
|
||||
pid: 1234,
|
||||
is_background: true,
|
||||
cpu_percent: 15.5,
|
||||
children_pids: vec![1235, 1236],
|
||||
cmd_line: "rustfs --config /etc/rustfs.conf".to_string(),
|
||||
num_connections: 10,
|
||||
create_time: 1640995200,
|
||||
cwd: "/opt/rustfs".to_string(),
|
||||
exec_path: "/usr/bin/rustfs".to_string(),
|
||||
gids: vec![1000, 1001],
|
||||
is_running: true,
|
||||
mem_percent: 8.2,
|
||||
name: "rustfs".to_string(),
|
||||
nice: 0,
|
||||
num_fds: 25,
|
||||
num_threads: 4,
|
||||
ppid: 1,
|
||||
status: "running".to_string(),
|
||||
tgid: 1234,
|
||||
uids: vec![1000],
|
||||
username: "rustfs".to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(proc_info.pid, 1234);
|
||||
assert!(proc_info.is_background);
|
||||
assert_eq!(proc_info.cpu_percent, 15.5);
|
||||
assert_eq!(proc_info.children_pids.len(), 2);
|
||||
assert_eq!(proc_info.name, "rustfs");
|
||||
assert!(proc_info.is_running);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_proc_info_function() {
|
||||
let proc_info = get_proc_info("127.0.0.1:9000");
|
||||
assert_eq!(proc_info.pid, 0);
|
||||
assert!(!proc_info.is_running);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sys_service_default() {
|
||||
let service = SysService::default();
|
||||
assert!(service.name.is_empty());
|
||||
assert!(service.status.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sys_service_with_values() {
|
||||
let service = SysService {
|
||||
name: "rustfs".to_string(),
|
||||
status: "active".to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(service.name, "rustfs");
|
||||
assert_eq!(service.status, "active");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sys_services_structure() {
|
||||
let services = SysServices {
|
||||
node_common: NodeCommon {
|
||||
addr: "service-node".to_string(),
|
||||
error: None,
|
||||
},
|
||||
services: vec![
|
||||
SysService {
|
||||
name: "rustfs".to_string(),
|
||||
status: "active".to_string(),
|
||||
},
|
||||
SysService {
|
||||
name: "nginx".to_string(),
|
||||
status: "inactive".to_string(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
assert_eq!(services.services.len(), 2);
|
||||
assert_eq!(services.services[0].name, "rustfs");
|
||||
assert_eq!(services.services[1].status, "inactive");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_sys_services_function() {
|
||||
let services = get_sys_services("localhost");
|
||||
assert!(services.node_common.addr.is_empty());
|
||||
assert!(services.services.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sys_config_default() {
|
||||
let config = SysConfig::default();
|
||||
assert!(config.node_common.addr.is_empty());
|
||||
assert!(config.config.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sys_config_with_values() {
|
||||
let mut config_map = HashMap::new();
|
||||
config_map.insert("max_connections".to_string(), "1000".to_string());
|
||||
config_map.insert("timeout".to_string(), "30".to_string());
|
||||
|
||||
let config = SysConfig {
|
||||
node_common: NodeCommon {
|
||||
addr: "config-node".to_string(),
|
||||
error: None,
|
||||
},
|
||||
config: config_map,
|
||||
};
|
||||
|
||||
assert_eq!(config.config.len(), 2);
|
||||
assert_eq!(config.config.get("max_connections").unwrap(), "1000");
|
||||
assert_eq!(config.config.get("timeout").unwrap(), "30");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_sys_config_function() {
|
||||
let config = get_sys_config("192.168.1.100");
|
||||
assert!(config.node_common.addr.is_empty());
|
||||
assert!(config.config.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sys_errors_default() {
|
||||
let errors = SysErrors::default();
|
||||
assert!(errors.node_common.addr.is_empty());
|
||||
assert!(errors.errors.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sys_errors_with_values() {
|
||||
let errors = SysErrors {
|
||||
node_common: NodeCommon {
|
||||
addr: "error-node".to_string(),
|
||||
error: None,
|
||||
},
|
||||
errors: vec![
|
||||
"Connection timeout".to_string(),
|
||||
"Memory allocation failed".to_string(),
|
||||
"Disk full".to_string(),
|
||||
],
|
||||
};
|
||||
|
||||
assert_eq!(errors.errors.len(), 3);
|
||||
assert!(errors.errors.contains(&"Connection timeout".to_string()));
|
||||
assert!(errors.errors.contains(&"Disk full".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_sys_errors_function() {
|
||||
let errors = get_sys_errors("test-node");
|
||||
assert!(errors.node_common.addr.is_empty());
|
||||
assert!(errors.errors.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mem_info_default() {
|
||||
let mem_info = MemInfo::default();
|
||||
assert!(mem_info.node_common.addr.is_empty());
|
||||
assert!(mem_info.total.is_none());
|
||||
assert!(mem_info.used.is_none());
|
||||
assert!(mem_info.free.is_none());
|
||||
assert!(mem_info.available.is_none());
|
||||
assert!(mem_info.shared.is_none());
|
||||
assert!(mem_info.cache.is_none());
|
||||
assert!(mem_info.buffers.is_none());
|
||||
assert!(mem_info.swap_space_total.is_none());
|
||||
assert!(mem_info.swap_space_free.is_none());
|
||||
assert!(mem_info.limit.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mem_info_with_values() {
|
||||
let mem_info = MemInfo {
|
||||
node_common: NodeCommon {
|
||||
addr: "memory-node".to_string(),
|
||||
error: None,
|
||||
},
|
||||
total: Some(16777216000),
|
||||
used: Some(8388608000),
|
||||
free: Some(4194304000),
|
||||
available: Some(12582912000),
|
||||
shared: Some(1048576000),
|
||||
cache: Some(2097152000),
|
||||
buffers: Some(524288000),
|
||||
swap_space_total: Some(4294967296),
|
||||
swap_space_free: Some(2147483648),
|
||||
limit: Some(16777216000),
|
||||
};
|
||||
|
||||
assert_eq!(mem_info.total.unwrap(), 16777216000);
|
||||
assert_eq!(mem_info.used.unwrap(), 8388608000);
|
||||
assert_eq!(mem_info.free.unwrap(), 4194304000);
|
||||
assert_eq!(mem_info.swap_space_total.unwrap(), 4294967296);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mem_info_serialization() {
|
||||
let mem_info = MemInfo {
|
||||
node_common: NodeCommon {
|
||||
addr: "test-node".to_string(),
|
||||
error: None,
|
||||
},
|
||||
total: Some(8000000000),
|
||||
used: Some(4000000000),
|
||||
free: None,
|
||||
available: Some(6000000000),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&mem_info).unwrap();
|
||||
assert!(json.contains("8000000000"));
|
||||
assert!(json.contains("4000000000"));
|
||||
assert!(json.contains("6000000000"));
|
||||
assert!(!json.contains("free"), "None values should be skipped");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_mem_info_function() {
|
||||
let mem_info = get_mem_info("memory-server");
|
||||
assert!(mem_info.node_common.addr.is_empty());
|
||||
assert!(mem_info.total.is_none());
|
||||
assert!(mem_info.used.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_structures_debug_format() {
|
||||
let node = NodeCommon::default();
|
||||
let cpu = Cpu::default();
|
||||
let partition = Partition::default();
|
||||
let proc_info = ProcInfo::default();
|
||||
let service = SysService::default();
|
||||
let mem_info = MemInfo::default();
|
||||
|
||||
// Test that all structures can be formatted with Debug
|
||||
assert!(!format!("{:?}", node).is_empty());
|
||||
assert!(!format!("{:?}", cpu).is_empty());
|
||||
assert!(!format!("{:?}", partition).is_empty());
|
||||
assert!(!format!("{:?}", proc_info).is_empty());
|
||||
assert!(!format!("{:?}", service).is_empty());
|
||||
assert!(!format!("{:?}", mem_info).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_memory_efficiency() {
|
||||
// Test that structures don't use excessive memory
|
||||
assert!(std::mem::size_of::<NodeCommon>() < 1000);
|
||||
assert!(std::mem::size_of::<Cpu>() < 2000);
|
||||
assert!(std::mem::size_of::<Partition>() < 2000);
|
||||
assert!(std::mem::size_of::<MemInfo>() < 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,3 +331,759 @@ pub struct InfoMessage {
|
||||
pub servers: Option<Vec<ServerProperties>>,
|
||||
pub pools: Option<std::collections::HashMap<i32, std::collections::HashMap<i32, ErasureSetInfo>>>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json;
|
||||
use std::collections::HashMap;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
#[test]
|
||||
fn test_item_state_to_string() {
|
||||
assert_eq!(ItemState::Offline.to_string(), ITEM_OFFLINE);
|
||||
assert_eq!(ItemState::Initializing.to_string(), ITEM_INITIALIZING);
|
||||
assert_eq!(ItemState::Online.to_string(), ITEM_ONLINE);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_item_state_from_string_valid() {
|
||||
assert_eq!(ItemState::from_string(ITEM_OFFLINE), Some(ItemState::Offline));
|
||||
assert_eq!(ItemState::from_string(ITEM_INITIALIZING), Some(ItemState::Initializing));
|
||||
assert_eq!(ItemState::from_string(ITEM_ONLINE), Some(ItemState::Online));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_item_state_from_string_invalid() {
|
||||
assert_eq!(ItemState::from_string("invalid"), None);
|
||||
assert_eq!(ItemState::from_string(""), None);
|
||||
assert_eq!(ItemState::from_string("OFFLINE"), None); // Case sensitive
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_disk_metrics_default() {
|
||||
let metrics = DiskMetrics::default();
|
||||
assert!(metrics.last_minute.is_empty());
|
||||
assert!(metrics.api_calls.is_empty());
|
||||
assert_eq!(metrics.total_waiting, 0);
|
||||
assert_eq!(metrics.total_errors_availability, 0);
|
||||
assert_eq!(metrics.total_errors_timeout, 0);
|
||||
assert_eq!(metrics.total_writes, 0);
|
||||
assert_eq!(metrics.total_deletes, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_disk_metrics_with_values() {
|
||||
let mut last_minute = HashMap::new();
|
||||
last_minute.insert("read".to_string(), TimedAction::default());
|
||||
|
||||
let mut api_calls = HashMap::new();
|
||||
api_calls.insert("GET".to_string(), 100);
|
||||
api_calls.insert("PUT".to_string(), 50);
|
||||
|
||||
let metrics = DiskMetrics {
|
||||
last_minute,
|
||||
api_calls,
|
||||
total_waiting: 5,
|
||||
total_errors_availability: 2,
|
||||
total_errors_timeout: 1,
|
||||
total_writes: 1000,
|
||||
total_deletes: 50,
|
||||
};
|
||||
|
||||
assert_eq!(metrics.last_minute.len(), 1);
|
||||
assert_eq!(metrics.api_calls.len(), 2);
|
||||
assert_eq!(metrics.total_waiting, 5);
|
||||
assert_eq!(metrics.total_writes, 1000);
|
||||
assert_eq!(metrics.total_deletes, 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_disk_default() {
|
||||
let disk = Disk::default();
|
||||
assert!(disk.endpoint.is_empty());
|
||||
assert!(!disk.root_disk);
|
||||
assert!(disk.drive_path.is_empty());
|
||||
assert!(!disk.healing);
|
||||
assert!(!disk.scanning);
|
||||
assert!(disk.state.is_empty());
|
||||
assert!(disk.uuid.is_empty());
|
||||
assert_eq!(disk.major, 0);
|
||||
assert_eq!(disk.minor, 0);
|
||||
assert!(disk.model.is_none());
|
||||
assert_eq!(disk.total_space, 0);
|
||||
assert_eq!(disk.used_space, 0);
|
||||
assert_eq!(disk.available_space, 0);
|
||||
assert_eq!(disk.read_throughput, 0.0);
|
||||
assert_eq!(disk.write_throughput, 0.0);
|
||||
assert_eq!(disk.read_latency, 0.0);
|
||||
assert_eq!(disk.write_latency, 0.0);
|
||||
assert_eq!(disk.utilization, 0.0);
|
||||
assert!(disk.metrics.is_none());
|
||||
assert!(disk.heal_info.is_none());
|
||||
assert_eq!(disk.used_inodes, 0);
|
||||
assert_eq!(disk.free_inodes, 0);
|
||||
assert!(!disk.local);
|
||||
assert_eq!(disk.pool_index, 0);
|
||||
assert_eq!(disk.set_index, 0);
|
||||
assert_eq!(disk.disk_index, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_disk_with_values() {
|
||||
let disk = Disk {
|
||||
endpoint: "http://localhost:9000".to_string(),
|
||||
root_disk: true,
|
||||
drive_path: "/data/disk1".to_string(),
|
||||
healing: false,
|
||||
scanning: true,
|
||||
state: "online".to_string(),
|
||||
uuid: "12345678-1234-1234-1234-123456789abc".to_string(),
|
||||
major: 8,
|
||||
minor: 1,
|
||||
model: Some("Samsung SSD 980".to_string()),
|
||||
total_space: 1000000000000,
|
||||
used_space: 500000000000,
|
||||
available_space: 500000000000,
|
||||
read_throughput: 100.5,
|
||||
write_throughput: 80.3,
|
||||
read_latency: 5.2,
|
||||
write_latency: 7.8,
|
||||
utilization: 50.0,
|
||||
metrics: Some(DiskMetrics::default()),
|
||||
heal_info: None,
|
||||
used_inodes: 1000000,
|
||||
free_inodes: 9000000,
|
||||
local: true,
|
||||
pool_index: 0,
|
||||
set_index: 1,
|
||||
disk_index: 2,
|
||||
};
|
||||
|
||||
assert_eq!(disk.endpoint, "http://localhost:9000");
|
||||
assert!(disk.root_disk);
|
||||
assert_eq!(disk.drive_path, "/data/disk1");
|
||||
assert!(disk.scanning);
|
||||
assert_eq!(disk.state, "online");
|
||||
assert_eq!(disk.major, 8);
|
||||
assert_eq!(disk.minor, 1);
|
||||
assert_eq!(disk.model.unwrap(), "Samsung SSD 980");
|
||||
assert_eq!(disk.total_space, 1000000000000);
|
||||
assert_eq!(disk.utilization, 50.0);
|
||||
assert!(disk.metrics.is_some());
|
||||
assert!(disk.local);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_healing_disk_default() {
|
||||
let healing_disk = HealingDisk::default();
|
||||
assert!(healing_disk.id.is_empty());
|
||||
assert!(healing_disk.heal_id.is_empty());
|
||||
assert!(healing_disk.pool_index.is_none());
|
||||
assert!(healing_disk.set_index.is_none());
|
||||
assert!(healing_disk.disk_index.is_none());
|
||||
assert!(healing_disk.endpoint.is_empty());
|
||||
assert!(healing_disk.path.is_empty());
|
||||
assert!(healing_disk.started.is_none());
|
||||
assert!(healing_disk.last_update.is_none());
|
||||
assert_eq!(healing_disk.retry_attempts, 0);
|
||||
assert_eq!(healing_disk.objects_total_count, 0);
|
||||
assert_eq!(healing_disk.objects_total_size, 0);
|
||||
assert_eq!(healing_disk.items_healed, 0);
|
||||
assert_eq!(healing_disk.items_failed, 0);
|
||||
assert_eq!(healing_disk.item_skipped, 0);
|
||||
assert_eq!(healing_disk.bytes_done, 0);
|
||||
assert_eq!(healing_disk.bytes_failed, 0);
|
||||
assert_eq!(healing_disk.bytes_skipped, 0);
|
||||
assert_eq!(healing_disk.objects_healed, 0);
|
||||
assert_eq!(healing_disk.objects_failed, 0);
|
||||
assert!(healing_disk.bucket.is_empty());
|
||||
assert!(healing_disk.object.is_empty());
|
||||
assert!(healing_disk.queue_buckets.is_empty());
|
||||
assert!(healing_disk.healed_buckets.is_empty());
|
||||
assert!(!healing_disk.finished);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_healing_disk_with_values() {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let system_time = std::time::SystemTime::now();
|
||||
|
||||
let healing_disk = HealingDisk {
|
||||
id: "heal-001".to_string(),
|
||||
heal_id: "heal-session-123".to_string(),
|
||||
pool_index: Some(0),
|
||||
set_index: Some(1),
|
||||
disk_index: Some(2),
|
||||
endpoint: "http://node1:9000".to_string(),
|
||||
path: "/data/disk1".to_string(),
|
||||
started: Some(now),
|
||||
last_update: Some(system_time),
|
||||
retry_attempts: 3,
|
||||
objects_total_count: 10000,
|
||||
objects_total_size: 1000000000,
|
||||
items_healed: 8000,
|
||||
items_failed: 100,
|
||||
item_skipped: 50,
|
||||
bytes_done: 800000000,
|
||||
bytes_failed: 10000000,
|
||||
bytes_skipped: 5000000,
|
||||
objects_healed: 7900,
|
||||
objects_failed: 100,
|
||||
bucket: "test-bucket".to_string(),
|
||||
object: "test-object".to_string(),
|
||||
queue_buckets: vec!["bucket1".to_string(), "bucket2".to_string()],
|
||||
healed_buckets: vec!["bucket3".to_string()],
|
||||
finished: false,
|
||||
};
|
||||
|
||||
assert_eq!(healing_disk.id, "heal-001");
|
||||
assert_eq!(healing_disk.heal_id, "heal-session-123");
|
||||
assert_eq!(healing_disk.pool_index.unwrap(), 0);
|
||||
assert_eq!(healing_disk.set_index.unwrap(), 1);
|
||||
assert_eq!(healing_disk.disk_index.unwrap(), 2);
|
||||
assert_eq!(healing_disk.retry_attempts, 3);
|
||||
assert_eq!(healing_disk.objects_total_count, 10000);
|
||||
assert_eq!(healing_disk.items_healed, 8000);
|
||||
assert_eq!(healing_disk.queue_buckets.len(), 2);
|
||||
assert_eq!(healing_disk.healed_buckets.len(), 1);
|
||||
assert!(!healing_disk.finished);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_byte_default() {
|
||||
let backend = BackendByte::default();
|
||||
assert!(matches!(backend, BackendByte::Unknown));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_byte_variants() {
|
||||
let unknown = BackendByte::Unknown;
|
||||
let fs = BackendByte::FS;
|
||||
let erasure = BackendByte::Erasure;
|
||||
|
||||
// Test that all variants can be created
|
||||
assert!(matches!(unknown, BackendByte::Unknown));
|
||||
assert!(matches!(fs, BackendByte::FS));
|
||||
assert!(matches!(erasure, BackendByte::Erasure));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_info_creation() {
|
||||
let storage_info = StorageInfo {
|
||||
disks: vec![
|
||||
Disk {
|
||||
endpoint: "node1:9000".to_string(),
|
||||
state: "online".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
Disk {
|
||||
endpoint: "node2:9000".to_string(),
|
||||
state: "offline".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
],
|
||||
backend: BackendInfo::default(),
|
||||
};
|
||||
|
||||
assert_eq!(storage_info.disks.len(), 2);
|
||||
assert_eq!(storage_info.disks[0].endpoint, "node1:9000");
|
||||
assert_eq!(storage_info.disks[1].state, "offline");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_disks_new() {
|
||||
let backend_disks = BackendDisks::new();
|
||||
assert!(backend_disks.0.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_disks_sum() {
|
||||
let mut backend_disks = BackendDisks::new();
|
||||
backend_disks.0.insert("pool1".to_string(), 4);
|
||||
backend_disks.0.insert("pool2".to_string(), 6);
|
||||
backend_disks.0.insert("pool3".to_string(), 2);
|
||||
|
||||
assert_eq!(backend_disks.sum(), 12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_disks_sum_empty() {
|
||||
let backend_disks = BackendDisks::new();
|
||||
assert_eq!(backend_disks.sum(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_info_default() {
|
||||
let backend_info = BackendInfo::default();
|
||||
assert!(matches!(backend_info.backend_type, BackendByte::Unknown));
|
||||
assert_eq!(backend_info.online_disks.sum(), 0);
|
||||
assert_eq!(backend_info.offline_disks.sum(), 0);
|
||||
assert!(backend_info.standard_sc_data.is_empty());
|
||||
assert!(backend_info.standard_sc_parities.is_empty());
|
||||
assert!(backend_info.standard_sc_parity.is_none());
|
||||
assert!(backend_info.rr_sc_data.is_empty());
|
||||
assert!(backend_info.rr_sc_parities.is_empty());
|
||||
assert!(backend_info.rr_sc_parity.is_none());
|
||||
assert!(backend_info.total_sets.is_empty());
|
||||
assert!(backend_info.drives_per_set.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_info_with_values() {
|
||||
let mut online_disks = BackendDisks::new();
|
||||
online_disks.0.insert("set1".to_string(), 4);
|
||||
online_disks.0.insert("set2".to_string(), 4);
|
||||
|
||||
let mut offline_disks = BackendDisks::new();
|
||||
offline_disks.0.insert("set1".to_string(), 0);
|
||||
offline_disks.0.insert("set2".to_string(), 1);
|
||||
|
||||
let backend_info = BackendInfo {
|
||||
backend_type: BackendByte::Erasure,
|
||||
online_disks,
|
||||
offline_disks,
|
||||
standard_sc_data: vec![4, 4],
|
||||
standard_sc_parities: vec![2, 2],
|
||||
standard_sc_parity: Some(2),
|
||||
rr_sc_data: vec![2, 2],
|
||||
rr_sc_parities: vec![1, 1],
|
||||
rr_sc_parity: Some(1),
|
||||
total_sets: vec![2],
|
||||
drives_per_set: vec![6, 6],
|
||||
};
|
||||
|
||||
assert!(matches!(backend_info.backend_type, BackendByte::Erasure));
|
||||
assert_eq!(backend_info.online_disks.sum(), 8);
|
||||
assert_eq!(backend_info.offline_disks.sum(), 1);
|
||||
assert_eq!(backend_info.standard_sc_data.len(), 2);
|
||||
assert_eq!(backend_info.standard_sc_parity.unwrap(), 2);
|
||||
assert_eq!(backend_info.total_sets.len(), 1);
|
||||
assert_eq!(backend_info.drives_per_set.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mem_stats_default() {
|
||||
let mem_stats = MemStats::default();
|
||||
assert_eq!(mem_stats.alloc, 0);
|
||||
assert_eq!(mem_stats.total_alloc, 0);
|
||||
assert_eq!(mem_stats.mallocs, 0);
|
||||
assert_eq!(mem_stats.frees, 0);
|
||||
assert_eq!(mem_stats.heap_alloc, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mem_stats_with_values() {
|
||||
let mem_stats = MemStats {
|
||||
alloc: 1024000,
|
||||
total_alloc: 5120000,
|
||||
mallocs: 1000,
|
||||
frees: 800,
|
||||
heap_alloc: 2048000,
|
||||
};
|
||||
|
||||
assert_eq!(mem_stats.alloc, 1024000);
|
||||
assert_eq!(mem_stats.total_alloc, 5120000);
|
||||
assert_eq!(mem_stats.mallocs, 1000);
|
||||
assert_eq!(mem_stats.frees, 800);
|
||||
assert_eq!(mem_stats.heap_alloc, 2048000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_properties_default() {
|
||||
let server_props = ServerProperties::default();
|
||||
assert!(server_props.state.is_empty());
|
||||
assert!(server_props.endpoint.is_empty());
|
||||
assert!(server_props.scheme.is_empty());
|
||||
assert_eq!(server_props.uptime, 0);
|
||||
assert!(server_props.version.is_empty());
|
||||
assert!(server_props.commit_id.is_empty());
|
||||
assert!(server_props.network.is_empty());
|
||||
assert!(server_props.disks.is_empty());
|
||||
assert_eq!(server_props.pool_number, 0);
|
||||
assert!(server_props.pool_numbers.is_empty());
|
||||
assert_eq!(server_props.mem_stats.alloc, 0);
|
||||
assert_eq!(server_props.max_procs, 0);
|
||||
assert_eq!(server_props.num_cpu, 0);
|
||||
assert!(server_props.runtime_version.is_empty());
|
||||
assert!(server_props.rustfs_env_vars.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_properties_with_values() {
|
||||
let mut network = HashMap::new();
|
||||
network.insert("interface".to_string(), "eth0".to_string());
|
||||
network.insert("ip".to_string(), "192.168.1.100".to_string());
|
||||
|
||||
let mut env_vars = HashMap::new();
|
||||
env_vars.insert("RUSTFS_ROOT_USER".to_string(), "admin".to_string());
|
||||
env_vars.insert("RUSTFS_ROOT_PASSWORD".to_string(), "password".to_string());
|
||||
|
||||
let server_props = ServerProperties {
|
||||
state: "online".to_string(),
|
||||
endpoint: "http://localhost:9000".to_string(),
|
||||
scheme: "http".to_string(),
|
||||
uptime: 3600,
|
||||
version: "1.0.0".to_string(),
|
||||
commit_id: "abc123def456".to_string(),
|
||||
network,
|
||||
disks: vec![Disk::default()],
|
||||
pool_number: 1,
|
||||
pool_numbers: vec![0, 1],
|
||||
mem_stats: MemStats {
|
||||
alloc: 1024000,
|
||||
total_alloc: 5120000,
|
||||
mallocs: 1000,
|
||||
frees: 800,
|
||||
heap_alloc: 2048000,
|
||||
},
|
||||
max_procs: 8,
|
||||
num_cpu: 4,
|
||||
runtime_version: "1.70.0".to_string(),
|
||||
rustfs_env_vars: env_vars,
|
||||
};
|
||||
|
||||
assert_eq!(server_props.state, "online");
|
||||
assert_eq!(server_props.endpoint, "http://localhost:9000");
|
||||
assert_eq!(server_props.uptime, 3600);
|
||||
assert_eq!(server_props.version, "1.0.0");
|
||||
assert_eq!(server_props.network.len(), 2);
|
||||
assert_eq!(server_props.disks.len(), 1);
|
||||
assert_eq!(server_props.pool_number, 1);
|
||||
assert_eq!(server_props.pool_numbers.len(), 2);
|
||||
assert_eq!(server_props.mem_stats.alloc, 1024000);
|
||||
assert_eq!(server_props.max_procs, 8);
|
||||
assert_eq!(server_props.num_cpu, 4);
|
||||
assert_eq!(server_props.rustfs_env_vars.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_kms_default() {
|
||||
let kms = Kms::default();
|
||||
assert!(kms.status.is_none());
|
||||
assert!(kms.encrypt.is_none());
|
||||
assert!(kms.decrypt.is_none());
|
||||
assert!(kms.endpoint.is_none());
|
||||
assert!(kms.version.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_kms_with_values() {
|
||||
let kms = Kms {
|
||||
status: Some("enabled".to_string()),
|
||||
encrypt: Some("AES256".to_string()),
|
||||
decrypt: Some("AES256".to_string()),
|
||||
endpoint: Some("https://kms.example.com".to_string()),
|
||||
version: Some("1.0".to_string()),
|
||||
};
|
||||
|
||||
assert_eq!(kms.status.unwrap(), "enabled");
|
||||
assert_eq!(kms.encrypt.unwrap(), "AES256");
|
||||
assert_eq!(kms.decrypt.unwrap(), "AES256");
|
||||
assert_eq!(kms.endpoint.unwrap(), "https://kms.example.com");
|
||||
assert_eq!(kms.version.unwrap(), "1.0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ldap_default() {
|
||||
let ldap = Ldap::default();
|
||||
assert!(ldap.status.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ldap_with_values() {
|
||||
let ldap = Ldap {
|
||||
status: Some("enabled".to_string()),
|
||||
};
|
||||
|
||||
assert_eq!(ldap.status.unwrap(), "enabled");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_status_default() {
|
||||
let status = Status::default();
|
||||
assert!(status.status.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_status_with_values() {
|
||||
let status = Status {
|
||||
status: Some("active".to_string()),
|
||||
};
|
||||
|
||||
assert_eq!(status.status.unwrap(), "active");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_services_default() {
|
||||
let services = Services::default();
|
||||
assert!(services.kms.is_none());
|
||||
assert!(services.kms_status.is_none());
|
||||
assert!(services.ldap.is_none());
|
||||
assert!(services.logger.is_none());
|
||||
assert!(services.audit.is_none());
|
||||
assert!(services.notifications.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_services_with_values() {
|
||||
let services = Services {
|
||||
kms: Some(Kms::default()),
|
||||
kms_status: Some(vec![Kms::default()]),
|
||||
ldap: Some(Ldap::default()),
|
||||
logger: Some(vec![HashMap::new()]),
|
||||
audit: Some(vec![HashMap::new()]),
|
||||
notifications: Some(vec![HashMap::new()]),
|
||||
};
|
||||
|
||||
assert!(services.kms.is_some());
|
||||
assert_eq!(services.kms_status.unwrap().len(), 1);
|
||||
assert!(services.ldap.is_some());
|
||||
assert_eq!(services.logger.unwrap().len(), 1);
|
||||
assert_eq!(services.audit.unwrap().len(), 1);
|
||||
assert_eq!(services.notifications.unwrap().len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buckets_default() {
|
||||
let buckets = Buckets::default();
|
||||
assert_eq!(buckets.count, 0);
|
||||
assert!(buckets.error.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buckets_with_values() {
|
||||
let buckets = Buckets {
|
||||
count: 10,
|
||||
error: Some("Access denied".to_string()),
|
||||
};
|
||||
|
||||
assert_eq!(buckets.count, 10);
|
||||
assert_eq!(buckets.error.unwrap(), "Access denied");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_objects_default() {
|
||||
let objects = Objects::default();
|
||||
assert_eq!(objects.count, 0);
|
||||
assert!(objects.error.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_versions_default() {
|
||||
let versions = Versions::default();
|
||||
assert_eq!(versions.count, 0);
|
||||
assert!(versions.error.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_markers_default() {
|
||||
let delete_markers = DeleteMarkers::default();
|
||||
assert_eq!(delete_markers.count, 0);
|
||||
assert!(delete_markers.error.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_usage_default() {
|
||||
let usage = Usage::default();
|
||||
assert_eq!(usage.size, 0);
|
||||
assert!(usage.error.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_erasure_set_info_default() {
|
||||
let erasure_set = ErasureSetInfo::default();
|
||||
assert_eq!(erasure_set.id, 0);
|
||||
assert_eq!(erasure_set.raw_usage, 0);
|
||||
assert_eq!(erasure_set.raw_capacity, 0);
|
||||
assert_eq!(erasure_set.usage, 0);
|
||||
assert_eq!(erasure_set.objects_count, 0);
|
||||
assert_eq!(erasure_set.versions_count, 0);
|
||||
assert_eq!(erasure_set.delete_markers_count, 0);
|
||||
assert_eq!(erasure_set.heal_disks, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_erasure_set_info_with_values() {
|
||||
let erasure_set = ErasureSetInfo {
|
||||
id: 1,
|
||||
raw_usage: 1000000000,
|
||||
raw_capacity: 2000000000,
|
||||
usage: 800000000,
|
||||
objects_count: 10000,
|
||||
versions_count: 15000,
|
||||
delete_markers_count: 500,
|
||||
heal_disks: 2,
|
||||
};
|
||||
|
||||
assert_eq!(erasure_set.id, 1);
|
||||
assert_eq!(erasure_set.raw_usage, 1000000000);
|
||||
assert_eq!(erasure_set.raw_capacity, 2000000000);
|
||||
assert_eq!(erasure_set.usage, 800000000);
|
||||
assert_eq!(erasure_set.objects_count, 10000);
|
||||
assert_eq!(erasure_set.versions_count, 15000);
|
||||
assert_eq!(erasure_set.delete_markers_count, 500);
|
||||
assert_eq!(erasure_set.heal_disks, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_type_default() {
|
||||
let backend_type = BackendType::default();
|
||||
assert!(matches!(backend_type, BackendType::FsType));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_type_variants() {
|
||||
let fs_type = BackendType::FsType;
|
||||
let erasure_type = BackendType::ErasureType;
|
||||
|
||||
assert!(matches!(fs_type, BackendType::FsType));
|
||||
assert!(matches!(erasure_type, BackendType::ErasureType));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fs_backend_creation() {
|
||||
let fs_backend = FSBackend {
|
||||
backend_type: BackendType::FsType,
|
||||
};
|
||||
|
||||
assert!(matches!(fs_backend.backend_type, BackendType::FsType));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_erasure_backend_default() {
|
||||
let erasure_backend = ErasureBackend::default();
|
||||
assert!(matches!(erasure_backend.backend_type, BackendType::FsType));
|
||||
assert_eq!(erasure_backend.online_disks, 0);
|
||||
assert_eq!(erasure_backend.offline_disks, 0);
|
||||
assert!(erasure_backend.standard_sc_parity.is_none());
|
||||
assert!(erasure_backend.rr_sc_parity.is_none());
|
||||
assert!(erasure_backend.total_sets.is_empty());
|
||||
assert!(erasure_backend.drives_per_set.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_erasure_backend_with_values() {
|
||||
let erasure_backend = ErasureBackend {
|
||||
backend_type: BackendType::ErasureType,
|
||||
online_disks: 8,
|
||||
offline_disks: 0,
|
||||
standard_sc_parity: Some(2),
|
||||
rr_sc_parity: Some(1),
|
||||
total_sets: vec![2],
|
||||
drives_per_set: vec![4, 4],
|
||||
};
|
||||
|
||||
assert!(matches!(erasure_backend.backend_type, BackendType::ErasureType));
|
||||
assert_eq!(erasure_backend.online_disks, 8);
|
||||
assert_eq!(erasure_backend.offline_disks, 0);
|
||||
assert_eq!(erasure_backend.standard_sc_parity.unwrap(), 2);
|
||||
assert_eq!(erasure_backend.rr_sc_parity.unwrap(), 1);
|
||||
assert_eq!(erasure_backend.total_sets.len(), 1);
|
||||
assert_eq!(erasure_backend.drives_per_set.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_info_message_creation() {
|
||||
let mut pools = HashMap::new();
|
||||
let mut pool_sets = HashMap::new();
|
||||
pool_sets.insert(0, ErasureSetInfo::default());
|
||||
pools.insert(0, pool_sets);
|
||||
|
||||
let info_message = InfoMessage {
|
||||
mode: Some("distributed".to_string()),
|
||||
domain: Some(vec!["example.com".to_string()]),
|
||||
region: Some("us-east-1".to_string()),
|
||||
sqs_arn: Some(vec!["arn:aws:sqs:us-east-1:123456789012:test-queue".to_string()]),
|
||||
deployment_id: Some("deployment-123".to_string()),
|
||||
buckets: Some(Buckets { count: 5, error: None }),
|
||||
objects: Some(Objects { count: 1000, error: None }),
|
||||
versions: Some(Versions { count: 1200, error: None }),
|
||||
delete_markers: Some(DeleteMarkers { count: 50, error: None }),
|
||||
usage: Some(Usage { size: 1000000000, error: None }),
|
||||
services: Some(Services::default()),
|
||||
backend: Some(ErasureBackend::default()),
|
||||
servers: Some(vec![ServerProperties::default()]),
|
||||
pools: Some(pools),
|
||||
};
|
||||
|
||||
assert_eq!(info_message.mode.unwrap(), "distributed");
|
||||
assert_eq!(info_message.domain.unwrap().len(), 1);
|
||||
assert_eq!(info_message.region.unwrap(), "us-east-1");
|
||||
assert_eq!(info_message.sqs_arn.unwrap().len(), 1);
|
||||
assert_eq!(info_message.deployment_id.unwrap(), "deployment-123");
|
||||
assert_eq!(info_message.buckets.unwrap().count, 5);
|
||||
assert_eq!(info_message.objects.unwrap().count, 1000);
|
||||
assert_eq!(info_message.versions.unwrap().count, 1200);
|
||||
assert_eq!(info_message.delete_markers.unwrap().count, 50);
|
||||
assert_eq!(info_message.usage.unwrap().size, 1000000000);
|
||||
assert!(info_message.services.is_some());
|
||||
assert_eq!(info_message.servers.unwrap().len(), 1);
|
||||
assert_eq!(info_message.pools.unwrap().len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization_deserialization() {
|
||||
let disk = Disk {
|
||||
endpoint: "http://localhost:9000".to_string(),
|
||||
state: "online".to_string(),
|
||||
total_space: 1000000000,
|
||||
used_space: 500000000,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&disk).unwrap();
|
||||
let deserialized: Disk = serde_json::from_str(&json).unwrap();
|
||||
|
||||
assert_eq!(deserialized.endpoint, "http://localhost:9000");
|
||||
assert_eq!(deserialized.state, "online");
|
||||
assert_eq!(deserialized.total_space, 1000000000);
|
||||
assert_eq!(deserialized.used_space, 500000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_debug_format_all_structures() {
|
||||
let item_state = ItemState::Online;
|
||||
let disk_metrics = DiskMetrics::default();
|
||||
let disk = Disk::default();
|
||||
let healing_disk = HealingDisk::default();
|
||||
let backend_byte = BackendByte::default();
|
||||
let storage_info = StorageInfo {
|
||||
disks: vec![],
|
||||
backend: BackendInfo::default(),
|
||||
};
|
||||
let backend_info = BackendInfo::default();
|
||||
let mem_stats = MemStats::default();
|
||||
let server_props = ServerProperties::default();
|
||||
|
||||
// Test that all structures can be formatted with Debug
|
||||
assert!(!format!("{:?}", item_state).is_empty());
|
||||
assert!(!format!("{:?}", disk_metrics).is_empty());
|
||||
assert!(!format!("{:?}", disk).is_empty());
|
||||
assert!(!format!("{:?}", healing_disk).is_empty());
|
||||
assert!(!format!("{:?}", backend_byte).is_empty());
|
||||
assert!(!format!("{:?}", storage_info).is_empty());
|
||||
assert!(!format!("{:?}", backend_info).is_empty());
|
||||
assert!(!format!("{:?}", mem_stats).is_empty());
|
||||
assert!(!format!("{:?}", server_props).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_memory_efficiency() {
|
||||
// Test that structures don't use excessive memory
|
||||
assert!(std::mem::size_of::<ItemState>() < 100);
|
||||
assert!(std::mem::size_of::<BackendByte>() < 100);
|
||||
assert!(std::mem::size_of::<BackendType>() < 100);
|
||||
assert!(std::mem::size_of::<MemStats>() < 1000);
|
||||
assert!(std::mem::size_of::<Buckets>() < 1000);
|
||||
assert!(std::mem::size_of::<Objects>() < 1000);
|
||||
assert!(std::mem::size_of::<Usage>() < 1000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_constants() {
|
||||
assert_eq!(ITEM_OFFLINE, "offline");
|
||||
assert_eq!(ITEM_INITIALIZING, "initializing");
|
||||
assert_eq!(ITEM_ONLINE, "online");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ impl UpdateServiceAccountReq {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AccountInfo {
|
||||
pub account_name: String,
|
||||
pub server: BackendInfo,
|
||||
@@ -233,7 +233,7 @@ pub struct AccountInfo {
|
||||
pub buckets: Vec<BucketAccessInfo>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BucketAccessInfo {
|
||||
pub name: String,
|
||||
pub size: u64,
|
||||
@@ -247,7 +247,7 @@ pub struct BucketAccessInfo {
|
||||
pub access: AccountAccess,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BucketDetails {
|
||||
pub versioning: bool,
|
||||
pub versioning_suspended: bool,
|
||||
@@ -256,8 +256,534 @@ pub struct BucketDetails {
|
||||
// pub tagging: Option<Tagging>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AccountAccess {
|
||||
pub read: bool,
|
||||
pub write: bool,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
#[test]
|
||||
fn test_account_status_default() {
|
||||
let status = AccountStatus::default();
|
||||
assert_eq!(status, AccountStatus::Disabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_status_as_ref() {
|
||||
assert_eq!(AccountStatus::Enabled.as_ref(), "enabled");
|
||||
assert_eq!(AccountStatus::Disabled.as_ref(), "disabled");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_status_try_from_valid() {
|
||||
assert_eq!(AccountStatus::try_from("enabled").unwrap(), AccountStatus::Enabled);
|
||||
assert_eq!(AccountStatus::try_from("disabled").unwrap(), AccountStatus::Disabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_status_try_from_invalid() {
|
||||
let result = AccountStatus::try_from("invalid");
|
||||
assert!(result.is_err());
|
||||
assert!(result.unwrap_err().contains("invalid account status"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_status_serialization() {
|
||||
let enabled = AccountStatus::Enabled;
|
||||
let disabled = AccountStatus::Disabled;
|
||||
|
||||
let enabled_json = serde_json::to_string(&enabled).unwrap();
|
||||
let disabled_json = serde_json::to_string(&disabled).unwrap();
|
||||
|
||||
assert_eq!(enabled_json, "\"enabled\"");
|
||||
assert_eq!(disabled_json, "\"disabled\"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_status_deserialization() {
|
||||
let enabled: AccountStatus = serde_json::from_str("\"enabled\"").unwrap();
|
||||
let disabled: AccountStatus = serde_json::from_str("\"disabled\"").unwrap();
|
||||
|
||||
assert_eq!(enabled, AccountStatus::Enabled);
|
||||
assert_eq!(disabled, AccountStatus::Disabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_auth_type_serialization() {
|
||||
let builtin = UserAuthType::Builtin;
|
||||
let ldap = UserAuthType::Ldap;
|
||||
|
||||
let builtin_json = serde_json::to_string(&builtin).unwrap();
|
||||
let ldap_json = serde_json::to_string(&ldap).unwrap();
|
||||
|
||||
assert_eq!(builtin_json, "\"builtin\"");
|
||||
assert_eq!(ldap_json, "\"ldap\"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_auth_info_creation() {
|
||||
let auth_info = UserAuthInfo {
|
||||
auth_type: UserAuthType::Ldap,
|
||||
auth_server: Some("ldap.example.com".to_string()),
|
||||
auth_server_user_id: Some("user123".to_string()),
|
||||
};
|
||||
|
||||
assert!(matches!(auth_info.auth_type, UserAuthType::Ldap));
|
||||
assert_eq!(auth_info.auth_server.unwrap(), "ldap.example.com");
|
||||
assert_eq!(auth_info.auth_server_user_id.unwrap(), "user123");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_auth_info_serialization() {
|
||||
let auth_info = UserAuthInfo {
|
||||
auth_type: UserAuthType::Builtin,
|
||||
auth_server: None,
|
||||
auth_server_user_id: None,
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&auth_info).unwrap();
|
||||
assert!(json.contains("builtin"));
|
||||
assert!(!json.contains("authServer"), "None fields should be skipped");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_info_default() {
|
||||
let user_info = UserInfo::default();
|
||||
assert!(user_info.auth_info.is_none());
|
||||
assert!(user_info.secret_key.is_none());
|
||||
assert!(user_info.policy_name.is_none());
|
||||
assert_eq!(user_info.status, AccountStatus::Disabled);
|
||||
assert!(user_info.member_of.is_none());
|
||||
assert!(user_info.updated_at.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_info_with_values() {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let user_info = UserInfo {
|
||||
auth_info: Some(UserAuthInfo {
|
||||
auth_type: UserAuthType::Builtin,
|
||||
auth_server: None,
|
||||
auth_server_user_id: None,
|
||||
}),
|
||||
secret_key: Some("secret123".to_string()),
|
||||
policy_name: Some("ReadOnlyAccess".to_string()),
|
||||
status: AccountStatus::Enabled,
|
||||
member_of: Some(vec!["group1".to_string(), "group2".to_string()]),
|
||||
updated_at: Some(now),
|
||||
};
|
||||
|
||||
assert!(user_info.auth_info.is_some());
|
||||
assert_eq!(user_info.secret_key.unwrap(), "secret123");
|
||||
assert_eq!(user_info.policy_name.unwrap(), "ReadOnlyAccess");
|
||||
assert_eq!(user_info.status, AccountStatus::Enabled);
|
||||
assert_eq!(user_info.member_of.unwrap().len(), 2);
|
||||
assert!(user_info.updated_at.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_or_update_user_req_creation() {
|
||||
let req = AddOrUpdateUserReq {
|
||||
secret_key: "newsecret".to_string(),
|
||||
policy: Some("FullAccess".to_string()),
|
||||
status: AccountStatus::Enabled,
|
||||
};
|
||||
|
||||
assert_eq!(req.secret_key, "newsecret");
|
||||
assert_eq!(req.policy.unwrap(), "FullAccess");
|
||||
assert_eq!(req.status, AccountStatus::Enabled);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_service_account_info_creation() {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let service_account = ServiceAccountInfo {
|
||||
parent_user: "admin".to_string(),
|
||||
account_status: "enabled".to_string(),
|
||||
implied_policy: true,
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE".to_string(),
|
||||
name: Some("test-service".to_string()),
|
||||
description: Some("Test service account".to_string()),
|
||||
expiration: Some(now),
|
||||
};
|
||||
|
||||
assert_eq!(service_account.parent_user, "admin");
|
||||
assert_eq!(service_account.account_status, "enabled");
|
||||
assert!(service_account.implied_policy);
|
||||
assert_eq!(service_account.access_key, "AKIAIOSFODNN7EXAMPLE");
|
||||
assert_eq!(service_account.name.unwrap(), "test-service");
|
||||
assert!(service_account.expiration.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_service_accounts_resp_creation() {
|
||||
let resp = ListServiceAccountsResp {
|
||||
accounts: vec![
|
||||
ServiceAccountInfo {
|
||||
parent_user: "user1".to_string(),
|
||||
account_status: "enabled".to_string(),
|
||||
implied_policy: false,
|
||||
access_key: "KEY1".to_string(),
|
||||
name: Some("service1".to_string()),
|
||||
description: None,
|
||||
expiration: None,
|
||||
},
|
||||
ServiceAccountInfo {
|
||||
parent_user: "user2".to_string(),
|
||||
account_status: "disabled".to_string(),
|
||||
implied_policy: true,
|
||||
access_key: "KEY2".to_string(),
|
||||
name: Some("service2".to_string()),
|
||||
description: Some("Second service".to_string()),
|
||||
expiration: None,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
assert_eq!(resp.accounts.len(), 2);
|
||||
assert_eq!(resp.accounts[0].parent_user, "user1");
|
||||
assert_eq!(resp.accounts[1].account_status, "disabled");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_service_account_req_validate_success() {
|
||||
let req = AddServiceAccountReq {
|
||||
policy: Some("ReadOnlyAccess".to_string()),
|
||||
target_user: Some("testuser".to_string()),
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE".to_string(),
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY".to_string(),
|
||||
name: Some("test-service".to_string()),
|
||||
description: Some("Test service account".to_string()),
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
let result = req.validate();
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_service_account_req_validate_empty_access_key() {
|
||||
let req = AddServiceAccountReq {
|
||||
policy: None,
|
||||
target_user: None,
|
||||
access_key: "".to_string(),
|
||||
secret_key: "secret".to_string(),
|
||||
name: Some("test".to_string()),
|
||||
description: None,
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
let result = req.validate();
|
||||
assert!(result.is_err());
|
||||
assert!(result.unwrap_err().contains("accessKey is empty"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_service_account_req_validate_empty_secret_key() {
|
||||
let req = AddServiceAccountReq {
|
||||
policy: None,
|
||||
target_user: None,
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE".to_string(),
|
||||
secret_key: "".to_string(),
|
||||
name: Some("test".to_string()),
|
||||
description: None,
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
let result = req.validate();
|
||||
assert!(result.is_err());
|
||||
assert!(result.unwrap_err().contains("secretKey is empty"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_service_account_req_validate_empty_name() {
|
||||
let req = AddServiceAccountReq {
|
||||
policy: None,
|
||||
target_user: None,
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE".to_string(),
|
||||
secret_key: "secret".to_string(),
|
||||
name: None,
|
||||
description: None,
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
let result = req.validate();
|
||||
assert!(result.is_err());
|
||||
assert!(result.unwrap_err().contains("name is empty"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_credentials_serialization() {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let credentials = Credentials {
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE",
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
||||
session_token: Some("session123"),
|
||||
expiration: Some(now),
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&credentials).unwrap();
|
||||
assert!(json.contains("AKIAIOSFODNN7EXAMPLE"));
|
||||
assert!(json.contains("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"));
|
||||
assert!(json.contains("session123"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_credentials_without_optional_fields() {
|
||||
let credentials = Credentials {
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE",
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
||||
session_token: None,
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&credentials).unwrap();
|
||||
assert!(json.contains("AKIAIOSFODNN7EXAMPLE"));
|
||||
assert!(!json.contains("sessionToken"), "None fields should be skipped");
|
||||
assert!(!json.contains("expiration"), "None fields should be skipped");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_service_account_resp_creation() {
|
||||
let credentials = Credentials {
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE",
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
||||
session_token: None,
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
let resp = AddServiceAccountResp { credentials };
|
||||
|
||||
assert_eq!(resp.credentials.access_key, "AKIAIOSFODNN7EXAMPLE");
|
||||
assert_eq!(resp.credentials.secret_key, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_info_service_account_resp_creation() {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let resp = InfoServiceAccountResp {
|
||||
parent_user: "admin".to_string(),
|
||||
account_status: "enabled".to_string(),
|
||||
implied_policy: true,
|
||||
policy: Some("ReadOnlyAccess".to_string()),
|
||||
name: Some("test-service".to_string()),
|
||||
description: Some("Test service account".to_string()),
|
||||
expiration: Some(now),
|
||||
};
|
||||
|
||||
assert_eq!(resp.parent_user, "admin");
|
||||
assert_eq!(resp.account_status, "enabled");
|
||||
assert!(resp.implied_policy);
|
||||
assert_eq!(resp.policy.unwrap(), "ReadOnlyAccess");
|
||||
assert_eq!(resp.name.unwrap(), "test-service");
|
||||
assert!(resp.expiration.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_service_account_req_validate() {
|
||||
let req = UpdateServiceAccountReq {
|
||||
new_policy: Some("FullAccess".to_string()),
|
||||
new_secret_key: Some("newsecret".to_string()),
|
||||
new_status: Some("enabled".to_string()),
|
||||
new_name: Some("updated-service".to_string()),
|
||||
new_description: Some("Updated description".to_string()),
|
||||
new_expiration: None,
|
||||
};
|
||||
|
||||
let result = req.validate();
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_info_creation() {
|
||||
use crate::BackendInfo;
|
||||
|
||||
let account_info = AccountInfo {
|
||||
account_name: "testuser".to_string(),
|
||||
server: BackendInfo::default(),
|
||||
policy: serde_json::json!({"Version": "2012-10-17"}),
|
||||
buckets: vec![],
|
||||
};
|
||||
|
||||
assert_eq!(account_info.account_name, "testuser");
|
||||
assert!(account_info.buckets.is_empty());
|
||||
assert!(account_info.policy.is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bucket_access_info_creation() {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let mut sizes_histogram = HashMap::new();
|
||||
sizes_histogram.insert("small".to_string(), 100);
|
||||
sizes_histogram.insert("large".to_string(), 50);
|
||||
|
||||
let mut versions_histogram = HashMap::new();
|
||||
versions_histogram.insert("v1".to_string(), 80);
|
||||
versions_histogram.insert("v2".to_string(), 70);
|
||||
|
||||
let mut prefix_usage = HashMap::new();
|
||||
prefix_usage.insert("logs/".to_string(), 1000000);
|
||||
prefix_usage.insert("data/".to_string(), 5000000);
|
||||
|
||||
let bucket_info = BucketAccessInfo {
|
||||
name: "test-bucket".to_string(),
|
||||
size: 6000000,
|
||||
objects: 150,
|
||||
object_sizes_histogram: sizes_histogram,
|
||||
object_versions_histogram: versions_histogram,
|
||||
details: Some(BucketDetails {
|
||||
versioning: true,
|
||||
versioning_suspended: false,
|
||||
locking: true,
|
||||
replication: false,
|
||||
}),
|
||||
prefix_usage,
|
||||
created: Some(now),
|
||||
access: AccountAccess {
|
||||
read: true,
|
||||
write: false,
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(bucket_info.name, "test-bucket");
|
||||
assert_eq!(bucket_info.size, 6000000);
|
||||
assert_eq!(bucket_info.objects, 150);
|
||||
assert_eq!(bucket_info.object_sizes_histogram.len(), 2);
|
||||
assert_eq!(bucket_info.object_versions_histogram.len(), 2);
|
||||
assert!(bucket_info.details.is_some());
|
||||
assert_eq!(bucket_info.prefix_usage.len(), 2);
|
||||
assert!(bucket_info.created.is_some());
|
||||
assert!(bucket_info.access.read);
|
||||
assert!(!bucket_info.access.write);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bucket_details_creation() {
|
||||
let details = BucketDetails {
|
||||
versioning: true,
|
||||
versioning_suspended: false,
|
||||
locking: true,
|
||||
replication: true,
|
||||
};
|
||||
|
||||
assert!(details.versioning);
|
||||
assert!(!details.versioning_suspended);
|
||||
assert!(details.locking);
|
||||
assert!(details.replication);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_account_access_creation() {
|
||||
let read_only = AccountAccess {
|
||||
read: true,
|
||||
write: false,
|
||||
};
|
||||
|
||||
let full_access = AccountAccess {
|
||||
read: true,
|
||||
write: true,
|
||||
};
|
||||
|
||||
let no_access = AccountAccess {
|
||||
read: false,
|
||||
write: false,
|
||||
};
|
||||
|
||||
assert!(read_only.read && !read_only.write);
|
||||
assert!(full_access.read && full_access.write);
|
||||
assert!(!no_access.read && !no_access.write);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization_deserialization_roundtrip() {
|
||||
let user_info = UserInfo {
|
||||
auth_info: Some(UserAuthInfo {
|
||||
auth_type: UserAuthType::Ldap,
|
||||
auth_server: Some("ldap.example.com".to_string()),
|
||||
auth_server_user_id: Some("user123".to_string()),
|
||||
}),
|
||||
secret_key: Some("secret123".to_string()),
|
||||
policy_name: Some("ReadOnlyAccess".to_string()),
|
||||
status: AccountStatus::Enabled,
|
||||
member_of: Some(vec!["group1".to_string()]),
|
||||
updated_at: None,
|
||||
};
|
||||
|
||||
let json = serde_json::to_string(&user_info).unwrap();
|
||||
let deserialized: UserInfo = serde_json::from_str(&json).unwrap();
|
||||
|
||||
assert_eq!(deserialized.secret_key.unwrap(), "secret123");
|
||||
assert_eq!(deserialized.policy_name.unwrap(), "ReadOnlyAccess");
|
||||
assert_eq!(deserialized.status, AccountStatus::Enabled);
|
||||
assert_eq!(deserialized.member_of.unwrap().len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_debug_format_all_structures() {
|
||||
let account_status = AccountStatus::Enabled;
|
||||
let user_auth_type = UserAuthType::Builtin;
|
||||
let user_info = UserInfo::default();
|
||||
let service_account = ServiceAccountInfo {
|
||||
parent_user: "test".to_string(),
|
||||
account_status: "enabled".to_string(),
|
||||
implied_policy: false,
|
||||
access_key: "key".to_string(),
|
||||
name: None,
|
||||
description: None,
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
// Test that all structures can be formatted with Debug
|
||||
assert!(!format!("{:?}", account_status).is_empty());
|
||||
assert!(!format!("{:?}", user_auth_type).is_empty());
|
||||
assert!(!format!("{:?}", user_info).is_empty());
|
||||
assert!(!format!("{:?}", service_account).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_memory_efficiency() {
|
||||
// Test that structures don't use excessive memory
|
||||
assert!(std::mem::size_of::<AccountStatus>() < 100);
|
||||
assert!(std::mem::size_of::<UserAuthType>() < 100);
|
||||
assert!(std::mem::size_of::<UserInfo>() < 2000);
|
||||
assert!(std::mem::size_of::<ServiceAccountInfo>() < 2000);
|
||||
assert!(std::mem::size_of::<AccountAccess>() < 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edge_cases() {
|
||||
// Test empty strings and edge cases
|
||||
let req = AddServiceAccountReq {
|
||||
policy: Some("".to_string()),
|
||||
target_user: Some("".to_string()),
|
||||
access_key: "valid_key".to_string(),
|
||||
secret_key: "valid_secret".to_string(),
|
||||
name: Some("valid_name".to_string()),
|
||||
description: Some("".to_string()),
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
// Should still validate successfully with empty optional strings
|
||||
assert!(req.validate().is_ok());
|
||||
|
||||
// Test very long strings
|
||||
let long_string = "a".repeat(1000);
|
||||
let long_req = AddServiceAccountReq {
|
||||
policy: Some(long_string.clone()),
|
||||
target_user: Some(long_string.clone()),
|
||||
access_key: long_string.clone(),
|
||||
secret_key: long_string.clone(),
|
||||
name: Some(long_string.clone()),
|
||||
description: Some(long_string),
|
||||
expiration: None,
|
||||
};
|
||||
|
||||
assert!(long_req.validate().is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user