From 75e3ad94aa8969acc0d5f0e2463dd7e5ce523526 Mon Sep 17 00:00:00 2001
From: Matthew Booth <mbooth@redhat.com>
Date: Mon, 13 Mar 2017 18:28:17 +0000
Subject: [PATCH] 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
---
 nova/tests/fixtures.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/nova/tests/fixtures.py b/nova/tests/fixtures.py
index e60590f96..53fa6a2a2 100644
--- a/nova/tests/fixtures.py
+++ b/nova/tests/fixtures.py
@@ -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]