From b3f87d8c99313942b90b9474a869f100f97814c6 Mon Sep 17 00:00:00 2001 From: monokai <2536818783@qq.com> Date: Fri, 25 Jan 2019 11:53:35 +0800 Subject: [PATCH] Add update service for RSD2.2 Change-Id: Ifcd79369e922859ed92496db1a00087388beef2b --- rsd_lib/resources/v2_2/__init__.py | 14 +++ .../resources/v2_2/update_service/__init__.py | 0 .../v2_2/update_service/action_info.py | 57 +++++++++ .../v2_2/update_service/update_service.py | 95 +++++++++++++++ .../tests/unit/json_samples/v2_2/root.json | 3 + .../json_samples/v2_2/update_service.json | 24 ++++ .../v2_2/update_service_action_info.json | 31 +++++ .../tests/unit/json_samples/v2_3/root.json | 3 + .../tests/unit/json_samples/v2_4/root.json | 3 + .../unit/resources/v2_2/test_rsdlib_v2_2.py | 12 ++ .../resources/v2_2/update_service/__init__.py | 0 .../v2_2/update_service/test_action_info.py | 109 ++++++++++++++++++ .../update_service/test_update_service.py | 102 ++++++++++++++++ .../unit/resources/v2_3/test_rsdlib_v2_3.py | 12 ++ .../unit/resources/v2_4/test_rsdlib_v2_4.py | 12 ++ 15 files changed, 477 insertions(+) create mode 100644 rsd_lib/resources/v2_2/update_service/__init__.py create mode 100644 rsd_lib/resources/v2_2/update_service/action_info.py create mode 100644 rsd_lib/resources/v2_2/update_service/update_service.py create mode 100644 rsd_lib/tests/unit/json_samples/v2_2/update_service.json create mode 100644 rsd_lib/tests/unit/json_samples/v2_2/update_service_action_info.json create mode 100644 rsd_lib/tests/unit/resources/v2_2/update_service/__init__.py create mode 100644 rsd_lib/tests/unit/resources/v2_2/update_service/test_action_info.py create mode 100644 rsd_lib/tests/unit/resources/v2_2/update_service/test_update_service.py diff --git a/rsd_lib/resources/v2_2/__init__.py b/rsd_lib/resources/v2_2/__init__.py index 6586d8d..c1beff5 100644 --- a/rsd_lib/resources/v2_2/__init__.py +++ b/rsd_lib/resources/v2_2/__init__.py @@ -21,6 +21,7 @@ from rsd_lib.resources.v2_2.manager import manager from rsd_lib.resources.v2_2.node import node from rsd_lib.resources.v2_2.system import system from rsd_lib.resources.v2_2.telemetry import telemetry +from rsd_lib.resources.v2_2.update_service import update_service class RSDLibV2_2(v2_1.RSDLibV2_1): @@ -41,6 +42,10 @@ class RSDLibV2_2(v2_1.RSDLibV2_1): required=True) """Telemetry Service path""" + _update_service_path = base.Field(['UpdateService', '@odata.id'], + required=True) + """Update Service path""" + def get_system(self, identity): """Given the identity return a System object @@ -123,3 +128,12 @@ class RSDLibV2_2(v2_1.RSDLibV2_1): return manager.Manager(self._conn, identity, redfish_version=self.redfish_version) + + def get_update_service(self): + """Get a UpdateService object + + :returns: The UpdateService object + """ + return update_service.UpdateService( + self._conn, self._update_service_path, + redfish_version=self.redfish_version) diff --git a/rsd_lib/resources/v2_2/update_service/__init__.py b/rsd_lib/resources/v2_2/update_service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rsd_lib/resources/v2_2/update_service/action_info.py b/rsd_lib/resources/v2_2/update_service/action_info.py new file mode 100644 index 0000000..1906524 --- /dev/null +++ b/rsd_lib/resources/v2_2/update_service/action_info.py @@ -0,0 +1,57 @@ +# Copyright 2019 Intel, Inc. +# All Rights Reserved. +# +# 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 import base +from sushy import utils + +NAME_MAPPING = { + "Name": "name", + "Required": "required", + "DataType": "data_type", + "AllowableValues": "allowable_values" +} + + +class ActionInfo(base.ResourceBase): + oem = base.Field("Oem") + """The action info oem""" + + def __init__(self, connector, identity, redfish_version=None): + """A class representing a ActionInfo + + :param connector: A Connector instance + :param identity: The identity of the ActionInfo resource + :param redfish_version: The version of RedFish. Used to construct + the object according to schema of the given version. + """ + super(ActionInfo, self).__init__( + connector, identity, redfish_version) + + @property + @utils.cache_it + def parameters(self): + """Property to provide reference to `ActionInfo` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + parameters = [] + for i in self.json.get('Parameters'): + item = {} + for key in i.keys(): + item[NAME_MAPPING[key]] = i.get(key, None) + parameters.append(item) + + return parameters diff --git a/rsd_lib/resources/v2_2/update_service/update_service.py b/rsd_lib/resources/v2_2/update_service/update_service.py new file mode 100644 index 0000000..e3589f0 --- /dev/null +++ b/rsd_lib/resources/v2_2/update_service/update_service.py @@ -0,0 +1,95 @@ +# Copyright 2019 Intel, Inc. +# All Rights Reserved. +# +# 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 rsd_lib.resources.v2_2.update_service import action_info +from rsd_lib import utils as rsd_lib_utils +from sushy.resources import base +from sushy import utils + + +class StatusField(base.CompositeField): + state = base.Field("State") + """The status state""" + + health = base.Field("Health", adapter=rsd_lib_utils.num_or_none) + """The status health""" + + health_rollup = base.Field("HealthRollup", + adapter=rsd_lib_utils.num_or_none) + """The status health rollup""" + + +class SimpleUpdateField(base.CompositeField): + target = base.Field("target") + """The simple update target""" + + +class ActionsField(base.CompositeField): + simple_update = SimpleUpdateField("#UpdateService.SimpleUpdate") + """The actions simple update""" + + oem = base.Field("Oem") + """The actions oem""" + + +class UpdateService(base.ResourceBase): + identity = base.Field("Id") + """The update service identity""" + + name = base.Field("Name") + """The update service name""" + + status = StatusField("Status") + """The update service name""" + + service_enabled = base.Field("ServiceEnabled", adapter=bool) + """Whether the update service is enabled""" + + actions = ActionsField("Actions") + """The update service actions""" + + oem = base.Field("Oem") + """The update service oem""" + + odata_context = base.Field("@odata.context") + """The update service odata context""" + + def __init__(self, connector, identity, redfish_version=None): + """A class representing a UpdateService + + :param connector: A Connector instance + :param identity: The identity of the UpdateService resource + :param redfish_version: The version of RedFish. Used to construct + the object according to schema of the given version. + """ + super(UpdateService, self).__init__(connector, identity, + redfish_version) + + def _get_action_info_path(self): + """Helper function to find the ActionInfo path""" + return self.json.get("Actions").get("#UpdateService.SimpleUpdate").get( + "@Redfish.ActionInfo") + + @property + @utils.cache_it + def action_info(self): + """Property to provide reference to `ActionInfo` instance + + It is calculated once when it is queried for the first time. On + refresh, this property is reset. + """ + return action_info.ActionInfo( + self._conn, self._get_action_info_path(), + redfish_version=self.redfish_version) diff --git a/rsd_lib/tests/unit/json_samples/v2_2/root.json b/rsd_lib/tests/unit/json_samples/v2_2/root.json index 92fdd15..38d7d37 100644 --- a/rsd_lib/tests/unit/json_samples/v2_2/root.json +++ b/rsd_lib/tests/unit/json_samples/v2_2/root.json @@ -46,5 +46,8 @@ } } }, + "UpdateService": { + "@odata.id": "/redfish/v1/UpdateService" + }, "Links": {} } \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_2/update_service.json b/rsd_lib/tests/unit/json_samples/v2_2/update_service.json new file mode 100644 index 0000000..0b7905e --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_2/update_service.json @@ -0,0 +1,24 @@ +{ + "@odata.type":"#UpdateService.v1_0_2.UpdateService", + "Id":"UpdateService", + "Name":"Update service", + "Status":{ + "State":"Disabled", + "Health":null, + "HealthRollup":null + }, + "ServiceEnabled":false, + "Actions":{ + "#UpdateService.SimpleUpdate":{ + "target":"/redfish/v1/UpdateService/Actions/SimpleUpdate", + "@Redfish.ActionInfo":"/redfish/v1/UpdateService/SimpleUpdateActionInfo" + }, + "Oem":{ + + } + }, + "Oem":{ + + }, + "@odata.context":"/redfish/v1/$metadata#UpdateService/$entity" +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_2/update_service_action_info.json b/rsd_lib/tests/unit/json_samples/v2_2/update_service_action_info.json new file mode 100644 index 0000000..f8eb546 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_2/update_service_action_info.json @@ -0,0 +1,31 @@ +{ + "@odata.type":"#ActionInfo.v1_0_0.ActionInfo", + "Parameters":[ + { + "Name":"ImageURI", + "Required":true, + "DataType":"String" + }, + { + "Name":"TransferProtocol", + "Required":false, + "DataType":"String", + "AllowableValues":[ + + ] + }, + { + "Name":"Targets", + "Required":false, + "DataType":"StringArray", + "AllowableValues":[ + + ] + } + ], + "Oem":{ + + }, + "@odata.context":"/redfish/v1/$metadata#ActionInfo.ActionInfo", + "@odata.id":"/redfish/v1/UpdateService/SimpleUpdateActionInfo" +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_3/root.json b/rsd_lib/tests/unit/json_samples/v2_3/root.json index b8c766c..3d2cb52 100644 --- a/rsd_lib/tests/unit/json_samples/v2_3/root.json +++ b/rsd_lib/tests/unit/json_samples/v2_3/root.json @@ -43,5 +43,8 @@ } } }, + "UpdateService": { + "@odata.id": "/redfish/v1/UpdateService" + }, "Links": {} } \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_4/root.json b/rsd_lib/tests/unit/json_samples/v2_4/root.json index afd04b8..585ea61 100644 --- a/rsd_lib/tests/unit/json_samples/v2_4/root.json +++ b/rsd_lib/tests/unit/json_samples/v2_4/root.json @@ -43,5 +43,8 @@ } } }, + "UpdateService": { + "@odata.id": "/redfish/v1/UpdateService" + }, "Links": {} } \ No newline at end of file diff --git a/rsd_lib/tests/unit/resources/v2_2/test_rsdlib_v2_2.py b/rsd_lib/tests/unit/resources/v2_2/test_rsdlib_v2_2.py index d5d5946..01c927d 100644 --- a/rsd_lib/tests/unit/resources/v2_2/test_rsdlib_v2_2.py +++ b/rsd_lib/tests/unit/resources/v2_2/test_rsdlib_v2_2.py @@ -31,6 +31,8 @@ from rsd_lib.resources.v2_2.manager import manager as v2_2_manager from rsd_lib.resources.v2_2.node import node as v2_2_node from rsd_lib.resources.v2_2.system import system as v2_2_system from rsd_lib.resources.v2_2.telemetry import telemetry as v2_2_telemetry +from rsd_lib.resources.v2_2.update_service import update_service \ + as v2_2_update_service class RSDLibV2_2TestCase(testtools.TestCase): @@ -58,6 +60,8 @@ class RSDLibV2_2TestCase(testtools.TestCase): self.rsd._task_service_path) self.assertEqual("/redfish/v1/Registries", self.rsd._registries_path) + self.assertEqual("/redfish/v1/UpdateService", + self.rsd._update_service_path) @mock.patch.object(v2_2_system, 'SystemCollection', autospec=True) def test_get_system_collection(self, mock_system_collection): @@ -193,3 +197,11 @@ class RSDLibV2_2TestCase(testtools.TestCase): self.rsd._conn, 'fake-registries-id', redfish_version=self.rsd.redfish_version ) + + @mock.patch.object(v2_2_update_service, 'UpdateService', autospec=True) + def test_get_update_service( + self, mock_update_service): + self.rsd.get_update_service() + mock_update_service.assert_called_once_with( + self.rsd._conn, '/redfish/v1/UpdateService', + redfish_version=self.rsd.redfish_version) diff --git a/rsd_lib/tests/unit/resources/v2_2/update_service/__init__.py b/rsd_lib/tests/unit/resources/v2_2/update_service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rsd_lib/tests/unit/resources/v2_2/update_service/test_action_info.py b/rsd_lib/tests/unit/resources/v2_2/update_service/test_action_info.py new file mode 100644 index 0000000..20984e5 --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_2/update_service/test_action_info.py @@ -0,0 +1,109 @@ +# Copyright 2019 Intel, Inc. +# All Rights Reserved. +# +# 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 + +import mock +import testtools + +from rsd_lib.resources.v2_2.update_service import action_info + + +class ActionInfoTestCase(testtools.TestCase): + + def setUp(self): + super(ActionInfoTestCase, self).setUp() + self.conn = mock.Mock() + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'update_service_action_info.json', + 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.action_info_inst = action_info.ActionInfo( + self.conn, '/redfish/v1/UpdateService/SimpleUpdateActionInfo', + redfish_version='1.1.0') + + def test__parse_attributes(self): + self.action_info_inst._parse_attributes() + self.assertEqual({}, self.action_info_inst.oem) + + def test_parameters(self): + # | WHEN | + actual_parameters = self.action_info_inst.parameters + # | THEN | + expected = [ + { + "name": "ImageURI", + "required": True, + "data_type": "String" + }, + { + "name": "TransferProtocol", + "required": False, + "data_type": "String", + "allowable_values": [ + + ] + }, + { + "name": "Targets", + "required": False, + "data_type": "StringArray", + "allowable_values": [ + + ] + } + ] + self.assertEqual(expected, actual_parameters) + + # tests for same object on invoking subsequently + self.assertIs(actual_parameters, + self.action_info_inst.parameters) + + def test_parameters_on_refresh(self): + expected = [ + { + "name": "ImageURI", + "required": True, + "data_type": "String" + }, + { + "name": "TransferProtocol", + "required": False, + "data_type": "String", + "allowable_values": [ + + ] + }, + { + "name": "Targets", + "required": False, + "data_type": "StringArray", + "allowable_values": [ + + ] + } + ] + self.assertEqual(expected, self.action_info_inst.parameters) + + self.action_info_inst.invalidate() + self.action_info_inst.refresh(force=False) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'update_service_action_info.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertEqual(expected, self.action_info_inst.parameters) diff --git a/rsd_lib/tests/unit/resources/v2_2/update_service/test_update_service.py b/rsd_lib/tests/unit/resources/v2_2/update_service/test_update_service.py new file mode 100644 index 0000000..d732eef --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_2/update_service/test_update_service.py @@ -0,0 +1,102 @@ +# Copyright 2019 Intel, Inc. +# All Rights Reserved. +# +# 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 + +import mock +import testtools + +from rsd_lib.resources.v2_2.update_service import action_info +from rsd_lib.resources.v2_2.update_service import update_service + + +class UpdateServiceTestCase(testtools.TestCase): + + def setUp(self): + super(UpdateServiceTestCase, self).setUp() + self.conn = mock.Mock() + with open('rsd_lib/tests/unit/json_samples/v2_2/update_service.json', + 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.update_service_inst = update_service.UpdateService( + self.conn, '/redfish/v1/UpdateService', + redfish_version='1.1.0') + + def test__parse_attributes(self): + self.update_service_inst._parse_attributes() + self.assertEqual("UpdateService", self.update_service_inst.identity) + self.assertEqual("Update service", self.update_service_inst.name) + self.assertEqual("Disabled", self.update_service_inst.status.state) + self.assertEqual(None, self.update_service_inst.status.health) + self.assertEqual(None, self.update_service_inst.status.health_rollup) + self.assertEqual(False, self.update_service_inst.service_enabled) + self.assertEqual("/redfish/v1/UpdateService/Actions/SimpleUpdate", + self.update_service_inst.actions.simple_update.target) + self.assertEqual({}, self.update_service_inst.actions.oem) + self.assertEqual({}, self.update_service_inst.oem) + self.assertEqual("/redfish/v1/$metadata#UpdateService/$entity", + self.update_service_inst.odata_context) + + def test__get_action_info_path(self): + expected = '/redfish/v1/UpdateService/SimpleUpdateActionInfo' + result = self.update_service_inst._get_action_info_path() + self.assertEqual(expected, result) + + def test_action_info(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'update_service_action_info.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_action_info = self.update_service_inst.action_info + # | THEN | + self.assertIsInstance(actual_action_info, + action_info.ActionInfo) + self.conn.get.return_value.json.assert_called_once_with() + + # reset mock + self.conn.get.return_value.json.reset_mock() + # | WHEN & THEN | + # tests for same object on invoking subsequently + self.assertIs(actual_action_info, + self.update_service_inst.action_info) + self.conn.get.return_value.json.assert_not_called() + + def test_action_info_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'update_service_action_info.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.update_service_inst.action_info, + action_info.ActionInfo) + + # On refreshing the update service instance... + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'update_service.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.update_service_inst.invalidate() + self.update_service_inst.refresh(force=False) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'update_service_action_info.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance(self.update_service_inst.action_info, + action_info.ActionInfo) diff --git a/rsd_lib/tests/unit/resources/v2_3/test_rsdlib_v2_3.py b/rsd_lib/tests/unit/resources/v2_3/test_rsdlib_v2_3.py index 6a14441..47e099e 100644 --- a/rsd_lib/tests/unit/resources/v2_3/test_rsdlib_v2_3.py +++ b/rsd_lib/tests/unit/resources/v2_3/test_rsdlib_v2_3.py @@ -22,6 +22,8 @@ from rsd_lib.resources.v2_1.registries import registries as v2_1_registries from rsd_lib.resources.v2_1.task import task_service as v2_1_task_service from rsd_lib.resources.v2_2.manager import manager as v2_2_manager from rsd_lib.resources.v2_2.system import system as v2_2_system +from rsd_lib.resources.v2_2.update_service import update_service \ + as v2_2_update_service from rsd_lib.resources import v2_3 from rsd_lib.resources.v2_3.ethernet_switch import ethernet_switch \ as v2_3_ethernet_switch @@ -55,6 +57,8 @@ class RSDLibV2_3TestCase(testtools.TestCase): self.rsd._task_service_path) self.assertEqual("/redfish/v1/Registries", self.rsd._registries_path) + self.assertEqual("/redfish/v1/UpdateService", + self.rsd._update_service_path) @mock.patch.object(v2_2_system, 'SystemCollection', autospec=True) def test_get_system_collection(self, mock_system_collection): @@ -184,6 +188,14 @@ class RSDLibV2_3TestCase(testtools.TestCase): redfish_version=self.rsd.redfish_version ) + @mock.patch.object(v2_2_update_service, 'UpdateService', autospec=True) + def test_get_update_service( + self, mock_update_service): + self.rsd.get_update_service() + mock_update_service.assert_called_once_with( + self.rsd._conn, '/redfish/v1/UpdateService', + redfish_version=self.rsd.redfish_version) + # @mock.patch.object(v2_2_telemetry, 'Telemetry', autospec=True) # def test_get_telemetry_service(self, mock_telemetry_service): # self.rsd.get_telemetry_service() diff --git a/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py b/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py index e269d13..1d1da81 100644 --- a/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py +++ b/rsd_lib/tests/unit/resources/v2_4/test_rsdlib_v2_4.py @@ -22,6 +22,8 @@ from rsd_lib.resources.v2_1.registries import registries as v2_1_registries from rsd_lib.resources.v2_1.task import task_service as v2_1_task_service from rsd_lib.resources.v2_2.manager import manager as v2_2_manager from rsd_lib.resources.v2_2.system import system as v2_2_system +from rsd_lib.resources.v2_2.update_service import update_service \ + as v2_2_update_service from rsd_lib.resources.v2_3.ethernet_switch import ethernet_switch \ as v2_3_ethernet_switch from rsd_lib.resources.v2_3.fabric import fabric as v2_3_fabric @@ -55,6 +57,8 @@ class RSDLibV2_3TestCase(testtools.TestCase): self.rsd._task_service_path) self.assertEqual("/redfish/v1/Registries", self.rsd._registries_path) + self.assertEqual("/redfish/v1/UpdateService", + self.rsd._update_service_path) @mock.patch.object(v2_2_system, 'SystemCollection', autospec=True) def test_get_system_collection(self, mock_system_collection): @@ -184,6 +188,14 @@ class RSDLibV2_3TestCase(testtools.TestCase): redfish_version=self.rsd.redfish_version ) + @mock.patch.object(v2_2_update_service, 'UpdateService', autospec=True) + def test_get_update_service( + self, mock_update_service): + self.rsd.get_update_service() + mock_update_service.assert_called_once_with( + self.rsd._conn, '/redfish/v1/UpdateService', + redfish_version=self.rsd.redfish_version) + # @mock.patch.object(v2_2_telemetry, 'Telemetry', autospec=True) # def test_get_telemetry_service(self, mock_telemetry_service): # self.rsd.get_telemetry_service()