Merge "Pecan: Add missing emulated bulk create method" into stable/pike

This commit is contained in:
Jenkins 2017-09-14 04:00:09 +00:00 committed by Gerrit Code Review
commit 8baed13677
3 changed files with 71 additions and 3 deletions

View File

@ -60,7 +60,6 @@ class ItemController(utils.NeutronPecanController):
def put(self, *args, **kwargs):
neutron_context = request.context['neutron_context']
resources = request.context['resources']
# TODO(kevinbenton): bulk?
# Bulk update is not supported, 'resources' always contains a single
# elemenet
data = {self.resource: resources[0]}

View File

@ -18,6 +18,8 @@ import copy
import functools
from neutron_lib import constants
from oslo_log import log as logging
from oslo_utils import excutils
import pecan
from pecan import request
@ -30,6 +32,8 @@ from neutron_lib import exceptions
# Utility functions for Pecan controllers.
LOG = logging.getLogger(__name__)
class Fakecode(object):
co_varnames = ()
@ -236,8 +240,32 @@ class NeutronPecanController(object):
@property
def plugin_bulk_creator(self):
return getattr(self.plugin,
'%s_bulk' % self._plugin_handlers[self.CREATE])
native = getattr(self.plugin,
'%s_bulk' % self._plugin_handlers[self.CREATE],
None)
# NOTE(kevinbenton): this flag is just to make testing easier since we
# don't have any in-tree plugins without native bulk support
if getattr(self.plugin, '_FORCE_EMULATED_BULK', False) or not native:
return self._emulated_bulk_creator
return native
def _emulated_bulk_creator(self, context, **kwargs):
objs = []
body = kwargs[self.collection]
try:
for item in body[self.collection]:
objs.append(self.plugin_creator(context, item))
return objs
except Exception:
with excutils.save_and_reraise_exception():
for obj in objs:
try:
self.plugin_deleter(context, obj['id'])
except Exception:
LOG.exception("Unable to undo bulk create for "
"%(resource)s %(id)s",
{'resource': self.collection,
'id': obj['id']})
@property
def plugin_deleter(self):

View File

@ -494,6 +494,47 @@ class TestResourceController(TestRootController):
self.assertIn('ports', json_body)
self.assertEqual(2, len(json_body['ports']))
def test_emulated_bulk_create(self):
self.plugin._FORCE_EMULATED_BULK = True
response = self.app.post_json(
'/v2.0/ports.json',
params={'ports': [{'network_id': self.port['network_id'],
'admin_state_up': True,
'tenant_id': 'tenid'},
{'network_id': self.port['network_id'],
'admin_state_up': True,
'tenant_id': 'tenid'}]
},
headers={'X-Project-Id': 'tenid'})
self.assertEqual(response.status_int, 201)
json_body = jsonutils.loads(response.body)
self.assertIn('ports', json_body)
self.assertEqual(2, len(json_body['ports']))
def test_emulated_bulk_create_rollback(self):
self.plugin._FORCE_EMULATED_BULK = True
response = self.app.post_json(
'/v2.0/ports.json',
params={'ports': [{'network_id': self.port['network_id'],
'admin_state_up': True,
'tenant_id': 'tenid'},
{'network_id': self.port['network_id'],
'admin_state_up': True,
'tenant_id': 'tenid'},
{'network_id': 'bad_net_id',
'admin_state_up': True,
'tenant_id': 'tenid'}]
},
headers={'X-Project-Id': 'tenid'},
expect_errors=True)
self.assertEqual(response.status_int, 400)
response = self.app.get(
'/v2.0/ports.json',
headers={'X-Project-Id': 'tenid'})
# all ports should be rolled back from above so we are just left
# with the one created in setup
self.assertEqual(1, len(jsonutils.loads(response.body)['ports']))
def test_bulk_create_one_item(self):
response = self.app.post_json(
'/v2.0/ports.json',