Merge "[OVN] Use the OVN agent in "neutron-tempest-plugin-ovn""
diff --git a/neutron_tempest_plugin/api/admin/test_logging.py b/neutron_tempest_plugin/api/admin/test_logging.py
index b76377d..dda31b4 100644
--- a/neutron_tempest_plugin/api/admin/test_logging.py
+++ b/neutron_tempest_plugin/api/admin/test_logging.py
@@ -15,12 +15,9 @@
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
-import testscenarios
from neutron_tempest_plugin.api import base
-load_tests = testscenarios.load_tests_apply_scenarios
-
class LoggingTestJSON(base.BaseAdminNetworkTest):
diff --git a/neutron_tempest_plugin/api/test_qos.py b/neutron_tempest_plugin/api/test_qos.py
index 448f391..f1867d1 100644
--- a/neutron_tempest_plugin/api/test_qos.py
+++ b/neutron_tempest_plugin/api/test_qos.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+
+import ddt
from neutron_lib.api.definitions import qos as qos_apidef
from neutron_lib import constants as n_constants
from neutron_lib.services.qos import constants as qos_consts
@@ -20,14 +22,11 @@
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions
-
-import testscenarios
import testtools
from neutron_tempest_plugin.api import base
from neutron_tempest_plugin import config
-load_tests = testscenarios.load_tests_apply_scenarios
CONF = config.CONF
@@ -484,15 +483,6 @@
policy_id, rule['id'])
return rule
- @property
- def opposite_direction(self):
- if self.direction == "ingress":
- return "egress"
- elif self.direction == "egress":
- return "ingress"
- else:
- return None
-
@decorators.idempotent_id('8a59b00b-3e9c-4787-92f8-93a5cdf5e378')
def test_rule_create(self):
policy = self.create_qos_policy(name=self.policy_name,
@@ -544,17 +534,20 @@
@decorators.idempotent_id('149a6988-2568-47d2-931e-2dbc858943b3')
def test_rule_update(self):
+ self._test_rule_update(opposite_direction=None)
+
+ def _test_rule_update(self, opposite_direction=None):
policy = self.create_qos_policy(name=self.policy_name,
description='test policy',
shared=False)
rule = self._create_qos_bw_limit_rule(
policy['id'], {'max_kbps': 1, 'max_burst_kbps': 1})
- if self.opposite_direction:
+ if opposite_direction:
self.qos_bw_limit_rule_client.update_limit_bandwidth_rule(
policy['id'], rule['id'],
**{'max_kbps': 200, 'max_burst_kbps': 1337,
- 'direction': self.opposite_direction})
+ 'direction': opposite_direction})
else:
self.qos_bw_limit_rule_client.update_limit_bandwidth_rule(
policy['id'], rule['id'],
@@ -564,8 +557,8 @@
retrieved_policy = retrieved_policy['bandwidth_limit_rule']
self.assertEqual(200, retrieved_policy['max_kbps'])
self.assertEqual(1337, retrieved_policy['max_burst_kbps'])
- if self.opposite_direction:
- self.assertEqual(self.opposite_direction,
+ if opposite_direction:
+ self.assertEqual(opposite_direction,
retrieved_policy['direction'])
@decorators.idempotent_id('67ee6efd-7b33-4a68-927d-275b4f8ba958')
@@ -697,16 +690,13 @@
policy['id'])
+@ddt.ddt
class QosBandwidthLimitRuleWithDirectionTestJSON(
QosBandwidthLimitRuleTestJSON):
required_extensions = (
QosBandwidthLimitRuleTestJSON.required_extensions +
['qos-bw-limit-direction']
)
- scenarios = [
- ('ingress', {'direction': 'ingress'}),
- ('egress', {'direction': 'egress'}),
- ]
@classmethod
@base.require_qos_rule_type(qos_consts.RULE_TYPE_BANDWIDTH_LIMIT)
@@ -753,6 +743,13 @@
{'max_kbps': 1025, 'max_burst_kbps': 1025,
'direction': n_constants.INGRESS_DIRECTION})
+ @decorators.idempotent_id('7ca7c83b-0555-4a0f-a422-4338f77f79e5')
+ @ddt.unpack
+ @ddt.data({'opposite_direction': 'ingress'},
+ {'opposite_direction': 'egress'})
+ def test_rule_update(self, opposite_direction):
+ self._test_rule_update(opposite_direction=opposite_direction)
+
class RbacSharedQosPoliciesTest(base.BaseAdminNetworkTest):
diff --git a/neutron_tempest_plugin/config.py b/neutron_tempest_plugin/config.py
index 4fad1fa..a6d5c09 100644
--- a/neutron_tempest_plugin/config.py
+++ b/neutron_tempest_plugin/config.py
@@ -242,6 +242,17 @@
CONF.register_group(taas_group)
CONF.register_opts(TaasGroup, group="taas")
+# DNS Integration with an External Service
+DnsFeatureGroup = [
+ cfg.IntOpt(
+ 'segmentation_id', default=12345,
+ help="For network types VLAN, GRE, VXLAN or GENEVE, the segmentation"
+ " ID must be outside the ranges assigned to project networks."),
+]
+dns_feature_group = cfg.OptGroup(
+ name='designate_feature_enabled', title='Enabled Designate Features')
+CONF.register_group(dns_feature_group)
+CONF.register_opts(DnsFeatureGroup, group="designate_feature_enabled")
config_opts_translator = {
'project_network_cidr': 'tenant_network_cidr',
diff --git a/neutron_tempest_plugin/fwaas/scenario/test_fwaas_v2.py b/neutron_tempest_plugin/fwaas/scenario/test_fwaas_v2.py
index 4d5fdac..9896073 100644
--- a/neutron_tempest_plugin/fwaas/scenario/test_fwaas_v2.py
+++ b/neutron_tempest_plugin/fwaas/scenario/test_fwaas_v2.py
@@ -14,8 +14,6 @@
# under the License.
-import testscenarios
-
from oslo_log import log as logging
from tempest.common import utils
from tempest import config
@@ -28,7 +26,6 @@
CONF = config.CONF
LOG = logging.getLogger(__name__)
-load_tests = testscenarios.load_tests_apply_scenarios
class TestFWaaS_v2(base.FWaaSScenarioTest_V2):
diff --git a/neutron_tempest_plugin/scenario/base.py b/neutron_tempest_plugin/scenario/base.py
index 9d53f79..72139de 100644
--- a/neutron_tempest_plugin/scenario/base.py
+++ b/neutron_tempest_plugin/scenario/base.py
@@ -236,7 +236,7 @@
@classmethod
def _wait_for_router_ha_active(cls, router_id):
router = cls.os_admin.network_client.show_router(router_id)['router']
- if not router.get('ha'):
+ if not router.get('ha') or cls.is_driver_ovn:
return
def _router_active_on_l3_agent():
@@ -285,7 +285,8 @@
client.delete_interface(server_id, port_id=port_id)
def setup_network_and_server(self, router=None, server_name=None,
- network=None, **kwargs):
+ network=None, use_stateless_sg=False,
+ **kwargs):
"""Create network resources and a server.
Creating a network, subnet, router, keypair, security group
@@ -296,8 +297,13 @@
self.subnet = self.create_subnet(self.network)
LOG.debug("Created subnet %s", self.subnet['id'])
+ sg_args = {
+ 'name': data_utils.rand_name('secgroup')
+ }
+ if use_stateless_sg:
+ sg_args['stateful'] = False
secgroup = self.os_primary.network_client.create_security_group(
- name=data_utils.rand_name('secgroup'))
+ **sg_args)
LOG.debug("Created security group %s",
secgroup['security_group']['name'])
self.security_groups.append(secgroup['security_group'])
@@ -307,6 +313,9 @@
self.keypair = self.create_keypair()
self.create_loginable_secgroup_rule(
secgroup_id=secgroup['security_group']['id'])
+ if use_stateless_sg:
+ self.create_ingress_metadata_secgroup_rule(
+ secgroup_id=secgroup['security_group']['id'])
server_kwargs = {
'flavor_ref': CONF.compute.flavor_ref,
diff --git a/neutron_tempest_plugin/scenario/test_dns_integration.py b/neutron_tempest_plugin/scenario/test_dns_integration.py
index be9a477..d520aa2 100644
--- a/neutron_tempest_plugin/scenario/test_dns_integration.py
+++ b/neutron_tempest_plugin/scenario/test_dns_integration.py
@@ -212,11 +212,10 @@
@classmethod
def resource_setup(cls):
super(DNSIntegrationAdminTests, cls).resource_setup()
- # TODO(jh): We should add the segmentation_id as tempest option
- # so that it can be changed to match the deployment if needed
- cls.network2 = cls.create_network(dns_domain=cls.zone['name'],
- provider_network_type='vxlan',
- provider_segmentation_id=12345)
+ segmentation_id = CONF.designate_feature_enabled.segmentation_id
+ cls.network2 = cls.create_network(
+ dns_domain=cls.zone['name'], provider_network_type='vxlan',
+ provider_segmentation_id=segmentation_id)
cls.subnet2 = cls.create_subnet(cls.network2)
def _verify_dns_assignment(self, port):
diff --git a/neutron_tempest_plugin/scenario/test_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index 804683d..ee1b192 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -15,6 +15,7 @@
import time
+import ddt
from neutron_lib import constants as lib_constants
from neutron_lib.services.qos import constants as qos_consts
from neutron_lib.utils import test
@@ -24,8 +25,6 @@
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
-import testscenarios
-from testscenarios.scenarios import multiply_scenarios
import testtools
from neutron_tempest_plugin.api import base as base_api
@@ -41,9 +40,6 @@
LOG = log.getLogger(__name__)
-load_tests = testscenarios.load_tests_apply_scenarios
-
-
class FloatingIpTestCasesMixin(object):
credentials = ['primary', 'admin']
@@ -104,10 +100,10 @@
constants.SERVER_STATUS_ACTIVE)
return {'port': port, 'fip': fip, 'server': server}
- def _test_east_west(self):
+ def _test_east_west(self, src_has_fip, dest_has_fip):
# The proxy VM is used to control the source VM when it doesn't
# have a floating-ip.
- if self.src_has_fip:
+ if src_has_fip:
proxy = None
proxy_client = None
else:
@@ -117,7 +113,7 @@
pkey=self.keypair['private_key'])
# Source VM
- if self.src_has_fip:
+ if src_has_fip:
src_server = self._create_server()
src_server_ip = src_server['fip']['floating_ip_address']
else:
@@ -129,7 +125,7 @@
proxy_client=proxy_client)
# Destination VM
- if self.dest_has_fip:
+ if dest_has_fip:
dest_server = self._create_server(network=self._dest_network)
else:
dest_server = self._create_server(create_floating_ip=False,
@@ -139,46 +135,46 @@
self.check_remote_connectivity(ssh_client,
dest_server['port']['fixed_ips'][0]['ip_address'],
servers=[src_server, dest_server])
- if self.dest_has_fip:
+ if dest_has_fip:
self.check_remote_connectivity(ssh_client,
dest_server['fip']['floating_ip_address'],
servers=[src_server, dest_server])
+@ddt.ddt
class FloatingIpSameNetwork(FloatingIpTestCasesMixin,
base.BaseTempestTestCase):
- scenarios = multiply_scenarios([
- ('SRC with FIP', dict(src_has_fip=True)),
- ('SRC without FIP', dict(src_has_fip=False)),
- ], [
- ('DEST with FIP', dict(dest_has_fip=True)),
- ('DEST without FIP', dict(dest_has_fip=False)),
- ])
same_network = True
@test.unstable_test("bug 1717302")
@decorators.idempotent_id('05c4e3b3-7319-4052-90ad-e8916436c23b')
- def test_east_west(self):
- self._test_east_west()
+ @ddt.unpack
+ @ddt.data({'src_has_fip': True, 'dest_has_fip': True},
+ {'src_has_fip': True, 'dest_has_fip': False},
+ {'src_has_fip': False, 'dest_has_fip': True},
+ {'src_has_fip': True, 'dest_has_fip': False})
+ def test_east_west(self, src_has_fip, dest_has_fip):
+ self._test_east_west(src_has_fip=src_has_fip,
+ dest_has_fip=dest_has_fip)
+@ddt.ddt
class FloatingIpSeparateNetwork(FloatingIpTestCasesMixin,
base.BaseTempestTestCase):
- scenarios = multiply_scenarios([
- ('SRC with FIP', dict(src_has_fip=True)),
- ('SRC without FIP', dict(src_has_fip=False)),
- ], [
- ('DEST with FIP', dict(dest_has_fip=True)),
- ('DEST without FIP', dict(dest_has_fip=False)),
- ])
same_network = False
@test.unstable_test("bug 1717302")
@decorators.idempotent_id('f18f0090-3289-4783-b956-a0f8ac511e8b')
- def test_east_west(self):
- self._test_east_west()
+ @ddt.unpack
+ @ddt.data({'src_has_fip': True, 'dest_has_fip': True},
+ {'src_has_fip': True, 'dest_has_fip': False},
+ {'src_has_fip': False, 'dest_has_fip': True},
+ {'src_has_fip': True, 'dest_has_fip': False})
+ def test_east_west(self, src_has_fip, dest_has_fip):
+ self._test_east_west(src_has_fip=src_has_fip,
+ dest_has_fip=dest_has_fip)
class DefaultSnatToExternal(FloatingIpTestCasesMixin,
diff --git a/neutron_tempest_plugin/scenario/test_portsecurity.py b/neutron_tempest_plugin/scenario/test_portsecurity.py
index c90db08..db0a056 100644
--- a/neutron_tempest_plugin/scenario/test_portsecurity.py
+++ b/neutron_tempest_plugin/scenario/test_portsecurity.py
@@ -11,7 +11,9 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+from tempest.common import utils
from tempest.lib import decorators
from neutron_tempest_plugin import config
@@ -24,15 +26,14 @@
credentials = ['primary', 'admin']
required_extensions = ['port-security']
- @decorators.idempotent_id('61ab176e-d48b-42b7-b38a-1ba571ecc033')
- def test_port_security_removed_added(self):
+ def _test_port_security_removed_added(self, use_stateless_sg):
"""Test connection works after port security has been removed
Initial test that vm is accessible. Then port security is removed,
checked connectivity. Port security is added back and checked
connectivity again.
"""
- self.setup_network_and_server()
+ self.setup_network_and_server(use_stateless_sg=use_stateless_sg)
self.check_connectivity(self.fip['floating_ip_address'],
CONF.validation.image_ssh_user,
self.keypair['private_key'])
@@ -51,3 +52,18 @@
self.check_connectivity(self.fip['floating_ip_address'],
CONF.validation.image_ssh_user,
self.keypair['private_key'])
+
+ @decorators.idempotent_id('61ab176e-d48b-42b7-b38a-1ba571ecc033')
+ def test_port_security_removed_added_stateful_sg(self):
+ self._test_port_security_removed_added(use_stateless_sg=False)
+
+ @decorators.idempotent_id('2f4005e1-cee1-40e5-adbd-b3e3cf218065')
+ @testtools.skipUnless(
+ utils.is_extension_enabled('stateful-security-group', 'network'),
+ "'stateful-security-group' API extension not available")
+ @testtools.skipIf(
+ CONF.neutron_plugin_options.firewall_driver in ['openvswitch', 'None'],
+ "Firewall driver other than 'openvswitch' is required to use "
+ "stateless security groups.")
+ def test_port_security_removed_added_stateless_sg(self):
+ self._test_port_security_removed_added(use_stateless_sg=True)
diff --git a/requirements.txt b/requirements.txt
index 34531e9..9423079 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -16,6 +16,5 @@
tenacity>=3.2.1 # Apache-2.0
ddt>=1.0.1 # MIT
testtools>=2.2.0 # MIT
-testscenarios>=0.4 # Apache-2.0/BSD
eventlet!=0.18.3,!=0.20.1,>=0.18.2 # MIT
debtcollector>=1.2.0 # Apache-2.0