Actively check type instead of WB_CONF.openstack_type

Plugin was built extensively around podified/devstack setups, maybe more
types in the future.
It isn't likely to be changed any time soon, such change will require
adding code into plenty of conditions spread around plugin.

We can replace manually maintained configuration with automated check
to reduce CI maintenance upstream/downstream.

As documented for devstack [1] home directory can optionally be
`/opt/stack`, for this plugin's devstack jobs it is commonly used,
check should work to tell the difference.

[1] https://docs.openstack.org/devstack/latest/

Related-Bug: #OSPRH-16056
Related-Bug: #OSPRH-15819
Change-Id: I2d3f807b07e5eb810b87320e31cf64ad72f2f2a9
This commit is contained in:
Maor Blaustein
2025-04-23 17:30:48 +03:00
parent 4d12e79276
commit ea0e811aa9
14 changed files with 95 additions and 108 deletions

View File

@@ -293,24 +293,10 @@ def wait_for_neutron_api(neutron_client, timeout=100):
common_utils.wait_until_true(_list_agents, timeout=timeout, sleep=1)
def get_neutron_api_service_name():
"""Return the Neutron API service name based on the test configuration"""
if WB_CONF.openstack_type == 'devstack':
# NOTE: in OSP18+, the Neutron API will use WSGI by default (not the
# eventlet server) and the name will be "neutron api"
return 'q svc'
else:
return 'neutron api'
def get_ml2_conf_file():
"""Neutron ML2 config file name depending on the installation type
The default value of WB_CONF.ml2_plugin_config is
'/etc/neutron/plugins/ml2/ml2_conf.ini'.
"""
if WB_CONF.openstack_type in ('podified', 'devstack'):
return WB_CONF.ml2_plugin_config
else:
return ('/var/lib/config-data/puppet-generated/neutron' +
WB_CONF.ml2_plugin_config)
return WB_CONF.ml2_plugin_config

View File

@@ -38,10 +38,6 @@ WhiteboxNeutronPluginOptions = [
cfg.StrOpt('tester_key_file',
default='',
help='Key file to access host to execute validated commands.'),
cfg.StrOpt('openstack_type',
default='podified',
help='Type of openstack deployment, '
'e.g. devstack, podified'),
cfg.StrOpt('pki_private_key',
default='/etc/pki/tls/private/ovn_controller.key',
help='File with private key. Need for TLS-everywhere '

View File

@@ -56,6 +56,12 @@ ConfigOption = collections.namedtuple(
class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
credentials = ['primary', 'admin']
# NOTE(mblue): change devstack check if CI must not use /opt/stack,
# currently used commonly for devstack jobs needed by plugin.
if 'is_devstack' not in locals():
is_devstack = bool(shell.execute(
'test -d /opt/stack && echo stack',
check=False).stdout.strip())
@classmethod
def resource_setup(cls):
@@ -74,25 +80,36 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
sriov_agents = [
agent for agent in agents if 'sriov' in agent['binary']]
cls.has_sriov_support = True if sriov_agents else False
cls.neutron_conf = local_constants.NEUTRON_CONF[WB_CONF.openstack_type]
cls.neutron_conf = local_constants.NEUTRON_CONF[
'devstack' if cls.is_devstack else 'podified']
# deployer tool dependent variables
cls.setup_proxy_host()
if WB_CONF.openstack_type == 'podified':
if not cls.is_devstack:
cls.neutron_api_prefix = '{} rsh {} '.format(
cls.OC, cls.get_pods_of_service()[0])
cls.external_network = cls.os_admin.network_client.show_network(
CONF.network.public_network_id)['network']
@classmethod
def get_neutron_api_service_name(cls):
"""Return the Neutron API service name based on test configuration"""
if cls.is_devstack:
# NOTE: in OSP18+, the Neutron API will use WSGI by default (not
# the eventlet server) and the name will be "neutron api"
return 'q svc'
else:
return 'neutron api'
@classmethod
def setup_proxy_host(cls):
# proxy host commonly used for commands such as oc or openstack
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
cls.master_node_client = cls.get_node_client(
'localhost')
cls.master_cont_cmd_executor = \
cls.run_on_master_controller
cls.neutron_api_prefix = ''
elif WB_CONF.openstack_type == 'podified':
else:
cls.OC = "oc -n openstack "
cls.proxy_host_client = cls.get_node_client(
host=WB_CONF.proxy_host_address,
@@ -105,20 +122,16 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
cls.master_node_client = cls.proxy_host_client
cls.master_cont_cmd_executor = \
cls.proxy_host_client.exec_command
else:
LOG.warning(("Unrecognized deployer tool '%s', plugin supports "
"openstack_type as devstack/podified.",
WB_CONF.openstack_type))
@classmethod
def run_on_master_controller(cls, cmd):
LOG.debug("Command: %s", cmd)
if WB_CONF.openstack_type == 'podified':
output = cls.proxy_host_client.exec_command(cmd)
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
output, errors = local_utils.run_local_cmd(cmd)
LOG.debug("Stderr: %s", errors.decode())
output = output.decode()
else:
output = cls.proxy_host_client.exec_command(cmd)
LOG.debug("Output: %s", output)
return output.strip()
@@ -318,7 +331,7 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
compute_hosts = [
host['hypervisor_hostname'] for host
in cls.os_admin.hv_client.list_hypervisors()['hypervisors']]
if WB_CONF.openstack_type == 'podified':
if not cls.is_devstack:
cls.nodes_data = cls.get_podified_nodes_data()
with open(WB_CONF.proxy_host_key_file, 'r') as file:
id_cifw_key = file.read()
@@ -346,7 +359,7 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
host['short_name'] = host['name'].split('.')[0]
host['is_compute'] = (host['name'] in compute_hosts)
host['is_networker'] = (host['name'] in l3_agent_hosts)
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
# Here we are checking if there are controller-specific
# processes running on the node
output = host['client'].exec_command(
@@ -432,7 +445,7 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
"""
assert config_list, ("At least one configuration parameter must be "
"supplied")
if WB_CONF.openstack_type == 'podified' and node_type != 'compute':
if not cls.is_devstack and node_type != 'compute':
service_pod = cls.get_pods_of_service(service)[0]
# TODO(mblue): process ini in python instead of crudini command,
# without depending on hardcoded conf filenames, crudini bin in pod
@@ -537,11 +550,11 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
"""
if WB_CONF.openstack_type == 'podified':
if cls.is_devstack:
service_prefix = ""
else:
service_prefix = "{} rsh {}".format(
cls.OC, cls.get_pods_of_service(service)[0])
else:
service_prefix = ""
cmd_prefix = "crudini --get"
# If we have config file with defaults and second one with overrides,
# the latter has the config that wins
@@ -592,7 +605,7 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
def reset_node_service(cls, service_alias, ssh_client,
wait_until_active=True, timeout=30):
host_ip = ssh_client.host
service_name = (None if WB_CONF.openstack_type != 'podified'
service_name = (None if cls.is_devstack
else WB_CONF.dataplane_podified_services.get(
service_alias))
service_name = service_name or ssh_client.exec_command(
@@ -814,13 +827,11 @@ class BaseTempestWhiteboxTestCase(base.BaseTempestTestCase):
@classmethod
def get_osp_cmd_prefix(cls, admin=True):
# TODO(mblue): figure how admin used in podified setup when needed
if WB_CONF.openstack_type == 'podified':
prefix = '{} rsh openstackclient '.format(cls.OC)
elif WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
prefix = '. /opt/stack/devstack/openrc{} && '.format(
' admin' if admin else '')
else:
prefix = '. ~/overcloudrc && '
prefix = '{} rsh openstackclient '.format(cls.OC)
return prefix
@staticmethod
@@ -1094,7 +1105,7 @@ class TrafficFlowTest(BaseTempestWhiteboxTestCase):
"for public network or public_network_id "
"is not configured.")
cls.discover_nodes()
if WB_CONF.openstack_type == 'podified':
if not cls.is_devstack:
cls.set_ovs_pods_for_nodes()
@classmethod
@@ -1122,7 +1133,7 @@ class TrafficFlowTest(BaseTempestWhiteboxTestCase):
'- a compute\n'
'- a networker', node['name'])
continue
elif (WB_CONF.openstack_type == 'podified' and
elif (not self.is_devstack and
node.get('ovs_pod')):
capture_client = self.proxy_host_client
command_prefix = "{} rsh {} ".format(self.OC, node['ovs_pod'])
@@ -1280,19 +1291,7 @@ class BaseTempestTestCaseOvn(BaseTempestWhiteboxTestCase):
@classmethod
def _get_ovn_db_monitor_cmds(cls):
monitorcmdprefix = 'timeout 300 ovsdb-client monitor -f json '
if WB_CONF.openstack_type == 'podified':
nb_monitor_connection_opts = cls.nbctl.replace(
'ovn-nbctl', '{} unix:/tmp/ovnnb_db.sock'.format(
monitorcmdprefix))
sb_monitor_connection_opts = cls.sbctl.replace(
'ovn-sbctl', '{} unix:/tmp/ovnsb_db.sock'.format(
monitorcmdprefix))
# strip --db parameter from connection opts since we're
# going to run monitoring via a local socket
return tuple(map(
lambda cmd: re.sub(r'--db=[^\s]+', '', cmd),
[nb_monitor_connection_opts, sb_monitor_connection_opts]))
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
regex = r'--db=(.*)$'
monitorcmdprefix = 'sudo ' + monitorcmdprefix
# this regex search will return the connection string
@@ -1302,6 +1301,18 @@ class BaseTempestTestCaseOvn(BaseTempestWhiteboxTestCase):
sb_monitor_connection_opts = re.search(regex, cls.sbctl).group(1)
return (monitorcmdprefix + nb_monitor_connection_opts,
monitorcmdprefix + sb_monitor_connection_opts)
# if podified
nb_monitor_connection_opts = cls.nbctl.replace(
'ovn-nbctl', '{} unix:/tmp/ovnnb_db.sock'.format(
monitorcmdprefix))
sb_monitor_connection_opts = cls.sbctl.replace(
'ovn-sbctl', '{} unix:/tmp/ovnsb_db.sock'.format(
monitorcmdprefix))
# strip --db parameter from connection opts since we're
# going to run monitoring via a local socket
return tuple(map(
lambda cmd: re.sub(r'--db=[^\s]+', '', cmd),
[nb_monitor_connection_opts, sb_monitor_connection_opts]))
@classmethod
def get_podified_ovn_db_cmd(cls, db):
@@ -1341,14 +1352,13 @@ class BaseTempestTestCaseOvn(BaseTempestWhiteboxTestCase):
@classmethod
def _get_ovn_dbs(cls):
if WB_CONF.openstack_type == 'podified':
return [cls.get_podified_ovn_db_cmd('nb'),
cls.get_podified_ovn_db_cmd('sb')]
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
sbdb = "unix:/var/run/ovn/ovnsb_db.sock"
nbdb = sbdb.replace('sb', 'nb')
cmd = "sudo ovn-{}ctl --db={}"
return [cmd.format('nb', nbdb), cmd.format('sb', sbdb)]
return [cls.get_podified_ovn_db_cmd('nb'),
cls.get_podified_ovn_db_cmd('sb')]
def get_router_gateway_chassis(self, router_port_id):
cmd = "{} get port_binding cr-lrp-{} chassis".format(

View File

@@ -51,8 +51,8 @@ class NeutronAPIServerTest(wb_base.BaseTempestTestCaseOvn):
wait_res='deploy/neutron')
# 3) Restart Neutron API on all controllers simultaneously.
if not WB_CONF.openstack_type == 'podified':
service_ptn = wb_utils.get_neutron_api_service_name()
if self.is_devstack:
service_ptn = self.get_neutron_api_service_name()
for node in self.nodes:
if node['is_controller']:
# NOTE(mblue): if reset fails on multinode, consider

View File

@@ -53,7 +53,7 @@ class OvnDvrBase(base.TrafficFlowTest, base.BaseTempestTestCaseOvn):
"The tests require environment with at least 2 nodes")
cls.bgp_expose_tenant_networks = False
for node in cls.nodes:
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
if not node['is_controller']:
continue
cls.check_service_setting(
@@ -71,7 +71,7 @@ class OvnDvrBase(base.TrafficFlowTest, base.BaseTempestTestCaseOvn):
# TODO(rsafrono) add code that defines
# cls.bgp_expose_tenant_networks on devstack
# in case such bgp environment will be ever created
if WB_CONF.openstack_type == 'podified':
if not cls.is_devstack:
config_files = cls.get_configs_of_service()
cls.check_service_setting(
{'client': cls.proxy_host_client},

View File

@@ -300,7 +300,7 @@ class InternalDNSInterruptionsAdvancedTestOvn(
@classmethod
def skip_checks(cls):
super(InternalDNSInterruptionsAdvancedTestOvn, cls).skip_checks()
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
raise cls.skipException(
"Devstack doesn't support powering nodes on/off, "
"skipping tests")

View File

@@ -178,7 +178,7 @@ class L3haOvnCommon(base.TrafficFlowTest, base.BaseTempestTestCaseOvn):
def refresh_nodes_data(self):
self.discover_nodes()
if WB_CONF.openstack_type == 'podified':
if not self.is_devstack:
self.set_ovs_pods_for_nodes()

View File

@@ -46,7 +46,7 @@ class TestMetadataRateLimiting(wb_base.BaseTempestWhiteboxTestCase):
cls.service_name = 'neutron l3 agent'
cls.metadata_nodes = [n for n in cls.nodes if cls.is_service_on_node(
cls.service_name, n['client'])]
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
cls.metadata_conf_file = (
'/etc/neutron/neutron_ovn_metadata_agent.ini')
else:

View File

@@ -119,7 +119,7 @@ class GatewayMtuTest(base.TrafficFlowTest, base.BaseTempestTestCaseOvn):
def _validate_environment_config(self):
msg = "ovn_emit_need_to_frag is not set to 'true' in config file"
for node in self.nodes:
if WB_CONF.openstack_type == 'devstack':
if self.is_devstack:
if node['is_controller'] is False:
continue
else:
@@ -128,7 +128,7 @@ class GatewayMtuTest(base.TrafficFlowTest, base.BaseTempestTestCaseOvn):
config_files=[WB_CONF.ml2_plugin_config],
section='ovn', param='ovn_emit_need_to_frag',
msg=msg)
if WB_CONF.openstack_type == 'podified':
if not self.is_devstack:
config_files = self.get_configs_of_service()
self.check_service_setting(
{'client': self.proxy_host_client},

View File

@@ -61,8 +61,8 @@ class OvnFdbAgingTest(wb_base.BaseTempestTestCaseOvn):
wait_res='deploy/neutron')
# 2) restart neutron api on all controllers simultaneously
if not WB_CONF.openstack_type == 'podified':
service_ptn = wb_utils.get_neutron_api_service_name()
if self.is_devstack:
service_ptn = self.get_neutron_api_service_name()
for node in self.nodes:
if node['is_controller']:
# NOTE(mblue): if reset fails on multinode, consider

View File

@@ -95,7 +95,7 @@ class QosBaseTest(test_qos.QoSTestMixin, base.TrafficFlowTest):
"nodes.")
msg = "Required QoS config is not set"
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
for node in cls.nodes:
if node['is_controller'] is False:
continue
@@ -107,8 +107,7 @@ class QosBaseTest(test_qos.QoSTestMixin, base.TrafficFlowTest):
host=node, service='',
config_files=[WB_CONF.ml2_plugin_config], section='ml2',
param='extension_drivers', value='qos')
if WB_CONF.openstack_type == 'podified':
else:
config_files = cls.get_configs_of_service('neutron')
cls.check_service_setting(
{'client': cls.proxy_host_client}, service='neutron',
@@ -1004,15 +1003,15 @@ class QosTestDscpInheritanceOvn(QosBaseTest, base.BaseTempestTestCaseOvn):
def test_dscp_inheritance_geneve(self):
cmd = "sudo ovs-vsctl get open . external_ids:ovn-encap-tos || true"
msg = "external_ids:ovn-encap-tos is not set to 'inherit'"
if WB_CONF.openstack_type == 'podified':
if self.is_devstack:
result = self.run_on_master_controller(cmd)
if 'inherit' not in result:
raise self.skipException(msg)
else:
for node in self.nodes:
result = node['client'].exec_command(cmd)
if 'inherit' not in result:
raise self.skipException(msg)
if WB_CONF.openstack_type == 'devstack':
result = self.run_on_master_controller(cmd)
if 'inherit' not in result:
raise self.skipException(msg)
self._check_dscp_inheritance()

View File

@@ -49,19 +49,6 @@ class BaseSecGroupLoggingTest(
required_extensions = ['router', 'security-group', 'logging']
ML2_CONF_FILE = utils.get_ml2_conf_file()
if WB_CONF.openstack_type == 'podified':
SG_LOG_FILE = '/var/log/messages'
rotate_service_fix = '-crond'
elif WB_CONF.openstack_type == 'devstack':
SG_LOG_FILE = '/var/log/ovn/ovn-controller.log'
rotate_service_fix = ''
else:
SG_LOG_FILE = '/var/log/containers/stdouts/ovn_controller.log'
rotate_service_fix = '-crond'
ROTATION_CHECK_CMD = (
'/usr/sbin/logrotate -s /var/lib/logrotate/'
'logrotate{0}.status /etc/logrotate{0}.conf').format(
rotate_service_fix)
SSH_DROP_EXCEPTIONS = (lib_exc.SSHTimeout,
ssh_exc.NoValidConnectionsError,
ssh_exc.SSHException,
@@ -113,6 +100,16 @@ class BaseSecGroupLoggingTest(
"""Setup resources for both classes of security group logging tests:
with either stateless/stateful security groups.
"""
if cls.is_devstack:
cls.sg_log_file = '/var/log/ovn/ovn-controller.log'
cls.rotate_service_fix = ''
else:
cls.sg_log_file = '/var/log/messages'
cls.rotate_service_fix = '-crond'
cls.rotation_check_cmd = (
'/usr/sbin/logrotate -s /var/lib/logrotate/'
'logrotate{0}.status /etc/logrotate{0}.conf').format(
cls.rotate_service_fix)
cls.network = cls.create_network()
cls.subnet = cls.create_subnet(cls.network)
router = cls.create_router_by_client()
@@ -223,14 +220,14 @@ class BaseSecGroupLoggingTest(
# tracks A value, before test traffic sent to be logged
_track_value = int(hypervisor_ssh.exec_command(
"sudo grep {} {} | tail -n1 | cut -d '|' -f 2"
.format(self.ENTRY_PTN, self.SG_LOG_FILE), timeout=120))
.format(self.ENTRY_PTN, self.sg_log_file), timeout=120))
self._hypervisors_counts[hypervisor_ssh.host]['A'] = _track_value
LOG.debug("Start log count value A on '%s' is %d",
hypervisor_ssh.host, _track_value)
else:
# tracks B value, after test traffic sent to be logged
cmd_outputs = hypervisor_ssh.exec_command(
"sudo grep {} {}".format(self.ENTRY_PTN, self.SG_LOG_FILE),
"sudo grep {} {}".format(self.ENTRY_PTN, self.sg_log_file),
timeout=120).splitlines()
b = self._hypervisors_counts[hypervisor_ssh.host]['B'] = int(
cmd_outputs[-1].split("|")[1])
@@ -447,7 +444,7 @@ class BaseSecGroupLoggingTest(
# 7) output not expected
'']
# NOTE(mblue): devstack: Extensions list not supported by Identity API
if WB_CONF.openstack_type == 'devstack':
if self.is_devstack:
cmds.pop(0)
stdout_patterns.pop(0)
for cmd, ptn in zip(cmds, stdout_patterns):
@@ -486,8 +483,8 @@ class BaseSecGroupLoggingTest(
config_list=config_list,
wait_res='deploy/neutron')
# 5) restart neutron api on all controllers simultaneously
if not WB_CONF.openstack_type == 'podified':
service_ptn = utils.get_neutron_api_service_name()
if self.is_devstack:
service_ptn = self.get_neutron_api_service_name()
for node in self.nodes:
if node['is_controller']:
# NOTE(mblue): if reset fails on multinode, consider
@@ -619,7 +616,7 @@ class BaseSecGroupLoggingTest(
self.verify_meter_and_band_amounts((1, 2), (1, 2))
# 12) verify same logging SGRs/ACLs amount linked to relevant meter
# NOTE(mblue): devstack ACLs for stateless SG with another meter name
if WB_CONF.openstack_type == 'devstack' and \
if self.is_devstack and \
not self.is_secgrp_stateful:
meter_postfix = '.log_stateless"'
else:
@@ -765,7 +762,7 @@ class BaseSecGroupLoggingTest(
(17, 19, 24).
"""
vm_a = self._create_server()
if WB_CONF.openstack_type == 'devstack':
if self.is_devstack:
rotate_prefix = 'sudo '
else:
rotate_prefix = 'sudo podman exec logrotate_crond '
@@ -806,7 +803,7 @@ class BaseSecGroupLoggingTest(
ssh_client=vm_a['hv_ssh_client']).rstrip().split(' ')[-1]
# if setup type supports log rotation due to size, then test.
# also skips rotation test on podified since logging to journal
if maxsize_si and WB_CONF.openstack_type != 'podified':
if maxsize_si and self.is_devstack:
# convert to bytes without SI prefixes k/M/G (logrotate SI options)
try:
power = 10 * ('kMG'.index(maxsize_si[-1]) + 1)
@@ -818,28 +815,28 @@ class BaseSecGroupLoggingTest(
overflow_size = maxsize + 1
# 13) force check if log rotation needed (before test start)
self.validate_command(
rotate_prefix + self.ROTATION_CHECK_CMD,
rotate_prefix + self.rotation_check_cmd,
ssh_client=vm_a['hv_ssh_client'])
# current active log file size in bytes (before size overflow)
active_log_pre_overflow = int(self.validate_command(
'sudo wc -c {}'.format(self.SG_LOG_FILE),
'sudo wc -c {}'.format(self.sg_log_file),
ssh_client=vm_a['hv_ssh_client']).split()[0])
# 14) adding bytes into active log file to pass 'maxsize' value
self.validate_command(('''python3 -c "print('A'*{})" | '''
'sudo tee -a {} 1> /dev/null').format(
overflow_size, self.SG_LOG_FILE),
overflow_size, self.sg_log_file),
ssh_client=vm_a['hv_ssh_client'])
# 15) force check if log rotation is needed
self.validate_command(
rotate_prefix + self.ROTATION_CHECK_CMD,
rotate_prefix + self.rotation_check_cmd,
ssh_client=vm_a['hv_ssh_client'])
# current active log file size in bytes (after size overflow)
active_log_post_overflow = int(self.validate_command(
'sudo wc -c {}'.format(self.SG_LOG_FILE),
'sudo wc -c {}'.format(self.sg_log_file),
ssh_client=vm_a['hv_ssh_client']).split()[0])
# new rotated log file size in bytes (after size overflow)
rotated_log_post_overflow = int(self.validate_command(
'sudo wc -c {}'.format(self.SG_LOG_FILE + '.1'),
'sudo wc -c {}'.format(self.sg_log_file + '.1'),
ssh_client=vm_a['hv_ssh_client']).split()[0])
# 16) verify log rotation succesful:
# - current new active log has a small size (below 'offset').

View File

@@ -68,7 +68,7 @@ class ProviderNetworkSriovBaseTest(base.ProviderBaseTest):
CONF.neutron_plugin_options.default_image_is_advanced):
raise cls.skipException(
'Advanced image is required to run these tests.')
if WB_CONF.openstack_type == 'devstack':
if cls.is_devstack:
raise cls.skipException("The tests are currently not supported "
"on devstack environment")

View File

@@ -214,7 +214,6 @@
available_type_drivers: flat,geneve,vlan,gre,local,vxlan
provider_net_base_segm_id: 1
whitebox_neutron_plugin_options:
openstack_type: devstack
broadcast_receivers_count: 1
compute-feature-enabled:
console_output: false