]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Big Switch: fix capabilities retrieval code
authorKevin Benton <blak111@gmail.com>
Tue, 3 Jun 2014 04:39:51 +0000 (21:39 -0700)
committerKevin Benton <blak111@gmail.com>
Tue, 3 Jun 2014 07:52:22 +0000 (00:52 -0700)
References the raw REST response in the capabilities
parsing code so json.loads doesn't get an object
that may already be decoded and fail.

Closes-Bug: #1326173
Change-Id: Ia3179b7499f35a6ab2e9ce1631ab15ed27d64647

neutron/plugins/bigswitch/servermanager.py
neutron/tests/unit/bigswitch/test_capabilities.py
neutron/tests/unit/bigswitch/test_servermanager.py

index 2ab629797e4cb3fbd73925a7e95e620d72d363f2..e33bbece55852ee211dda3212187931175026802 100644 (file)
@@ -110,11 +110,11 @@ class ServerProxy(object):
 
     def get_capabilities(self):
         try:
-            body = self.rest_call('GET', CAPABILITIES_PATH)[3]
+            body = self.rest_call('GET', CAPABILITIES_PATH)[2]
             self.capabilities = json.loads(body)
         except Exception:
-            LOG.error(_("Couldn't retrieve capabilities. "
-                        "Newer API calls won't be supported."))
+            LOG.exception(_("Couldn't retrieve capabilities. "
+                            "Newer API calls won't be supported."))
         LOG.info(_("The following capabilities were received "
                    "for %(server)s: %(cap)s"), {'server': self.server,
                                                 'cap': self.capabilities})
index cc81b70b0a3694b18585db83ce78058196f00054..89e4c5b728f163e58cf0903a8c06fd5ad238e103 100644 (file)
@@ -34,7 +34,7 @@ class CapabilitiesTests(test_router_db.RouterDBTestBase):
     def test_floating_ip_capability(self):
         with contextlib.nested(
             mock.patch(SERVERRESTCALL,
-                       return_value=(200, None, None, '["floatingip"]')),
+                       return_value=(200, None, '["floatingip"]', None)),
             mock.patch(SERVERPOOL + '.rest_create_floatingip',
                        return_value=(200, None, None, None)),
             mock.patch(SERVERPOOL + '.rest_delete_floatingip',
@@ -53,7 +53,7 @@ class CapabilitiesTests(test_router_db.RouterDBTestBase):
     def test_floating_ip_capability_neg(self):
         with contextlib.nested(
             mock.patch(SERVERRESTCALL,
-                       return_value=(200, None, None, '[""]')),
+                       return_value=(200, None, '[""]', None)),
             mock.patch(SERVERPOOL + '.rest_update_network',
                        return_value=(200, None, None, None))
         ) as (mock_rest, mock_netupdate):
@@ -67,7 +67,7 @@ class CapabilitiesTests(test_router_db.RouterDBTestBase):
 
     def test_keep_alive_capability(self):
         with mock.patch(
-            SERVERRESTCALL, return_value=(200, None, None, '["keep-alive"]')
+            SERVERRESTCALL, return_value=(200, None, '["keep-alive"]', None)
         ):
             # perform a task to cause capabilities to be retrieved
             with self.floatingip_with_assoc():
index 914a8874431d0fd73acd603926019fe8dd4cbedb..d37e8504eb1dd3827c998c8ae51cb5bbd19858d8 100644 (file)
@@ -174,6 +174,37 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
         self.assertIn('EXTRA-HEADER', callheaders)
         self.assertEqual(callheaders['EXTRA-HEADER'], 'HI')
 
+    def test_capabilities_retrieval(self):
+        sp = servermanager.ServerPool()
+        with mock.patch(HTTPCON) as conmock:
+            rv = conmock.return_value.getresponse.return_value
+            rv.getheader.return_value = 'HASHHEADER'
+
+            # each server will get different capabilities
+            rv.read.side_effect = ['["a","b","c"]', '["b","c","d"]']
+            # pool capabilities is intersection between both
+            self.assertEqual(set(['b', 'c']), sp.get_capabilities())
+            self.assertEqual(2, rv.read.call_count)
+
+            # the pool should cache after the first call so no more
+            # HTTP calls should be made
+            rv.read.side_effect = ['["w","x","y"]', '["x","y","z"]']
+            self.assertEqual(set(['b', 'c']), sp.get_capabilities())
+            self.assertEqual(2, rv.read.call_count)
+
+    def test_capabilities_retrieval_failure(self):
+        sp = servermanager.ServerPool()
+        with mock.patch(HTTPCON) as conmock:
+            rv = conmock.return_value.getresponse.return_value
+            rv.getheader.return_value = 'HASHHEADER'
+            # a failure to parse should result in an empty capability set
+            rv.read.return_value = 'XXXXX'
+            self.assertEqual([], sp.servers[0].get_capabilities())
+
+            # One broken server should affect all capabilities
+            rv.read.side_effect = ['{"a": "b"}', '["b","c","d"]']
+            self.assertEqual(set(), sp.get_capabilities())
+
     def test_reconnect_on_timeout_change(self):
         sp = servermanager.ServerPool()
         with mock.patch(HTTPCON) as conmock: