Adds a sleep(3s) after performing power on/off/reset

In async mode, performing power on/off/reset will return
immediately. However, if we perform multiple power actions
in parallel or in a tight sequence, an Error 5 (Input/Output
error) will happen. This bug can be reproduced by doing
RAID config from Ironic CLI.

This patch adds a sleep of 3 seconds to make sure calling
code can't perform some power actions too quickly.

Change-Id: Iacf43a2ca34822b2b59683f4c5b08b78074e5b5f
This commit is contained in:
Dao Cong Tien 2019-10-31 15:48:32 +07:00
parent 07500a0c3e
commit 3e595d8026
2 changed files with 19 additions and 3 deletions

View File

@ -301,6 +301,16 @@ def scci_cmd(host, userid, password, cmd, port=443, auth_method='basic',
if not do_async:
time.sleep(5)
else:
# Async mode
# Even in async mode, return immediately may cause error 5
# (Input/Output error) for some commands such as POWER_ON,
# POWER_OFF, POWER_RESET if we perform multiple calls of them
# in a tight sequence or in parallel.
# So, we sleep some time for such commands.
if cmd in (POWER_ON, POWER_OFF, POWER_RESET):
time.sleep(3)
if DEBUG:
print(cmd)
print(r.text)

View File

@ -270,7 +270,8 @@ class SCCITestCase(testtools.TestCase):
'HTTP PROTOCOL ERROR, STATUS CODE = 302',
str(e))
def test_power_on_ok(self):
@mock.patch.object(time, 'sleep')
def test_power_on_ok(self, mock_sleep):
self.requests_mock.post("http://" + self.irmc_address + "/config",
text="""<?xml version="1.0" encoding="UTF-8"?>
<Status>
@ -287,8 +288,10 @@ class SCCITestCase(testtools.TestCase):
client_timeout=self.irmc_client_timeout)
r = client(scci.POWER_ON)
self.assertEqual(r.status_code, 200)
mock_sleep.assert_called_once_with(3)
def test_power_off_ok(self):
@mock.patch.object(time, 'sleep')
def test_power_off_ok(self, mock_sleep):
self.requests_mock.post("http://" + self.irmc_address + "/config",
text="""<?xml version="1.0" encoding="UTF-8"?>
<Status>
@ -305,6 +308,7 @@ class SCCITestCase(testtools.TestCase):
client_timeout=self.irmc_client_timeout)
r = client(scci.POWER_OFF)
self.assertEqual(r.status_code, 200)
mock_sleep.assert_called_once_with(3)
def test_power_cycle_ok(self):
self.requests_mock.post("http://" + self.irmc_address + "/config",
@ -324,7 +328,8 @@ class SCCITestCase(testtools.TestCase):
r = client(scci.POWER_CYCLE)
self.assertEqual(r.status_code, 200)
def test_power_reset_ok(self):
@mock.patch.object(time, 'sleep')
def test_power_reset_ok(self, mock_sleep):
self.requests_mock.post("http://" + self.irmc_address + "/config",
text="""<?xml version="1.0" encoding="UTF-8"?>
<Status>
@ -341,6 +346,7 @@ class SCCITestCase(testtools.TestCase):
client_timeout=self.irmc_client_timeout)
r = client(scci.POWER_RESET)
self.assertEqual(r.status_code, 200)
mock_sleep.assert_called_once_with(3)
def test_power_raise_nmi_ok(self):
self.requests_mock.post("http://" + self.irmc_address + "/config",