Pure functions for ServiceRoot, ComputerSystem (facts, power state, reset action and ActionInfo), Processors, Memory, Storage/Drives/SimpleStorage, Chassis Thermal and Power as well as ThermalSubsystem/PowerSubsystem/Sensors (with environment_sources to pick whichever exists), Manager, EthernetInterfaces, ManagerNetworkProtocol, accounts, firmware inventory and log services/entries.
130 lines
4.8 KiB
Python
130 lines
4.8 KiB
Python
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}
|