Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Use parameterized in redfish unit tests. #55

Merged
merged 2 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/unit/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cachetools
parameterized
pytest
freezegun
158 changes: 38 additions & 120 deletions tests/unit/test_redfish.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from unittest.mock import Mock, patch

import redfish_utilities
from parameterized import parameterized
from redfish.rest.v1 import (
InvalidCredentialsError,
RetriesExhaustedError,
Expand Down Expand Up @@ -41,8 +42,11 @@ def test_redfish_helper_context_manager_success(self, mock_redfish_client):
mock_redfish_login.assert_called_once_with(auth="session")
mock_redfish_logout.assert_called_once()

@parameterized.expand(
[InvalidCredentialsError, ConnectionError, SessionCreationError, RetriesExhaustedError]
)
@patch("prometheus_hardware_exporter.collectors.redfish.redfish_client")
def test_redfish_helper_context_manager_fail(self, mock_redfish_client):
def test_redfish_helper_context_manager_fail(self, err, mock_redfish_client):
mock_config = Config(
redfish_host="",
redfish_username="",
Expand All @@ -51,23 +55,10 @@ def test_redfish_helper_context_manager_fail(self, mock_redfish_client):
redfish_client_max_retry=5,
redfish_discover_cache_ttl=5,
)
for err in [
InvalidCredentialsError(),
ConnectionError(),
SessionCreationError(),
RetriesExhaustedError(),
]:
mock_redfish_client.side_effect = err
with self.assertRaises(
(
InvalidCredentialsError,
ConnectionError,
SessionCreationError,
RetriesExhaustedError,
)
):
with RedfishHelper(mock_config):
pass
mock_redfish_client.side_effect = err
with self.assertRaises(err):
with RedfishHelper(mock_config):
pass

@patch("prometheus_hardware_exporter.collectors.redfish.redfish_client")
def test_verify_redfish_call_success(self, mock_redfish_client):
Expand Down Expand Up @@ -478,6 +469,7 @@ def test__storage_root_uri(self):
uri = RedfishHelper._storage_root_uri("S1", storage_name)
assert uri == expected_uri

@parameterized.expand(["Storage", "Storages"])
@patch("prometheus_hardware_exporter.collectors.redfish.redfish_client")
@patch(
"prometheus_hardware_exporter.collectors.redfish.redfish_utilities.collections.get_collection_ids" # noqa: E501
Expand All @@ -486,7 +478,7 @@ def test__storage_root_uri(self):
"prometheus_hardware_exporter.collectors.redfish.redfish_utilities.systems.get_system_ids"
)
def test_get_storage_controller_data_success(
self, mock_get_system_ids, mock_get_collection_ids, mock_redfish_client
self, storage_name, mock_get_system_ids, mock_get_collection_ids, mock_redfish_client
):
mock_redfish_obj = Mock()
mock_system_ids = ["s1"]
Expand All @@ -498,7 +490,8 @@ def test_get_storage_controller_data_success(

def mock_get_response(uri):
response = Mock()
if "Systems/s1/Storage/STOR1" in uri:
storage_root = f"Systems/s1/{storage_name}"
if f"{storage_root}/STOR1" in uri:
response.dict = {
"StorageControllers": [
{
Expand All @@ -507,7 +500,7 @@ def mock_get_response(uri):
}
]
}
elif "Systems/s1/Storage/STOR2" in uri:
elif f"{storage_root}/STOR2" in uri:
response.dict = {
"StorageControllers": [
{
Expand All @@ -518,7 +511,9 @@ def mock_get_response(uri):
}
# response for GET request to /redfish/v1/Systems/<sys_id>/
elif "Systems" in uri:
rgildein marked this conversation as resolved.
Show resolved Hide resolved
response.dict = {"Storage": {"@odata.id": "/redfish/v1/Systems/sX/Storage"}}
response.dict = {
"Storage": {"@odata.id": f"/redfish/v1/Systems/sX/{storage_name}"}
}
return response

mock_redfish_obj.get.side_effect = mock_get_response
Expand Down Expand Up @@ -550,87 +545,6 @@ def mock_get_response(uri):
},
)

@patch("prometheus_hardware_exporter.collectors.redfish.redfish_client")
@patch(
"prometheus_hardware_exporter.collectors.redfish.redfish_utilities.collections.get_collection_ids" # noqa: E501
)
@patch(
"prometheus_hardware_exporter.collectors.redfish.redfish_utilities.systems.get_system_ids"
)
def test_non_standard_storage_uri_name(
self, mock_get_system_ids, mock_get_collection_ids, mock_redfish_client
):
"""Test non-standard name for "Storage" in URI for storage controller and drives.

Eg: /redfish/v1/Systems/S1/Storages
"""
mock_redfish_obj = Mock()
mock_get_system_ids.return_value = ["s1"]
mock_get_collection_ids.return_value = ["STOR1"]
mock_redfish_client.return_value = mock_redfish_obj

def mock_get_response(uri):
response = Mock()
if "Systems/s1/Storages/STOR1/Drives/d11" in uri:
response.dict = {
"Id": "d11",
"Status": {"Health": "OK", "State": "Enabled"},
}
elif "Systems/s1/Storages/STOR1" in uri:
response.dict = {
"StorageControllers": [
{
"MemberId": "sc0",
"Status": {"Health": "OK", "State": "Enabled"},
}
],
"Drives": [
{"@odata.id": "/redfish/v1/Systems/s1/Storages/STOR1/Drives/d11"},
],
}
# response for GET request to /redfish/v1/Systems/<sys_id>/
elif "Systems" in uri:
response.dict = {"Storage": {"@odata.id": "/redfish/v1/Systems/sX/Storages"}}
return response

mock_redfish_obj.get.side_effect = mock_get_response

with RedfishHelper(Mock()) as helper:
sc_count, sc_data = helper.get_storage_controller_data()
drive_count, drive_data = helper.get_storage_drive_data()

# storage controller
self.assertEqual(sc_count, {"s1": 1})
self.assertEqual(
sc_data,
{
"s1": [
{
"storage_id": "STOR1",
"controller_id": "sc0",
"health": "OK",
"state": "Enabled",
},
],
},
)

# storage drives
self.assertEqual(drive_count, {"s1": 1})
self.assertEqual(
drive_data,
{
"s1": [
{
"storage_id": "STOR1",
"drive_id": "d11",
"health": "OK",
"state": "Enabled",
},
],
},
)

@patch("prometheus_hardware_exporter.collectors.redfish.redfish_client")
@patch(
"prometheus_hardware_exporter.collectors.redfish.redfish_utilities.inventory.get_chassis_ids" # noqa: E501
Expand Down Expand Up @@ -746,6 +660,7 @@ def mock_get_response(uri):
},
)

@parameterized.expand(["Storage", "Storages"])
@patch("prometheus_hardware_exporter.collectors.redfish.redfish_client")
@patch(
"prometheus_hardware_exporter.collectors.redfish.redfish_utilities.collections.get_collection_ids" # noqa: E501
Expand All @@ -754,7 +669,7 @@ def mock_get_response(uri):
"prometheus_hardware_exporter.collectors.redfish.redfish_utilities.systems.get_system_ids"
)
def test_get_storage_drive_data_success(
self, mock_get_system_ids, mock_get_collection_ids, mock_redfish_client
self, storage_name, mock_get_system_ids, mock_get_collection_ids, mock_redfish_client
):
mock_redfish_obj = Mock()
mock_system_ids = ["s1"]
Expand All @@ -766,39 +681,42 @@ def test_get_storage_drive_data_success(

def mock_get_response(uri):
response = Mock()
if "Systems/s1/Storage/STOR1/Drives/d11" in uri:
storage_root = f"Systems/s1/{storage_name}"
if f"{storage_root}/STOR1/Drives/d11" in uri:
response.dict = {
"Id": "d11",
"Status": {"Health": "OK", "State": "Enabled"},
}

elif "Systems/s1/Storage/STOR1/Drives/d12" in uri:
elif f"{storage_root}/STOR1/Drives/d12" in uri:
response.dict = {
"Id": "d12",
"Status": {"Health": "OK", "State": "Disabled"},
}

elif "Systems/s1/Storage/STOR2/Drives/d21" in uri:
elif f"{storage_root}/STOR2/Drives/d21" in uri:
response.dict = {
"Id": "d21",
"Status": {"Health": None, "State": "Enabled"},
}
elif "Systems/s1/Storage/STOR1" in uri:
elif f"{storage_root}/STOR1" in uri:
response.dict = {
"Drives": [
{"@odata.id": "/redfish/v1/Systems/s1/Storage/STOR1/Drives/d11"},
{"@odata.id": "/redfish/v1/Systems/s1/Storage/STOR1/Drives/d12"},
{"@odata.id": f"/redfish/v1/Systems/s1/{storage_name}/STOR1/Drives/d11"},
{"@odata.id": f"/redfish/v1/Systems/s1/{storage_name}/STOR1/Drives/d12"},
]
}
elif "Systems/s1/Storage/STOR2" in uri:
elif f"{storage_root}/STOR2" in uri:
response.dict = {
"Drives": [
{"@odata.id": "/redfish/v1/Systems/s1/Storage/STOR2/Drives/d21"},
{"@odata.id": f"/redfish/v1/Systems/s1/{storage_name}/STOR2/Drives/d21"},
]
}
# response for GET request to /redfish/v1/Systems/<sys_id>/
elif "Systems" in uri:
response.dict = {"Storage": {"@odata.id": "/redfish/v1/Systems/sX/Storage"}}
response.dict = {
"Storage": {"@odata.id": f"/redfish/v1/Systems/sX/{storage_name}"}
}
return response

mock_redfish_obj.get.side_effect = mock_get_response
Expand Down Expand Up @@ -1006,17 +924,17 @@ def test_get_chassis_id_fail(self, mock_get_chassis_ids, mock_redfish_client):
class TestRedfishServiceDiscovery(unittest.TestCase):
"""Test redfish service discovery."""

@parameterized.expand([SessionCreationError, InvalidCredentialsError])
@patch("prometheus_hardware_exporter.collectors.redfish.redfish_client")
def test_redfish_available_login_fail(self, mock_redfish_client):
def test_redfish_available_login_fail(self, exc, mock_redfish_client):
test_ttl = 10
mock_redfish_obj = Mock()
mock_redfish_client.return_value = mock_redfish_obj
for exc in [SessionCreationError, InvalidCredentialsError]:
mock_redfish_obj.login.side_effect = exc
discover = RedfishHelper.get_cached_discover_method(ttl=test_ttl)
host = ""
available = discover(host)
self.assertEqual(available, True)
mock_redfish_obj.login.side_effect = exc
discover = RedfishHelper.get_cached_discover_method(ttl=test_ttl)
host = ""
available = discover(host)
self.assertEqual(available, True)

mock_redfish_client.assert_called()
mock_redfish_obj.login.assert_called()
Expand Down