api: Add HA router delete test
The test makes sure deleting router does not influence any HA network
segmentation details being wiped out.
Change-Id: Ib12986c25eda25970445169310c7c0334d6da49c
Related-bug: #1732543
diff --git a/neutron_tempest_plugin/api/admin/test_routers_ha.py b/neutron_tempest_plugin/api/admin/test_routers_ha.py
index fafe209..da3b9af 100644
--- a/neutron_tempest_plugin/api/admin/test_routers_ha.py
+++ b/neutron_tempest_plugin/api/admin/test_routers_ha.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.common import utils as tutils
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -19,6 +20,7 @@
class RoutersTestHA(base.BaseRouterTest):
required_extensions = ['router', 'l3-ha']
+ HA_NETWORK_NAME_TEMPL = "HA network tenant %s"
@classmethod
def resource_setup(cls):
@@ -90,3 +92,30 @@
router = self.admin_client.update_router(router['router']['id'],
ha=True)
self.assertTrue(router['router']['ha'])
+
+ @decorators.idempotent_id('0d8c0c8f-3809-4acc-a2c8-e0941333ff6c')
+ @tutils.requires_ext(extension="provider", service="network")
+ def test_delete_ha_router_keeps_ha_network_segment_data(self):
+ """Test deleting an HA router keeps correct segment data for network.
+
+ Each tenant with HA router has an HA network. The HA network is a
+ normal tenant network with segmentation data like type (vxlan) and
+ segmenation id. This test makes sure that after an HA router is
+ deleted, those segmentation data are kept in HA network. This tests
+ regression of https://bugs.launchpad.net/neutron/+bug/1732543.
+ """
+ for i in range(2):
+ router = self._create_admin_router(
+ data_utils.rand_name('router%d' % i),
+ ha=True)
+ ha_net_name = self.HA_NETWORK_NAME_TEMPL % router['tenant_id']
+ ha_network_pre_delete = self.admin_client.list_networks(
+ name=ha_net_name)['networks'][0]
+ segmentation_id = ha_network_pre_delete['provider:segmentation_id']
+ self._delete_router(router['id'], self.admin_client)
+
+ ha_network_post_delete = self.admin_client.show_network(
+ ha_network_pre_delete['id'])['network']
+ self.assertEqual(
+ ha_network_post_delete['provider:segmentation_id'],
+ segmentation_id)
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index 8db5108..ec66818 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -412,17 +412,18 @@
return qos_rule
@classmethod
- def delete_router(cls, router):
- body = cls.client.list_router_interfaces(router['id'])
+ def delete_router(cls, router, client=None):
+ client = client or cls.client
+ body = client.list_router_interfaces(router['id'])
interfaces = [port for port in body['ports']
if port['device_owner'] in const.ROUTER_INTERFACE_OWNERS]
for i in interfaces:
try:
- cls.client.remove_router_interface_with_subnet_id(
+ client.remove_router_interface_with_subnet_id(
router['id'], i['fixed_ips'][0]['subnet_id'])
except lib_exc.NotFound:
pass
- cls.client.delete_router(router['id'])
+ client.delete_router(router['id'])
@classmethod
def create_address_scope(cls, name, is_admin=False, **kwargs):
diff --git a/neutron_tempest_plugin/api/base_routers.py b/neutron_tempest_plugin/api/base_routers.py
index c8d3783..52db742 100644
--- a/neutron_tempest_plugin/api/base_routers.py
+++ b/neutron_tempest_plugin/api/base_routers.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib import exceptions
+
from neutron_tempest_plugin.api import base
@@ -21,9 +23,12 @@
# as some router operations, such as enabling or disabling SNAT
# require admin credentials by default
- def _cleanup_router(self, router):
- self.delete_router(router)
- self.routers.remove(router)
+ def _cleanup_router(self, router, client=None):
+ try:
+ self.delete_router(router, client)
+ self.routers.remove(router)
+ except exceptions.NotFound:
+ pass
def _create_router(self, name, admin_state_up=False,
external_network_id=None, enable_snat=None):
@@ -33,6 +38,12 @@
self.addCleanup(self._cleanup_router, router)
return router
+ def _create_admin_router(self, *args, **kwargs):
+ router = self.create_admin_router(*args, **kwargs)
+ self.addCleanup(
+ self._cleanup_router, router, self.os_admin.network_client)
+ return router
+
def _delete_router(self, router_id, network_client=None):
client = network_client or self.client
client.delete_router(router_id)