From 8876b9c1dabc9850e55db9d8fe6ec4476296abd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Arta=C4=8D?= Date: Mon, 15 Jul 2019 15:46:33 +0200 Subject: [PATCH 1/7] Add Redfish unit tests Added unit tests for Redfish system. These unit tests employ `unittest.mock`, which is a Python 3 feature only. --- requirements.txt | 2 +- tests/test_redfish.py | 246 +++++++++++++++++++++++++++++++++++ wrapanapi/systems/redfish.py | 5 +- 3 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 tests/test_redfish.py diff --git a/requirements.txt b/requirements.txt index 7d00e51b..f5b0faec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,7 +26,7 @@ python-novaclient==7.1.2 python-heatclient pyvcloud==19.1.2 py3winrm==0.0.1 -redfish-client==0.1.0 +redfish-client==0.2.1 requests six tzlocal diff --git a/tests/test_redfish.py b/tests/test_redfish.py new file mode 100644 index 00000000..57b11586 --- /dev/null +++ b/tests/test_redfish.py @@ -0,0 +1,246 @@ +# coding: utf-8 +# Unit tests for the Redfish API +from unittest import mock, TestCase + +from redfish_client.root import Root +from wrapanapi.exceptions import InvalidValueException +from wrapanapi.entities import ServerState +from wrapanapi.systems import RedfishSystem +from wrapanapi.systems.redfish import RedfishChassis, RedfishRack, RedfishServer + + +@mock.patch("redfish_client.connect") +class TestRedfishSystemSetup: + def test_connect_non_ssl(self, mock_connector): + RedfishSystem("dummy", "user", "pass", "Non-SSL", "8000") + mock_connector.assert_called_with("http://dummy:8000/", "user", "pass") + + def test_connect_ssl(self, mock_connector): + RedfishSystem("dummy", "user", "pass", "SSL", "443") + mock_connector.assert_called_with("https://dummy:443/", "user", "pass") + + +@mock.patch("redfish_client.Connector") +class TestRedfishSystem(TestCase): + def mock_redfish_system(self, mock_connector, data): + def mock_get(url): + res = mock.Mock() + res.status = 200 + res.json = data.get(url, {}) + return res + + mock_connector.get.side_effect = mock_get + api_client = Root(mock_connector) + + rf = RedfishSystem("dummy", "user", "pass", "Non-SSL", "8000", + api_client=api_client) + return rf + + def test_find_resource(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/BlankResource": { + "@odata.id": "id" + } + }) + resource = rf.find("/redfish/v1/BlankResource") + self.assertEqual(resource.raw, {"@odata.id": "id"}) + + def test_get_server(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Systems/System-1-2-1-1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", + } + }) + rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") + self.assertEqual(type(rf_server), RedfishServer) + + def test_server_simple_properties(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Systems/System-1-2-1-1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", + "Description": "A server", + "Id": "System-1-2-1-1", + "Manufacturer": "Dell Inc.", + "Name": "System", + "PowerState": "On", + "SerialNumber": "945hjf0927mf", + } + }) + rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") + self.assertEqual(rf_server.name, "Dell Inc. System (945hjf0927mf)") + self.assertEqual(rf_server.description, "A server") + self.assertEqual(rf_server.state, "On") + self.assertEqual(rf_server._identifying_attrs, + {"odata_id": "/redfish/v1/Systems/System-1-2-1-1"}) + self.assertEqual(rf_server.uuid(), "System-1-2-1-1") + + def test_server_complex_properties(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Systems/System-1-2-1-1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", + "Description": "A server", + "Id": "System-1-2-1-1", + "Manufacturer": "Dell Inc.", + "MemorySummary": { + "TotalSystemMemoryGiB": 32, + }, + "Name": "System", + "PowerState": "On", + "Processors": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors" + }, + "SerialNumber": "945hjf0927mf", + }, + "/redfish/v1/Systems/System-1-2-1-1/Processors": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors", + "Members": [{ + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1" + }], + }, + "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1", + "TotalCores": 20, + } + }) + rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") + self.assertEqual(rf_server.server_cores, 20) + self.assertEqual(rf_server.server_memory, 32768) + self.assertEqual(rf_server.state, "On") + self.assertEqual(rf_server._get_state(), ServerState.ON) + self.assertTrue(rf_server.is_on) + self.assertFalse(rf_server.is_off) + self.assertFalse(rf_server.is_powering_on) + self.assertFalse(rf_server.is_powering_off) + + def test_server_power_states(self, mock_connector): + # string, + # is_on, is_off, is_powering_on, is_powering_off + test_data = { + "On": + [True, False, False, False, ServerState.ON], # noqa: E241 + "Off": + [False, True, False, False, ServerState.OFF], # noqa: E241 + "PoweringOn": + [False, False, True, False, ServerState.POWERING_ON], # noqa: E241 + "PoweringOff": + [False, False, False, True, ServerState.POWERING_OFF], # noqa: E241 + } + + for str_state, states in test_data.items(): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Systems/System-1-2-1-1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", + "PowerState": str_state, + } + }) + rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") + self.assertEqual(rf_server.is_on, states[0]) + self.assertEqual(rf_server.is_off, states[1]) + self.assertEqual(rf_server.is_powering_on, states[2]) + self.assertEqual(rf_server.is_powering_off, states[3]) + self.assertEqual(rf_server._get_state(), states[4]) + + def test_server_name_no_sn(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Systems/System-1-2-1-1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", + "Id": "System-1-2-1-1", + "Manufacturer": "Dell Inc.", + "Name": "System", + } + }) + rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") + self.assertEqual(rf_server.name, "Dell Inc. System") + + def test_get_chassis(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Sled-1-2-1": { + "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", + } + }) + rf_chassis = rf.get_chassis("/redfish/v1/Chassis/Sled-1-2-1") + self.assertEqual(type(rf_chassis), RedfishChassis) + + def test_get_chassis_properties(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Sled-1-2-1": { + "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", + "ChassisType": "Sled", + "Description": "G5 Sled-Level Enclosure", + "Id": "Sled-1-2-1", + "IndicatorLED": "Blinking", + "Links": { + "ComputerSystems": [ + { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1" + }, + { + "@odata.id": "/redfish/v1/Systems/System-1-1-2-2" + } + ] + }, + "Manufacturer": "Dell", + "Name": "G5_Sled", + "SerialNumber": "5555A", + } + }) + rf_chassis = rf.get_chassis("/redfish/v1/Chassis/Sled-1-2-1") + self.assertEqual(rf_chassis.chassis_type, "Sled") + self.assertEqual(rf_chassis.name, "Dell G5_Sled (5555A)") + self.assertEqual(rf_chassis.description, "G5 Sled-Level Enclosure") + self.assertEqual(rf_chassis.led_state, "Blinking") + self.assertEqual(rf_chassis._identifying_attrs, + {"odata_id": "/redfish/v1/Chassis/Sled-1-2-1"}) + self.assertEqual(rf_chassis.uuid(), "Sled-1-2-1") + self.assertEqual(rf_chassis.num_servers, 2) + + def test_get_rack(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Rack-1": { + "@odata.id": "/redfish/v1/Chassis/Rack-1", + "ChassisType": "Rack", + } + }) + rf_rack = rf.get_rack("/redfish/v1/Chassis/Rack-1") + self.assertEqual(type(rf_rack), RedfishRack) + + def test_get_rack_bad(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Sled-1-2-1": { + "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", + "ChassisType": "Sled", + } + }) + with self.assertRaises(InvalidValueException, + msg="Chassis type Sled does not match that of a Rack"): + rf.get_rack("/redfish/v1/Chassis/Sled-1-2-1") + + def test_get_rack_properties(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Rack-1": { + "@odata.id": "/redfish/v1/Chassis/Rack-1", + "ChassisType": "Rack", + "Description": "Redfish Rack", + "Id": "Rack-1", + "IndicatorLED": "Blinking", + "Links": { + "ComputerSystems": [ + { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1" + } + ] + }, + "Manufacturer": "Dell", + "Name": "G5_Rack", + "SerialNumber": "1ABC", + } + }) + rf_rack = rf.get_rack("/redfish/v1/Chassis/Rack-1") + self.assertEqual(rf_rack.chassis_type, "Rack") + self.assertEqual(rf_rack.name, "Rack-1") + self.assertEqual(rf_rack.description, "Redfish Rack") + self.assertEqual(rf_rack.uuid(), "Rack-1") + self.assertEqual(rf_rack._identifying_attrs, {"odata_id": + "/redfish/v1/Chassis/Rack-1"}) + self.assertEqual(rf_rack.led_state, "Blinking") + self.assertEqual(rf_rack.num_servers, 1) diff --git a/wrapanapi/systems/redfish.py b/wrapanapi/systems/redfish.py index b5f69533..db288292 100644 --- a/wrapanapi/systems/redfish.py +++ b/wrapanapi/systems/redfish.py @@ -196,7 +196,10 @@ def __init__(self, hostname, username, password, security_protocol, api_port=443 protocol = 'http' if security_protocol == 'Non-SSL' else 'https' self.url = '{}://{}:{}/'.format(protocol, hostname, api_port) self.kwargs = kwargs - self.api_client = redfish_client.connect(self.url, username, password) + if kwargs is not None and "api_client" in kwargs: + self.api_client = kwargs["api_client"] + else: + self.api_client = redfish_client.connect(self.url, username, password) @property def _identifying_attrs(self): From bde2c7a274f668cd4d992bdb0d586a18b1541ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Arta=C4=8D?= Date: Fri, 19 Jul 2019 15:07:30 +0200 Subject: [PATCH 2/7] Add redfish wrapanapi properties This adds `machine_type` and `product_name` properties to `RedfishServer`. Related PR: * https://github.com/ManageIQ/manageiq-providers-redfish/pull/83 --- tests/test_redfish.py | 5 +++++ wrapanapi/systems/redfish.py | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/tests/test_redfish.py b/tests/test_redfish.py index 57b11586..57f154a8 100644 --- a/tests/test_redfish.py +++ b/tests/test_redfish.py @@ -99,6 +99,9 @@ def test_server_complex_properties(self, mock_connector): }, "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1": { "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1", + "InstructionSet": [{ + "Member": "x86-64" + }], "TotalCores": 20, } }) @@ -111,6 +114,8 @@ def test_server_complex_properties(self, mock_connector): self.assertFalse(rf_server.is_off) self.assertFalse(rf_server.is_powering_on) self.assertFalse(rf_server.is_powering_off) + self.assertEqual(rf_server.machine_type, "x86-64") + self.assertEqual(rf_server.product_name, "System") def test_server_power_states(self, mock_connector): # string, diff --git a/wrapanapi/systems/redfish.py b/wrapanapi/systems/redfish.py index db288292..6debc471 100644 --- a/wrapanapi/systems/redfish.py +++ b/wrapanapi/systems/redfish.py @@ -106,6 +106,16 @@ def state(self): """Retrieve the current power status of the physical server.""" return self.raw.PowerState + @property + def machine_type(self): + """Retrieve the server's machine type.""" + return self.raw.Processors.Members[0].InstructionSet[0]["Member"] + + @property + def product_name(self): + """Reurn the product name of the server""" + return self.raw.Name + def _get_state(self): """ Return ServerState object representing the server's current state. From 3c025a96e5420837b75f2e7528f66eb3b634a4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Arta=C4=8D?= Date: Wed, 28 Aug 2019 11:17:53 +0200 Subject: [PATCH 3/7] Remove a Python 2 leftover We address Python 3's `Exception` not having `message` anymore. --- wrapanapi/systems/redfish.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrapanapi/systems/redfish.py b/wrapanapi/systems/redfish.py index 6debc471..b7a6c812 100644 --- a/wrapanapi/systems/redfish.py +++ b/wrapanapi/systems/redfish.py @@ -347,7 +347,7 @@ def find(self, resource_id): try: return self.api_client.find(resource_id) except Exception as e: - raise RedfishItemNotFound(resource_id, "Redfish item", e.message) + raise RedfishItemNotFound(resource_id, "Redfish item", e) def get_server(self, resource_id): """ From 826182196c33f04fd1d93b2aa5b4d2db99d5446d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Arta=C4=8D?= Date: Wed, 28 Aug 2019 13:05:39 +0200 Subject: [PATCH 4/7] Add travis steps to remove Python 3+ tests The Redfish tests are Python 3 only. With this change we remove the tests if running in anything less than Python 3.6. --- .travis.yml | 1 + kill_python3_tests.sh | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100755 kill_python3_tests.sh diff --git a/.travis.yml b/.travis.yml index 950a0cfd..e3ab1920 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,7 @@ matrix: python: "2.7" dist: trusty # trusty required for 2.7 install: + - bash ./kill_python3_tests.sh - pip install -U pip setuptools - pip install -Ur requirements-test.txt --upgrade-strategy eager script: py.test tests/ -v --cov wrapanapi diff --git a/kill_python3_tests.sh b/kill_python3_tests.sh new file mode 100755 index 00000000..c34a860a --- /dev/null +++ b/kill_python3_tests.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +BLACKLISTED_TEST_FILES=test_redfish.py + +PYTHON_VERSION=$(python -c 'import sys ; print("%d%d"%sys.version_info[0:2])') + +echo "Python at version $PYTHON_VERSION" +if (( "$PYTHON_VERSION" < "36" )) +then + echo "Blacklisting files that require at least Python 3.6" + for F in $BLACKLISTED_TEST_FILES + do + echo "tests/$F" + [[ -f "tests/$F" ]] && mv "tests/$F" "tests/$F.disable" + done +fi From f2694f910a4a8e7a0fb0f9e8c8066088f372a7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Arta=C4=8D?= Date: Thu, 29 Aug 2019 09:01:08 +0200 Subject: [PATCH 5/7] Additional tests for redfish systems --- tests/test_redfish.py | 212 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 181 insertions(+), 31 deletions(-) diff --git a/tests/test_redfish.py b/tests/test_redfish.py index 57f154a8..93daa52f 100644 --- a/tests/test_redfish.py +++ b/tests/test_redfish.py @@ -20,8 +20,7 @@ def test_connect_ssl(self, mock_connector): mock_connector.assert_called_with("https://dummy:443/", "user", "pass") -@mock.patch("redfish_client.Connector") -class TestRedfishSystem(TestCase): +class RedfishTestCase(TestCase): def mock_redfish_system(self, mock_connector, data): def mock_get(url): res = mock.Mock() @@ -31,11 +30,15 @@ def mock_get(url): mock_connector.get.side_effect = mock_get api_client = Root(mock_connector) + api_client._content = data.get("/redfish/v1", None) rf = RedfishSystem("dummy", "user", "pass", "Non-SSL", "8000", api_client=api_client) return rf + +@mock.patch("redfish_client.Connector") +class TestRedfishSystem(RedfishTestCase): def test_find_resource(self, mock_connector): rf = self.mock_redfish_system(mock_connector, data={ "/redfish/v1/BlankResource": { @@ -45,6 +48,147 @@ def test_find_resource(self, mock_connector): resource = rf.find("/redfish/v1/BlankResource") self.assertEqual(resource.raw, {"@odata.id": "id"}) + def test_redfish_system(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/BlankResource": { + "@odata.id": "id" + } + }) + self.assertEqual(rf._identifying_attrs, + {"url": "http://dummy:8000/"}) + self.assertEqual(rf.info(), + "RedfishSystem url=http://dummy:8000/") + + def test_num_servers(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1": { + "Systems": { + "@odata.id": "/redfish/v1/Systems" + } + }, + "/redfish/v1/Systems": { + "@odata.id": "/redfish/v1/Systems/", + "Members@odata.count": 4, + "@odata.context": + "/redfish/v1/$metadata#ComputerSystemCollection.ComputerSystemCollection", + "Members": [ + {"@odata.id": "/redfish/v1/Systems/1"}, + {"@odata.id": "/redfish/v1/Systems/2"}, + {"@odata.id": "/redfish/v1/Systems/3"}, + {"@odata.id": "/redfish/v1/Systems/4"}, + ], + "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection", + "Members@odata.navigationLink": "/redfish/v1/Systems/Members", + "@odata.etag": "W/\"e48557da1bf040a5d45d1e5aa726bf3a\"", + "Name": "ComputerSystemCollection", + "Description": "A Collection of ComputerSystem resource instances."} + }) + self.assertEqual(rf.num_servers, 4) + + def test_num_chassis(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1": { + "Chassis": { + "@odata.id": "/redfish/v1/Chassis" + } + }, + "/redfish/v1/Chassis": { + "@odata.id": "/redfish/v1/Chassis/", + "Members@odata.count": 6, + "@odata.context": "/redfish/v1/$metadata#ChassisCollection.ChassisCollection", + "Members": [ + {"@odata.id": "/redfish/v1/Chassis/Block-1"}, + {"@odata.id": "/redfish/v1/Chassis/Block-2"}, + {"@odata.id": "/redfish/v1/Chassis/Block-3"}, + {"@odata.id": "/redfish/v1/Chassis/Rack-4"}, + {"@odata.id": "/redfish/v1/Chassis/Rack-5"}, + {"@odata.id": "/redfish/v1/Chassis/Sled-6"}, + ], + "@odata.type": "#ChassisCollection.ChassisCollection", + "Members@odata.navigationLink": "/redfish/v1/Chassis/Members", + "@odata.etag": "W/\"aef74912345d8e2ae00d008591fc5d85\"", + "Name": "ChassisCollection", + "Description": "A Collection of Chassis resource instances." + }, + "/redfish/v1/Chassis/Block-1": { + "@odata.id": "/redfish/v1/Chassis/Block-1", + "ChassisType": "Enclosure", + }, + "/redfish/v1/Chassis/Block-2": { + "@odata.id": "/redfish/v1/Chassis/Block-2", + "ChassisType": "Enclosure", + }, + "/redfish/v1/Chassis/Block-3": { + "@odata.id": "/redfish/v1/Chassis/Block-3", + "ChassisType": "Enclosure", + }, + "/redfish/v1/Chassis/Rack-4": { + "@odata.id": "/redfish/v1/Chassis/Rack-4", + "ChassisType": "Rack", + }, + "/redfish/v1/Chassis/Rack-5": { + "@odata.id": "/redfish/v1/Chassis/Rack-5", + "ChassisType": "Rack", + }, + "/redfish/v1/Chassis/Sled-6": { + "@odata.id": "/redfish/v1/Chassis/Sled-6", + "ChassisType": "Sled", + }, + }) + self.assertEqual(rf.num_chassis, 4) + + def test_num_racks(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1": { + "Chassis": { + "@odata.id": "/redfish/v1/Chassis" + } + }, + "/redfish/v1/Chassis": { + "@odata.id": "/redfish/v1/Chassis/", + "Members@odata.count": 6, + "@odata.context": "/redfish/v1/$metadata#ChassisCollection.ChassisCollection", + "Members": [ + {"@odata.id": "/redfish/v1/Chassis/Block-1"}, + {"@odata.id": "/redfish/v1/Chassis/Block-2"}, + {"@odata.id": "/redfish/v1/Chassis/Block-3"}, + {"@odata.id": "/redfish/v1/Chassis/Rack-4"}, + {"@odata.id": "/redfish/v1/Chassis/Rack-5"}, + {"@odata.id": "/redfish/v1/Chassis/Sled-6"}, + ], + "@odata.type": "#ChassisCollection.ChassisCollection", + "Members@odata.navigationLink": "/redfish/v1/Chassis/Members", + "@odata.etag": "W/\"aef74912345d8e2ae00d008591fc5d85\"", + "Name": "ChassisCollection", + "Description": "A Collection of Chassis resource instances." + }, + "/redfish/v1/Chassis/Block-1": { + "@odata.id": "/redfish/v1/Chassis/Block-1", + "ChassisType": "Enclosure", + }, + "/redfish/v1/Chassis/Block-2": { + "@odata.id": "/redfish/v1/Chassis/Block-2", + "ChassisType": "Enclosure", + }, + "/redfish/v1/Chassis/Block-3": { + "@odata.id": "/redfish/v1/Chassis/Block-3", + "ChassisType": "Enclosure", + }, + "/redfish/v1/Chassis/Rack-4": { + "@odata.id": "/redfish/v1/Chassis/Rack-4", + "ChassisType": "Rack", + }, + "/redfish/v1/Chassis/Rack-5": { + "@odata.id": "/redfish/v1/Chassis/Rack-5", + "ChassisType": "Rack", + }, + "/redfish/v1/Chassis/Sled-6": { + "@odata.id": "/redfish/v1/Chassis/Sled-6", + "ChassisType": "Sled", + }, + }) + self.assertEqual(rf.num_racks, 2) + def test_get_server(self, mock_connector): rf = self.mock_redfish_system(mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { @@ -54,6 +198,39 @@ def test_get_server(self, mock_connector): rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") self.assertEqual(type(rf_server), RedfishServer) + def test_get_chassis(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Sled-1-2-1": { + "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", + } + }) + rf_chassis = rf.get_chassis("/redfish/v1/Chassis/Sled-1-2-1") + self.assertEqual(type(rf_chassis), RedfishChassis) + + def test_get_rack(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Rack-1": { + "@odata.id": "/redfish/v1/Chassis/Rack-1", + "ChassisType": "Rack", + } + }) + rf_rack = rf.get_rack("/redfish/v1/Chassis/Rack-1") + self.assertEqual(type(rf_rack), RedfishRack) + + def test_get_rack_bad(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Sled-1-2-1": { + "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", + "ChassisType": "Sled", + } + }) + with self.assertRaises(InvalidValueException, + msg="Chassis type Sled does not match that of a Rack"): + rf.get_rack("/redfish/v1/Chassis/Sled-1-2-1") + + +@mock.patch("redfish_client.Connector") +class TestRedfishServer(RedfishTestCase): def test_server_simple_properties(self, mock_connector): rf = self.mock_redfish_system(mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { @@ -157,15 +334,9 @@ def test_server_name_no_sn(self, mock_connector): rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") self.assertEqual(rf_server.name, "Dell Inc. System") - def test_get_chassis(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ - "/redfish/v1/Chassis/Sled-1-2-1": { - "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", - } - }) - rf_chassis = rf.get_chassis("/redfish/v1/Chassis/Sled-1-2-1") - self.assertEqual(type(rf_chassis), RedfishChassis) +@mock.patch("redfish_client.Connector") +class TestRedfishChassis(RedfishTestCase): def test_get_chassis_properties(self, mock_connector): rf = self.mock_redfish_system(mock_connector, data={ "/redfish/v1/Chassis/Sled-1-2-1": { @@ -199,27 +370,6 @@ def test_get_chassis_properties(self, mock_connector): self.assertEqual(rf_chassis.uuid(), "Sled-1-2-1") self.assertEqual(rf_chassis.num_servers, 2) - def test_get_rack(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ - "/redfish/v1/Chassis/Rack-1": { - "@odata.id": "/redfish/v1/Chassis/Rack-1", - "ChassisType": "Rack", - } - }) - rf_rack = rf.get_rack("/redfish/v1/Chassis/Rack-1") - self.assertEqual(type(rf_rack), RedfishRack) - - def test_get_rack_bad(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ - "/redfish/v1/Chassis/Sled-1-2-1": { - "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", - "ChassisType": "Sled", - } - }) - with self.assertRaises(InvalidValueException, - msg="Chassis type Sled does not match that of a Rack"): - rf.get_rack("/redfish/v1/Chassis/Sled-1-2-1") - def test_get_rack_properties(self, mock_connector): rf = self.mock_redfish_system(mock_connector, data={ "/redfish/v1/Chassis/Rack-1": { From 1537347dd6d34c1a359d3e3041e5a64b75198a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Arta=C4=8D?= Date: Thu, 29 Aug 2019 11:27:17 +0200 Subject: [PATCH 6/7] Push for coverage --- tests/test_redfish.py | 105 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tests/test_redfish.py b/tests/test_redfish.py index 93daa52f..d402868e 100644 --- a/tests/test_redfish.py +++ b/tests/test_redfish.py @@ -228,6 +228,111 @@ def test_get_rack_bad(self, mock_connector): msg="Chassis type Sled does not match that of a Rack"): rf.get_rack("/redfish/v1/Chassis/Sled-1-2-1") + def test_server_stats_inventory(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Systems/System-1-2-1-1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", + "Description": "A server", + "Id": "System-1-2-1-1", + "Manufacturer": "Dell Inc.", + "MemorySummary": { + "TotalSystemMemoryGiB": 32, + }, + "Name": "System", + "PowerState": "On", + "Processors": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors" + }, + "SerialNumber": "945hjf0927mf", + }, + "/redfish/v1/Systems/System-1-2-1-1/Processors": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors", + "Members": [{ + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1" + }], + }, + "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1": { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1/Processors/CPU.Socket.1", + "InstructionSet": [{ + "Member": "x86-64" + }], + "TotalCores": 20, + } + }) + physical_server = mock.Mock() + physical_server.ems_ref = "/redfish/v1/Systems/System-1-2-1-1" + requested_stats = ["cores_capacity", "memory_capacity", + # "num_network_devices", "num_storage_devices" + ] + requested_inventory = ["power_state"] + self.assertEqual(rf.server_stats(physical_server, requested_stats), + {"cores_capacity": 20, "memory_capacity": 32768}) + self.assertEqual(rf.server_inventory(physical_server, requested_inventory), + {"power_state": "on"}) + + def test_rack_stats_inventory(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Rack-1": { + "@odata.id": "/redfish/v1/Chassis/Rack-1", + "ChassisType": "Rack", + "Description": "Redfish Rack", + "Id": "Rack-1", + "IndicatorLED": "Blinking", + "Links": { + "ComputerSystems": [ + { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1" + } + ] + }, + "Manufacturer": "Dell", + "Name": "G5_Rack", + "SerialNumber": "1ABC", + } + }) + physical_rack = mock.Mock() + physical_rack.ems_ref = "/redfish/v1/Chassis/Rack-1" + requested_stats = [] + requested_inventory = ["rack_name"] + self.assertEqual(rf.rack_stats(physical_rack, requested_stats), + {}) + self.assertEqual(rf.rack_inventory(physical_rack, requested_inventory), + {"rack_name": "Rack-1"}) + + def test_chassis_stats_inventory(self, mock_connector): + rf = self.mock_redfish_system(mock_connector, data={ + "/redfish/v1/Chassis/Sled-1-2-1": { + "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", + "ChassisType": "Sled", + "Description": "G5 Sled-Level Enclosure", + "Id": "Sled-1-2-1", + "IndicatorLED": "Blinking", + "Links": { + "ComputerSystems": [ + { + "@odata.id": "/redfish/v1/Systems/System-1-2-1-1" + }, + { + "@odata.id": "/redfish/v1/Systems/System-1-1-2-2" + } + ] + }, + "Manufacturer": "Dell", + "Name": "G5_Sled", + "SerialNumber": "5555A", + } + }) + phsyical_chassis = mock.Mock() + phsyical_chassis.ems_ref = "/redfish/v1/Chassis/Sled-1-2-1" + requested_stats = ["num_physical_servers"] + requested_inventory = ["chassis_name", "description", "identify_led_state"] + self.assertEqual(rf.chassis_stats(phsyical_chassis, requested_stats), + {"num_physical_servers": 2}) + self.assertEqual(rf.chassis_inventory(phsyical_chassis, requested_inventory), + {"chassis_name": "Dell G5_Sled (5555A)", + "description": "G5 Sled-Level Enclosure", + "identify_led_state": "Blinking"}) + @mock.patch("redfish_client.Connector") class TestRedfishServer(RedfishTestCase): From a97bcc1196937734d9387661d6fe0de6678da325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Arta=C4=8D?= Date: Thu, 5 Sep 2019 08:10:07 +0200 Subject: [PATCH 7/7] Convert redfish tests to pytest This commit replaces the use of unittest with the constructs from pytest. We started off using unittest, but then we'd introduce parametrization, which wouldn't work because the mix with unit test caused parametrization to get lost. Now we use mainly the equivalent pytest constructs. --- tests/test_redfish.py | 219 +++++++++++++++++++++--------------------- 1 file changed, 110 insertions(+), 109 deletions(-) diff --git a/tests/test_redfish.py b/tests/test_redfish.py index d402868e..a735cac3 100644 --- a/tests/test_redfish.py +++ b/tests/test_redfish.py @@ -1,6 +1,7 @@ # coding: utf-8 # Unit tests for the Redfish API -from unittest import mock, TestCase +import pytest +from unittest import mock from redfish_client.root import Root from wrapanapi.exceptions import InvalidValueException @@ -20,7 +21,7 @@ def test_connect_ssl(self, mock_connector): mock_connector.assert_called_with("https://dummy:443/", "user", "pass") -class RedfishTestCase(TestCase): +class RedfishTestCase(): def mock_redfish_system(self, mock_connector, data): def mock_get(url): res = mock.Mock() @@ -36,31 +37,36 @@ def mock_get(url): api_client=api_client) return rf + def setup_method(self, method): + self.patcher = mock.patch("redfish_client.Connector") + ConnectorMockClass = self.patcher.start() + self.mock_connector = ConnectorMockClass() + + def teardown_method(self, method): + self.patcher.stop() + -@mock.patch("redfish_client.Connector") class TestRedfishSystem(RedfishTestCase): - def test_find_resource(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_find_resource(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/BlankResource": { "@odata.id": "id" } }) resource = rf.find("/redfish/v1/BlankResource") - self.assertEqual(resource.raw, {"@odata.id": "id"}) + assert resource.raw == {"@odata.id": "id"} - def test_redfish_system(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_redfish_system(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/BlankResource": { "@odata.id": "id" } }) - self.assertEqual(rf._identifying_attrs, - {"url": "http://dummy:8000/"}) - self.assertEqual(rf.info(), - "RedfishSystem url=http://dummy:8000/") + assert rf._identifying_attrs == {"url": "http://dummy:8000/"} + assert rf.info() == "RedfishSystem url=http://dummy:8000/" - def test_num_servers(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_num_servers(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1": { "Systems": { "@odata.id": "/redfish/v1/Systems" @@ -83,10 +89,10 @@ def test_num_servers(self, mock_connector): "Name": "ComputerSystemCollection", "Description": "A Collection of ComputerSystem resource instances."} }) - self.assertEqual(rf.num_servers, 4) + assert rf.num_servers == 4 - def test_num_chassis(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_num_chassis(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1": { "Chassis": { "@odata.id": "/redfish/v1/Chassis" @@ -135,10 +141,10 @@ def test_num_chassis(self, mock_connector): "ChassisType": "Sled", }, }) - self.assertEqual(rf.num_chassis, 4) + assert rf.num_chassis == 4 - def test_num_racks(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_num_racks(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1": { "Chassis": { "@odata.id": "/redfish/v1/Chassis" @@ -187,49 +193,49 @@ def test_num_racks(self, mock_connector): "ChassisType": "Sled", }, }) - self.assertEqual(rf.num_racks, 2) + assert rf.num_racks == 2 - def test_get_server(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_get_server(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", } }) rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") - self.assertEqual(type(rf_server), RedfishServer) + assert type(rf_server) == RedfishServer - def test_get_chassis(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_get_chassis(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Chassis/Sled-1-2-1": { "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", } }) rf_chassis = rf.get_chassis("/redfish/v1/Chassis/Sled-1-2-1") - self.assertEqual(type(rf_chassis), RedfishChassis) + assert type(rf_chassis) == RedfishChassis - def test_get_rack(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_get_rack(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Chassis/Rack-1": { "@odata.id": "/redfish/v1/Chassis/Rack-1", "ChassisType": "Rack", } }) rf_rack = rf.get_rack("/redfish/v1/Chassis/Rack-1") - self.assertEqual(type(rf_rack), RedfishRack) + assert type(rf_rack) == RedfishRack - def test_get_rack_bad(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_get_rack_bad(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Chassis/Sled-1-2-1": { "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", "ChassisType": "Sled", } }) - with self.assertRaises(InvalidValueException, - msg="Chassis type Sled does not match that of a Rack"): + with pytest.raises(InvalidValueException) as e: rf.get_rack("/redfish/v1/Chassis/Sled-1-2-1") + assert e == "Chassis type Sled does not match that of a Rack" - def test_server_stats_inventory(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_server_stats_inventory(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", "Description": "A server", @@ -265,13 +271,13 @@ def test_server_stats_inventory(self, mock_connector): # "num_network_devices", "num_storage_devices" ] requested_inventory = ["power_state"] - self.assertEqual(rf.server_stats(physical_server, requested_stats), - {"cores_capacity": 20, "memory_capacity": 32768}) - self.assertEqual(rf.server_inventory(physical_server, requested_inventory), - {"power_state": "on"}) + assert (rf.server_stats(physical_server, requested_stats) == { + "cores_capacity": 20, "memory_capacity": 32768}) + assert (rf.server_inventory(physical_server, requested_inventory) == { + "power_state": "on"}) - def test_rack_stats_inventory(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_rack_stats_inventory(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Chassis/Rack-1": { "@odata.id": "/redfish/v1/Chassis/Rack-1", "ChassisType": "Rack", @@ -294,13 +300,12 @@ def test_rack_stats_inventory(self, mock_connector): physical_rack.ems_ref = "/redfish/v1/Chassis/Rack-1" requested_stats = [] requested_inventory = ["rack_name"] - self.assertEqual(rf.rack_stats(physical_rack, requested_stats), - {}) - self.assertEqual(rf.rack_inventory(physical_rack, requested_inventory), - {"rack_name": "Rack-1"}) + assert rf.rack_stats(physical_rack, requested_stats) == {} + assert (rf.rack_inventory(physical_rack, requested_inventory) == { + "rack_name": "Rack-1"}) - def test_chassis_stats_inventory(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_chassis_stats_inventory(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Chassis/Sled-1-2-1": { "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", "ChassisType": "Sled", @@ -326,18 +331,17 @@ def test_chassis_stats_inventory(self, mock_connector): phsyical_chassis.ems_ref = "/redfish/v1/Chassis/Sled-1-2-1" requested_stats = ["num_physical_servers"] requested_inventory = ["chassis_name", "description", "identify_led_state"] - self.assertEqual(rf.chassis_stats(phsyical_chassis, requested_stats), - {"num_physical_servers": 2}) - self.assertEqual(rf.chassis_inventory(phsyical_chassis, requested_inventory), - {"chassis_name": "Dell G5_Sled (5555A)", - "description": "G5 Sled-Level Enclosure", - "identify_led_state": "Blinking"}) + assert (rf.chassis_stats(phsyical_chassis, requested_stats) == { + "num_physical_servers": 2}) + assert (rf.chassis_inventory(phsyical_chassis, requested_inventory) == { + "chassis_name": "Dell G5_Sled (5555A)", + "description": "G5 Sled-Level Enclosure", + "identify_led_state": "Blinking"}) -@mock.patch("redfish_client.Connector") class TestRedfishServer(RedfishTestCase): - def test_server_simple_properties(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_server_simple_properties(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", "Description": "A server", @@ -349,15 +353,14 @@ def test_server_simple_properties(self, mock_connector): } }) rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") - self.assertEqual(rf_server.name, "Dell Inc. System (945hjf0927mf)") - self.assertEqual(rf_server.description, "A server") - self.assertEqual(rf_server.state, "On") - self.assertEqual(rf_server._identifying_attrs, - {"odata_id": "/redfish/v1/Systems/System-1-2-1-1"}) - self.assertEqual(rf_server.uuid(), "System-1-2-1-1") - - def test_server_complex_properties(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + assert rf_server.name == "Dell Inc. System (945hjf0927mf)" + assert rf_server.description == "A server" + assert rf_server.state == "On" + assert rf_server._identifying_attrs == {"odata_id": "/redfish/v1/Systems/System-1-2-1-1"} + assert rf_server.uuid() == "System-1-2-1-1" + + def test_server_complex_properties(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", "Description": "A server", @@ -388,18 +391,18 @@ def test_server_complex_properties(self, mock_connector): } }) rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") - self.assertEqual(rf_server.server_cores, 20) - self.assertEqual(rf_server.server_memory, 32768) - self.assertEqual(rf_server.state, "On") - self.assertEqual(rf_server._get_state(), ServerState.ON) - self.assertTrue(rf_server.is_on) - self.assertFalse(rf_server.is_off) - self.assertFalse(rf_server.is_powering_on) - self.assertFalse(rf_server.is_powering_off) - self.assertEqual(rf_server.machine_type, "x86-64") - self.assertEqual(rf_server.product_name, "System") - - def test_server_power_states(self, mock_connector): + assert rf_server.server_cores == 20 + assert rf_server.server_memory == 32768 + assert rf_server.state == "On" + assert rf_server._get_state() == ServerState.ON + assert rf_server.is_on + assert not rf_server.is_off + assert not rf_server.is_powering_on + assert not rf_server.is_powering_off + assert rf_server.machine_type == "x86-64" + assert rf_server.product_name == "System" + + def test_server_power_states(self): # string, # is_on, is_off, is_powering_on, is_powering_off test_data = { @@ -414,21 +417,21 @@ def test_server_power_states(self, mock_connector): } for str_state, states in test_data.items(): - rf = self.mock_redfish_system(mock_connector, data={ + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", "PowerState": str_state, } }) rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") - self.assertEqual(rf_server.is_on, states[0]) - self.assertEqual(rf_server.is_off, states[1]) - self.assertEqual(rf_server.is_powering_on, states[2]) - self.assertEqual(rf_server.is_powering_off, states[3]) - self.assertEqual(rf_server._get_state(), states[4]) - - def test_server_name_no_sn(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + assert rf_server.is_on == states[0] + assert rf_server.is_off == states[1] + assert rf_server.is_powering_on == states[2] + assert rf_server.is_powering_off == states[3] + assert rf_server._get_state() == states[4] + + def test_server_name_no_sn(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Systems/System-1-2-1-1": { "@odata.id": "/redfish/v1/Systems/System-1-2-1-1", "Id": "System-1-2-1-1", @@ -437,13 +440,12 @@ def test_server_name_no_sn(self, mock_connector): } }) rf_server = rf.get_server("/redfish/v1/Systems/System-1-2-1-1") - self.assertEqual(rf_server.name, "Dell Inc. System") + assert rf_server.name == "Dell Inc. System" -@mock.patch("redfish_client.Connector") class TestRedfishChassis(RedfishTestCase): - def test_get_chassis_properties(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + def test_get_chassis_properties(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Chassis/Sled-1-2-1": { "@odata.id": "/redfish/v1/Chassis/Sled-1-2-1", "ChassisType": "Sled", @@ -466,17 +468,16 @@ def test_get_chassis_properties(self, mock_connector): } }) rf_chassis = rf.get_chassis("/redfish/v1/Chassis/Sled-1-2-1") - self.assertEqual(rf_chassis.chassis_type, "Sled") - self.assertEqual(rf_chassis.name, "Dell G5_Sled (5555A)") - self.assertEqual(rf_chassis.description, "G5 Sled-Level Enclosure") - self.assertEqual(rf_chassis.led_state, "Blinking") - self.assertEqual(rf_chassis._identifying_attrs, - {"odata_id": "/redfish/v1/Chassis/Sled-1-2-1"}) - self.assertEqual(rf_chassis.uuid(), "Sled-1-2-1") - self.assertEqual(rf_chassis.num_servers, 2) - - def test_get_rack_properties(self, mock_connector): - rf = self.mock_redfish_system(mock_connector, data={ + assert rf_chassis.chassis_type == "Sled" + assert rf_chassis.name == "Dell G5_Sled (5555A)" + assert rf_chassis.description == "G5 Sled-Level Enclosure" + assert rf_chassis.led_state == "Blinking" + assert rf_chassis._identifying_attrs == {"odata_id": "/redfish/v1/Chassis/Sled-1-2-1"} + assert rf_chassis.uuid() == "Sled-1-2-1" + assert rf_chassis.num_servers == 2 + + def test_get_rack_properties(self): + rf = self.mock_redfish_system(self.mock_connector, data={ "/redfish/v1/Chassis/Rack-1": { "@odata.id": "/redfish/v1/Chassis/Rack-1", "ChassisType": "Rack", @@ -496,11 +497,11 @@ def test_get_rack_properties(self, mock_connector): } }) rf_rack = rf.get_rack("/redfish/v1/Chassis/Rack-1") - self.assertEqual(rf_rack.chassis_type, "Rack") - self.assertEqual(rf_rack.name, "Rack-1") - self.assertEqual(rf_rack.description, "Redfish Rack") - self.assertEqual(rf_rack.uuid(), "Rack-1") - self.assertEqual(rf_rack._identifying_attrs, {"odata_id": + assert rf_rack.chassis_type == "Rack" + assert rf_rack.name == "Rack-1" + assert rf_rack.description == "Redfish Rack" + assert rf_rack.uuid() == "Rack-1" + assert (rf_rack._identifying_attrs == {"odata_id": "/redfish/v1/Chassis/Rack-1"}) - self.assertEqual(rf_rack.led_state, "Blinking") - self.assertEqual(rf_rack.num_servers, 1) + assert rf_rack.led_state == "Blinking" + assert rf_rack.num_servers == 1