diff --git a/.stestr.conf b/.stestr.conf new file mode 100644 index 0000000..33e15e5 --- /dev/null +++ b/.stestr.conf @@ -0,0 +1,3 @@ +[DEFAULT] +test_path=./sushy_oem_dellemc/tests +top_dir=. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..2190b38 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,17 @@ +If you would like to contribute to the development of OpenStack, you must +follow the steps in this page: + + http://docs.openstack.org/infra/manual/developers.html + +If you already have a good understanding of how the system works and your +OpenStack accounts are set up, you can skip to the development workflow +section of this documentation to learn how changes to OpenStack should be +submitted for review via the Gerrit tool: + + http://docs.openstack.org/infra/manual/developers.html#development-workflow + +Pull requests submitted through GitHub will be ignored. + +Bugs should be filed in StoryBoard, not GitHub: + + https://storyboard.openstack.org/#!/project/960 diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..493b7c9 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,3 @@ +CHANGES +======= + diff --git a/HACKING.rst b/HACKING.rst new file mode 100644 index 0000000..9660e99 --- /dev/null +++ b/HACKING.rst @@ -0,0 +1,4 @@ +Sushy Style Commandments +======================== + +Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ diff --git a/LICENSE b/LICENSE index 261eeb9..68c771a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -173,29 +174,3 @@ incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a293868 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ + +Dell EMC OEM extension for sushy +================================ + +**EARLY PROTOTYPE, WORK IS IN PROGRESS** + +Sushy is a client [library](https://github.com/openstack/sushy) designed to +communicate with [Redfish](https://en.wikipedia.org/wiki/Redfish_(specification)) +based BMC. + +Redfish specification offers extensibility mechanism to let hardware vendors +introduce their own features with the common Redfish framework. At the same +time, `sushy` supports extending its data model by loading extensions found +within its "oem" namespace. + +The `sushy-oem-dellemc` package is a sushy extension package that adds +high-level hardware management abstractions, that are specific to Dell EMC +BMC (which is known under the name of iDRAC), to the tree of sushy Redfish +resources. + +Example use +----------- + +Once installed, sushy user can access Dell EMC OEM resources: + +```python + +import sushy + +root = sushy.Sushy('http://mydellemcbmc.example.com') +manager = root.get_manager('iDRAC.Embedded.1') + +oem = manager.get_oem_extension('Dell') + +print(oem.import_system_configuration_uri) + +``` diff --git a/babel.cfg b/babel.cfg new file mode 100644 index 0000000..15cd6cb --- /dev/null +++ b/babel.cfg @@ -0,0 +1,2 @@ +[python: **.py] + diff --git a/lower-constraints.txt b/lower-constraints.txt new file mode 100644 index 0000000..bcfcd5d --- /dev/null +++ b/lower-constraints.txt @@ -0,0 +1,44 @@ +alabaster==0.7.10 +appdirs==1.3.0 +Babel==2.3.4 +coverage==4.0 +docutils==0.11 +dulwich==0.15.0 +extras==1.0.0 +fixtures==3.0.0 +flake8==2.5.5 +hacking==1.0.0 +imagesize==0.7.1 +iso8601==0.1.11 +Jinja2==2.10 +keystoneauth1==3.4.0 +linecache2==1.0.0 +MarkupSafe==1.0 +mccabe==0.2.1 +mock==2.0.0 +mox3==0.20.0 +openstackdocstheme==1.18.1 +os-client-config==1.28.0 +oslotest==3.2.0 +pbr==2.0.0 +pep8==1.5.7 +pyflakes==0.8.1 +Pygments==2.2.0 +python-dateutil==2.7.0 +python-mimeparse==1.6.0 +python-subunit==1.0.0 +pytz==2013.6 +PyYAML==3.12 +reno==2.5.0 +requests==2.14.2 +requestsexceptions==1.2.0 +six==1.10.0 +snowballstemmer==1.2.1 +Sphinx==1.6.2 +sphinxcontrib-websupport==1.0.1 +stevedore==1.29.0 +stestr==2.0.0 +testscenarios==0.4 +testtools==2.2.0 +traceback2==1.4.0 +unittest2==1.1.0 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2818345 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. + +pbr!=2.1.0,>=2.0.0 # Apache-2.0 +six>=1.10.0 # MIT +sushy # Apache-2.0 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..15de5b8 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,63 @@ +[metadata] +name = sushy-oem-dellemc +summary = Dell EMC OEM extension package for the sushy library +description-file = + README.md +author = OpenStack +author-email = openstack-discuss@lists.openstack.org +home-page = https://docs.openstack.org/sushy/latest/ +classifier = + Environment :: OpenStack + Intended Audience :: Information Technology + Intended Audience :: System Administrators + License :: OSI Approved :: Apache Software License + Operating System :: POSIX :: Linux + Programming Language :: Python + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + +[files] +packages = + sushy_oem_dellemc + +[entry_points] +sushy.resources.manager.oems = + dell = sushy_oem_dellemc.resources.manager.manager:DellManagerExtension + + +[build_sphinx] +source-dir = doc/source +build-dir = doc/build +all_files = 1 +warning-is-error = 1 + +[upload_sphinx] +upload-dir = doc/build/html + +[compile_catalog] +directory = sushy_oem_dellemc/locale +domain = sushy_oem_dellemc + +[update_catalog] +domain = sushy_oem_dellemc +output_dir = sushy_oem_dellemc/locale +input_file = sushy_oem_dellemc/locale/sushy_oem_dellemc.pot + +[extract_messages] +keywords = _ gettext ngettext l_ lazy_gettext +mapping_file = babel.cfg +output_file = sushy_oem_dellemc/locale/sushy_oem_dellemc.pot + +[build_releasenotes] +all_files = 1 +build-dir = releasenotes/build +source-dir = releasenotes/source + +[pbr] +autodoc_index_modules = True +api_doc_dir = reference/api +autodoc_exclude_modules = + sushy_oem_dellemc.tests.* diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..566d844 --- /dev/null +++ b/setup.py @@ -0,0 +1,29 @@ +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. +# +# 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. + +# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT +import setuptools + +# In python < 2.7.4, a lazy loading of package `pbr` will break +# setuptools if some other modules registered functions in `atexit`. +# solution from: http://bugs.python.org/issue15881#msg170215 +try: + import multiprocessing # noqa +except ImportError: + pass + +setuptools.setup( + setup_requires=['pbr>=2.0.0'], + pbr=True) diff --git a/sushy_oem_dellemc/__init__.py b/sushy_oem_dellemc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sushy_oem_dellemc/resources/__init__.py b/sushy_oem_dellemc/resources/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sushy_oem_dellemc/resources/manager/__init__.py b/sushy_oem_dellemc/resources/manager/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sushy_oem_dellemc/resources/manager/manager.py b/sushy_oem_dellemc/resources/manager/manager.py new file mode 100644 index 0000000..b066d8e --- /dev/null +++ b/sushy_oem_dellemc/resources/manager/manager.py @@ -0,0 +1,40 @@ +# 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 logging + +from sushy.resources.oem import base as oem_base + +LOG = logging.getLogger(__name__) + + +class DellManagerActionsField(oem_base.OEMActionsField): + import_system_configuration = oem_base.OEMActionField( + lambda key, **kwargs: key.endswith( + '#OemManager.ImportSystemConfiguration')) + + +class DellManagerExtension(oem_base.OEMExtensionResourceBase): + + _actions = DellManagerActionsField('Actions') + + def __init__(self, resource, *args, **kwargs): + """A class representing Manager OEM extension for Dell + + :param resource: The parent Manager resource instance + """ + super(DellManagerExtension, self).__init__( + resource, 'Dell', *args, **kwargs) + + @property + def import_system_configuration_uri(self): + return self._actions.import_system_configuration.target_uri diff --git a/sushy_oem_dellemc/tests/__init__.py b/sushy_oem_dellemc/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sushy_oem_dellemc/tests/unit/__init__.py b/sushy_oem_dellemc/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sushy_oem_dellemc/tests/unit/base.py b/sushy_oem_dellemc/tests/unit/base.py new file mode 100644 index 0000000..56d846a --- /dev/null +++ b/sushy_oem_dellemc/tests/unit/base.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +# Copyright 2019 OpenStack Foundation +# +# 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 oslotest import base + + +class TestCase(base.BaseTestCase): + """Test case base class for all unit tests""" diff --git a/sushy_oem_dellemc/tests/unit/json_samples/manager.json b/sushy_oem_dellemc/tests/unit/json_samples/manager.json new file mode 100644 index 0000000..64af169 --- /dev/null +++ b/sushy_oem_dellemc/tests/unit/json_samples/manager.json @@ -0,0 +1,275 @@ +{ + "@odata.context": "/redfish/v1/$metadata#Manager.Manager", + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1", + "@odata.type": "#Manager.v1_3_3.Manager", + "Actions": { + "#Manager.Reset": { + "ResetType@Redfish.AllowableValues": [ + "GracefulRestart" + ], + "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Manager.Reset" + }, + "Oem": { + "DellManager.v1_0_0#DellManager.ResetToDefaults": { + "ResetType@Redfish.AllowableValues": [ + "All", + "ResetAllWithRootDefaults", + "Default" + ], + "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/DellManager.ResetToDefaults" + }, + "OemManager.v1_0_0#OemManager.ExportSystemConfiguration": { + "ExportFormat@Redfish.AllowableValues": [ + "XML", + "JSON" + ], + "ExportUse@Redfish.AllowableValues": [ + "Default", + "Clone", + "Replace" + ], + "IncludeInExport@Redfish.AllowableValues": [ + "Default", + "IncludeReadOnly", + "IncludePasswordHashValues", + "IncludeReadOnly,IncludePasswordHashValues" + ], + "ShareParameters": { + "IgnoreCertificateWarning@Redfish.AllowableValues": [ + "Disabled", + "Enabled" + ], + "ProxySupport@Redfish.AllowableValues": [ + "Disabled", + "EnabledProxyDefault", + "Enabled" + ], + "ProxyType@Redfish.AllowableValues": [ + "HTTP", + "SOCKS4" + ], + "ShareType@Redfish.AllowableValues": [ + "LOCAL", + "NFS", + "CIFS", + "HTTP", + "HTTPS" + ], + "Target@Redfish.AllowableValues": [ + "ALL", + "IDRAC", + "BIOS", + "NIC", + "RAID" + ] + }, + "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager.ExportSystemConfiguration" + }, + "OemManager.v1_0_0#OemManager.ImportSystemConfiguration": { + "HostPowerState@Redfish.AllowableValues": [ + "On", + "Off" + ], + "ImportSystemConfiguration@Redfish.AllowableValues": [ + "TimeToWait", + "ImportBuffer" + ], + "ShareParameters": { + "IgnoreCertificateWarning@Redfish.AllowableValues": [ + "Disabled", + "Enabled" + ], + "ProxySupport@Redfish.AllowableValues": [ + "Disabled", + "EnabledProxyDefault", + "Enabled" + ], + "ProxyType@Redfish.AllowableValues": [ + "HTTP", + "SOCKS4" + ], + "ShareType@Redfish.AllowableValues": [ + "LOCAL", + "NFS", + "CIFS", + "HTTP", + "HTTPS" + ], + "Target@Redfish.AllowableValues": [ + "ALL", + "IDRAC", + "BIOS", + "NIC", + "RAID" + ] + }, + "ShutdownType@Redfish.AllowableValues": [ + "Graceful", + "Forced", + "NoReboot" + ], + "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager.ImportSystemConfiguration" + }, + "OemManager.v1_0_0#OemManager.ImportSystemConfigurationPreview": { + "ImportSystemConfigurationPreview@Redfish.AllowableValues": [ + "ImportBuffer" + ], + "ShareParameters": { + "IgnoreCertificateWarning@Redfish.AllowableValues": [ + "Disabled", + "Enabled" + ], + "ProxySupport@Redfish.AllowableValues": [ + "Disabled", + "EnabledProxyDefault", + "Enabled" + ], + "ProxyType@Redfish.AllowableValues": [ + "HTTP", + "SOCKS4" + ], + "ShareType@Redfish.AllowableValues": [ + "LOCAL", + "NFS", + "CIFS", + "HTTP", + "HTTPS" + ], + "Target@Redfish.AllowableValues": [ + "ALL" + ] + }, + "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager.ImportSystemConfigurationPreview" + } + } + }, + "CommandShell": { + "ConnectTypesSupported": [ + "SSH", + "Telnet", + "IPMI" + ], + "ConnectTypesSupported@odata.count": 3, + "MaxConcurrentSessions": 5, + "ServiceEnabled": true + }, + "DateTime": "2019-08-07T12:47:37-04:00", + "DateTimeLocalOffset": "-04:00", + "Description": "BMC", + "EthernetInterfaces": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces" + }, + "FirmwareVersion": "3.34.34.34", + "GraphicalConsole": { + "ConnectTypesSupported": [ + "KVMIP" + ], + "ConnectTypesSupported@odata.count": 1, + "MaxConcurrentSessions": 6, + "ServiceEnabled": true + }, + "HostInterfaces": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/HostInterfaces" + }, + "Id": "iDRAC.Embedded.1", + "Links": { + "ManagerForChassis": [ + { + "@odata.id": "/redfish/v1/Chassis/System.Embedded.1" + } + ], + "ManagerForChassis@odata.count": 1, + "ManagerForServers": [ + { + "@odata.id": "/redfish/v1/Systems/System.Embedded.1" + } + ], + "ManagerForServers@odata.count": 1, + "ManagerInChassis": { + "@odata.id": "/redfish/v1/Chassis/System.Embedded.1" + }, + "Oem": { + "Dell": { + "DellAttributes": [ + { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Attributes" + }, + { + "@odata.id": "/redfish/v1/Managers/System.Embedded.1/Attributes" + }, + { + "@odata.id": "/redfish/v1/Managers/LifecycleController.Embedded.1/Attributes" + } + ], + "DellAttributes@odata.count": 3, + "DellJobService": { + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellJobService" + }, + "DellLCService": { + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLCService" + }, + "DellLicenseCollection": { + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLicenseCollection" + }, + "DellLicenseManagementService": { + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLicenseManagementService" + }, + "DellPersistentStorageService": { + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellPersistentStorageService" + }, + "DellSwitchConnectionCollection": { + "@odata.id": "/redfish/v1/Dell/Systems/System.Embedded.1/NetworkPorts/DellSwitchConnectionCollection" + }, + "DelliDRACCardService": { + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DelliDRACCardService" + }, + "DellvFlashCollection": { + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellvFlashCollection" + }, + "Jobs": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs" + } + } + } + }, + "LogServices": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/LogServices" + }, + "ManagerType": "BMC", + "Model": "14G Monolithic", + "Name": "Manager", + "NetworkProtocol": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/NetworkProtocol" + }, + "Oem": { + "Dell": { + "DelliDRACCard": { + "@odata.context": "/redfish/v1/$metadata#DelliDRACCard.DelliDRACCard", + "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DelliDRACCard/iDRAC.Embedded.1-1%23IDRACinfo", + "@odata.type": "#DelliDRACCard.v1_0_0.DelliDRACCard", + "IPMIVersion": "2.0", + "URLString": "https://10.19.133.11:443" + } + } + }, + "PowerState": "On", + "Redundancy": [], + "Redundancy@odata.count": 0, + "SerialConsole": { + "ConnectTypesSupported": [], + "ConnectTypesSupported@odata.count": 0, + "MaxConcurrentSessions": 0, + "ServiceEnabled": false + }, + "SerialInterfaces": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/SerialInterfaces" + }, + "Status": { + "Health": "OK", + "State": "Enabled" + }, + "UUID": "3256444f-c0c7-3780-5310-00544c4c4544", + "VirtualMedia": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/VirtualMedia" + } +} diff --git a/sushy_oem_dellemc/tests/unit/json_samples/manager_collection.json b/sushy_oem_dellemc/tests/unit/json_samples/manager_collection.json new file mode 100644 index 0000000..df2fea2 --- /dev/null +++ b/sushy_oem_dellemc/tests/unit/json_samples/manager_collection.json @@ -0,0 +1,13 @@ +{ + "@odata.context": "/redfish/v1/$metadata#ManagerCollection.ManagerCollection", + "@odata.id": "/redfish/v1/Managers", + "@odata.type": "#ManagerCollection.ManagerCollection", + "Description": "BMC", + "Members": [ + { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1" + } + ], + "Members@odata.count": 1, + "Name": "Manager" +} diff --git a/sushy_oem_dellemc/tests/unit/json_samples/root.json b/sushy_oem_dellemc/tests/unit/json_samples/root.json new file mode 100644 index 0000000..2a161d2 --- /dev/null +++ b/sushy_oem_dellemc/tests/unit/json_samples/root.json @@ -0,0 +1,68 @@ +{ + "@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot", + "@odata.id": "/redfish/v1", + "@odata.type": "#ServiceRoot.v1_3_0.ServiceRoot", + "AccountService": { + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/AccountService" + }, + "Chassis": { + "@odata.id": "/redfish/v1/Chassis" + }, + "Description": "Root Service", + "EventService": { + "@odata.id": "/redfish/v1/EventService" + }, + "Fabrics": { + "@odata.id": "/redfish/v1/Fabrics" + }, + "Id": "RootService", + "JsonSchemas": { + "@odata.id": "/redfish/v1/JSONSchemas" + }, + "Links": { + "Sessions": { + "@odata.id": "/redfish/v1/Sessions" + } + }, + "Managers": { + "@odata.id": "/redfish/v1/Managers" + }, + "Name": "Root Service", + "Oem": { + "Dell": { + "@odata.context": "/redfish/v1/$metadata#DellServiceRoot.DellServiceRoot", + "@odata.type": "#DellServiceRoot.v1_0_0.ServiceRootSummary", + "IsBranded": 0, + "ManagerMACAddress": "4c:d9:8f:20:73:84", + "ServiceTag": "GTS7DV2" + } + }, + "Product": "Integrated Dell Remote Access Controller", + "ProtocolFeaturesSupported": { + "ExpandQuery": { + "ExpandAll": true, + "Levels": true, + "Links": true, + "MaxLevels": 1, + "NoLinks": true + }, + "FilterQuery": true, + "SelectQuery": true + }, + "RedfishVersion": "1.4.0", + "Registries": { + "@odata.id": "/redfish/v1/Registries" + }, + "SessionService": { + "@odata.id": "/redfish/v1/SessionService" + }, + "Systems": { + "@odata.id": "/redfish/v1/Systems" + }, + "Tasks": { + "@odata.id": "/redfish/v1/TaskService" + }, + "UpdateService": { + "@odata.id": "/redfish/v1/UpdateService" + } +} diff --git a/sushy_oem_dellemc/tests/unit/test_manager.py b/sushy_oem_dellemc/tests/unit/test_manager.py new file mode 100644 index 0000000..d98a491 --- /dev/null +++ b/sushy_oem_dellemc/tests/unit/test_manager.py @@ -0,0 +1,40 @@ +# Copyright 2017 Red Hat, 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 + +from sushy.resources.manager import manager +from sushy.tests.unit import base + + +class MainTestCase(base.TestCase): + + def setUp(self): + super(MainTestCase, self).setUp() + self.conn = mock.Mock() + with open('sushy_oem_dellemc/tests/unit/json_samples/' + 'manager.json') as f: + self.conn.get.return_value.json.return_value = json.load(f) + self.manager = manager.Manager(self.conn, '/redfish/v1/Managers/BMC', + redfish_version='1.0.2') + + def test_oem_vendors(self): + oem = self.manager.get_oem_extension('Dell') + + self.assertEqual( + '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' + '.ImportSystemConfiguration', + oem.import_system_configuration_uri) diff --git a/sushy_oem_dellemc/tests/unit/test_root.py b/sushy_oem_dellemc/tests/unit/test_root.py new file mode 100644 index 0000000..a24ee6d --- /dev/null +++ b/sushy_oem_dellemc/tests/unit/test_root.py @@ -0,0 +1,42 @@ +# Copyright 2017 Red Hat, 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 + +from sushy import main +from sushy.tests.unit import base + + +class RootTestCase(base.TestCase): + + @mock.patch('sushy.auth.SessionOrBasicAuth', autospec=True) + @mock.patch('sushy.connector.Connector', autospec=True) + @mock.patch('sushy.resources.sessionservice.sessionservice.' + 'SessionService', autospec=True) + def setUp(self, mock_session_service, mock_connector, mock_auth): + super(RootTestCase, self).setUp() + self.conn = mock.Mock() + self.sess_serv = mock.Mock() + self.sess_serv.create_session.return_value = (None, None) + mock_session_service.return_value = self.sess_serv + mock_connector.return_value = self.conn + with open('sushy_oem_dellemc/tests/unit/json_samples/root.json') as f: + self.conn.get.return_value.json.return_value = json.load(f) + self.root = main.Sushy('http://foo.bar:1234', + verify=True, auth=mock_auth) + + def test_oem_vendors(self): + self.assertEqual(['Dell'], self.root.oem_vendors) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..6f8ebee --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,18 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. + +hacking>=1.0.0,<1.1.0 # Apache-2.0 + +coverage!=4.4,>=4.0 # Apache-2.0 +python-subunit>=1.0.0 # Apache-2.0/BSD +sphinx!=1.6.6,!=1.6.7,>=1.6.2,<2.0.0;python_version=='2.7' # BSD +sphinx!=1.6.6,!=1.6.7,>=1.6.2;python_version>='3.4' # BSD +openstackdocstheme>=1.18.1 # Apache-2.0 +oslotest>=3.2.0 # Apache-2.0 +stestr>=2.0.0 # Apache-2.0 +testscenarios>=0.4 # Apache-2.0/BSD +testtools>=2.2.0 # MIT + +# releasenotes +reno>=2.5.0 # Apache-2.0 diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..3b3fa83 --- /dev/null +++ b/tox.ini @@ -0,0 +1,73 @@ +[tox] +minversion = 2.0 +envlist = py3,py27,pep8 +skipsdist = True + +[testenv] +usedevelop = True +setenv = + VIRTUAL_ENV={envdir} + PYTHONWARNINGS=default::DeprecationWarning +install_command = pip install {opts} {packages} +deps = + -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/master/upper-constraints.txt} + -r{toxinidir}/test-requirements.txt + -r{toxinidir}/requirements.txt +commands = stestr run --slowest {posargs} + +[testenv:pep8] +basepython = python3 +commands = flake8 {posargs} + +[testenv:venv] +basepython = python3 +commands = {posargs} + +[testenv:cover] +basepython = python3 +setenv = + {[testenv]setenv} + PYTHON=coverage run --parallel-mode +# After running this target, visit sushy_oem_dellemc/cover/index.html +# in your browser, to see a nicer presentation report with annotated +# HTML listings detailing missed lines. +commands = coverage erase + stestr run {posargs} + coverage combine + coverage report + coverage html + coverage xml -o cover/coverage.xml + +[testenv:docs] +basepython = python3 +commands = python setup.py build_sphinx + +[testenv:releasenotes] +basepython = python3 +commands = + sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html + +[testenv:debug] +basepython = python3 +commands = oslo_debug_helper -t sushy_oem_dellemc/tests {posargs} + +[flake8] +# E123, E125 skipped as they are invalid PEP-8. +show-source = True +ignore = E123,E125 +# [H106] Don't put vim configuration in source files. +# [H203] Use assertIs(Not)None to check for None. +# [H204] Use assert(Not)Equal to check for equality. +# [H205] Use assert(Greater|Less)(Equal) for comparison. +# [H210] Require 'autospec', 'spec', or 'spec_set' in mock.patch/mock.patch.object calls +# [H904] Delay string interpolations at logging calls. +enable-extensions=H106,H203,H204,H205,H210,H904 +builtins = _ +exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build + +[testenv:lower-constraints] +basepython = python3 +deps = + -c{toxinidir}/lower-constraints.txt + -r{toxinidir}/test-requirements.txt + -r{toxinidir}/requirements.txt