Files
napalm-redfish/tests/test_x10_redfish.py
T
Christian Manivong adf152ee12 fix: read a Supermicro X10 with only the OOB license over Redfish (0.3.1)
First run against real hardware over Redfish: an X10DRL-i (BMC 3.91) with
SFT-OOB-LIC. Its Redfish tree is recorded under
tests/fixtures/supermicro-x10drl-i-3.91/redfish, scrubbed.

- A resource refused for want of a further license (403 OemLicenseNotPassed)
  no longer fails the getter. Storage then falls back to SimpleStorage. The
  firmware list falls back to the BMC and BIOS versions when UpdateService
  is withheld.
- get_device_warnings reports bmc_license_partial with the licenses and the
  withheld parts (drives, firmware inventory).
- A placeholder system model ("Super Server") is replaced by the board
  (PartNumber, else the chassis model).
2026-10-17 09:32:09 +02:00

92 lines
3.2 KiB
Python

"""RedfishDriver against a recording of a real Supermicro X10DRL-i (BMC 3.91, Redfish 1.0.1).
Recorded 2026-10-17 with an SFT-OOB-LIC license only: the service root and most resources
answer, but ``Systems/1/Storage`` and ``UpdateService`` want the DCMS license as well (403,
``OemLicenseNotPassed``). Serial numbers, UUIDs, MACs, addresses, the host name and the SNMP
communities are scrubbed. ``STATUS.json`` lists the paths that did not answer 200; their
files hold the error body the BMC sent.
"""
import json
import pytest
from napalm_device_types import models
from napalm_redfish import RedfishDriver
from tests.conftest import BASE_URL, FIXTURES, MockupServer
MOCKUP = "supermicro-x10drl-i-3.91/redfish"
REFUSED = json.loads((FIXTURES / MOCKUP / "STATUS.json").read_text())
@pytest.fixture
def x10(http):
server = MockupServer(http, MOCKUP)
for path, status in REFUSED.items():
body = json.loads((FIXTURES / MOCKUP / path[len("/redfish/v1/"):] / "index.json")
.read_text())
server.override("GET", path, status, body)
return server
@pytest.fixture
def driver(x10):
d = RedfishDriver(BASE_URL.removeprefix("https://"), "netork", "secret",
optional_args={"verify_ssl": False})
d.open()
yield d
d.close()
def test_the_facts_name_the_board_not_super_server(driver):
facts = driver.get_facts()
assert facts["vendor"] == "Supermicro"
# Systems/1 says "Super Server"; the board is its PartNumber and the chassis model.
assert facts["model"] == "X10DRL-i"
assert facts["os_version"] == "3.91"
assert facts["serial_number"] == "ZM000S000001"
def test_the_inventory_survives_the_storage_it_may_not_read(driver):
inv = driver.get_hardware_inventory()
assert set(inv) == set(models.HardwareInventoryDict.__annotations__)
assert inv["model"] == "X10DRL-i"
assert inv["system_uuid"] == "00000000-0000-0000-0000-00005e00534c"
assert len(inv["cpus"]) == 2
assert len(inv["memory"]) == 8
assert inv["drives"] == []
def test_the_firmware_comes_from_the_manager_and_the_system_without_updateservice(driver):
assert driver.get_firmware_inventory() == [
{"name": "BMC", "version": "3.91", "updateable": None},
{"name": "BIOS", "version": "3.1c", "updateable": None},
]
def test_the_missing_license_is_named_with_what_it_withholds(driver):
assert driver.get_device_warnings() == [{
"code": "bmc_license_partial",
"meta": {"licenses": "DCMS", "parts": ["drives", "firmware inventory"]},
}]
def test_the_power_actions_are_the_ones_the_bmc_advertises(driver):
assert driver.get_power_state() == {
"state": "On",
"actions": ["GracefulShutdown", "ForceOff", "GracefulRestart", "ForceRestart"],
}
def test_the_protocols_report_ipmi_over_lan_on(driver):
protocols = driver.get_management_protocols()
assert protocols["ipmi"] == {"enabled": True, "port": 623}
assert protocols["https"] == {"enabled": True, "port": 443}
def test_the_sensors_and_the_event_log_read(driver):
env = driver.get_environment()
assert len(env["temperature"]) == 19
assert len(env["fans"]) == 4
assert isinstance(driver.get_event_log(limit=5), list)