Do not use async parameter

We have method passthru that is accepting parameter async,
but since python 3.7 use async as reserved word,
the async parameter is deprecated,
async_call should be used instead.
async parameter will be removed in the next cycle.

Change-Id: I6299aafd30faae9a93df2cb901c1505df47e6b45
Task: 9289
Story: 1751306
This commit is contained in:
Oleksiy Petrenko 2018-03-27 13:38:57 +03:00
parent b8725e5d2b
commit 0267c271d0
7 changed files with 64 additions and 24 deletions

View File

@ -82,7 +82,7 @@ the node vendor passthru endpoint:
if 'raw_bytes' not in kwargs:
raise MissingParameterValue()
@base.driver_passthru(['GET'], async=False)
@base.driver_passthru(['GET'], async_call=False)
def authentication_types(self, context, **kwargs):
return {"types": ["NONE", "MD5", "MD2"]}
@ -122,9 +122,11 @@ Both decorators accept these parameters:
.. _VendorInterface: ../api/ironic.drivers.base.html#ironic.drivers.base.VendorInterface
* async: A boolean value to determine whether this method should run
* async_call: A boolean value to determine whether this method should run
asynchronously or synchronously. Defaults to True (Asynchronously).
.. note:: This parameter was previously called "async".
The node vendor passthru decorator (`@passthru`) also accepts the following
parameter:

View File

@ -619,8 +619,9 @@ VendorMetadata = collections.namedtuple('VendorMetadata', ['method',
'metadata'])
def _passthru(http_methods, method=None, async=True, driver_passthru=False,
description=None, attach=False, require_exclusive_lock=True):
def _passthru(http_methods, method=None, async=None, async_call=None,
driver_passthru=False, description=None,
attach=False, require_exclusive_lock=True):
"""A decorator for registering a function as a passthru function.
Decorator ensures function is ready to catch any ironic exceptions
@ -634,7 +635,8 @@ def _passthru(http_methods, method=None, async=True, driver_passthru=False,
:param http_methods: A list of supported HTTP methods by the vendor
function.
:param method: an arbitrary string describing the action to be taken.
:param async: Boolean value. If True invoke the passthru function
:param async: Deprecated, please use async_call instead.
:param async_call: Boolean value. If True invoke the passthru function
asynchronously; if False, synchronously. If a passthru
function touches the BMC we strongly recommend it to
run asynchronously. Defaults to True.
@ -653,6 +655,22 @@ def _passthru(http_methods, method=None, async=True, driver_passthru=False,
for a synchronous passthru method. If False,
don't lock the node. Defaults to True.
"""
if async_call is None:
if async is not None:
LOG.warning(
'async parameter is deprecated, please use async_call instead.'
'deprecated parameter will be removed in the next cycle.'
)
async_call = async
else:
async_call = True
else:
if async is not None:
raise TypeError(
"async_call and async parameters couldn't be used together, "
"use async_call instead of async"
)
def handle_passthru(func):
api_method = method
if api_method is None:
@ -661,7 +679,7 @@ def _passthru(http_methods, method=None, async=True, driver_passthru=False,
supported_ = [i.upper() for i in http_methods]
description_ = description or ''
metadata = VendorMetadata(api_method, {'http_methods': supported_,
'async': async,
'async': async_call,
'description': description_,
'attach': attach})
if driver_passthru:
@ -687,17 +705,19 @@ def _passthru(http_methods, method=None, async=True, driver_passthru=False,
return handle_passthru
def passthru(http_methods, method=None, async=True, description=None,
attach=False, require_exclusive_lock=True):
return _passthru(http_methods, method, async, driver_passthru=False,
def passthru(http_methods, method=None, async=None, description=None,
attach=False, require_exclusive_lock=True, async_call=None):
return _passthru(http_methods, method, async, async_call,
driver_passthru=False,
description=description, attach=attach,
require_exclusive_lock=require_exclusive_lock)
def driver_passthru(http_methods, method=None, async=True, description=None,
attach=False):
return _passthru(http_methods, method, async, driver_passthru=True,
description=description, attach=attach)
def driver_passthru(http_methods, method=None, async=None, description=None,
attach=False, async_call=None):
return _passthru(http_methods, method, async, async_call,
driver_passthru=True, description=description,
attach=attach)
class VendorInterface(BaseInterface):

View File

@ -50,7 +50,7 @@ class DracVendorPassthru(base.VendorInterface):
return drac_common.parse_driver_info(task.node)
@METRICS.timer('DracVendorPassthru.get_bios_config')
@base.passthru(['GET'], async=False,
@base.passthru(['GET'], async_call=False,
description=_("Returns a dictionary containing the BIOS "
"settings from a node."))
def get_bios_config(self, task, **kwargs):
@ -70,7 +70,7 @@ class DracVendorPassthru(base.VendorInterface):
return bios_attrs
@METRICS.timer('DracVendorPassthru.set_bios_config')
@base.passthru(['POST'], async=False,
@base.passthru(['POST'], async_call=False,
description=_("Change the BIOS configuration on a node. "
"Required argument : a dictionary of "
"{'AttributeName': 'NewValue'}. Returns "
@ -94,7 +94,7 @@ class DracVendorPassthru(base.VendorInterface):
return drac_bios.set_config(task, **kwargs)
@METRICS.timer('DracVendorPassthru.commit_bios_config')
@base.passthru(['POST'], async=False,
@base.passthru(['POST'], async_call=False,
description=_("Commit a BIOS configuration job submitted "
"through set_bios_config(). Required "
"argument: 'reboot' - indicates whether a "
@ -126,7 +126,7 @@ class DracVendorPassthru(base.VendorInterface):
return {'job_id': job_id, 'reboot_required': not reboot}
@METRICS.timer('DracVendorPassthru.abandon_bios_config')
@base.passthru(['DELETE'], async=False,
@base.passthru(['DELETE'], async_call=False,
description=_("Abandon a BIOS configuration job previously "
"submitted through set_bios_config()."))
@task_manager.require_exclusive_lock
@ -142,7 +142,7 @@ class DracVendorPassthru(base.VendorInterface):
"""
drac_bios.abandon_config(task)
@base.passthru(['GET'], async=False,
@base.passthru(['GET'], async_call=False,
description=_('Returns a dictionary containing the key '
'"unfinished_jobs"; its value is a list of '
'dictionaries. Each dictionary represents '

View File

@ -154,7 +154,7 @@ class FakeVendorB(base.VendorInterface):
def second_method(self, task, http_method, bar):
return True if bar == 'kazoo' else False
@base.passthru(['POST'], async=False,
@base.passthru(['POST'], async_call=False,
description=_("Test if the value of bar is meow"))
def third_method_sync(self, task, http_method, bar):
return True if bar == 'meow' else False

View File

@ -617,9 +617,13 @@ class TestVendorPassthru(base.TestCase):
@mock.patch.object(pecan, 'request',
spec_set=['method', 'context', 'rpcapi'])
def _vendor_passthru(self, mock_request, async=True,
def _vendor_passthru(self, mock_request, async_call=True,
driver_passthru=False):
return_value = {'return': 'SpongeBob', 'async': async, 'attach': False}
return_value = {
'return': 'SpongeBob',
'async': async_call,
'attach': False
}
mock_request.method = 'post'
mock_request.context = 'fake-context'
@ -640,20 +644,20 @@ class TestVendorPassthru(base.TestCase):
self.assertIsInstance(response, wsme.api.Response)
self.assertEqual('SpongeBob', response.obj)
self.assertEqual(response.return_type, wsme.types.Unset)
sc = http_client.ACCEPTED if async else http_client.OK
sc = http_client.ACCEPTED if async_call else http_client.OK
self.assertEqual(sc, response.status_code)
def test_vendor_passthru_async(self):
self._vendor_passthru()
def test_vendor_passthru_sync(self):
self._vendor_passthru(async=False)
self._vendor_passthru(async_call=False)
def test_driver_vendor_passthru_async(self):
self._vendor_passthru(driver_passthru=True)
def test_driver_vendor_passthru_sync(self):
self._vendor_passthru(async=False, driver_passthru=True)
self._vendor_passthru(async_call=False, driver_passthru=True)
@mock.patch.object(pecan, 'response', spec_set=['app_iter'])
@mock.patch.object(pecan, 'request',

View File

@ -102,6 +102,16 @@ class PassthruDecoratorTestCase(base.TestCase):
self.assertNotEqual(inst1.driver_routes['driver_noexception']['func'],
inst2.driver_routes['driver_noexception']['func'])
@mock.patch.object(driver_base.LOG, 'warning')
def test_old_async_warning(self, mock_log_warning):
driver_base.passthru(['POST'], async=True)
mock_log_warning.assert_called_once()
@mock.patch.object(driver_base.LOG, 'warning')
def test_new_async_call_without_warning(self, mock_log_warning):
driver_base.passthru(['POST'], async_call=True)
mock_log_warning.assert_not_called()
class CleanStepDecoratorTestCase(base.TestCase):

View File

@ -0,0 +1,4 @@
---
other:
async parameter of passthru and driver_passthru decorators is deprecated
and will be removed in next cycle. async_call should be used instead.