]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Defer segment lookup in NetworkContext object
authorKevin Benton <blak111@gmail.com>
Thu, 4 Jun 2015 02:03:29 +0000 (19:03 -0700)
committerKevin Benton <kevinbenton@buttewifi.com>
Tue, 9 Jun 2015 04:47:07 +0000 (04:47 +0000)
Avoid call to get network segments for network context objects until
a caller actually tries to lookup the segments. This optimizes cases
where the user of a port context never looks at the segments of the
associated network context (e.g. update_port_status).

Closes-Bug: #1463254
Change-Id: I7e95f81d9a3ef26ccdb18c6bfdf9adc29523aa79

neutron/plugins/ml2/driver_context.py
neutron/tests/unit/plugins/ml2/test_driver_context.py

index ef418fe16e21770dc2569fcac7401ddc2c485736..6e9b295b594de9056cf9c36d1b160738f9614c42 100644 (file)
@@ -42,8 +42,8 @@ class NetworkContext(MechanismDriverContext, api.NetworkContext):
         super(NetworkContext, self).__init__(plugin, plugin_context)
         self._network = network
         self._original_network = original_network
-        self._segments = db.get_network_segments(plugin_context.session,
-                                                 network['id'])
+        self._segments = None
+        self._session = plugin_context.session
 
     @property
     def current(self):
@@ -55,6 +55,9 @@ class NetworkContext(MechanismDriverContext, api.NetworkContext):
 
     @property
     def network_segments(self):
+        if not self._segments:
+            self._segments = db.get_network_segments(self._session,
+                                                     self._network['id'])
         return self._segments
 
 
index e30349c9c6c39d1e31e8e898241c26768531c277..8171071b6c243f4b2e6b2841efdbc791cc8e69a2 100644 (file)
@@ -37,13 +37,12 @@ class TestPortContext(base.BaseTestCase):
         port = {'device_owner': constants.DEVICE_OWNER_DVR_INTERFACE}
         binding.host = 'foohost'
 
-        with mock.patch.object(driver_context.db, 'get_network_segments'):
-            ctx = driver_context.PortContext(plugin,
-                                             plugin_context,
-                                             port,
-                                             network,
-                                             binding,
-                                             None)
+        ctx = driver_context.PortContext(plugin,
+                                         plugin_context,
+                                         port,
+                                         network,
+                                         binding,
+                                         None)
         self.assertEqual('foohost', ctx.host)
 
     def test_host_super(self):
@@ -56,13 +55,12 @@ class TestPortContext(base.BaseTestCase):
                 portbindings.HOST_ID: 'host'}
         binding.host = 'foohost'
 
-        with mock.patch.object(driver_context.db, 'get_network_segments'):
-            ctx = driver_context.PortContext(plugin,
-                                             plugin_context,
-                                             port,
-                                             network,
-                                             binding,
-                                             None)
+        ctx = driver_context.PortContext(plugin,
+                                         plugin_context,
+                                         port,
+                                         network,
+                                         binding,
+                                         None)
         self.assertEqual('host', ctx.host)
 
     def test_status(self):
@@ -74,13 +72,12 @@ class TestPortContext(base.BaseTestCase):
         port = {'device_owner': constants.DEVICE_OWNER_DVR_INTERFACE}
         binding.status = 'foostatus'
 
-        with mock.patch.object(driver_context.db, 'get_network_segments'):
-            ctx = driver_context.PortContext(plugin,
-                                             plugin_context,
-                                             port,
-                                             network,
-                                             binding,
-                                             None)
+        ctx = driver_context.PortContext(plugin,
+                                         plugin_context,
+                                         port,
+                                         network,
+                                         binding,
+                                         None)
         self.assertEqual('foostatus', ctx.status)
 
     def test_status_super(self):
@@ -93,11 +90,37 @@ class TestPortContext(base.BaseTestCase):
                 'status': 'status'}
         binding.status = 'foostatus'
 
-        with mock.patch.object(driver_context.db, 'get_network_segments'):
+        ctx = driver_context.PortContext(plugin,
+                                         plugin_context,
+                                         port,
+                                         network,
+                                         binding,
+                                         None)
+        self.assertEqual('status', ctx.status)
+
+    def test_segments_lazy_lookup(self):
+        plugin = mock.Mock()
+        plugin_context = mock.Mock()
+        network = mock.MagicMock()
+        binding = mock.Mock()
+
+        port = {'device_owner': 'compute',
+                'status': 'status'}
+        binding.status = 'foostatus'
+
+        with mock.patch.object(driver_context.db,
+                               'get_network_segments') as gs:
             ctx = driver_context.PortContext(plugin,
                                              plugin_context,
                                              port,
                                              network,
                                              binding,
                                              None)
-        self.assertEqual('status', ctx.status)
+            self.assertFalse(gs.called)
+            # accessing the network_segments property should trigger
+            # a lookup the first time
+            seg = ctx.network.network_segments
+            self.assertTrue(gs.called)
+            gs.reset_mock()
+            self.assertEqual(seg, ctx.network.network_segments)
+            self.assertFalse(gs.called)