EventService support

This commit adds support for the EventService in Redfish

Story: 2008366
Task: 42486
Change-Id: I8991bed87cea60e2834b05b1af879a146b12e04c
This commit is contained in:
Iury Gregory Melo Ferreira
2021-05-16 19:23:49 +02:00
parent 6ae294b3e0
commit b11e99a861
16 changed files with 691 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
---
features:
- |
Adds support for the Redfish EventService resource.
`EventService` is responsible for managing event subscriptions and
generates the events sent to subscribers.

View File

@@ -19,6 +19,7 @@ import pbr.version
from sushy.main import Sushy
from sushy.resources.chassis.constants import * # noqa
from sushy.resources.constants import * # noqa
from sushy.resources.eventservice.constants import * # noqa
from sushy.resources.fabric.constants import * # noqa
from sushy.resources.manager.constants import * # noqa
from sushy.resources.system.constants import * # noqa

View File

@@ -24,6 +24,7 @@ from sushy import exceptions
from sushy.resources import base
from sushy.resources.chassis import chassis
from sushy.resources.compositionservice import compositionservice
from sushy.resources.eventservice import eventservice
from sushy.resources.fabric import fabric
from sushy.resources.manager import manager
from sushy.resources.registry import message_registry
@@ -145,6 +146,9 @@ class Sushy(base.ResourceBase):
_update_service_path = base.Field(['UpdateService', '@odata.id'])
"""UpdateService path"""
_event_service_path = base.Field(['EventService', '@odata.id'])
"""EventService path"""
def __init__(self, base_url, username=None, password=None,
root_prefix='/redfish/v1/', verify=True,
auth=None, connector=None,
@@ -444,6 +448,21 @@ class Sushy(base.ResourceBase):
redfish_version=self.redfish_version,
registries=self.lazy_registries)
def get_event_service(self):
"""Get the EventService object
:raises: MissingAttributeError, if the EventService is not found
:returns: The EventService object
"""
if not self._event_service_path:
raise exceptions.MissingAttributeError(
attribute='EventService/@odata.id',
resource=self._path)
return eventservice.EventService(
self._conn, self._event_service_path,
redfish_version=self.redfish_version,
registries=self.lazy_registries)
def _get_standard_message_registry_collection(self):
"""Load packaged standard message registries

View File

View File

@@ -0,0 +1,38 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# EventType constants
# http://redfish.dmtf.org/schemas/v1/Event.json#/definitions/EventType
# https://redfish.dmtf.org/schemas/v1/EventService.v1_0_6.json
EVENT_TYPE_STATUS_CHANGE = "Status Change"
"""The status of a resource has changed"""
EVENT_TYPE_RESOURCE_ADDED = "Resource Added"
"""A resource has been added."""
EVENT_TYPE_RESOURCE_REMOVED = "Resource Removed"
"""A resource has been removed"""
EVENT_TYPE_RESOURCE_UPDATED = "Resource Updated"
"""A resource has been updated"""
EVENT_TYPE_ALERT = "Alert"
"""A condition requires attention"""
EVENT_TYPE_METRIC_REPORT = "Metric Report"
"""The telemetry service is sending a metric report"""
EVENT_TYPE_OTHER = "Other"
"""Because EventType is deprecated as of Redfish Specification v1.6,
the event is based on a registry or resource but not an EventType."""

View File

@@ -0,0 +1,123 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Redfish standard schema.
# https://redfish.dmtf.org/schemas/v1/EventDestination.v1_0_0.json
import logging
from sushy.resources import base
LOG = logging.getLogger(__name__)
class EventDestination(base.ResourceBase):
identity = base.Field('Id', required=True)
"""The EventDestination resource identity"""
name = base.Field('Name', required=True)
"""The EventDestination resource name"""
context = base.Field('Context', required=True)
"""A client-supplied string that is stored with the event destination
subscription"""
description = base.Field('Description')
"""The description of the EventDestination resource"""
destination = base.Field('Destination')
"""The URI of the destination Event Service"""
event_types = base.Field('EventTypes', adapter=list)
"""The types of events that shall be sent to the destination"""
protocol = base.Field('Protocol')
"""Contain the protocol type that the event will use for sending
the event to the destination. A value of Redfish shall be used
to indicate that the event type shall adhere to that defined in
the Redfish specification"""
http_headers = base.Field('HttpHeaders', adapter=list)
"""This is for setting HTTP headers, such as authorization information.
This object will be null on a GET."""
def __init__(self, connector, identity, redfish_version=None,
registries=None):
"""A class representing an EventDestination
:param connector: A Connector instance
:param identity: The identity of the EventDestination resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of given version.
:param registries: Dict of registries to be used in any resource
that needs registries to parse messages.
"""
super(EventDestination, self).__init__(
connector, identity, redfish_version, registries)
def delete(self):
"""Delete an EventDestination
:raises: ConnectionError
:raises: HTTPError
"""
self._conn.delete(self._path)
class EventDestinationCollection(base.ResourceCollectionBase):
name = base.Field('Name')
"""The EventDestination collection name"""
description = base.Field('Description')
"""The EventDestination collection description"""
@property
def _resource_type(self):
return EventDestination
def __init__(self, connector, identity, redfish_version=None,
registries=None):
"""A class representing a EventDestinationCollection
:param connector: A Connector instance
:param identity: The identity of the EventDestination resource
:param redfish_version: The version of RedFish. Used to construct
the object according to schema of given version.
:param registries: Dict of registries to be used in any resource
that needs registries to parse messages.
"""
super(EventDestinationCollection, self).__init__(
connector, identity, redfish_version, registries)
def _create(self, payload):
r = self._conn.post(self._path, data=payload)
location = r.headers.get('Location')
return r, location
def create(self, payload):
"""Create a Subscription
:param payload: The payload representing the subscription.
:raises: ConnectionError
:raises: HTTPError
:returns: The new subscription
"""
r, location = self._create(payload)
if r.status_code == 201:
if location:
self.refresh()
return self.get_member(location)

View File

@@ -0,0 +1,150 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Redfish standard schema.
# https://redfish.dmtf.org/schemas/v1/EventService.v1_0_8.json
import logging
from sushy import exceptions
from sushy.resources import base
from sushy.resources import common
from sushy.resources.eventservice import eventdestination
from sushy.resources.eventservice import mappings as evs_maps
LOG = logging.getLogger(__name__)
class ActionsField(base.CompositeField):
submit_test_event = common.ActionField(
'#EventService.SubmitTestEvent')
class EventService(base.ResourceBase):
identity = base.Field('Id', required=True)
"""The EventService resource identity"""
name = base.Field('Name', required=True)
"""The EventService resource name"""
delivery_retry_attempts = base.Field('DeliveryRetryAttempts')
"""Number of attempts an event posting is retried before the subscription
is terminated. This retry is at the service level, meaning the HTTP POST
to the Event Destination was returned by the HTTP operation as unsuccessful
(4xx or 5xx return code) or an HTTP timeout occurred this many times before
the Event Destination subscription is terminated
"""
delivery_retry_interval = base.Field('DeliveryRetryIntervalSeconds')
"""Number of seconds between retry attempts for sending any given Event"""
event_types_for_subscription = base.Field('EventTypesForSubscription',
adapter=list)
"""Types of Events that can be subscribed to"""
service_enabled = base.Field('ServiceEnabled', adapter=bool)
"""Indicates whether the EventService is enabled"""
status = common.StatusField('Status')
"""The status of the EventService"""
_actions = ActionsField('Actions', required=True)
def __init__(self, connector, identity, redfish_version=None,
registries=None):
"""A class representing a EventService
:param connector: A Connector instance
:param identity: The identity of the EventService resource
:param redfish_version: The version of Redfish. Used to construct
the object according to schema of given version
:param registries: Dict of registries to be used in any resource
that needs registries to parse messages.
"""
super(EventService, self).__init__(
connector, identity, redfish_version, registries)
def _get_submit_test_event(self):
submit_test_event_action = self._actions.submit_test_event
if not submit_test_event_action:
raise exceptions.MissingActionError(
action='#EventService.SubmitTestEvent',
resource=self._path)
return submit_test_event_action
def submit_test_event(self, event_id, event_timestamp, event_type,
message, message_args, message_id, origin,
severity):
"""Submit Test Event is used to to send a test event to the BMC
:param event_id: ID of event to be added.
:param event_timestamp: time stamp of event to be added.
:param event_type: type of event to be added.
:param message: human readable message of event to be added.
:param message_args: array of message arguments of the event to
be added.
:param message_id: message ID of event to be added.
:param origin: string of the URL within the OriginOfCondition
property of the event to be added
:param severity: the Severity of event to be added.
:param target: The link to invoke action.
:raises: MissingActionError if the EvenService does not have the
action.
"""
target_uri = self._get_submit_test_event().target_uri
data = {
'EventId': event_id,
'EventTimestamp': event_timestamp,
'EventType': event_type,
'Message': message,
'MessageArgs': message_args,
'MessageId': message_id,
'OriginOfCondition': origin,
'Severity': severity
}
self._conn.post(target_uri, data=data)
def get_event_types_for_subscription(self):
"""Get the Types of Events that can be subscribed to
:returns: A set with the types of Events that can be subscribed to.
"""
if not self.event_types_for_subscription:
LOG.warning('Could not figure out the Event types supported by '
'the EventService %s', self.identity)
return set(evs_maps.EVENT_TYPE_VALUE_MAP.values())
return set([evs_maps.EVENT_TYPE_VALUE_MAP[v] for v in
set(evs_maps.EVENT_TYPE_VALUE_MAP).
intersection(self.event_types_for_subscription)])
def _get_subscriptions_collection_path(self):
"""Helper function to find the EventDestinationCollections path"""
subscriptions = self.json.get('Subscriptions')
if not subscriptions:
raise exceptions.MissingAttributeError(
attribute='Subscriptions', resource=self._path)
return subscriptions.get('@odata.id')
@property
def subscriptions(self):
"""Reference to a collection of Event Destination resources"""
return eventdestination.EventDestinationCollection(
self._conn, self._get_subscriptions_collection_path(),
self.redfish_version, self.registries)

View File

@@ -0,0 +1,24 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sushy.resources.eventservice import constants as evt_cons
EVENT_TYPE_VALUE_MAP = {
'StatusChange': evt_cons.EVENT_TYPE_STATUS_CHANGE,
'ResourceAdded': evt_cons.EVENT_TYPE_RESOURCE_ADDED,
'ResourceRemoved': evt_cons.EVENT_TYPE_RESOURCE_REMOVED,
'ResourceUpdated': evt_cons.EVENT_TYPE_RESOURCE_UPDATED,
'Alert': evt_cons.EVENT_TYPE_ALERT,
'MetricReport': evt_cons.EVENT_TYPE_METRIC_REPORT,
'Other': evt_cons.EVENT_TYPE_OTHER
}

View File

@@ -0,0 +1,16 @@
{
"@odata.context": "/redfish/v1/$metadata#EventDestination.EventDestination",
"@odata.id": "/redfish/v1/EventService/Subscriptions/1",
"@odata.type": "#EventDestination.v1_0_0.EventDestination",
"Id": "1",
"Context": "SomeContext",
"Description": "Event Subscription",
"Destination": "https://localhost/RedfishEvents/EventReceiver.php",
"EventTypes": [
"Alert",
"StatusChange"
],
"HttpHeaders": [],
"Name": "Event Subscription",
"Protocol": "Redfish"
}

View File

@@ -0,0 +1,15 @@
{
"@odata.context": "/redfish/v1/$metadata#EventDestination.EventDestination",
"@odata.id": "/redfish/v1/EventService/Subscriptions/2",
"@odata.type": "#EventDestination.v1_0_0.EventDestination",
"Id": "2",
"Context": "IronicContext",
"Description": "Event Subscription",
"Destination": "https://localhost/RedfishEvents/EventReceiver.php",
"EventTypes": [
"Alert"
],
"HttpHeaders": [],
"Name": "Event Subscription",
"Protocol": "Redfish"
}

View File

@@ -0,0 +1,16 @@
{
"@odata.context": "/redfish/v1/$metadata#EventDestinationCollection.EventDestinationCollection",
"@odata.id": "/redfish/v1/EventService/Subscriptions",
"@odata.type": "#EventDestinationCollection.EventDestinationCollection",
"Description": "User Event Subscriptions",
"Name": "EventSubscriptions",
"Members": [
{
"@odata.id": "/redfish/v1/EventService/Subscriptions/1"
},
{
"@odata.id": "/redfish/v1/EventService/Subscriptions/2"
}
],
"Members@odata.count": 2
}

View File

@@ -0,0 +1,33 @@
{
"@odata.context": "/redfish/v1/$metadata#EventService.EventService",
"@odata.id": "/redfish/v1/EventService/",
"@odata.type": "#EventService.v1_0_8.EventService",
"Id": "EventService",
"Actions": {
"#EventService.SubmitTestEvent": {
"target": "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/"
}
},
"DeliveryRetryAttempts": 3,
"DeliveryRetryIntervalSeconds": 30,
"Description": "Event Subscription service",
"EventTypesForSubscription": [
"StatusChange",
"ResourceUpdated",
"ResourceAdded",
"ResourceRemoved",
"Alert"
],
"Name": "Event Service",
"Oem": {
},
"ServiceEnabled": true,
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"Subscriptions": {
"@odata.id": "/redfish/v1/EventService/Subscriptions/"
}
}

View File

@@ -0,0 +1,125 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
from unittest import mock
from sushy.resources.eventservice import eventdestination
from sushy.tests.unit import base
class EventDestinationTestCase(base.TestCase):
def setUp(self):
super(EventDestinationTestCase, self).setUp()
self.conn = mock.Mock()
with open('sushy/tests/unit/json_samples/eventdestination1.json') as f:
self.json_doc = json.load(f)
self.conn.get.return_value.json.return_value = self.json_doc
self.subscription = eventdestination.EventDestination(
self.conn, '/redfish/v1/EventService',
redfish_version='1.0.0')
def test__parse_attributes(self):
self.subscription._parse_attributes(self.json_doc)
self.assertEqual(self.subscription.identity, '1')
self.assertEqual(self.subscription.name, 'Event Subscription')
self.assertEqual(self.subscription.context, 'SomeContext')
self.assertEqual(self.subscription.destination,
'https://localhost/RedfishEvents/EventReceiver.php')
self.assertEqual(self.subscription.protocol, 'Redfish')
self.assertEqual(set(self.subscription.event_types),
set(["Alert", "StatusChange"]))
self.assertEqual(self.subscription.http_headers, [])
def test__delete(self):
self.subscription.delete()
self.subscription._conn.delete.assert_called_once_with(
self.subscription._path)
class EventDestinationCollectionTestCase(base.TestCase):
def setUp(self):
super(EventDestinationCollectionTestCase, self).setUp()
self.conn = mock.Mock()
with open('sushy/tests/unit/json_samples/'
'eventdestination_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.eventdestination = eventdestination.EventDestinationCollection(
self.conn, '/redfish/v1/EventService/Subscriptions',
redfish_version='1.0.0')
@mock.patch.object(eventdestination, 'EventDestination', autospec=True)
def test_get_member(self, subscription_mock):
self.eventdestination.get_member(
'/redfish/v1/EventService/Subscriptions/1')
subscription_mock.assert_called_once_with(
self.eventdestination._conn,
'/redfish/v1/EventService/Subscriptions/1',
self.eventdestination.redfish_version, None)
@mock.patch.object(eventdestination, 'EventDestination', autospec=True)
def test_get_members(self, subscription_mock):
members = self.eventdestination.get_members()
calls = [
mock.call(self.eventdestination._conn,
'/redfish/v1/EventService/Subscriptions/%s' % member,
self.eventdestination.redfish_version, None)
for member in ('1', '2')
]
subscription_mock.assert_has_calls(calls)
self.assertIsInstance(members, list)
self.assertEqual(2, len(members))
def test__create_subscription_with_required_parameters(self):
payload = {
'Protocol': 'Redfish',
'Destination': 'https://localhost/RedfishEvents/EventReceiver.php',
'Context': 'IronicContext',
'EventTypes': ["Alert"]
}
with open('sushy/tests/unit/json_samples/eventdestination2.json') as f:
self.conn.get.return_value.json.return_value = json.load(f)
self.conn.post.return_value.status_code = 201
self.conn.post.return_value.headers.return_value = {
'Location': '/redfish/v1/EventService/Subscriptions/2'
}
new_subscription = self.eventdestination.create(payload)
self.eventdestination._conn.post.assert_called_once_with(
'/redfish/v1/EventService/Subscriptions',
data=payload,
)
self.assertIsNotNone(new_subscription)
self.assertEqual(new_subscription.identity, '2')
self.assertEqual(new_subscription.context, 'IronicContext')
self.assertEqual(new_subscription.destination,
'https://localhost/RedfishEvents/EventReceiver.php')
self.assertIn("Alert", new_subscription.event_types)
def test__create_subscription_with_invalid_event_type(self):
payload = {
'Protocol': 'Redfish',
'Destination': 'https://localhost/RedfishEvents/EventReceiver.php',
'Context': 'IronicContext',
'EventTypes': ["Other"]
}
self.conn.post.return_value.status_code = 400
new_subscription = self.eventdestination.create(payload)
self.eventdestination._conn.post.assert_called_once_with(
'/redfish/v1/EventService/Subscriptions',
data=payload,
)
self.assertIsNone(new_subscription)

View File

@@ -0,0 +1,109 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
from unittest import mock
import sushy
from sushy import exceptions
from sushy.resources.eventservice import eventservice
from sushy.tests.unit import base
class EventServiceTestCase(base.TestCase):
def setUp(self):
super(EventServiceTestCase, self).setUp()
self.conn = mock.Mock()
with open('sushy/tests/unit/json_samples/eventservice.json') as f:
self.json_doc = json.load(f)
self.conn.get.return_value.json.return_value = self.json_doc
self.eventservice = eventservice.EventService(
self.conn, '/redfish/v1/EventService',
redfish_version='1.0.8')
def test__parse_attributes(self):
self.eventservice._parse_attributes(self.json_doc)
self.assertEqual(self.eventservice.identity, 'EventService')
self.assertEqual(self.eventservice.name, 'Event Service')
self.assertEqual(self.eventservice.delivery_retry_attempts, 3)
self.assertEqual(self.eventservice.delivery_retry_interval, 30)
self.assertEqual(self.eventservice.service_enabled, True)
self.assertEqual(self.eventservice.status.health, 'ok')
self.assertEqual(self.eventservice.status.health_rollup, 'ok')
self.assertEqual(self.eventservice.status.state, 'enabled')
self.assertEqual(self.eventservice.subscriptions._path,
'/redfish/v1/EventService/Subscriptions/')
def test__get_event_types_for_subscription(self):
expected = set([sushy.EVENT_TYPE_STATUS_CHANGE,
sushy.EVENT_TYPE_RESOURCE_ADDED,
sushy.EVENT_TYPE_RESOURCE_REMOVED,
sushy.EVENT_TYPE_RESOURCE_UPDATED,
sushy.EVENT_TYPE_ALERT])
values = self.eventservice.get_event_types_for_subscription()
self.assertEqual(expected, values)
self.assertIsInstance(values, set)
def test__no_event_types_for_subscription(self):
expected = set([sushy.EVENT_TYPE_STATUS_CHANGE,
sushy.EVENT_TYPE_RESOURCE_ADDED,
sushy.EVENT_TYPE_RESOURCE_REMOVED,
sushy.EVENT_TYPE_RESOURCE_UPDATED,
sushy.EVENT_TYPE_ALERT,
sushy.EVENT_TYPE_METRIC_REPORT,
sushy.EVENT_TYPE_OTHER])
self.eventservice.event_types_for_subscription = []
values = self.eventservice.get_event_types_for_subscription()
self.assertEqual(expected, values)
self.assertIsInstance(values, set)
def test__eventservice_missing_action(self):
self.eventservice._actions.submit_test_event = None
self.assertRaisesRegex(
exceptions.MissingActionError, '#EventService.SubmitTestEvent',
self.eventservice.submit_test_event, mock.ANY, mock.ANY, mock.ANY,
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY)
def test__missing_submit_test_event_target(self):
evt_json = self.eventservice.json
evt_json['Actions']['#EventService.SubmitTestEvent'].pop('target')
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'attribute Actions/#EventService.SubmitTestEvent/target',
self.eventservice._parse_attributes, self.json_doc)
def test__submit_test_event(self):
self.assertIsNotNone(self.eventservice._actions.submit_test_event)
payload = {
"EventId": "myEventId",
"EventTimestamp": "2016-10-11T09:42:59Z",
"EventType": "StatusChange",
"Message": "This is a test message",
"MessageArgs": ["arg0", "arg1"],
"MessageId": "iLOEvents.0.9.ResourceStatusChanged",
"OriginOfCondition": "/rest/v1/Chassis/1/FooBar",
"Severity": "OK"
}
self.eventservice.submit_test_event(
payload["EventId"], payload["EventTimestamp"],
payload["EventType"], payload["Message"],
payload["MessageArgs"], payload["MessageId"],
payload["OriginOfCondition"], payload["Severity"])
self.eventservice._conn.post.assert_called_once_with(
'/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/',
data=payload)

View File

@@ -22,6 +22,7 @@ from sushy import exceptions
from sushy import main
from sushy.resources.chassis import chassis
from sushy.resources.compositionservice import compositionservice
from sushy.resources.eventservice import eventservice
from sushy.resources.fabric import fabric
from sushy.resources.manager import manager
from sushy.resources.registry import message_registry_file
@@ -72,6 +73,8 @@ class MainTestCase(base.TestCase):
self.assertEqual('/redfish/v1/Managers', self.root._managers_path)
self.assertEqual('/redfish/v1/Chassis', self.root._chassis_path)
self.assertEqual('/redfish/v1/Fabrics', self.root._fabrics_path)
self.assertEqual('/redfish/v1/EventService',
self.root._event_service_path)
self.assertEqual('/redfish/v1/SessionService',
self.root._session_service_path)
self.assertEqual('/redfish/v1/CompositionService',
@@ -306,6 +309,13 @@ class MainTestCase(base.TestCase):
self.root._conn, '/redfish/v1/CompositionService',
self.root.redfish_version, self.root.lazy_registries)
@mock.patch.object(eventservice, 'EventService', autospec=True)
def test_get_event_service(self, mock_event_service):
self.root.get_event_service()
mock_event_service.assert_called_once_with(
self.root._conn, '/redfish/v1/EventService',
self.root.redfish_version, self.root.lazy_registries)
def test__get_standard_message_registry_collection(self):
registries = self.root._get_standard_message_registry_collection()
@@ -460,3 +470,9 @@ class BareMinimumMainTestCase(base.TestCase):
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'Links/Sessions/@data.id', self.root.get_sessions_path)
def test_get_event_service_when_eventservice_attr_absent(self):
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'EventService/@odata.id', self.root.get_event_service
)