Add tempest test for l3-ha extension
Add missing l3-ha extension under neutron tempest tests.
Change-Id: Ia608d3f5d63a88eefa4e61da6df2f3656c8446a0
Closes-Bug: #1684065
diff --git a/neutron/tests/tempest/api/admin/test_routers_ha.py b/neutron/tests/tempest/api/admin/test_routers_ha.py
new file mode 100644
index 0000000..187eb6d
--- /dev/null
+++ b/neutron/tests/tempest/api/admin/test_routers_ha.py
@@ -0,0 +1,93 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
+from tempest import test
+
+from neutron.tests.tempest.api import base_routers as base
+
+
+class RoutersTestHA(base.BaseRouterTest):
+
+ @classmethod
+ @test.requires_ext(extension="router", service="network")
+ @test.requires_ext(extension="l3-ha", service="network")
+ def resource_setup(cls):
+ # The check above will pass if api_extensions=all, which does
+ # not mean "l3-ha" extension itself is present.
+ # Instead, we have to check whether "ha" is actually present by using
+ # admin credentials to create router with ha=True attribute
+ # and checking for BadRequest exception and that the resulting router
+ # has a high availability attribute.
+ super(RoutersTestHA, cls).resource_setup()
+ name = data_utils.rand_name('pretest-check')
+ router = cls.admin_client.create_router(name)
+ if 'ha' not in router['router']:
+ cls.admin_client.delete_router(router['router']['id'])
+ msg = "'ha' attribute not found. HA Possibly not enabled"
+ raise cls.skipException(msg)
+
+ @decorators.idempotent_id('8abc177d-14f1-4018-9f01-589b299cbee1')
+ def test_ha_router_creation(self):
+ """
+ Test uses administrative credentials to create a
+ HA (High Availability) router using the ha=True.
+
+ Acceptance
+ The router is created and the "ha" attribute is set to True
+ """
+ name = data_utils.rand_name('router')
+ router = self.admin_client.create_router(name, ha=True)
+ self.addCleanup(self.admin_client.delete_router,
+ router['router']['id'])
+ self.assertTrue(router['router']['ha'])
+
+ @decorators.idempotent_id('97b5f7ef-2192-4fa3-901e-979cd5c1097a')
+ def test_legacy_router_creation(self):
+ """
+ Test uses administrative credentials to create a
+ SF (Single Failure) router using the ha=False.
+
+ Acceptance
+ The router is created and the "ha" attribute is
+ set to False, thus making it a "Single Failure Router"
+ as opposed to a "High Availability Router"
+ """
+ name = data_utils.rand_name('router')
+ router = self.admin_client.create_router(name, ha=False)
+ self.addCleanup(self.admin_client.delete_router,
+ router['router']['id'])
+ self.assertFalse(router['router']['ha'])
+
+ @decorators.idempotent_id('5a6bfe82-5b23-45a4-b027-5160997d4753')
+ def test_legacy_router_update_to_ha(self):
+ """
+ Test uses administrative credentials to create a
+ SF (Single Failure) router using the ha=False.
+ Then it will "update" the router ha attribute to True
+
+ Acceptance
+ The router is created and the "ha" attribute is
+ set to False. Once the router is updated, the ha
+ attribute will be set to True
+ """
+ name = data_utils.rand_name('router')
+ # router needs to be in admin state down in order to be upgraded to HA
+ router = self.admin_client.create_router(name, ha=False,
+ admin_state_up=False)
+ self.addCleanup(self.admin_client.delete_router,
+ router['router']['id'])
+ self.assertFalse(router['router']['ha'])
+ router = self.admin_client.update_router(router['router']['id'],
+ ha=True)
+ self.assertTrue(router['router']['ha'])
diff --git a/neutron/tests/tempest/api/test_routers.py b/neutron/tests/tempest/api/test_routers.py
index 7a1e458..85bfe82 100644
--- a/neutron/tests/tempest/api/test_routers.py
+++ b/neutron/tests/tempest/api/test_routers.py
@@ -259,6 +259,26 @@
self.assertNotIn('distributed', show_body['router'])
+class HaRoutersTest(base_routers.BaseRouterTest):
+
+ @classmethod
+ @test.requires_ext(extension="l3-ha", service="network")
+ def skip_checks(cls):
+ super(HaRoutersTest, cls).skip_checks()
+
+ @decorators.idempotent_id('77db8eae-3aa3-4e61-bf2a-e739ce042e53')
+ def test_convert_legacy_router(self):
+ router = self._create_router(data_utils.rand_name('router'))
+ self.assertNotIn('ha', router)
+ update_body = self.admin_client.update_router(router['id'],
+ ha=True)
+ self.assertTrue(update_body['router']['ha'])
+ show_body = self.admin_client.show_router(router['id'])
+ self.assertTrue(show_body['router']['ha'])
+ show_body = self.client.show_router(router['id'])
+ self.assertNotIn('ha', show_body['router'])
+
+
class RoutersSearchCriteriaTest(base.BaseSearchCriteriaTest):
resource = 'router'
diff --git a/neutron/tests/tempest/api/test_routers_negative.py b/neutron/tests/tempest/api/test_routers_negative.py
index 049b9c8..b97e30d 100644
--- a/neutron/tests/tempest/api/test_routers_negative.py
+++ b/neutron/tests/tempest/api/test_routers_negative.py
@@ -85,3 +85,18 @@
with testtools.ExpectedException(lib_exc.Forbidden):
self.create_router(
data_utils.rand_name('router'), distributed=True)
+
+
+class HaRoutersNegativeTest(RoutersNegativeTestBase):
+
+ @classmethod
+ @test.requires_ext(extension="l3-ha", service="network")
+ def skip_checks(cls):
+ super(HaRoutersNegativeTest, cls).skip_checks()
+
+ @test.attr(type='negative')
+ @decorators.idempotent_id('821b85b9-9c51-40f3-831f-bf223a7e0084')
+ def test_router_create_tenant_ha_returns_forbidden(self):
+ with testtools.ExpectedException(lib_exc.Forbidden):
+ self.create_router(
+ data_utils.rand_name('router'), ha=True)