iboot: add wait loop for pstate to activate

Add a short retry loop so that power state changes can
have some time to become active on iboot devices with
remote switches.

Closes bug: #1512478

Change-Id: Ifad4b6a22f0289b2bcec25528566326a2688e76b
This commit is contained in:
Dan Prince 2015-11-02 15:30:31 -05:00
parent cf8e0273e6
commit 90a52931dd
2 changed files with 30 additions and 7 deletions

View File

@ -151,6 +151,18 @@ def _sleep_switch(seconds):
time.sleep(seconds)
def _check_power_state(driver_info, pstate):
"""Function to check power state is correct. Up to max retries."""
# always try once + number of retries
for num in range(0, 1 + CONF.iboot.max_retry):
state = _power_status(driver_info)
if state == pstate:
return
if num < CONF.iboot.max_retry:
time.sleep(CONF.iboot.retry_interval)
raise exception.PowerStateFailure(pstate=pstate)
def _power_status(driver_info):
conn = _get_connection(driver_info)
relay_id = driver_info['relay_id']
@ -251,9 +263,7 @@ class IBootPower(base.PowerInterface):
_("set_power_state called with invalid "
"power state %s.") % pstate)
state = _power_status(driver_info)
if state != pstate:
raise exception.PowerStateFailure(pstate=pstate)
_check_power_state(driver_info, pstate)
@task_manager.require_exclusive_lock
def reboot(self, task):
@ -272,7 +282,4 @@ class IBootPower(base.PowerInterface):
_switch(driver_info, False)
_sleep_switch(CONF.iboot.reboot_delay)
_switch(driver_info, True)
state = _power_status(driver_info)
if state != states.POWER_ON:
raise exception.PowerStateFailure(pstate=states.POWER_ON)
_check_power_state(driver_info, states.POWER_ON)

View File

@ -300,6 +300,22 @@ class IBootDriverTestCase(db_base.DbTestCase):
mock_switch.assert_called_once_with(self.info, True)
mock_power_status.assert_called_once_with(self.info)
@mock.patch.object(iboot, '_power_status', autospec=True)
@mock.patch.object(iboot, '_switch', autospec=True)
def test_set_power_state_retry(self, mock_switch, mock_power_status):
self.config(max_retry=2, group='iboot')
mock_power_status.return_value = states.POWER_OFF
with task_manager.acquire(self.context, self.node.uuid) as task:
self.assertRaises(exception.PowerStateFailure,
task.driver.power.set_power_state,
task, states.POWER_ON)
# ensure functions were called with the valid parameters
mock_switch.assert_called_once_with(self.info, True)
# 1 + 2 retries
self.assertEqual(3, mock_power_status.call_count)
@mock.patch.object(iboot, '_power_status', autospec=True)
@mock.patch.object(iboot, '_switch', autospec=True)
def test_set_power_state_invalid_parameter(self, mock_switch,