use rufish::*;
use rufish::registry::*;
use rufish::bios_config::*;
use serde_json::json;
#[test]
fn test_parse_bios_registry_basic() {
let registry = json!({
"RegistryEntries": {
"Attributes": [
{
"AttributeName": "BootMode",
"DisplayName": "Boot Mode",
"HelpText": "Select UEFI or Legacy boot mode",
"Type": "Enumeration",
"ReadOnly": false,
"MenuPath": "Boot",
"Value": [
{"ValueName": "Uefi", "ValueDisplayName": "UEFI Mode"},
{"ValueName": "LegacyBios", "ValueDisplayName": "Legacy BIOS"}
]
},
{
"AttributeName": "HyperThreading",
"DisplayName": "Hyper-Threading",
"HelpText": "Enable or disable HT",
"Type": "Enumeration",
"ReadOnly": false,
"MenuPath": "Processor",
"Value": [
{"ValueName": "Enabled"},
{"ValueName": "Disabled"}
]
}
]
}
});
let current = json!({"BootMode": "Uefi", "HyperThreading": "Enabled"});
let pending = json!({"BootMode": "LegacyBios", "HyperThreading": "Enabled"});
let attrs = parse_bios_registry(®istry, Some(¤t), Some(&pending));
assert_eq!(attrs.len(), 2);
let boot = &attrs[0];
assert_eq!(boot.name, "BootMode");
assert_eq!(boot.display_name, "Boot Mode");
assert_eq!(boot.attr_type, AttrType::Enumeration);
assert_eq!(boot.current_value, Some(json!("Uefi")));
assert_eq!(boot.pending_value, Some(json!("LegacyBios")));
assert_eq!(boot.group, Some("Boot".to_string()));
assert!(!boot.read_only);
let allowed = boot.allowed_values.as_ref().unwrap();
assert_eq!(allowed.len(), 2);
assert_eq!(allowed[0].value, "Uefi");
assert_eq!(allowed[0].display_name, Some("UEFI Mode".to_string()));
}
#[test]
fn test_parse_bios_registry_integer() {
let registry = json!({
"RegistryEntries": {
"Attributes": [{
"AttributeName": "NumCores",
"DisplayName": "Active Cores",
"HelpText": "Number of active cores per CPU",
"Type": "Integer",
"LowerBound": 1,
"UpperBound": 128,
"ReadOnly": false
}]
}
});
let current = json!({"NumCores": 64});
let attrs = parse_bios_registry(®istry, Some(¤t), None);
assert_eq!(attrs.len(), 1);
assert_eq!(attrs[0].attr_type, AttrType::Integer);
assert_eq!(attrs[0].lower_bound, Some(1));
assert_eq!(attrs[0].upper_bound, Some(128));
assert_eq!(attrs[0].current_value, Some(json!(64)));
assert_eq!(attrs[0].pending_value, None);
}
#[test]
fn test_parse_bios_registry_string() {
let registry = json!({
"RegistryEntries": {
"Attributes": [{
"AttributeName": "AssetTag",
"DisplayName": "Asset Tag",
"HelpText": "System asset tag",
"Type": "String",
"MinLength": 0,
"MaxLength": 64,
"ReadOnly": false
}]
}
});
let attrs = parse_bios_registry(®istry, None, None);
assert_eq!(attrs[0].attr_type, AttrType::String);
assert_eq!(attrs[0].min_length, Some(0));
assert_eq!(attrs[0].max_length, Some(64));
}
#[test]
fn test_parse_bios_registry_readonly_hidden() {
let registry = json!({
"RegistryEntries": {
"Attributes": [{
"AttributeName": "BiosVersion",
"DisplayName": "BIOS Version",
"Type": "String",
"ReadOnly": true,
"Hidden": true
}]
}
});
let attrs = parse_bios_registry(®istry, None, None);
assert!(attrs[0].read_only);
assert!(attrs[0].hidden);
}
#[test]
fn test_parse_bios_registry_empty() {
let registry = json!({"RegistryEntries": {"Attributes": []}});
let attrs = parse_bios_registry(®istry, None, None);
assert!(attrs.is_empty());
}
#[test]
fn test_parse_bios_registry_missing_entries() {
let registry = json!({"something": "else"});
let attrs = parse_bios_registry(®istry, None, None);
assert!(attrs.is_empty());
}
#[test]
fn test_parse_message_registry() {
let registry = json!({
"Id": "Base.1.0",
"Name": "Base Message Registry",
"Description": "Base messages for Redfish",
"RegistryVersion": "1.0.0",
"OwningEntity": "DMTF",
"Messages": {
"Success": {
"Description": "Operation completed successfully",
"Message": "Successfully completed request.",
"Severity": "OK",
"NumberOfArgs": 0,
"Resolution": "None"
},
"GeneralError": {
"Description": "A general error occurred",
"Message": "A general error has occurred. See Resolution for details.",
"Severity": "Critical",
"NumberOfArgs": 0,
"Resolution": "Check the BMC logs."
}
}
});
let (info, messages) = parse_message_registry(®istry);
assert_eq!(info.registry_id, "Base.1.0");
assert_eq!(info.name, "Base Message Registry");
assert_eq!(info.registry_version, Some("1.0.0".to_string()));
assert_eq!(messages.len(), 2);
let success = messages.iter().find(|m| m.message_id == "Success").unwrap();
assert_eq!(success.severity, Some("OK".to_string()));
assert_eq!(success.number_of_args, Some(0));
}
#[test]
fn test_bios_config_diff_identical() {
let config = BiosConfig {
source: None,
attributes: [("BootMode".into(), json!("Uefi"))].into_iter().collect(),
};
let diff = config.diff(&config);
assert!(diff.changed.is_empty());
assert!(diff.only_in_source.is_empty());
assert!(diff.only_in_target.is_empty());
}
#[test]
fn test_bios_config_diff_changed() {
let a = BiosConfig {
source: None,
attributes: [
("BootMode".into(), json!("Uefi")),
("HT".into(), json!("Enabled")),
].into_iter().collect(),
};
let b = BiosConfig {
source: None,
attributes: [
("BootMode".into(), json!("Legacy")),
("HT".into(), json!("Enabled")),
].into_iter().collect(),
};
let diff = a.diff(&b);
assert_eq!(diff.changed.len(), 1);
assert!(diff.changed.contains_key("BootMode"));
assert!(diff.only_in_source.is_empty());
assert!(diff.only_in_target.is_empty());
}
#[test]
fn test_bios_config_diff_missing() {
let a = BiosConfig {
source: None,
attributes: [
("A".into(), json!("1")),
("B".into(), json!("2")),
].into_iter().collect(),
};
let b = BiosConfig {
source: None,
attributes: [
("B".into(), json!("2")),
("C".into(), json!("3")),
].into_iter().collect(),
};
let diff = a.diff(&b);
assert_eq!(diff.only_in_source.len(), 1);
assert!(diff.only_in_source.contains_key("A"));
assert_eq!(diff.only_in_target.len(), 1);
assert!(diff.only_in_target.contains_key("C"));
}
#[test]
fn test_bios_config_json_roundtrip() {
let config = BiosConfig {
source: Some(BiosConfigSource {
host: Some("https://10.0.0.1".into()),
system_id: Some("1".into()),
model: Some("PowerEdge R750".into()),
bios_version: Some("2.1.0".into()),
exported_at: Some("2025-01-01T00:00:00Z".into()),
}),
attributes: [
("BootMode".into(), json!("Uefi")),
("NumCores".into(), json!(32)),
].into_iter().collect(),
};
let json_str = config.to_json().unwrap();
let restored = BiosConfig::from_json(&json_str).unwrap();
assert_eq!(restored.attributes.len(), 2);
assert_eq!(restored.attributes["BootMode"], json!("Uefi"));
assert_eq!(restored.source.unwrap().model, Some("PowerEdge R750".into()));
}
#[test]
fn test_bios_config_filter() {
let config = BiosConfig {
source: None,
attributes: [
("A".into(), json!("1")),
("B".into(), json!("2")),
("C".into(), json!("3")),
].into_iter().collect(),
};
let filtered = config.filter(&["A", "C"]);
assert_eq!(filtered.attributes.len(), 2);
assert!(filtered.attributes.contains_key("A"));
assert!(filtered.attributes.contains_key("C"));
assert!(!filtered.attributes.contains_key("B"));
}
#[test]
fn test_health_status_from_str() {
assert_eq!(HealthStatus::from_str_opt(Some("OK")), HealthStatus::OK);
assert_eq!(HealthStatus::from_str_opt(Some("Warning")), HealthStatus::Warning);
assert_eq!(HealthStatus::from_str_opt(Some("Critical")), HealthStatus::Critical);
assert_eq!(HealthStatus::from_str_opt(None), HealthStatus::Unknown);
assert_eq!(HealthStatus::from_str_opt(Some("garbage")), HealthStatus::Unknown);
}
#[test]
fn test_health_status_worse() {
assert_eq!(HealthStatus::OK.worse(HealthStatus::OK), HealthStatus::OK);
assert_eq!(HealthStatus::OK.worse(HealthStatus::Warning), HealthStatus::Warning);
assert_eq!(HealthStatus::OK.worse(HealthStatus::Critical), HealthStatus::Critical);
assert_eq!(HealthStatus::Warning.worse(HealthStatus::OK), HealthStatus::Warning);
assert_eq!(HealthStatus::Warning.worse(HealthStatus::Critical), HealthStatus::Critical);
assert_eq!(HealthStatus::Critical.worse(HealthStatus::OK), HealthStatus::Critical);
assert_eq!(HealthStatus::Unknown.worse(HealthStatus::OK), HealthStatus::OK);
}
#[test]
fn test_pool_add_remove() {
let mut pool = RedfishPool::new(5);
pool.add("10.0.0.1", "admin", "pass").unwrap();
pool.add("10.0.0.2", "admin", "pass").unwrap();
assert_eq!(pool.hosts().len(), 2);
pool.remove("10.0.0.1");
assert_eq!(pool.hosts().len(), 1);
assert!(pool.get("10.0.0.2").is_some());
assert!(pool.get("10.0.0.1").is_none());
}
#[test]
fn test_client_builder_basic() {
let client = RedfishClient::new("10.0.0.1", "admin", "password").unwrap();
assert_eq!(client.session_token(), None);
assert_eq!(client.session_uri(), None);
}
#[test]
fn test_client_builder_with_session() {
let client = RedfishClient::builder("10.0.0.1")
.credentials("admin", "pass")
.session("my-token", "/redfish/v1/Sessions/1")
.build()
.unwrap();
assert_eq!(client.session_token(), Some("my-token"));
assert_eq!(client.session_uri(), Some("/redfish/v1/Sessions/1"));
}
#[test]
fn test_client_builder_https_prefix() {
let client = RedfishClient::new("https://10.0.0.1", "admin", "pass").unwrap();
assert_eq!(client.session_token(), None);
}
#[test]
fn test_status_deserialize() {
let json = json!({"State": "Enabled", "Health": "OK", "HealthRollup": "OK"});
let status: Status = serde_json::from_value(json).unwrap();
assert_eq!(status.state, Some("Enabled".to_string()));
assert_eq!(status.health, Some("OK".to_string()));
}
#[test]
fn test_collection_deserialize() {
let json = json!({
"@odata.id": "/redfish/v1/Systems",
"Name": "Computer System Collection",
"Members@odata.count": 2,
"Members": [
{"@odata.id": "/redfish/v1/Systems/1"},
{"@odata.id": "/redfish/v1/Systems/2"}
]
});
let col: Collection = serde_json::from_value(json).unwrap();
assert_eq!(col.members_count, Some(2));
assert_eq!(col.members.as_ref().unwrap().len(), 2);
}
#[test]
fn test_bios_deserialize() {
let json = json!({
"@odata.id": "/redfish/v1/Systems/1/Bios",
"Id": "Bios",
"Name": "BIOS Configuration",
"Attributes": {
"BootMode": "Uefi",
"NumCores": 32
}
});
let bios: Bios = serde_json::from_value(json).unwrap();
assert_eq!(bios.id, Some("Bios".to_string()));
assert!(bios.attributes.is_some());
}
#[test]
fn test_computer_system_deserialize() {
let json = json!({
"@odata.id": "/redfish/v1/Systems/1",
"Id": "1",
"Name": "System",
"Manufacturer": "Dell",
"Model": "PowerEdge R750",
"PowerState": "On",
"BiosVersion": "2.1.0",
"Status": {"State": "Enabled", "Health": "OK"}
});
let sys: ComputerSystem = serde_json::from_value(json).unwrap();
assert_eq!(sys.model, Some("PowerEdge R750".to_string()));
assert_eq!(sys.power_state, Some("On".to_string()));
}