import pytest from napalm_redfish.parsers import ( parse_action_info, parse_power_state, parse_reset_action, parse_system, ) SYSTEM = "/redfish/v1/Systems/437XR1138R2" def test_system_facts(rackmount): s = parse_system(rackmount(SYSTEM)) assert s["id"] == "437XR1138R2" assert s["name"] == "WebFrontEnd483" assert s["manufacturer"] == "Contoso" assert s["model"] == "3500" assert s["serial_number"] == "437XR1138R2" assert s["uuid"] == "38947555-7742-3448-3784-823347823834" assert s["hostname"] == "web483" assert s["sku"] == "8675309" assert s["part_number"] == "224071-J23" assert s["asset_tag"] == "Chicago-45Z-2381" assert s["bios_version"] == "P79 v1.45 (12/06/2017)" assert s["system_type"] == "Physical" assert s["power_state"] == "On" assert s["state"] == "Enabled" assert s["health"] == "OK" assert s["processor_count"] == 2 assert s["processor_model"] == "Multi-Core Intel(R) Xeon(R) processor 7xxx Series" assert s["memory_gib"] == 96 def test_system_links(rackmount): links = parse_system(rackmount(SYSTEM))["links"] assert links["Processors"] == SYSTEM + "/Processors" assert links["Memory"] == SYSTEM + "/Memory" assert links["SimpleStorage"] == SYSTEM + "/SimpleStorage" assert links["EthernetInterfaces"] == SYSTEM + "/EthernetInterfaces" assert links["LogServices"] == SYSTEM + "/LogServices" assert "Storage" not in links s = parse_system(rackmount(SYSTEM)) assert s["chassis"] == ["/redfish/v1/Chassis/1U"] assert s["managed_by"] == ["/redfish/v1/Managers/BMC"] def test_system_placeholders_and_blanks_are_none(): # Supermicro boards report the DMI defaults the board vendor never filled in. s = parse_system( { "Id": "1", "Manufacturer": "Supermicro", "Model": "X10DRL-i", "SerialNumber": "0123456789", "SKU": "To Be Filled By O.E.M.", "HostName": "", "UUID": " ", "PartNumber": "Default string", } ) assert s["manufacturer"] == "Supermicro" assert s["model"] == "X10DRL-i" assert s["serial_number"] is None assert s["sku"] is None assert s["hostname"] is None assert s["uuid"] is None assert s["part_number"] is None assert s["processor_count"] is None assert s["memory_gib"] is None assert s["links"] == {} assert s["chassis"] == [] def test_power_state(rackmount): assert parse_power_state(rackmount(SYSTEM)) == "On" @pytest.mark.parametrize("value", ["On", "Off", "PoweringOn", "PoweringOff", "Paused"]) def test_power_state_values(value): assert parse_power_state({"PowerState": value}) == value def test_power_state_missing(): assert parse_power_state({}) is None assert parse_power_state({"PowerState": None}) is None def test_reset_action_inline_allowable_values(rackmount): reset = parse_reset_action(rackmount(SYSTEM)) assert reset["target"] == SYSTEM + "/Actions/ComputerSystem.Reset" assert reset["allowed"] == [ "On", "ForceOff", "GracefulShutdown", "GracefulRestart", "ForceRestart", "Nmi", "ForceOn", "PushPowerButton", "FullPowerCycle", ] assert reset["action_info"] is None def test_reset_action_with_action_info(telemetry): reset = parse_reset_action(telemetry("/redfish/v1/Systems/1")) assert reset["target"] == "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset" # Values live in the ActionInfo resource, not inline: unknown until that is read. assert reset["allowed"] is None assert reset["action_info"] == "/redfish/v1/Systems/1/ResetActionInfo" def test_action_info(telemetry): allowed = parse_action_info(telemetry("/redfish/v1/Systems/1/ResetActionInfo")) assert allowed == [ "On", "ForceOff", "GracefulShutdown", "GracefulRestart", "ForceRestart", "Nmi", "ForceOn", "PushPowerButton", ] def test_action_info_other_parameter(): info = { "Parameters": [ {"Name": "ResetType", "AllowableValues": ["On"]}, {"Name": "Delay", "AllowableValues": ["0", "5"]}, ] } assert parse_action_info(info, "Delay") == ["0", "5"] assert parse_action_info(info, "Missing") is None assert parse_action_info({}) is None def test_reset_action_manager(rackmount): reset = parse_reset_action(rackmount("/redfish/v1/Managers/BMC"), "#Manager.Reset") assert reset["target"] == "/redfish/v1/Managers/BMC/Actions/Manager.Reset" assert reset["allowed"] == ["ForceRestart", "GracefulRestart"] def test_reset_action_missing(): assert parse_reset_action({}) == {"target": None, "allowed": None, "action_info": None} # Reset advertised without allowable values: allowed stays unknown, not empty. reset = parse_reset_action({"Actions": {"#ComputerSystem.Reset": {"target": "/x"}}}) assert reset == {"target": "/x", "allowed": None, "action_info": None}