Rename drivers
to resources/systems
This change internally renames backend `drivers` abstraction to `resources/systems` drivers to set the stage for clear separation of independently emulated resources. This change is proposed in preparation of the upcoming Redfish "Managers", "Chassis", "VirtualMedia" and "IndicatorLED" resources implementation. No user-visible changes should be caused by this modification. Change-Id: I811aa18b7c55b1f9b573f7fcc479edf3619742e3
This commit is contained in:
parent
aae0242c81
commit
f206d8ca12
@ -21,8 +21,8 @@ import os
|
||||
import ssl
|
||||
import sys
|
||||
|
||||
from sushy_tools.emulator.drivers import libvirtdriver
|
||||
from sushy_tools.emulator.drivers import novadriver
|
||||
from sushy_tools.emulator.resources.systems import libvirtdriver
|
||||
from sushy_tools.emulator.resources.systems import novadriver
|
||||
from sushy_tools import error
|
||||
from sushy_tools.error import FishyError
|
||||
|
||||
@ -33,22 +33,22 @@ app = flask.Flask(__name__)
|
||||
# Turn off strict_slashes on all routes
|
||||
app.url_map.strict_slashes = False
|
||||
|
||||
DRIVER = None
|
||||
SYSTEMS = None
|
||||
|
||||
|
||||
def init_virt_driver(decorated_func):
|
||||
def init_systems(decorated_func):
|
||||
@functools.wraps(decorated_func)
|
||||
def decorator(*args, **kwargs):
|
||||
global DRIVER
|
||||
global SYSTEMS
|
||||
|
||||
if DRIVER is None:
|
||||
if SYSTEMS is None:
|
||||
|
||||
if 'OS_CLOUD' in os.environ:
|
||||
if not novadriver.is_loaded:
|
||||
app.logger.error('Nova driver not loaded')
|
||||
sys.exit(1)
|
||||
|
||||
DRIVER = novadriver.OpenStackDriver.initialize(
|
||||
SYSTEMS = novadriver.OpenStackDriver.initialize(
|
||||
app.config, os.environ['OS_CLOUD'])
|
||||
|
||||
else:
|
||||
@ -56,7 +56,7 @@ def init_virt_driver(decorated_func):
|
||||
app.logger.error('libvirt driver not loaded')
|
||||
sys.exit(1)
|
||||
|
||||
DRIVER = libvirtdriver.LibvirtDriver.initialize(
|
||||
SYSTEMS = libvirtdriver.LibvirtDriver.initialize(
|
||||
app.config,
|
||||
os.environ.get(
|
||||
'SUSHY_EMULATOR_LIBVIRT_URI',
|
||||
@ -64,13 +64,18 @@ def init_virt_driver(decorated_func):
|
||||
os.environ.get('SUSHY_EMULATOR_LIBVIRT_URL'))
|
||||
)
|
||||
|
||||
app.logger.debug('Running with %s', DRIVER.driver)
|
||||
app.logger.debug('Running with %s', SYSTEMS.driver)
|
||||
|
||||
return decorated_func(*args, **kwargs)
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def systems_driver():
|
||||
yield SYSTEMS()
|
||||
|
||||
|
||||
def instance_denied(**kwargs):
|
||||
deny = True
|
||||
|
||||
@ -100,11 +105,6 @@ def ensure_instance_access(decorated_func):
|
||||
return decorator
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def virt_driver():
|
||||
yield DRIVER()
|
||||
|
||||
|
||||
def returns_json(decorated_func):
|
||||
@functools.wraps(decorated_func)
|
||||
def decorator(*args, **kwargs):
|
||||
@ -131,18 +131,18 @@ def all_exception_handler(message):
|
||||
|
||||
|
||||
@app.route('/redfish/v1/')
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@returns_json
|
||||
def root_resource():
|
||||
return flask.render_template('root.json')
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems')
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@returns_json
|
||||
def system_collection_resource():
|
||||
with virt_driver() as driver:
|
||||
systems = [system for system in driver.systems
|
||||
with systems_driver() as systems:
|
||||
systems = [system for system in systems.systems
|
||||
if not instance_denied(identity=system)]
|
||||
|
||||
app.logger.debug('Serving systems list')
|
||||
@ -152,7 +152,7 @@ def system_collection_resource():
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>', methods=['GET', 'PATCH'])
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def system_resource(identity):
|
||||
@ -160,16 +160,17 @@ def system_resource(identity):
|
||||
|
||||
app.logger.debug('Serving resources for system "%s"', identity)
|
||||
|
||||
with virt_driver() as driver:
|
||||
with systems_driver() as systems:
|
||||
return flask.render_template(
|
||||
'system.json', identity=identity,
|
||||
name=driver.name(identity),
|
||||
uuid=driver.uuid(identity),
|
||||
power_state=driver.get_power_state(identity),
|
||||
total_memory_gb=driver.get_total_memory(identity),
|
||||
total_cpus=driver.get_total_cpus(identity),
|
||||
boot_source_target=driver.get_boot_device(identity),
|
||||
boot_source_mode=driver.get_boot_mode(identity)
|
||||
'system.json',
|
||||
identity=identity,
|
||||
name=systems.name(identity),
|
||||
uuid=systems.uuid(identity),
|
||||
power_state=systems.get_power_state(identity),
|
||||
total_memory_gb=systems.get_total_memory(identity),
|
||||
total_cpus=systems.get_total_cpus(identity),
|
||||
boot_source_target=systems.get_boot_device(identity),
|
||||
boot_source_mode=systems.get_boot_mode(identity)
|
||||
)
|
||||
|
||||
elif flask.request.method == 'PATCH':
|
||||
@ -177,7 +178,7 @@ def system_resource(identity):
|
||||
if not boot:
|
||||
return 'PATCH only works for the Boot element', 400
|
||||
|
||||
with virt_driver() as driver:
|
||||
with systems_driver() as systems:
|
||||
|
||||
target = boot.get('BootSourceOverrideTarget')
|
||||
|
||||
@ -186,7 +187,7 @@ def system_resource(identity):
|
||||
# device frequency to "continuous" so, we are ignoring the
|
||||
# BootSourceOverrideEnabled element here
|
||||
|
||||
driver.set_boot_device(identity, target)
|
||||
systems.set_boot_device(identity, target)
|
||||
|
||||
app.logger.info('Set boot device to "%s" for system "%s"',
|
||||
target, identity)
|
||||
@ -194,7 +195,7 @@ def system_resource(identity):
|
||||
mode = boot.get('BootSourceOverrideMode')
|
||||
|
||||
if mode:
|
||||
driver.set_boot_mode(identity, mode)
|
||||
systems.set_boot_mode(identity, mode)
|
||||
|
||||
app.logger.info('Set boot mode to "%s" for system "%s"',
|
||||
mode, identity)
|
||||
@ -203,31 +204,32 @@ def system_resource(identity):
|
||||
return ('Missing the BootSourceOverrideTarget and/or '
|
||||
'BootSourceOverrideMode element', 400)
|
||||
|
||||
return '', 204
|
||||
return '', 204
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/EthernetInterfaces',
|
||||
methods=['GET'])
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def ethernet_interfaces_collection(identity):
|
||||
with virt_driver() as driver:
|
||||
nics = driver.get_nics(identity)
|
||||
with systems_driver() as systems:
|
||||
|
||||
return flask.render_template(
|
||||
'ethernet_interfaces_collection.json', identity=identity,
|
||||
nics=nics)
|
||||
nics = systems.get_nics(identity)
|
||||
|
||||
return flask.render_template(
|
||||
'ethernet_interfaces_collection.json', identity=identity,
|
||||
nics=nics)
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/EthernetInterfaces/<nic_id>',
|
||||
methods=['GET'])
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def ethernet_interface(identity, nic_id):
|
||||
with virt_driver() as driver:
|
||||
nics = driver.get_nics(identity)
|
||||
with systems_driver() as systems:
|
||||
nics = systems.get_nics(identity)
|
||||
|
||||
for nic in nics:
|
||||
if nic['id'] == nic_id:
|
||||
@ -239,14 +241,14 @@ def ethernet_interface(identity, nic_id):
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/Actions/ComputerSystem.Reset',
|
||||
methods=['POST'])
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def system_reset_action(identity):
|
||||
reset_type = flask.request.json.get('ResetType')
|
||||
|
||||
with virt_driver() as driver:
|
||||
driver.set_power_state(identity, reset_type)
|
||||
with systems_driver() as systems:
|
||||
systems.set_power_state(identity, reset_type)
|
||||
|
||||
app.logger.info('System "%s" power state set to "%s"',
|
||||
identity, reset_type)
|
||||
@ -255,12 +257,12 @@ def system_reset_action(identity):
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/BIOS', methods=['GET'])
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def bios(identity):
|
||||
with virt_driver() as driver:
|
||||
bios = driver.get_bios(identity)
|
||||
with systems_driver() as systems:
|
||||
bios = systems.get_bios(identity)
|
||||
|
||||
app.logger.debug('Serving BIOS for system "%s"', identity)
|
||||
|
||||
@ -272,14 +274,14 @@ def bios(identity):
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/BIOS/Settings',
|
||||
methods=['GET', 'PATCH'])
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def bios_settings(identity):
|
||||
|
||||
if flask.request.method == 'GET':
|
||||
with virt_driver() as driver:
|
||||
bios = driver.get_bios(identity)
|
||||
with systems_driver() as systems:
|
||||
bios = systems.get_bios(identity)
|
||||
|
||||
app.logger.debug('Serving BIOS Settings for system "%s"', identity)
|
||||
|
||||
@ -291,8 +293,8 @@ def bios_settings(identity):
|
||||
elif flask.request.method == 'PATCH':
|
||||
attributes = flask.request.json.get('Attributes')
|
||||
|
||||
with virt_driver() as driver:
|
||||
driver.set_bios(identity, attributes)
|
||||
with systems_driver() as systems:
|
||||
systems.set_bios(identity, attributes)
|
||||
|
||||
app.logger.info('System "%s" BIOS attributes "%s" updated',
|
||||
identity, attributes)
|
||||
@ -301,13 +303,13 @@ def bios_settings(identity):
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/BIOS/Actions/Bios.ResetBios',
|
||||
methods=['POST'])
|
||||
@init_virt_driver
|
||||
@init_systems
|
||||
@ensure_instance_access
|
||||
@returns_json
|
||||
def system_reset_bios(identity):
|
||||
|
||||
with virt_driver() as driver:
|
||||
driver.reset_bios(identity)
|
||||
with systems_driver() as systems:
|
||||
systems.reset_bios(identity)
|
||||
|
||||
app.logger.info('BIOS for system "%s" reset', identity)
|
||||
|
||||
@ -357,7 +359,7 @@ def parse_args():
|
||||
|
||||
|
||||
def main():
|
||||
global DRIVER
|
||||
global SYSTEMS
|
||||
|
||||
args = parse_args()
|
||||
|
||||
@ -371,21 +373,21 @@ def main():
|
||||
app.logger.error('Nova driver not loaded')
|
||||
return 1
|
||||
|
||||
DRIVER = novadriver.OpenStackDriver.initialize(
|
||||
app.config, args.os_cloud)
|
||||
SYSTEMS = novadriver.OpenStackDriver.initialize(
|
||||
app.config, os_cloud)
|
||||
|
||||
else:
|
||||
if not libvirtdriver.is_loaded:
|
||||
app.logger.error('libvirt driver not loaded')
|
||||
return 1
|
||||
|
||||
DRIVER = libvirtdriver.LibvirtDriver.initialize(
|
||||
SYSTEMS = libvirtdriver.LibvirtDriver.initialize(
|
||||
app.config,
|
||||
args.libvirt_uri or
|
||||
app.config.get('SUSHY_EMULATOR_LIBVIRT_URI', '')
|
||||
)
|
||||
|
||||
app.logger.debug('Running with %s', DRIVER.driver)
|
||||
app.logger.debug('Running with %s', SYSTEMS.driver)
|
||||
|
||||
ssl_context = None
|
||||
|
||||
|
38
sushy_tools/emulator/resources/base.py
Normal file
38
sushy_tools/emulator/resources/base.py
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright 2019 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.
|
||||
|
||||
|
||||
class DriverBase(object):
|
||||
"""Common base for emulated Redfish resource drivers"""
|
||||
|
||||
@classmethod
|
||||
def initialize(cls, *args, **kwargs):
|
||||
"""Initialize class attributes
|
||||
|
||||
Since drivers may need to cache thing short-term. The emulator
|
||||
instantiates the driver every time it serves a client query.
|
||||
|
||||
Driver objects can cache whenever it makes sense for the duration
|
||||
of a single session. It is guaranteed that the driver object will
|
||||
never be reused for any other session.
|
||||
|
||||
The `initialize` method is provided to set up the driver in a way
|
||||
that would affect all the subsequent sessions.
|
||||
|
||||
:params *args: driver-specific parameters
|
||||
:params **kwargs: driver-specific parameters
|
||||
:returns: initialized driver class
|
||||
"""
|
||||
return cls
|
0
sushy_tools/emulator/resources/systems/__init__.py
Normal file
0
sushy_tools/emulator/resources/systems/__init__.py
Normal file
@ -16,30 +16,13 @@
|
||||
import abc
|
||||
import six
|
||||
|
||||
from sushy_tools.emulator.resources.base import DriverBase
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class AbstractDriver(object):
|
||||
class AbstractSystemsDriver(DriverBase):
|
||||
"""Base class for all virtualization drivers"""
|
||||
|
||||
@classmethod
|
||||
def initialize(cls, **kwargs):
|
||||
"""Initialize class attributes
|
||||
|
||||
Since drivers may need to cache thing short-term. The emulator
|
||||
instantiates the driver every time it serves a client query.
|
||||
|
||||
Driver objects can cache whenever it makes sense for the duration
|
||||
of a single session. It is guaranteed that the driver object will
|
||||
never be reused for any other session.
|
||||
|
||||
The `initialize` method is provided to set up the driver in a way
|
||||
that would affect all the subsequent sessions.
|
||||
|
||||
:params **kwargs: driver-specific parameters
|
||||
:returns: initialized driver class
|
||||
"""
|
||||
return cls
|
||||
|
||||
@abc.abstractproperty
|
||||
def driver(self):
|
||||
"""Return human-friendly driver information
|
@ -18,8 +18,8 @@ import logging
|
||||
import uuid
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from sushy_tools.emulator.drivers.base import AbstractDriver
|
||||
from sushy_tools.emulator.drivers import memoize
|
||||
from sushy_tools.emulator import memoize
|
||||
from sushy_tools.emulator.resources.systems.base import AbstractSystemsDriver
|
||||
from sushy_tools import error
|
||||
|
||||
try:
|
||||
@ -64,7 +64,7 @@ class libvirt_open(object):
|
||||
self._conn.close()
|
||||
|
||||
|
||||
class LibvirtDriver(AbstractDriver):
|
||||
class LibvirtDriver(AbstractSystemsDriver):
|
||||
"""Libvirt driver"""
|
||||
|
||||
# XML schema: https://libvirt.org/formatdomain.html#elementsOSBIOS
|
@ -16,8 +16,8 @@
|
||||
import logging
|
||||
import math
|
||||
|
||||
from sushy_tools.emulator.drivers.base import AbstractDriver
|
||||
from sushy_tools.emulator.drivers import memoize
|
||||
from sushy_tools.emulator import memoize
|
||||
from sushy_tools.emulator.resources.systems.base import AbstractSystemsDriver
|
||||
from sushy_tools import error
|
||||
|
||||
try:
|
||||
@ -32,7 +32,7 @@ is_loaded = bool(openstack)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OpenStackDriver(AbstractDriver):
|
||||
class OpenStackDriver(AbstractSystemsDriver):
|
||||
"""OpenStack driver"""
|
||||
|
||||
NOVA_POWER_STATE_ON = 1
|
@ -16,7 +16,7 @@ from oslotest import base
|
||||
from six.moves import mock
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from sushy_tools.emulator.drivers.libvirtdriver import LibvirtDriver
|
||||
from sushy_tools.emulator.resources.systems.libvirtdriver import LibvirtDriver
|
||||
from sushy_tools import error
|
||||
|
||||
|
@ -17,7 +17,7 @@ from munch import Munch
|
||||
from oslotest import base
|
||||
from six.moves import mock
|
||||
|
||||
from sushy_tools.emulator.drivers.novadriver import OpenStackDriver
|
||||
from sushy_tools.emulator.resources.systems.novadriver import OpenStackDriver
|
||||
from sushy_tools import error
|
||||
|
||||
|
@ -16,32 +16,33 @@ from six.moves import mock
|
||||
from sushy_tools.emulator import main
|
||||
|
||||
|
||||
@mock.patch.object(main, 'DRIVER') # This enables libvirt driver
|
||||
@mock.patch('sushy_tools.emulator.main.SYSTEMS')
|
||||
class EmulatorTestCase(base.BaseTestCase):
|
||||
|
||||
name = 'QEmu-fedora-i686'
|
||||
uuid = 'c7a5fdbd-cdaf-9455-926a-d65c16db1809'
|
||||
|
||||
def setUp(self):
|
||||
main.DRIVER = None
|
||||
main.SYSTEMS = None
|
||||
self.app = main.app.test_client()
|
||||
|
||||
super(EmulatorTestCase, self).setUp()
|
||||
|
||||
def test_error(self, driver_mock):
|
||||
driver_mock.return_value.get_power_state.side_effect = (
|
||||
Exception('Fish is dead'))
|
||||
def test_error(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.get_power_state.side_effect = Exception('Fish is dead')
|
||||
response = self.app.get('/redfish/v1/Systems/' + self.uuid)
|
||||
|
||||
self.assertEqual(500, response.status_code)
|
||||
|
||||
def test_root_resource(self, driver_mock):
|
||||
def test_root_resource(self, systems_mock):
|
||||
response = self.app.get('/redfish/v1/')
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertEqual('RedvirtService', response.json['Id'])
|
||||
|
||||
def test_collection_resource(self, driver_mock):
|
||||
type(driver_mock.return_value).systems = mock.PropertyMock(
|
||||
def test_collection_resource(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
type(systems_mock).systems = mock.PropertyMock(
|
||||
return_value=['host0', 'host1'])
|
||||
response = self.app.get('/redfish/v1/Systems')
|
||||
self.assertEqual(200, response.status_code)
|
||||
@ -50,13 +51,14 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
self.assertEqual({'@odata.id': '/redfish/v1/Systems/host1'},
|
||||
response.json['Members'][1])
|
||||
|
||||
def test_system_resource_get(self, driver_mock):
|
||||
driver_mock.return_value.uuid.return_value = 'zzzz-yyyy-xxxx'
|
||||
driver_mock.return_value.get_power_state.return_value = 'On'
|
||||
driver_mock.return_value.get_total_memory.return_value = 1
|
||||
driver_mock.return_value.get_total_cpus.return_value = 2
|
||||
driver_mock.return_value.get_boot_device.return_value = 'Cd'
|
||||
driver_mock.return_value.get_boot_mode.return_value = 'Legacy'
|
||||
def test_system_resource_get(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.uuid.return_value = 'zzzz-yyyy-xxxx'
|
||||
systems_mock.get_power_state.return_value = 'On'
|
||||
systems_mock.get_total_memory.return_value = 1
|
||||
systems_mock.get_total_cpus.return_value = 2
|
||||
systems_mock.get_boot_device.return_value = 'Cd'
|
||||
systems_mock.get_boot_mode.return_value = 'Legacy'
|
||||
|
||||
response = self.app.get('/redfish/v1/Systems/xxxx-yyyy-zzzz')
|
||||
|
||||
@ -72,108 +74,116 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
self.assertEqual(
|
||||
'Legacy', response.json['Boot']['BootSourceOverrideMode'])
|
||||
|
||||
def test_system_resource_patch(self, driver_mock):
|
||||
def test_system_resource_patch(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'Boot': {'BootSourceOverrideTarget': 'Cd'}}
|
||||
response = self.app.patch('/redfish/v1/Systems/xxxx-yyyy-zzzz',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_boot_device = driver_mock.return_value.set_boot_device
|
||||
set_boot_device = systems_mock.set_boot_device
|
||||
set_boot_device.assert_called_once_with('xxxx-yyyy-zzzz', 'Cd')
|
||||
|
||||
def test_system_reset_action_on(self, driver_mock):
|
||||
def test_system_reset_action_on(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'ResetType': 'On'}
|
||||
response = self.app.post(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/Actions/ComputerSystem.Reset',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_power_state = driver_mock.return_value.set_power_state
|
||||
set_power_state = systems_mock.set_power_state
|
||||
set_power_state.assert_called_once_with('xxxx-yyyy-zzzz', 'On')
|
||||
|
||||
def test_system_reset_action_forceon(self, driver_mock):
|
||||
def test_system_reset_action_forceon(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'ResetType': 'ForceOn'}
|
||||
response = self.app.post(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/Actions/ComputerSystem.Reset',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_power_state = driver_mock.return_value.set_power_state
|
||||
set_power_state = systems_mock.set_power_state
|
||||
set_power_state.assert_called_once_with('xxxx-yyyy-zzzz', 'ForceOn')
|
||||
|
||||
def test_system_reset_action_forceoff(self, driver_mock):
|
||||
def test_system_reset_action_forceoff(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'ResetType': 'ForceOff'}
|
||||
response = self.app.post(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/Actions/ComputerSystem.Reset',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_power_state = driver_mock.return_value.set_power_state
|
||||
set_power_state = systems_mock.set_power_state
|
||||
set_power_state.assert_called_once_with('xxxx-yyyy-zzzz', 'ForceOff')
|
||||
|
||||
def test_system_reset_action_shutdown(self, driver_mock):
|
||||
def test_system_reset_action_shutdown(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'ResetType': 'GracefulShutdown'}
|
||||
response = self.app.post(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/Actions/ComputerSystem.Reset',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_power_state = driver_mock.return_value.set_power_state
|
||||
set_power_state = systems_mock.set_power_state
|
||||
set_power_state.assert_called_once_with(
|
||||
'xxxx-yyyy-zzzz', 'GracefulShutdown')
|
||||
|
||||
def test_system_reset_action_restart(self, driver_mock):
|
||||
def test_system_reset_action_restart(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'ResetType': 'GracefulRestart'}
|
||||
response = self.app.post(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/Actions/ComputerSystem.Reset',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_power_state = driver_mock.return_value.set_power_state
|
||||
set_power_state = systems_mock.set_power_state
|
||||
set_power_state.assert_called_once_with(
|
||||
'xxxx-yyyy-zzzz', 'GracefulRestart')
|
||||
|
||||
def test_system_reset_action_forcerestart(self, driver_mock):
|
||||
def test_system_reset_action_forcerestart(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'ResetType': 'ForceRestart'}
|
||||
response = self.app.post(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/Actions/ComputerSystem.Reset',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_power_state = driver_mock.return_value.set_power_state
|
||||
set_power_state = systems_mock.set_power_state
|
||||
set_power_state.assert_called_once_with(
|
||||
'xxxx-yyyy-zzzz', 'ForceRestart')
|
||||
|
||||
def test_system_reset_action_nmi(self, driver_mock):
|
||||
def test_system_reset_action_nmi(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'ResetType': 'Nmi'}
|
||||
response = self.app.post(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/Actions/ComputerSystem.Reset',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
set_power_state = driver_mock.return_value.set_power_state
|
||||
set_power_state = systems_mock.set_power_state
|
||||
set_power_state.assert_called_once_with('xxxx-yyyy-zzzz', 'Nmi')
|
||||
|
||||
@mock.patch.dict(main.app.config, {}, clear=True)
|
||||
def test_instance_denied_allow_all(self, driver_mock):
|
||||
def test_instance_denied_allow_all(self, systems_mock):
|
||||
self.assertFalse(main.instance_denied(identity='x'))
|
||||
|
||||
@mock.patch.dict(
|
||||
main.app.config, {'SUSHY_EMULATOR_ALLOWED_INSTANCES': {}})
|
||||
def test_instance_denied_disallow_all(self, driver_mock):
|
||||
def test_instance_denied_disallow_all(self, systems_mock):
|
||||
self.assertTrue(main.instance_denied(identity='a'))
|
||||
|
||||
def test_instance_denied_undefined_option(self, driver_mock):
|
||||
def test_instance_denied_undefined_option(self, systems_mock):
|
||||
with mock.patch.dict(main.app.config):
|
||||
main.app.config.pop('SUSHY_EMULATOR_ALLOWED_INSTANCES', None)
|
||||
self.assertFalse(main.instance_denied(identity='a'))
|
||||
|
||||
@mock.patch.dict(
|
||||
main.app.config, {'SUSHY_EMULATOR_ALLOWED_INSTANCES': {'a'}})
|
||||
def test_instance_denied_allow_some(self, driver_mock):
|
||||
def test_instance_denied_allow_some(self, systems_mock):
|
||||
self.assertFalse(main.instance_denied(identity='a'))
|
||||
|
||||
@mock.patch.dict(
|
||||
main.app.config, {'SUSHY_EMULATOR_ALLOWED_INSTANCES': {'a'}})
|
||||
def test_instance_denied_disallow_some(self, driver_mock):
|
||||
def test_instance_denied_disallow_some(self, systems_mock):
|
||||
self.assertTrue(main.instance_denied(identity='b'))
|
||||
|
||||
def test_get_bios(self, driver_mock):
|
||||
driver_mock.return_value.get_bios.return_value = {
|
||||
"attribute 1": "value 1",
|
||||
"attribute 2": "value 2"}
|
||||
def test_get_bios(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.get_bios.return_value = {"attribute 1": "value 1",
|
||||
"attribute 2": "value 2"}
|
||||
response = self.app.get('/redfish/v1/Systems/' + self.uuid + '/BIOS')
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
@ -182,9 +192,10 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
"attribute 2": "value 2"},
|
||||
response.json['Attributes'])
|
||||
|
||||
def test_get_bios_existing(self, driver_mock):
|
||||
driver_mock.return_value.get_bios.return_value = {
|
||||
"attribute 1": "value 1", "attribute 2": "value 2"}
|
||||
def test_get_bios_existing(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.get_bios.return_value = {"attribute 1": "value 1",
|
||||
"attribute 2": "value 2"}
|
||||
response = self.app.get(
|
||||
'/redfish/v1/Systems/' + self.uuid + '/BIOS/Settings')
|
||||
|
||||
@ -194,35 +205,43 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
"attribute 2": "value 2"},
|
||||
response.json['Attributes'])
|
||||
|
||||
def test_bios_settings_patch(self, driver_mock):
|
||||
def test_bios_settings_patch(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'Attributes': {'key': 'value'}}
|
||||
self.app.driver = systems_mock
|
||||
response = self.app.patch(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/BIOS/Settings',
|
||||
json=data)
|
||||
self.assertEqual(204, response.status_code)
|
||||
driver_mock.return_value.set_bios.assert_called_once_with(
|
||||
'xxxx-yyyy-zzzz', {'key': 'value'})
|
||||
systems_mock.set_bios.assert_called_once_with('xxxx-yyyy-zzzz',
|
||||
{'key': 'value'})
|
||||
|
||||
def test_set_bios(self, driver_mock):
|
||||
def test_set_bios(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
data = {'Attributes': {'key': 'value'}}
|
||||
self.app.driver = systems_mock
|
||||
response = self.app.patch(
|
||||
'/redfish/v1/Systems/xxxx-yyyy-zzzz/BIOS/Settings',
|
||||
json=data)
|
||||
|
||||
self.assertEqual(204, response.status_code)
|
||||
driver_mock.return_value.set_bios.assert_called_once_with(
|
||||
systems_mock.set_bios.assert_called_once_with(
|
||||
'xxxx-yyyy-zzzz', data['Attributes'])
|
||||
|
||||
def test_reset_bios(self, driver_mock):
|
||||
def test_reset_bios(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
self.app.driver = systems_mock
|
||||
response = self.app.post('/redfish/v1/Systems/' + self.uuid +
|
||||
'/BIOS/Actions/Bios.ResetBios')
|
||||
self.assertEqual(204, response.status_code)
|
||||
driver_mock.return_value.reset_bios.assert_called_once_with(self.uuid)
|
||||
systems_mock.reset_bios.assert_called_once_with(self.uuid)
|
||||
|
||||
def test_ethernet_interfaces_collection(self, driver_mock):
|
||||
driver_mock.return_value.get_nics.return_value = [
|
||||
{'id': 'nic1', 'mac': '52:54:00:4e:5d:37'},
|
||||
{'id': 'nic2', 'mac': '00:11:22:33:44:55'}]
|
||||
def test_ethernet_interfaces_collection(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.get_nics.return_value = [{'id': 'nic1',
|
||||
'mac': '52:54:00:4e:5d:37'},
|
||||
{'id': 'nic2',
|
||||
'mac': '00:11:22:33:44:55'}]
|
||||
response = self.app.get('redfish/v1/Systems/' + self.uuid +
|
||||
'/EthernetInterfaces')
|
||||
|
||||
@ -236,8 +255,9 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
'/EthernetInterfaces/nic2'],
|
||||
[m['@odata.id'] for m in response.json['Members']])
|
||||
|
||||
def test_ethernet_interfaces_collection_empty(self, driver_mock):
|
||||
driver_mock.return_value.get_nics.return_value = []
|
||||
def test_ethernet_interfaces_collection_empty(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.get_nics.return_value = []
|
||||
response = self.app.get('redfish/v1/Systems/' + self.uuid +
|
||||
'/EthernetInterfaces')
|
||||
|
||||
@ -247,10 +267,12 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
self.assertEqual(0, response.json['Members@odata.count'])
|
||||
self.assertEqual([], response.json['Members'])
|
||||
|
||||
def test_ethernet_interface(self, driver_mock):
|
||||
driver_mock.return_value.get_nics.return_value = [
|
||||
{'id': 'nic1', 'mac': '52:54:00:4e:5d:37'},
|
||||
{'id': 'nic2', 'mac': '00:11:22:33:44:55'}]
|
||||
def test_ethernet_interface(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.get_nics.return_value = [{'id': 'nic1',
|
||||
'mac': '52:54:00:4e:5d:37'},
|
||||
{'id': 'nic2',
|
||||
'mac': '00:11:22:33:44:55'}]
|
||||
response = self.app.get('/redfish/v1/Systems/' + self.uuid +
|
||||
'/EthernetInterfaces/nic2')
|
||||
|
||||
@ -265,10 +287,12 @@ class EmulatorTestCase(base.BaseTestCase):
|
||||
'/EthernetInterfaces/nic2',
|
||||
response.json['@odata.id'])
|
||||
|
||||
def test_ethernet_interface_not_found(self, driver_mock):
|
||||
driver_mock.return_value.get_nics.return_value = [
|
||||
{'id': 'nic1', 'mac': '52:54:00:4e:5d:37'},
|
||||
{'id': 'nic2', 'mac': '00:11:22:33:44:55'}]
|
||||
def test_ethernet_interface_not_found(self, systems_mock):
|
||||
systems_mock = systems_mock.return_value
|
||||
systems_mock.get_nics.return_value = [{'id': 'nic1',
|
||||
'mac': '52:54:00:4e:5d:37'},
|
||||
{'id': 'nic2',
|
||||
'mac': '00:11:22:33:44:55'}]
|
||||
response = self.app.get('/redfish/v1/Systems/' + self.uuid +
|
||||
'/EthernetInterfaces/nic3')
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
from oslotest import base
|
||||
|
||||
from sushy_tools.emulator.drivers import memoize
|
||||
from sushy_tools.emulator import memoize
|
||||
|
||||
|
||||
class MemoizeTestCase(base.BaseTestCase):
|
||||
|
Loading…
x
Reference in New Issue
Block a user