Merge "Fix target_cell usage for scatter_gather_cells"
This commit is contained in:
commit
783c429057
@ -419,9 +419,11 @@ def scatter_gather_cells(context, cell_mappings, timeout, fn, *args, **kwargs):
|
|||||||
queue = eventlet.queue.LightQueue()
|
queue = eventlet.queue.LightQueue()
|
||||||
results = {}
|
results = {}
|
||||||
|
|
||||||
def gather_result(cell_uuid, fn, *args, **kwargs):
|
def gather_result(cell_mapping, fn, context, *args, **kwargs):
|
||||||
|
cell_uuid = cell_mapping.uuid
|
||||||
try:
|
try:
|
||||||
result = fn(*args, **kwargs)
|
with target_cell(context, cell_mapping) as cctxt:
|
||||||
|
result = fn(cctxt, *args, **kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.exception('Error gathering result from cell %s', cell_uuid)
|
LOG.exception('Error gathering result from cell %s', cell_uuid)
|
||||||
result = raised_exception_sentinel
|
result = raised_exception_sentinel
|
||||||
@ -429,10 +431,9 @@ def scatter_gather_cells(context, cell_mappings, timeout, fn, *args, **kwargs):
|
|||||||
queue.put((cell_uuid, result))
|
queue.put((cell_uuid, result))
|
||||||
|
|
||||||
for cell_mapping in cell_mappings:
|
for cell_mapping in cell_mappings:
|
||||||
with target_cell(context, cell_mapping) as cctxt:
|
greenthreads.append((cell_mapping.uuid,
|
||||||
greenthreads.append((cell_mapping.uuid,
|
utils.spawn(gather_result, cell_mapping,
|
||||||
utils.spawn(gather_result, cell_mapping.uuid,
|
fn, context, *args, **kwargs)))
|
||||||
fn, cctxt, *args, **kwargs)))
|
|
||||||
|
|
||||||
with eventlet.timeout.Timeout(timeout, exception.CellTimeout):
|
with eventlet.timeout.Timeout(timeout, exception.CellTimeout):
|
||||||
try:
|
try:
|
||||||
|
@ -309,21 +309,35 @@ class ContextTestCase(test.NoDBTestCase):
|
|||||||
@mock.patch('nova.context.target_cell')
|
@mock.patch('nova.context.target_cell')
|
||||||
@mock.patch('nova.objects.InstanceList.get_by_filters')
|
@mock.patch('nova.objects.InstanceList.get_by_filters')
|
||||||
def test_scatter_gather_cells(self, mock_get_inst, mock_target_cell):
|
def test_scatter_gather_cells(self, mock_get_inst, mock_target_cell):
|
||||||
self.useFixture(nova_fixtures.SpawnIsSynchronousFixture())
|
|
||||||
ctxt = context.get_context()
|
ctxt = context.get_context()
|
||||||
mapping = objects.CellMapping(database_connection='fake://db',
|
mapping = objects.CellMapping(database_connection='fake://db',
|
||||||
transport_url='fake://mq',
|
transport_url='fake://mq',
|
||||||
uuid=uuids.cell)
|
uuid=uuids.cell)
|
||||||
mappings = objects.CellMappingList(objects=[mapping])
|
mappings = objects.CellMappingList(objects=[mapping])
|
||||||
|
|
||||||
|
# Use a mock manager to assert call order across mocks.
|
||||||
|
manager = mock.Mock()
|
||||||
|
manager.attach_mock(mock_get_inst, 'get_inst')
|
||||||
|
manager.attach_mock(mock_target_cell, 'target_cell')
|
||||||
|
|
||||||
filters = {'deleted': False}
|
filters = {'deleted': False}
|
||||||
context.scatter_gather_cells(
|
context.scatter_gather_cells(
|
||||||
ctxt, mappings, 60, objects.InstanceList.get_by_filters, filters,
|
ctxt, mappings, 60, objects.InstanceList.get_by_filters, filters,
|
||||||
sort_dir='foo')
|
sort_dir='foo')
|
||||||
|
|
||||||
mock_get_inst.assert_called_once_with(
|
# NOTE(melwitt): This only works without the SpawnIsSynchronous fixture
|
||||||
|
# because when the spawn is treated as synchronous and the thread
|
||||||
|
# function is called immediately, it will occur inside the target_cell
|
||||||
|
# context manager scope when it wouldn't with a real spawn.
|
||||||
|
|
||||||
|
# Assert that InstanceList.get_by_filters was called before the
|
||||||
|
# target_cell context manager exited.
|
||||||
|
get_inst_call = mock.call.get_inst(
|
||||||
mock_target_cell.return_value.__enter__.return_value, filters,
|
mock_target_cell.return_value.__enter__.return_value, filters,
|
||||||
sort_dir='foo')
|
sort_dir='foo')
|
||||||
|
expected_calls = [get_inst_call,
|
||||||
|
mock.call.target_cell().__exit__(None, None, None)]
|
||||||
|
manager.assert_has_calls(expected_calls)
|
||||||
|
|
||||||
@mock.patch('nova.context.LOG.warning')
|
@mock.patch('nova.context.LOG.warning')
|
||||||
@mock.patch('eventlet.timeout.Timeout')
|
@mock.patch('eventlet.timeout.Timeout')
|
||||||
|
Loading…
Reference in New Issue
Block a user