Removes agent mixin from oneview drivers
This patch removes the agent mixin interface from oneview drivers and adds a flag based solution instead. Once a set boot device operation needs to be performed, the operation is stored to driver_internal_info until the server power on. Before power the server on again, the operation stored is performed and then the server is powered on. Change-Id: I8dabf7ef1ff6e44c062310c5cb3509e545585c0a Closes-Bug: #1503855
This commit is contained in:
parent
5187e80f03
commit
8f45317d43
@ -1,3 +1,4 @@
|
||||
# Copyright 2017 Hewlett Packard Enterprise Development Company LP.
|
||||
# Copyright 2015 Hewlett Packard Development Company, LP
|
||||
# Copyright 2015 Universidade Federal de Campina Grande
|
||||
#
|
||||
@ -236,26 +237,41 @@ def _verify_node_info(node_namespace, node_info_dict, info_required):
|
||||
def node_has_server_profile(func):
|
||||
"""Checks if the node's Server Hardware has a Server Profile associated.
|
||||
|
||||
Decorator to execute before the function execution if the Server Profile
|
||||
is applied to the Server Hardware.
|
||||
|
||||
:param func: a given decorated function.
|
||||
"""
|
||||
def inner(self, *args, **kwargs):
|
||||
oneview_client = self.oneview_client
|
||||
task = args[0]
|
||||
oneview_info = get_oneview_info(task.node)
|
||||
try:
|
||||
node_has_server_profile = (
|
||||
oneview_client.get_server_profile_from_hardware(oneview_info)
|
||||
)
|
||||
except oneview_exceptions.OneViewException as oneview_exc:
|
||||
LOG.error(
|
||||
"Failed to get server profile from OneView appliance for"
|
||||
" node %(node)s. Error: %(message)s",
|
||||
{"node": task.node.uuid, "message": oneview_exc}
|
||||
)
|
||||
raise exception.OneViewError(error=oneview_exc)
|
||||
if not node_has_server_profile:
|
||||
raise exception.OperationNotPermitted(
|
||||
_("A Server Profile is not associated with node %s.") %
|
||||
task.node.uuid
|
||||
)
|
||||
has_server_profile(task, oneview_client)
|
||||
return func(self, *args, **kwargs)
|
||||
return inner
|
||||
|
||||
|
||||
def has_server_profile(task, oneview_client):
|
||||
"""Checks if the node's Server Hardware has a Server Profile associated.
|
||||
|
||||
Function to check if the Server Profile is applied to the Server Hardware.
|
||||
|
||||
:param oneview_client: an instance of the OneView client
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
"""
|
||||
oneview_info = get_oneview_info(task.node)
|
||||
try:
|
||||
node_has_server_profile = (
|
||||
oneview_client.get_server_profile_from_hardware(oneview_info)
|
||||
)
|
||||
except oneview_exceptions.OneViewException as oneview_exc:
|
||||
LOG.error(
|
||||
"Failed to get server profile from OneView appliance for"
|
||||
" node %(node)s. Error: %(message)s",
|
||||
{"node": task.node.uuid, "message": oneview_exc}
|
||||
)
|
||||
raise exception.OneViewError(error=oneview_exc)
|
||||
if not node_has_server_profile:
|
||||
raise exception.OperationNotPermitted(
|
||||
_("A Server Profile is not associated with node %s.") %
|
||||
task.node.uuid
|
||||
)
|
||||
|
@ -1,3 +1,4 @@
|
||||
# Copyright 2017 Hewlett Packard Enterprise Development Company LP.
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development LP.
|
||||
# Copyright 2016 Universidade Federal de Campina Grande
|
||||
# All Rights Reserved.
|
||||
@ -19,17 +20,12 @@ import abc
|
||||
from futurist import periodics
|
||||
from ironic_lib import metrics_utils
|
||||
from oslo_log import log as logging
|
||||
import retrying
|
||||
import six
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.common.i18n import _
|
||||
from ironic.common import states
|
||||
from ironic.conductor import utils as manager_utils
|
||||
from ironic.conf import CONF
|
||||
from ironic.drivers.modules import agent
|
||||
from ironic.drivers.modules import agent_base_vendor
|
||||
from ironic.drivers.modules import deploy_utils as ironic_deploy_utils
|
||||
from ironic.drivers.modules import iscsi_deploy
|
||||
from ironic.drivers.modules.oneview import common
|
||||
from ironic.drivers.modules.oneview import deploy_utils
|
||||
@ -266,94 +262,7 @@ class OneViewIscsiDeploy(iscsi_deploy.ISCSIDeploy, OneViewPeriodicTasks):
|
||||
super(OneViewIscsiDeploy, self).tear_down_cleaning(task)
|
||||
|
||||
|
||||
# NOTE (thiagop): We overwrite this interface because we cannot change the boot
|
||||
# device of OneView managed blades while they are still powered on. We moved
|
||||
# the call of node_set_boot_device from reboot_to_instance to
|
||||
# reboot_and_finish_deploy and changed the behavior to shutdown the node before
|
||||
# doing it.
|
||||
# TODO(thiagop): remove this interface once bug/1503855 is fixed
|
||||
class OneViewAgentDeployMixin(object):
|
||||
|
||||
@METRICS.timer('OneViewAgentDeployMixin.reboot_to_instance')
|
||||
def reboot_to_instance(self, task, **kwargs):
|
||||
task.process_event('resume')
|
||||
node = task.node
|
||||
error = self.check_deploy_success(node)
|
||||
if error is not None:
|
||||
# TODO(jimrollenhagen) power off if using neutron dhcp to
|
||||
# align with pxe driver?
|
||||
msg = (_('node %(node)s command status errored: %(error)s') %
|
||||
{'node': node.uuid, 'error': error})
|
||||
LOG.error(msg)
|
||||
ironic_deploy_utils.set_failed_state(task, msg)
|
||||
return
|
||||
|
||||
LOG.info('Image successfully written to node %s', node.uuid)
|
||||
LOG.debug('Rebooting node %s to instance', node.uuid)
|
||||
|
||||
self.reboot_and_finish_deploy(task)
|
||||
|
||||
# NOTE(TheJulia): If we deployed a whole disk image, we
|
||||
# should expect a whole disk image and clean-up the tftp files
|
||||
# on-disk incase the node is disregarding the boot preference.
|
||||
# TODO(rameshg87): Not all in-tree drivers using reboot_to_instance
|
||||
# have a boot interface. So include a check for now. Remove this
|
||||
# check once all in-tree drivers have a boot interface.
|
||||
if task.driver.boot:
|
||||
task.driver.boot.clean_up_ramdisk(task)
|
||||
|
||||
@METRICS.timer('OneViewAgentDeployMixin.reboot_and_finish_deploy')
|
||||
def reboot_and_finish_deploy(self, task):
|
||||
"""Helper method to trigger reboot on the node and finish deploy.
|
||||
|
||||
This method initiates a reboot on the node. On success, it
|
||||
marks the deploy as complete. On failure, it logs the error
|
||||
and marks deploy as failure.
|
||||
|
||||
:param task: a TaskManager object containing the node
|
||||
:raises: InstanceDeployFailure, if node reboot failed.
|
||||
"""
|
||||
wait = CONF.agent.post_deploy_get_power_state_retry_interval * 1000
|
||||
attempts = CONF.agent.post_deploy_get_power_state_retries + 1
|
||||
|
||||
@retrying.retry(
|
||||
stop_max_attempt_number=attempts,
|
||||
retry_on_result=lambda state: state != states.POWER_OFF,
|
||||
wait_fixed=wait
|
||||
)
|
||||
def _wait_until_powered_off(task):
|
||||
return task.driver.power.get_power_state(task)
|
||||
|
||||
node = task.node
|
||||
|
||||
try:
|
||||
try:
|
||||
self._client.power_off(node)
|
||||
_wait_until_powered_off(task)
|
||||
except Exception as e:
|
||||
LOG.warning(
|
||||
'Failed to soft power off node %(node_uuid)s '
|
||||
'in at least %(timeout)d seconds. Error: %(error)s',
|
||||
{'node_uuid': node.uuid,
|
||||
'timeout': (wait * (attempts - 1)) / 1000,
|
||||
'error': e})
|
||||
manager_utils.node_power_action(task, states.POWER_OFF)
|
||||
|
||||
manager_utils.node_set_boot_device(task, 'disk',
|
||||
persistent=True)
|
||||
manager_utils.node_power_action(task, states.POWER_ON)
|
||||
except Exception as e:
|
||||
msg = (_('Error rebooting node %(node)s after deploy. '
|
||||
'Error: %(error)s') %
|
||||
{'node': node.uuid, 'error': e})
|
||||
agent_base_vendor.log_and_raise_deployment_error(task, msg)
|
||||
|
||||
task.process_event('done')
|
||||
LOG.info('Deployment to node %s done', task.node.uuid)
|
||||
|
||||
|
||||
class OneViewAgentDeploy(OneViewAgentDeployMixin, agent.AgentDeploy,
|
||||
OneViewPeriodicTasks):
|
||||
class OneViewAgentDeploy(agent.AgentDeploy, OneViewPeriodicTasks):
|
||||
"""Class for OneView Agent deployment driver."""
|
||||
|
||||
oneview_driver = common.AGENT_PXE_ONEVIEW
|
||||
|
@ -1,4 +1,4 @@
|
||||
#
|
||||
# Copyright 2017 Hewlett Packard Enterprise Development Company LP.
|
||||
# Copyright 2015 Hewlett Packard Development Company, LP
|
||||
# Copyright 2015 Universidade Federal de Campina Grande
|
||||
#
|
||||
@ -44,6 +44,59 @@ BOOT_DEVICE_OV_TO_GENERIC = {
|
||||
oneview_exceptions = importutils.try_import('oneview_client.exceptions')
|
||||
|
||||
|
||||
def set_boot_device(task):
|
||||
"""Sets the boot device for a node.
|
||||
|
||||
Sets the boot device to use on next reboot of the node.
|
||||
|
||||
:param task: a task from TaskManager.
|
||||
:raises: InvalidParameterValue if an invalid boot device is
|
||||
specified.
|
||||
:raises: OperationNotPermitted if the server has no server profile or
|
||||
if the server is already powered on.
|
||||
:raises: OneViewError if the communication with OneView fails
|
||||
"""
|
||||
oneview_client = common.get_oneview_client()
|
||||
common.has_server_profile(task, oneview_client)
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = driver_internal_info.get('next_boot_device')
|
||||
|
||||
if next_boot_device:
|
||||
boot_device = next_boot_device.get('boot_device')
|
||||
persistent = next_boot_device.get('persistent')
|
||||
|
||||
if boot_device not in sorted(BOOT_DEVICE_MAPPING_TO_OV):
|
||||
raise exception.InvalidParameterValue(
|
||||
_("Invalid boot device %s specified.") % boot_device)
|
||||
|
||||
LOG.debug("Setting boot device to %(boot_device)s and "
|
||||
"persistent to %(persistent)s for node %(node)s",
|
||||
{"boot_device": boot_device, "persistent": persistent,
|
||||
"node": task.node.uuid})
|
||||
|
||||
try:
|
||||
oneview_info = common.get_oneview_info(task.node)
|
||||
device_to_oneview = BOOT_DEVICE_MAPPING_TO_OV.get(boot_device)
|
||||
oneview_client.set_boot_device(oneview_info,
|
||||
device_to_oneview,
|
||||
onetime=not persistent)
|
||||
driver_internal_info.pop('next_boot_device', None)
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
task.node.save()
|
||||
except oneview_exceptions.OneViewException as oneview_exc:
|
||||
msg = (_(
|
||||
"Error setting boot device on OneView. Error: %s")
|
||||
% oneview_exc
|
||||
)
|
||||
raise exception.OneViewError(error=msg)
|
||||
|
||||
else:
|
||||
LOG.debug("Not going to set boot device because there is no "
|
||||
"'next_boot_device' on driver_internal_info "
|
||||
"for the %(node)s",
|
||||
{"node": task.node.uuid})
|
||||
|
||||
|
||||
class OneViewManagement(base.ManagementInterface):
|
||||
|
||||
def __init__(self):
|
||||
@ -99,9 +152,11 @@ class OneViewManagement(base.ManagementInterface):
|
||||
@task_manager.require_exclusive_lock
|
||||
@common.node_has_server_profile
|
||||
def set_boot_device(self, task, device, persistent=False):
|
||||
"""Sets the boot device for a node.
|
||||
"""Set the next boot device to the node.
|
||||
|
||||
Sets the boot device to use on next reboot of the node.
|
||||
Sets the boot device to the node next_boot_device on
|
||||
driver_internal_info namespace. The operation will be
|
||||
performed before the next node power on.
|
||||
|
||||
:param task: a task from TaskManager.
|
||||
:param device: the boot device, one of the supported devices
|
||||
@ -111,36 +166,32 @@ class OneViewManagement(base.ManagementInterface):
|
||||
Default: False.
|
||||
:raises: InvalidParameterValue if an invalid boot device is
|
||||
specified.
|
||||
:raises: OperationNotPermitted if the server has no server profile or
|
||||
if the server is already powered on.
|
||||
:raises: OneViewError if the communication with OneView fails
|
||||
"""
|
||||
oneview_info = common.get_oneview_info(task.node)
|
||||
|
||||
if device not in self.get_supported_boot_devices(task):
|
||||
raise exception.InvalidParameterValue(
|
||||
_("Invalid boot device %s specified.") % device)
|
||||
|
||||
LOG.debug("Setting boot device to %(device)s for node %(node)s",
|
||||
{"device": device, "node": task.node.uuid})
|
||||
try:
|
||||
device_to_oneview = BOOT_DEVICE_MAPPING_TO_OV.get(device)
|
||||
self.oneview_client.set_boot_device(oneview_info,
|
||||
device_to_oneview,
|
||||
onetime=not persistent)
|
||||
except oneview_exceptions.OneViewException as oneview_exc:
|
||||
msg = (_(
|
||||
"Error setting boot device on OneView. Error: %s")
|
||||
% oneview_exc
|
||||
)
|
||||
raise exception.OneViewError(error=msg)
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = {'boot_device': device,
|
||||
'persistent': persistent}
|
||||
driver_internal_info['next_boot_device'] = next_boot_device
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
task.node.save()
|
||||
LOG.debug("The 'next_boot_device' flag was updated on "
|
||||
"driver_internal_info with device=%(boot_device)s "
|
||||
"and persistent=%(persistent)s for the node "
|
||||
"%(node)s",
|
||||
{"boot_device": device, "persistent": persistent,
|
||||
"node": task.node.uuid})
|
||||
|
||||
@METRICS.timer('OneViewManagement.get_boot_device')
|
||||
@common.node_has_server_profile
|
||||
def get_boot_device(self, task):
|
||||
"""Get the current boot device for the task's node.
|
||||
"""Get the current boot device from the node.
|
||||
|
||||
Provides the current boot device of the node.
|
||||
Gets the boot device from the node 'next_boot_device on
|
||||
driver_internal_info namespace if exists. Gets through
|
||||
a request to OneView otherwise.
|
||||
|
||||
:param task: a task from TaskManager.
|
||||
:returns: a dictionary containing:
|
||||
@ -153,6 +204,12 @@ class OneViewManagement(base.ManagementInterface):
|
||||
:raises: InvalidParameterValue if the boot device is unknown
|
||||
:raises: OneViewError if the communication with OneView fails
|
||||
"""
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = driver_internal_info.get('next_boot_device')
|
||||
|
||||
if next_boot_device:
|
||||
return next_boot_device
|
||||
|
||||
oneview_info = common.get_oneview_info(task.node)
|
||||
|
||||
try:
|
||||
|
@ -1,4 +1,4 @@
|
||||
#
|
||||
# Copyright 2017 Hewlett Packard Enterprise Development Company LP.
|
||||
# Copyright 2015 Hewlett Packard Development Company, LP
|
||||
# Copyright 2015 Universidade Federal de Campina Grande
|
||||
#
|
||||
@ -25,6 +25,7 @@ from ironic.conductor import task_manager
|
||||
from ironic.drivers import base
|
||||
from ironic.drivers.modules.oneview import common
|
||||
from ironic.drivers.modules.oneview import deploy_utils
|
||||
from ironic.drivers.modules.oneview import management
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -130,11 +131,13 @@ class OneViewPower(base.PowerInterface):
|
||||
|
||||
try:
|
||||
if power_state == states.POWER_ON:
|
||||
management.set_boot_device(task)
|
||||
self.oneview_client.power_on(oneview_info)
|
||||
elif power_state == states.POWER_OFF:
|
||||
self.oneview_client.power_off(oneview_info)
|
||||
elif power_state == states.REBOOT:
|
||||
self.oneview_client.power_off(oneview_info)
|
||||
management.set_boot_device(task)
|
||||
self.oneview_client.power_on(oneview_info)
|
||||
else:
|
||||
raise exception.InvalidParameterValue(
|
||||
|
@ -1,3 +1,4 @@
|
||||
# Copyright 2017 Hewlett Packard Enterprise Development Company LP.
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development LP.
|
||||
# Copyright 2016 Universidade Federal de Campina Grande
|
||||
# All Rights Reserved.
|
||||
@ -14,9 +15,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import time
|
||||
import types
|
||||
|
||||
import mock
|
||||
from oslo_utils import importutils
|
||||
|
||||
@ -24,17 +22,12 @@ from ironic.common import driver_factory
|
||||
from ironic.common import exception
|
||||
from ironic.common import states
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.conductor import utils as manager_utils
|
||||
from ironic.conf import CONF
|
||||
from ironic.drivers.modules import agent
|
||||
from ironic.drivers.modules import agent_client
|
||||
from ironic.drivers.modules import iscsi_deploy
|
||||
from ironic.drivers.modules.oneview import common
|
||||
from ironic.drivers.modules.oneview import deploy
|
||||
from ironic.drivers.modules.oneview import deploy_utils
|
||||
from ironic.drivers.modules.oneview import power
|
||||
from ironic.drivers.modules import pxe
|
||||
from ironic.drivers import utils as driver_utils
|
||||
from ironic.tests.unit.conductor import mgr_utils
|
||||
from ironic.tests.unit.db import base as db_base
|
||||
from ironic.tests.unit.db import utils as db_utils
|
||||
@ -266,301 +259,6 @@ class OneViewPeriodicTasks(db_base.DbTestCase):
|
||||
self.assertFalse('oneview_error' in self.node.driver_internal_info)
|
||||
|
||||
|
||||
@mock.patch.object(common, 'get_oneview_client', spec_set=True, autospec=True)
|
||||
class TestOneViewAgentDeploy(db_base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestOneViewAgentDeploy, self).setUp()
|
||||
self.config(
|
||||
post_deploy_get_power_state_retries=GET_POWER_STATE_RETRIES,
|
||||
group='agent')
|
||||
mgr_utils.mock_the_extension_manager(driver="agent_pxe_oneview")
|
||||
self.driver = driver_factory.get_driver("agent_pxe_oneview")
|
||||
self.node = obj_utils.create_test_node(
|
||||
self.context, driver='agent_pxe_oneview',
|
||||
properties=db_utils.get_test_oneview_properties(),
|
||||
driver_info=db_utils.get_test_oneview_driver_info(),
|
||||
driver_internal_info={'agent_url': 'http://1.2.3.4:5678'},
|
||||
)
|
||||
|
||||
@mock.patch.object(time, 'sleep', lambda seconds: None)
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(power.OneViewPower, 'get_power_state',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch('ironic.conductor.utils.node_set_boot_device', autospec=True)
|
||||
def test_reboot_and_finish_deploy(self, set_bootdev_mock, power_off_mock,
|
||||
get_power_state_mock,
|
||||
node_power_action_mock,
|
||||
mock_get_ov_client):
|
||||
self.node.provision_state = states.DEPLOYING
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
get_power_state_mock.side_effect = [states.POWER_ON,
|
||||
states.POWER_OFF]
|
||||
task.driver.deploy.reboot_and_finish_deploy(task)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
self.assertEqual(2, get_power_state_mock.call_count)
|
||||
set_bootdev_mock.assert_called_once_with(task, 'disk',
|
||||
persistent=True)
|
||||
node_power_action_mock.assert_called_once_with(
|
||||
task, states.POWER_ON)
|
||||
self.assertEqual(states.ACTIVE, task.node.provision_state)
|
||||
self.assertEqual(states.NOSTATE, task.node.target_provision_state)
|
||||
|
||||
@mock.patch.object(time, 'sleep', lambda seconds: None)
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(power.OneViewPower, 'get_power_state',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
def test_reboot_and_finish_deploy_soft_poweroff_doesnt_complete(
|
||||
self, power_off_mock, get_power_state_mock,
|
||||
node_power_action_mock, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client.return_value
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
fake_server_hardware = oneview_models.ServerHardware()
|
||||
fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
|
||||
oneview_client.get_server_hardware_by_uuid.return_value = (
|
||||
fake_server_hardware
|
||||
)
|
||||
mock_get_ov_client.return_value = oneview_client
|
||||
|
||||
self.node.provision_state = states.DEPLOYING
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
|
||||
driver_info = self.node.driver_info
|
||||
driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
|
||||
|
||||
self.node.driver_info = driver_info
|
||||
self.node.save()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
get_power_state_mock.return_value = states.POWER_ON
|
||||
task.driver.deploy.reboot_and_finish_deploy(task)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
self.assertEqual(GET_POWER_STATE_RETRIES + 1,
|
||||
get_power_state_mock.call_count)
|
||||
node_power_action_mock.assert_has_calls([
|
||||
mock.call(task, states.POWER_OFF),
|
||||
mock.call(task, states.POWER_ON)
|
||||
])
|
||||
self.assertEqual(states.ACTIVE, task.node.provision_state)
|
||||
self.assertEqual(states.NOSTATE, task.node.target_provision_state)
|
||||
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
def test_reboot_and_finish_deploy_soft_poweroff_fails(
|
||||
self, power_off_mock, node_power_action_mock,
|
||||
mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client.return_value
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
|
||||
fake_server_hardware = oneview_models.ServerHardware()
|
||||
fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
|
||||
oneview_client.get_server_hardware_by_uuid.return_value = (
|
||||
fake_server_hardware
|
||||
)
|
||||
mock_get_ov_client.return_value = oneview_client
|
||||
|
||||
power_off_mock.side_effect = RuntimeError("boom")
|
||||
|
||||
self.node.provision_state = states.DEPLOYING
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
|
||||
driver_info = self.node.driver_info
|
||||
driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
|
||||
|
||||
self.node.driver_info = driver_info
|
||||
self.node.save()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
task.driver.deploy.reboot_and_finish_deploy(task)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
node_power_action_mock.assert_has_calls([
|
||||
mock.call(task, states.POWER_OFF),
|
||||
mock.call(task, states.POWER_ON)
|
||||
])
|
||||
self.assertEqual(states.ACTIVE, task.node.provision_state)
|
||||
self.assertEqual(states.NOSTATE, task.node.target_provision_state)
|
||||
|
||||
@mock.patch.object(time, 'sleep', lambda seconds: None)
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(power.OneViewPower, 'get_power_state',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
def test_reboot_and_finish_deploy_get_power_state_fails(
|
||||
self, power_off_mock, get_power_state_mock,
|
||||
node_power_action_mock, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client.return_value
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
fake_server_hardware = oneview_models.ServerHardware()
|
||||
fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
|
||||
oneview_client.get_server_hardware_by_uuid.return_value = (
|
||||
fake_server_hardware
|
||||
)
|
||||
mock_get_ov_client.return_value = oneview_client
|
||||
|
||||
self.node.provision_state = states.DEPLOYING
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
|
||||
driver_info = self.node.driver_info
|
||||
driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
|
||||
|
||||
self.node.driver_info = driver_info
|
||||
self.node.save()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
get_power_state_mock.side_effect = RuntimeError("boom")
|
||||
task.driver.deploy.reboot_and_finish_deploy(task)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
self.assertEqual(GET_POWER_STATE_RETRIES + 1,
|
||||
get_power_state_mock.call_count)
|
||||
node_power_action_mock.assert_has_calls([
|
||||
mock.call(task, states.POWER_OFF),
|
||||
mock.call(task, states.POWER_ON)
|
||||
])
|
||||
self.assertEqual(states.ACTIVE, task.node.provision_state)
|
||||
self.assertEqual(states.NOSTATE, task.node.target_provision_state)
|
||||
|
||||
@mock.patch.object(driver_utils, 'collect_ramdisk_logs', autospec=True)
|
||||
@mock.patch.object(time, 'sleep', lambda seconds: None)
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(power.OneViewPower, 'get_power_state',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
def test_reboot_and_finish_deploy_power_action_fails(
|
||||
self, power_off_mock, get_power_state_mock,
|
||||
node_power_action_mock, collect_ramdisk_logs_mock,
|
||||
mock_get_ov_client):
|
||||
self.node.provision_state = states.DEPLOYING
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
get_power_state_mock.return_value = states.POWER_ON
|
||||
node_power_action_mock.side_effect = RuntimeError("boom")
|
||||
self.assertRaises(exception.InstanceDeployFailure,
|
||||
task.driver.deploy.reboot_and_finish_deploy,
|
||||
task)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
self.assertEqual(GET_POWER_STATE_RETRIES + 1,
|
||||
get_power_state_mock.call_count)
|
||||
node_power_action_mock.assert_has_calls([
|
||||
mock.call(task, states.POWER_OFF),
|
||||
mock.call(task, states.POWER_OFF)])
|
||||
self.assertEqual(states.DEPLOYFAIL, task.node.provision_state)
|
||||
self.assertEqual(states.ACTIVE, task.node.target_provision_state)
|
||||
collect_ramdisk_logs_mock.assert_called_once_with(task.node)
|
||||
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(power.OneViewPower, 'get_power_state',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch('ironic.drivers.modules.agent.AgentDeploy'
|
||||
'.check_deploy_success', autospec=True)
|
||||
@mock.patch.object(pxe.PXEBoot, 'clean_up_ramdisk', autospec=True)
|
||||
def test_reboot_to_instance(self, clean_pxe_mock, check_deploy_mock,
|
||||
power_off_mock, get_power_state_mock,
|
||||
node_power_action_mock, mock_get_ov_client):
|
||||
check_deploy_mock.return_value = None
|
||||
|
||||
oneview_client = mock_get_ov_client.return_value
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
fake_server_hardware = oneview_models.ServerHardware()
|
||||
fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
|
||||
oneview_client.get_server_hardware_by_uuid.return_value = (
|
||||
fake_server_hardware
|
||||
)
|
||||
mock_get_ov_client.return_value = oneview_client
|
||||
|
||||
self.node.provision_state = states.DEPLOYWAIT
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
|
||||
driver_info = self.node.driver_info
|
||||
driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
|
||||
|
||||
self.node.driver_info = driver_info
|
||||
self.node.save()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
get_power_state_mock.return_value = states.POWER_OFF
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||
|
||||
task.driver.deploy.reboot_to_instance(task)
|
||||
|
||||
clean_pxe_mock.assert_called_once_with(task.driver.boot, task)
|
||||
check_deploy_mock.assert_called_once_with(mock.ANY, task.node)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
get_power_state_mock.assert_called_once_with(task)
|
||||
node_power_action_mock.assert_called_once_with(
|
||||
task, states.POWER_ON)
|
||||
self.assertEqual(states.ACTIVE, task.node.provision_state)
|
||||
self.assertEqual(states.NOSTATE, task.node.target_provision_state)
|
||||
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(power.OneViewPower, 'get_power_state',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch('ironic.drivers.modules.agent.AgentDeploy'
|
||||
'.check_deploy_success', autospec=True)
|
||||
@mock.patch.object(pxe.PXEBoot, 'clean_up_ramdisk', autospec=True)
|
||||
def test_reboot_to_instance_boot_none(self, clean_pxe_mock,
|
||||
check_deploy_mock,
|
||||
power_off_mock,
|
||||
get_power_state_mock,
|
||||
node_power_action_mock,
|
||||
mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client.return_value
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
fake_server_hardware = oneview_models.ServerHardware()
|
||||
fake_server_hardware.server_profile_uri = 'any/applied_sp_uri/'
|
||||
oneview_client.get_server_hardware_by_uuid.return_value = (
|
||||
fake_server_hardware
|
||||
)
|
||||
mock_get_ov_client.return_value = oneview_client
|
||||
|
||||
check_deploy_mock.return_value = None
|
||||
|
||||
self.node.provision_state = states.DEPLOYWAIT
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
|
||||
driver_info = self.node.driver_info
|
||||
driver_info['applied_server_profile_uri'] = 'any/applied_sp_uri/'
|
||||
|
||||
self.node.driver_info = driver_info
|
||||
self.node.save()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
get_power_state_mock.return_value = states.POWER_OFF
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||
task.driver.boot = None
|
||||
|
||||
task.driver.deploy.reboot_to_instance(task)
|
||||
|
||||
self.assertFalse(clean_pxe_mock.called)
|
||||
check_deploy_mock.assert_called_once_with(mock.ANY, task.node)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
get_power_state_mock.assert_called_once_with(task)
|
||||
node_power_action_mock.assert_called_once_with(
|
||||
task, states.POWER_ON)
|
||||
self.assertEqual(states.ACTIVE, task.node.provision_state)
|
||||
self.assertEqual(states.NOSTATE, task.node.target_provision_state)
|
||||
|
||||
|
||||
@mock.patch.object(common, 'get_oneview_client', spec_set=True, autospec=True)
|
||||
class OneViewIscsiDeployTestCase(db_base.DbTestCase):
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2017 Hewlett Packard Enterprise Development Company LP.
|
||||
# Copyright 2015 Hewlett Packard Development Company, LP
|
||||
# Copyright 2015 Universidade Federal de Campina Grande
|
||||
#
|
||||
@ -35,6 +34,117 @@ oneview_exceptions = importutils.try_import('oneview_client.exceptions')
|
||||
oneview_models = importutils.try_import('oneview_client.models')
|
||||
|
||||
|
||||
@mock.patch.object(common, 'get_oneview_client', spect_set=True, autospec=True)
|
||||
class OneViewManagementDriverFunctionsTestCase(db_base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(OneViewManagementDriverFunctionsTestCase, self).setUp()
|
||||
self.config(manager_url='https://1.2.3.4', group='oneview')
|
||||
self.config(username='user', group='oneview')
|
||||
self.config(password='password', group='oneview')
|
||||
|
||||
mgr_utils.mock_the_extension_manager(driver="fake_oneview")
|
||||
self.driver = driver_factory.get_driver("fake_oneview")
|
||||
|
||||
self.node = obj_utils.create_test_node(
|
||||
self.context, driver='fake_oneview',
|
||||
properties=db_utils.get_test_oneview_properties(),
|
||||
driver_info=db_utils.get_test_oneview_driver_info(),
|
||||
)
|
||||
self.info = common.get_oneview_info(self.node)
|
||||
|
||||
def test_set_boot_device(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = {'boot_device': boot_devices.PXE,
|
||||
'persistent': False}
|
||||
driver_internal_info['next_boot_device'] = next_boot_device
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
management.set_boot_device(task)
|
||||
oneview_client.set_boot_device.assert_called_once_with(
|
||||
self.info,
|
||||
management.BOOT_DEVICE_MAPPING_TO_OV[boot_devices.PXE],
|
||||
onetime=True
|
||||
)
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
self.assertNotIn('next_boot_device', driver_internal_info)
|
||||
|
||||
def test_set_boot_device_persistent(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = {'boot_device': boot_devices.PXE,
|
||||
'persistent': True}
|
||||
driver_internal_info['next_boot_device'] = next_boot_device
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
management.set_boot_device(task)
|
||||
oneview_client.set_boot_device.assert_called_once_with(
|
||||
self.info,
|
||||
management.BOOT_DEVICE_MAPPING_TO_OV[boot_devices.PXE],
|
||||
onetime=False
|
||||
)
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
self.assertNotIn('next_boot_device', driver_internal_info)
|
||||
|
||||
def test_set_boot_device_invalid_device(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = {'boot_device': 'pixie-boots',
|
||||
'persistent': True}
|
||||
driver_internal_info['next_boot_device'] = next_boot_device
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
management.set_boot_device,
|
||||
task)
|
||||
self.assertFalse(oneview_client.set_boot_device.called)
|
||||
self.assertIn('next_boot_device', driver_internal_info)
|
||||
|
||||
def test_set_boot_device_fail_to_get_server_profile(
|
||||
self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
oneview_client.get_server_profile_from_hardware.side_effect = \
|
||||
oneview_exceptions.OneViewException()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = {'boot_device': 'disk',
|
||||
'persistent': True}
|
||||
driver_internal_info['next_boot_device'] = next_boot_device
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
self.assertRaises(exception.OneViewError,
|
||||
management.set_boot_device,
|
||||
task)
|
||||
self.assertFalse(oneview_client.set_boot_device.called)
|
||||
self.assertIn('next_boot_device', driver_internal_info)
|
||||
|
||||
def test_set_boot_device_without_server_profile(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
oneview_client.get_server_profile_from_hardware.return_value = False
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = {'device': 'disk',
|
||||
'persistent': True}
|
||||
driver_internal_info['next_boot_device'] = next_boot_device
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
expected_msg = (
|
||||
'A Server Profile is not associated with node %s.'
|
||||
% self.node.uuid
|
||||
)
|
||||
self.assertRaisesRegex(
|
||||
exception.OperationNotPermitted,
|
||||
expected_msg,
|
||||
management.set_boot_device,
|
||||
task
|
||||
)
|
||||
self.assertIn('next_boot_device', driver_internal_info)
|
||||
|
||||
|
||||
@mock.patch.object(common, 'get_oneview_client', spect_set=True, autospec=True)
|
||||
class OneViewManagementDriverTestCase(db_base.DbTestCase):
|
||||
|
||||
@ -126,70 +236,35 @@ class OneViewManagementDriverTestCase(db_base.DbTestCase):
|
||||
self.assertItemsEqual(expected,
|
||||
self.driver.management.get_properties())
|
||||
|
||||
def test_set_boot_device(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
|
||||
def test_set_boot_device_persistent_true(self, mock_get_ov_client):
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.driver.management.set_boot_device(task, boot_devices.PXE)
|
||||
oneview_client.set_boot_device.assert_called_once_with(
|
||||
self.info,
|
||||
management.BOOT_DEVICE_MAPPING_TO_OV[boot_devices.PXE],
|
||||
onetime=True
|
||||
)
|
||||
|
||||
def test_set_boot_device_persistent(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
task.driver.management.set_boot_device(
|
||||
task, boot_devices.PXE, True)
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = driver_internal_info.get('next_boot_device')
|
||||
self.assertIn('next_boot_device', driver_internal_info)
|
||||
self.assertEqual(
|
||||
next_boot_device.get('boot_device'), boot_devices.PXE)
|
||||
self.assertTrue(next_boot_device.get('persistent'))
|
||||
|
||||
def test_set_boot_device_persistent_false(self, mock_get_ov_client):
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.driver.management.set_boot_device(task, boot_devices.PXE,
|
||||
persistent=True)
|
||||
oneview_client.set_boot_device.assert_called_once_with(
|
||||
self.info,
|
||||
management.BOOT_DEVICE_MAPPING_TO_OV[boot_devices.PXE],
|
||||
onetime=False
|
||||
)
|
||||
task.driver.management.set_boot_device(
|
||||
task, boot_devices.PXE, False)
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = driver_internal_info.get('next_boot_device')
|
||||
self.assertIn('next_boot_device', driver_internal_info)
|
||||
self.assertEqual(
|
||||
next_boot_device.get('boot_device'), boot_devices.PXE)
|
||||
self.assertFalse(next_boot_device.get('persistent'))
|
||||
|
||||
def test_set_boot_device_invalid_device(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
self.driver.management.set_boot_device,
|
||||
task, 'fake-device')
|
||||
self.assertFalse(oneview_client.set_boot_device.called)
|
||||
|
||||
def test_set_boot_device_fail_to_get_server_profile(self,
|
||||
mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
oneview_client.get_server_profile_from_hardware.side_effect = \
|
||||
oneview_exceptions.OneViewException()
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertRaises(exception.OneViewError,
|
||||
self.driver.management.set_boot_device,
|
||||
task, 'disk')
|
||||
self.assertFalse(oneview_client.set_boot_device.called)
|
||||
|
||||
def test_set_boot_device_without_server_profile(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
oneview_client.get_server_profile_from_hardware.return_value = False
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
expected_msg = (
|
||||
'A Server Profile is not associated with node %s.'
|
||||
% self.node.uuid
|
||||
)
|
||||
self.assertRaisesRegex(
|
||||
exception.OperationNotPermitted,
|
||||
expected_msg,
|
||||
self.driver.management.set_boot_device,
|
||||
task,
|
||||
'disk'
|
||||
)
|
||||
task.driver.management.set_boot_device,
|
||||
task, 'unknown-device', False)
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
self.assertNotIn('next_boot_device', driver_internal_info)
|
||||
|
||||
def test_get_supported_boot_devices(self, mock_get_ov_client):
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
@ -218,6 +293,25 @@ class OneViewManagementDriverTestCase(db_base.DbTestCase):
|
||||
self.assertEqual(expected_response, response)
|
||||
oneview_client.get_boot_order.assert_called_with(self.info)
|
||||
|
||||
def test_get_boot_device_from_next_boot_device(
|
||||
self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
self.driver.management.oneview_client = oneview_client
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
next_boot_device = {'boot_device': boot_devices.DISK,
|
||||
'persistent': True}
|
||||
driver_internal_info['next_boot_device'] = next_boot_device
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
expected_response = {
|
||||
'boot_device': boot_devices.DISK,
|
||||
'persistent': True
|
||||
}
|
||||
response = self.driver.management.get_boot_device(task)
|
||||
self.assertEqual(expected_response, response)
|
||||
self.assertFalse(oneview_client.get_boot_order.called)
|
||||
|
||||
def test_get_boot_device_fail(self, mock_get_ov_client):
|
||||
oneview_client = mock_get_ov_client()
|
||||
oneview_client.get_boot_order.side_effect = \
|
||||
|
@ -25,6 +25,7 @@ from ironic.common import states
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.drivers.modules.oneview import common
|
||||
from ironic.drivers.modules.oneview import deploy_utils
|
||||
from ironic.drivers.modules.oneview import management
|
||||
from ironic.tests.unit.conductor import mgr_utils
|
||||
from ironic.tests.unit.db import base as db_base
|
||||
from ironic.tests.unit.db import utils as db_utils
|
||||
@ -142,7 +143,9 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
task
|
||||
)
|
||||
|
||||
def test_set_power_on(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_set_power_on(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -158,10 +161,13 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
driver_info['applied_server_profile_uri'] = sp_uri
|
||||
task.node.driver_info = driver_info
|
||||
self.driver.power.set_power_state(task, states.POWER_ON)
|
||||
mock_set_boot_device.assert_called_once_with(task)
|
||||
self.info['applied_server_profile_uri'] = sp_uri
|
||||
oneview_client.power_on.assert_called_once_with(self.info)
|
||||
|
||||
def test_set_power_off(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_set_power_off(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -177,10 +183,13 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
driver_info['applied_server_profile_uri'] = sp_uri
|
||||
task.node.driver_info = driver_info
|
||||
self.driver.power.set_power_state(task, states.POWER_OFF)
|
||||
self.assertFalse(mock_set_boot_device.called)
|
||||
self.info['applied_server_profile_uri'] = sp_uri
|
||||
oneview_client.power_off.assert_called_once_with(self.info)
|
||||
|
||||
def test_set_power_on_fail(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_set_power_on_fail(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -198,10 +207,13 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
self.assertRaises(exception.OneViewError,
|
||||
self.driver.power.set_power_state, task,
|
||||
states.POWER_ON)
|
||||
mock_set_boot_device.assert_called_once_with(task)
|
||||
self.info['applied_server_profile_uri'] = sp_uri
|
||||
oneview_client.power_on.assert_called_once_with(self.info)
|
||||
|
||||
def test_set_power_off_fail(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_set_power_off_fail(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -219,10 +231,13 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
self.assertRaises(exception.OneViewError,
|
||||
self.driver.power.set_power_state, task,
|
||||
states.POWER_OFF)
|
||||
self.assertFalse(mock_set_boot_device.called)
|
||||
self.info['applied_server_profile_uri'] = sp_uri
|
||||
oneview_client.power_off.assert_called_once_with(self.info)
|
||||
|
||||
def test_set_power_invalid_state(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_set_power_invalid_state(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -240,8 +255,11 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
self.driver.power.set_power_state, task,
|
||||
'fake state')
|
||||
self.assertFalse(mock_set_boot_device.called)
|
||||
|
||||
def test_set_power_reboot(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_set_power_reboot(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -257,12 +275,15 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
driver_info['applied_server_profile_uri'] = sp_uri
|
||||
task.node.driver_info = driver_info
|
||||
self.driver.power.set_power_state(task, states.REBOOT)
|
||||
mock_set_boot_device.assert_called_once_with(task)
|
||||
self.info['applied_server_profile_uri'] = sp_uri
|
||||
oneview_client.power_off.assert_called_once_with(self.info)
|
||||
oneview_client.power_off.assert_called_once_with(self.info)
|
||||
oneview_client.power_on.assert_called_once_with(self.info)
|
||||
|
||||
def test_reboot(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_reboot(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -278,11 +299,14 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
driver_info['applied_server_profile_uri'] = sp_uri
|
||||
task.node.driver_info = driver_info
|
||||
self.driver.power.reboot(task)
|
||||
mock_set_boot_device.assert_called_once_with(task)
|
||||
self.info['applied_server_profile_uri'] = sp_uri
|
||||
oneview_client.power_off.assert_called_once_with(self.info)
|
||||
oneview_client.power_on.assert_called_once_with(self.info)
|
||||
|
||||
def test_reboot_fail(self, mock_get_ov_client):
|
||||
@mock.patch.object(management, 'set_boot_device')
|
||||
def test_reboot_fail(
|
||||
self, mock_set_boot_device, mock_get_ov_client):
|
||||
|
||||
sp_uri = '/any/server-profile'
|
||||
oneview_client = mock_get_ov_client()
|
||||
@ -300,6 +324,7 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
||||
task.node.driver_info = driver_info
|
||||
self.assertRaises(exception.OneViewError,
|
||||
self.driver.power.reboot, task)
|
||||
self.assertFalse(mock_set_boot_device.called)
|
||||
self.info['applied_server_profile_uri'] = sp_uri
|
||||
oneview_client.power_off.assert_called_once_with(self.info)
|
||||
self.assertFalse(oneview_client.power_on.called)
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Oneview drivers caches the next boot device in node's internal
|
||||
info when set_boot_device() is called. It is applied on the
|
||||
bare metal when node is power cycled.
|
Loading…
Reference in New Issue
Block a user