Fix and optimize external_events for multiple cells

server_external_events was previously making an api db query and a
cell db query for every instance reference. We improve this by
making exactly 1 api db query to fetch all instance mappings, and then
1 cell db query per cell to fetch all relevant instances from that
cell. Further, it wasn't properly handling the case where events
were delivered in one request for multiple instances across cells,
which this also fixes.

We also document an obtuse edge condition in
ComputeAPI.external_instance_event which will cause the current code
to break when we support migration between cells.

Note this includes a tweak to the SingleCellSimple fixture to mock out
the new InstanceMappingList method we use, as well as a fix to the other
InstanceMapping mock, which was returning mappings with bogus instance
uuids. This patch relies on the results of those being realistic and
thus requires those changes.

Closes-Bug: #1702959

Co-Authored-By: Dan Smith <dms@danplanet.com>

Change-Id: If59453f1899e99040c554bcb9ad54c8a506adc56
This commit is contained in:
Matthew Booth 2017-03-13 18:28:17 +00:00 committed by Matt Riedemann
parent f774a511c1
commit 75e3ad94aa

@ -288,6 +288,9 @@ class SingleCellSimple(fixtures.Fixture):
self.useFixture(fixtures.MonkeyPatch(
'nova.objects.InstanceMapping._get_by_instance_uuid_from_db',
self._fake_instancemapping_get))
self.useFixture(fixtures.MonkeyPatch(
'nova.objects.InstanceMappingList._get_by_instance_uuids_from_db',
self._fake_instancemapping_get_uuids))
self.useFixture(fixtures.MonkeyPatch(
'nova.objects.InstanceMapping._save_in_db',
self._fake_instancemapping_get))
@ -310,13 +313,17 @@ class SingleCellSimple(fixtures.Fixture):
'id': 1,
'updated_at': None,
'created_at': None,
'instance_uuid': uuidsentinel.instance,
'instance_uuid': args[-1],
'cell_id': (self.instances_created and 1 or None),
'project_id': 'project',
'cell_mapping': (
self.instances_created and self._fake_cell_get() or None),
}
def _fake_instancemapping_get_uuids(self, *args):
return [self._fake_instancemapping_get(uuid)
for uuid in args[-1]]
def _fake_cell_get(self, *args):
return self._fake_cell_list()[0]