summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-06-16 15:37:22 +0000
committerGerrit Code Review <review@openstack.org>2017-06-16 15:37:22 +0000
commit2c5523f74042641f938bf0133ca9301d245920b6 (patch)
tree707d871d2c9fe644680686f70b2037d804e5508c
parenteb4ffe1010f719ee420c2c4834fabe688e407a00 (diff)
parent0ac6a2ec0abe85c94a08a47b242e1374aad74fa6 (diff)
Merge "Workaround failing UT for asr1k router type driver"
-rw-r--r--networking_cisco/plugins/cisco/db/l3/l3_router_appliance_db.py3
-rw-r--r--networking_cisco/plugins/cisco/l3/drivers/asr1k/asr1k_routertype_driver.py19
-rw-r--r--networking_cisco/tests/unit/cisco/l3/test_asr1k_routertype_driver.py114
3 files changed, 128 insertions, 8 deletions
diff --git a/networking_cisco/plugins/cisco/db/l3/l3_router_appliance_db.py b/networking_cisco/plugins/cisco/db/l3/l3_router_appliance_db.py
index ca191cf..a0077ad 100644
--- a/networking_cisco/plugins/cisco/db/l3/l3_router_appliance_db.py
+++ b/networking_cisco/plugins/cisco/db/l3/l3_router_appliance_db.py
@@ -423,8 +423,7 @@ class L3RouterApplianceDBMixin(extraroute_db.ExtraRoute_dbonly_mixin):
423 with excutils.save_and_reraise_exception(): 423 with excutils.save_and_reraise_exception():
424 # put router back in backlog if deletion failed so that it 424 # put router back in backlog if deletion failed so that it
425 # gets reinstated 425 # gets reinstated
426 LOG.exception(_LE("Deletion of router %s failed. It will be " 426 LOG.error(_LE("Deletion of router %s failed."), router_id)
427 "re-hosted."), router_id)
428 if was_hosted is True or r_hd_binding_db.auto_schedule is True: 427 if was_hosted is True or r_hd_binding_db.auto_schedule is True:
429 LOG.info(_LI("Router %s will be re-hosted."), router_id) 428 LOG.info(_LI("Router %s will be re-hosted."), router_id)
430 self.backlog_router(context, r_hd_binding_db) 429 self.backlog_router(context, r_hd_binding_db)
diff --git a/networking_cisco/plugins/cisco/l3/drivers/asr1k/asr1k_routertype_driver.py b/networking_cisco/plugins/cisco/l3/drivers/asr1k/asr1k_routertype_driver.py
index 0cfd82f..bbe0975 100644
--- a/networking_cisco/plugins/cisco/l3/drivers/asr1k/asr1k_routertype_driver.py
+++ b/networking_cisco/plugins/cisco/l3/drivers/asr1k/asr1k_routertype_driver.py
@@ -24,7 +24,7 @@ from neutron.extensions import l3
24from neutron_lib import constants as l3_constants 24from neutron_lib import constants as l3_constants
25from neutron_lib import exceptions as n_exc 25from neutron_lib import exceptions as n_exc
26 26
27from networking_cisco._i18n import _, _LW 27from networking_cisco._i18n import _, _LI
28from networking_cisco import backwards_compatibility as bc 28from networking_cisco import backwards_compatibility as bc
29from networking_cisco.plugins.cisco.common import cisco_constants 29from networking_cisco.plugins.cisco.common import cisco_constants
30from networking_cisco.plugins.cisco.db.l3 import ha_db 30from networking_cisco.plugins.cisco.db.l3 import ha_db
@@ -195,6 +195,7 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
195 return group_id 195 return group_id
196 196
197 def pre_backlog_processing(self, context): 197 def pre_backlog_processing(self, context):
198 LOG.info(_LI('Performing pre-backlog processing'))
198 filters = {routerrole.ROUTER_ROLE_ATTR: [ROUTER_ROLE_GLOBAL]} 199 filters = {routerrole.ROUTER_ROLE_ATTR: [ROUTER_ROLE_GLOBAL]}
199 global_routers = self._l3_plugin.get_routers(context, filters=filters) 200 global_routers = self._l3_plugin.get_routers(context, filters=filters)
200 if not global_routers: 201 if not global_routers:
@@ -214,9 +215,9 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
214 {'name': gr['name'], 'id': gr['id'], 215 {'name': gr['name'], 'id': gr['id'],
215 'hd': gr[HOSTING_DEVICE_ATTR], 'num': num_rtrs, }) 216 'hd': gr[HOSTING_DEVICE_ATTR], 'num': num_rtrs, })
216 if num_rtrs == 0: 217 if num_rtrs == 0:
217 LOG.warning( 218 LOG.info(
218 _LW("Global router:%(name)s[id:%(id)s] is present for " 219 _LI("Global router %(name)s[id:%(id)s] is present for "
219 "hosting device:%(hd)s but there are no tenant or " 220 "hosting device %(hd)s but there are no tenant or "
220 "redundancy routers with gateway set on that hosting " 221 "redundancy routers with gateway set on that hosting "
221 "device. Proceeding to delete global router."), 222 "device. Proceeding to delete global router."),
222 {'name': gr['name'], 'id': gr['id'], 223 {'name': gr['name'], 'id': gr['id'],
@@ -531,7 +532,10 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
531 self._core_plugin.delete_port(context, port['id'], 532 self._core_plugin.delete_port(context, port['id'],
532 l3_port_check=False) 533 l3_port_check=False)
533 except (exc.ObjectDeletedError, n_exc.PortNotFound) as e: 534 except (exc.ObjectDeletedError, n_exc.PortNotFound) as e:
534 LOG.warning(e) 535 LOG.info(_LI('Unable to delete port for Global router '
536 '%(r_id). It has likely been concurrently '
537 'deleted. %(err)s'), {'r_id': router_id,
538 'err': e})
535 539
536 def _delete_global_router(self, context, global_router_id, logical=False): 540 def _delete_global_router(self, context, global_router_id, logical=False):
537 # ensure we clean up any stale auxiliary gateway ports 541 # ensure we clean up any stale auxiliary gateway ports
@@ -547,7 +551,10 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
547 self._l3_plugin.delete_router( 551 self._l3_plugin.delete_router(
548 context, global_router_id, unschedule=False) 552 context, global_router_id, unschedule=False)
549 except (exc.ObjectDeletedError, l3.RouterNotFound) as e: 553 except (exc.ObjectDeletedError, l3.RouterNotFound) as e:
550 LOG.warning(e) 554 g_r_type = 'Logical Global' if logical is True else 'Global'
555 LOG.info(_LI('Unable to delete %(g_r_type)s router. It has likely '
556 'been concurrently deleted. %(err)s'),
557 {'g_r_type': g_r_type, 'err': e})
551 558
552 def _get_gateway_routers_count(self, context, ext_net_id, routertype_id, 559 def _get_gateway_routers_count(self, context, ext_net_id, routertype_id,
553 router_role, hosting_device_id=None): 560 router_role, hosting_device_id=None):
diff --git a/networking_cisco/tests/unit/cisco/l3/test_asr1k_routertype_driver.py b/networking_cisco/tests/unit/cisco/l3/test_asr1k_routertype_driver.py
index 6f8c401..fe1317e 100644
--- a/networking_cisco/tests/unit/cisco/l3/test_asr1k_routertype_driver.py
+++ b/networking_cisco/tests/unit/cisco/l3/test_asr1k_routertype_driver.py
@@ -16,23 +16,31 @@ import copy
16import mock 16import mock
17 17
18from oslo_config import cfg 18from oslo_config import cfg
19from oslo_log import log as logging
19from oslo_utils import uuidutils 20from oslo_utils import uuidutils
21from sqlalchemy.orm import exc as db_exc
20from webob import exc 22from webob import exc
21 23
22from neutron.extensions import l3 24from neutron.extensions import l3
23 25
24from networking_cisco import backwards_compatibility as bc 26from networking_cisco import backwards_compatibility as bc
25from networking_cisco.plugins.cisco.common import cisco_constants 27from networking_cisco.plugins.cisco.common import cisco_constants
28from networking_cisco.plugins.cisco.db.l3.l3_router_appliance_db import (
29 L3RouterApplianceDBMixin)
26from networking_cisco.plugins.cisco.extensions import ha 30from networking_cisco.plugins.cisco.extensions import ha
27from networking_cisco.plugins.cisco.extensions import routerhostingdevice 31from networking_cisco.plugins.cisco.extensions import routerhostingdevice
28from networking_cisco.plugins.cisco.extensions import routerrole 32from networking_cisco.plugins.cisco.extensions import routerrole
29from networking_cisco.plugins.cisco.extensions import routertype 33from networking_cisco.plugins.cisco.extensions import routertype
30from networking_cisco.plugins.cisco.extensions import routertypeawarescheduler 34from networking_cisco.plugins.cisco.extensions import routertypeawarescheduler
35from networking_cisco.plugins.cisco.l3.drivers.asr1k import (
36 asr1k_routertype_driver as drv)
31from networking_cisco.tests.unit.cisco.l3 import ( 37from networking_cisco.tests.unit.cisco.l3 import (
32 test_ha_l3_router_appliance_plugin as cisco_ha_test) 38 test_ha_l3_router_appliance_plugin as cisco_ha_test)
33from networking_cisco.tests.unit.cisco.l3 import ( 39from networking_cisco.tests.unit.cisco.l3 import (
34 test_l3_routertype_aware_schedulers as cisco_test_case) 40 test_l3_routertype_aware_schedulers as cisco_test_case)
35 41
42LOG = logging.getLogger(__name__)
43
36 44
37_uuid = uuidutils.generate_uuid 45_uuid = uuidutils.generate_uuid
38 46
@@ -52,6 +60,9 @@ ROUTER_ROLE_ATTR = routerrole.ROUTER_ROLE_ATTR
52HOSTING_DEVICE_ATTR = routerhostingdevice.HOSTING_DEVICE_ATTR 60HOSTING_DEVICE_ATTR = routerhostingdevice.HOSTING_DEVICE_ATTR
53AUTO_SCHEDULE_ATTR = routertypeawarescheduler.AUTO_SCHEDULE_ATTR 61AUTO_SCHEDULE_ATTR = routertypeawarescheduler.AUTO_SCHEDULE_ATTR
54 62
63TestSchedulingL3RouterApplianceExtensionManager = (
64 cisco_test_case.TestSchedulingL3RouterApplianceExtensionManager)
65
55 66
56class Asr1kRouterTypeDriverTestCase( 67class Asr1kRouterTypeDriverTestCase(
57 cisco_test_case.L3RoutertypeAwareHostingDeviceSchedulerTestCaseBase): 68 cisco_test_case.L3RoutertypeAwareHostingDeviceSchedulerTestCaseBase):
@@ -61,6 +72,23 @@ class Asr1kRouterTypeDriverTestCase(
61 # that router type in the test setup which makes scheduling deterministic 72 # that router type in the test setup which makes scheduling deterministic
62 router_type = 'Nexus_ToR_Neutron_router' 73 router_type = 'Nexus_ToR_Neutron_router'
63 74
75 def setUp(self, core_plugin=None, l3_plugin=None, dm_plugin=None,
76 ext_mgr=None):
77 if l3_plugin is None:
78 l3_plugin = cisco_test_case.L3_PLUGIN_KLASS
79 if ext_mgr is None:
80 ext_mgr = TestSchedulingL3RouterApplianceExtensionManager()
81 super(Asr1kRouterTypeDriverTestCase, self).setUp(
82 core_plugin, l3_plugin, dm_plugin, ext_mgr)
83
84 #TODO(bobmel): Remove this mock once bug/#1676435 is fixed
85 def noop_pre_backlog_processing(context):
86 LOG.debug('No-op pre_backlog_processing during UTs')
87
88 mock.patch('networking_cisco.plugins.cisco.l3.drivers.asr1k'
89 '.asr1k_routertype_driver.ASR1kL3RouterDriver'
90 '.pre_backlog_processing', new=noop_pre_backlog_processing)
91
64 def _verify_global_router(self, role, hd_id, ext_net_ids): 92 def _verify_global_router(self, role, hd_id, ext_net_ids):
65 # The 'ext_net_ids' argument is a dict where key is ext_net_id and 93 # The 'ext_net_ids' argument is a dict where key is ext_net_id and
66 # value is a list of subnet_ids that the global router should be 94 # value is a list of subnet_ids that the global router should be
@@ -678,6 +706,92 @@ class Asr1kRouterTypeDriverTestCase(
678 self._test_router_update_unset_msn_gw(same_tenant=False, 706 self._test_router_update_unset_msn_gw(same_tenant=False,
679 same_ext_net=False) 707 same_ext_net=False)
680 708
709 def _test_router_update_unset_msn_gw_concurrent(
710 self, delete_global=True, delete_ports=False,
711 delete_logical=False):
712
713 def _concurrent_delete_global_router(local_self, context,
714 global_router_id, logical=False):
715 if delete_ports is True:
716 delete_p_fcn(local_self, context, global_router_id)
717 try:
718 if logical is True:
719 if delete_logical is True:
720 super(L3RouterApplianceDBMixin,
721 self.l3_plugin).delete_router(context,
722 global_router_id)
723 else:
724 if delete_global is True:
725 self.l3_plugin.delete_router(
726 context, global_router_id, unschedule=False)
727 except (db_exc.ObjectDeletedError, l3.RouterNotFound) as e:
728 LOG.warning(e)
729 delete_gr_fcn(local_self, context, global_router_id, logical)
730
731 set_context = False
732 tenant_id = _uuid()
733 with self.network(tenant_id=tenant_id) as msn_n_external:
734 msn_ext_net_id = msn_n_external['network']['id']
735 self._set_net_external(msn_ext_net_id)
736 sn_1 = self._make_subnet(
737 self.fmt, msn_n_external, '10.0.1.1', cidr='10.0.1.0/24',
738 tenant_id=tenant_id)['subnet']
739 sn_2 = self._make_subnet(
740 self.fmt, msn_n_external, '20.0.1.1', cidr='20.0.1.0/24',
741 tenant_id=tenant_id)['subnet']
742 ext_gw_subnets = [sn_1['id'], sn_2['id']]
743 ext_net_ids = {msn_ext_net_id: ext_gw_subnets}
744 ext_gw = {
745 'network_id': msn_ext_net_id,
746 'external_fixed_ips': [{'subnet_id': sid}
747 for sid in ext_gw_subnets]}
748 with self.router(tenant_id=tenant_id,
749 external_gateway_info=ext_gw,
750 set_context=set_context) as router:
751 r = router['router']
752 # backlog processing will trigger one routers_updated
753 # notification containing r1 and r2
754 self.l3_plugin._process_backlogged_routers()
755 r_after = self._show('routers', r['id'])['router']
756 hd_id = r_after[HOSTING_DEVICE_ATTR]
757 r_ids = {r['id']}
758 # should have one global router now
759 self._verify_routers(r_ids, ext_net_ids, hd_id)
760 ext_gw['external_fixed_ips'] = [{'subnet_id': sn_1['id']}]
761 r_spec = {'router': {l3.EXTERNAL_GW_INFO: ext_gw}}
762 r_after_2 = self._update('routers', r['id'], r_spec)['router']
763 res_ips = r_after_2[l3.EXTERNAL_GW_INFO]['external_fixed_ips']
764 self.assertEqual(1, len(res_ips))
765 self.assertEqual(sn_1['id'], res_ips[0]['subnet_id'])
766 # should still have one global router
767 self._verify_routers(r_ids, ext_net_ids, hd_id)
768 # now we simulate that there is another router with similar
769 # gateway that is unset concurrently and that its REST API
770 # thread manages to delete the global router
771 r_spec = {'router': {l3.EXTERNAL_GW_INFO: None}}
772
773 delete_gr_fcn = drv.ASR1kL3RouterDriver._delete_global_router
774 delete_p_fcn = (
775 drv.ASR1kL3RouterDriver._delete_auxiliary_gateway_ports)
776 with mock.patch(
777 'networking_cisco.plugins.cisco.l3.drivers.asr1k'
778 '.asr1k_routertype_driver.ASR1kL3RouterDriver'
779 '._delete_global_router',
780 new=_concurrent_delete_global_router):
781 self._update('routers', r['id'], r_spec)
782 # should have no global router now
783 self._verify_routers(r_ids, ext_net_ids)
784
785 def test_router_update_unset_msn_gw_concurrent_global_delete(self):
786 self._test_router_update_unset_msn_gw_concurrent()
787
788 def test_router_update_unset_msn_gw_concurrent_global_port_delete(self):
789 self._test_router_update_unset_msn_gw_concurrent(delete_ports=True)
790
791 def test_router_update_unset_msn_gw_concurrent_port_delete(self):
792 self._test_router_update_unset_msn_gw_concurrent(delete_global=False,
793 delete_ports=True)
794
681 def _test_delete_gateway_router(self, set_context=False, same_tenant=True, 795 def _test_delete_gateway_router(self, set_context=False, same_tenant=True,
682 same_ext_net=True): 796 same_ext_net=True):
683 self._test_router_update_unset_gw_or_delete( 797 self._test_router_update_unset_gw_or_delete(