Merge "update the home-page url"
diff --git a/releasenotes/notes/add-port-profile-config-option-2610b2fa67027960.yaml b/releasenotes/notes/add-port-profile-config-option-2610b2fa67027960.yaml
new file mode 100644
index 0000000..b54ee8b
--- /dev/null
+++ b/releasenotes/notes/add-port-profile-config-option-2610b2fa67027960.yaml
@@ -0,0 +1,11 @@
+---
+prelude: >
+ When using OVS HW offload feature we need to create
+ Neutron port with a certain capability. This is done
+ by creating Neutron port with binding profile. To be
+ able to test this we need profile capability support
+ in Tempest as well.
+features:
+ - A new config option 'port_profile' is added to the section
+ 'network' to specify capabilities of the port.
+ By default this is set to {}.
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
index 18c974a..d32a5b4 100644
--- a/tempest/api/compute/admin/test_servers_on_multinodes.py
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -43,6 +43,28 @@
return cls.os_admin.servers_client.show_server(
server_id)['server']['OS-EXT-SRV-ATTR:host']
+ def _create_servers_with_group(self, policy):
+ group_id = self.create_test_server_group(policy=[policy])['id']
+ hints = {'group': group_id}
+ reservation_id = self.create_test_server(
+ scheduler_hints=hints, wait_until='ACTIVE', min_count=2,
+ return_reservation_id=True)['reservation_id']
+
+ # Get the servers using the reservation_id.
+ servers = self.servers_client.list_servers(
+ detail=True, reservation_id=reservation_id)['servers']
+ self.assertEqual(2, len(servers))
+
+ # Assert the servers are in the group.
+ server_group = self.server_groups_client.show_server_group(
+ group_id)['server_group']
+ hosts = {}
+ for server in servers:
+ self.assertIn(server['id'], server_group['members'])
+ hosts[server['id']] = self._get_host(server['id'])
+
+ return hosts
+
@decorators.idempotent_id('26a9d5df-6890-45f2-abc4-a659290cb130')
@testtools.skipUnless(
compute.is_scheduler_filter_enabled("SameHostFilter"),
@@ -87,28 +109,8 @@
Creates two servers in an anti-affinity server group and
asserts the servers are in the group and on different hosts.
"""
- group_id = self.create_test_server_group(
- policy=['anti-affinity'])['id']
- hints = {'group': group_id}
- reservation_id = self.create_test_server(
- scheduler_hints=hints, wait_until='ACTIVE', min_count=2,
- return_reservation_id=True)['reservation_id']
-
- # Get the servers using the reservation_id.
- servers = self.servers_client.list_servers(
- detail=True, reservation_id=reservation_id)['servers']
- self.assertEqual(2, len(servers))
-
- # Assert the servers are in the group.
- server_group = self.server_groups_client.show_server_group(
- group_id)['server_group']
- hosts = {}
- for server in servers:
- self.assertIn(server['id'], server_group['members'])
- hosts[server['id']] = self._get_host(server['id'])
-
- # Assert the servers are on different hosts.
- hostnames = list(hosts.values())
+ hosts = self._create_servers_with_group('anti-affinity')
+ hostnames = hosts.values()
self.assertNotEqual(hostnames[0], hostnames[1],
'Servers are on the same host: %s' % hosts)
@@ -122,26 +124,7 @@
Creates two servers in an affinity server group and
asserts the servers are in the group and on same host.
"""
- group_id = self.create_test_server_group(policy=['affinity'])['id']
- hints = {'group': group_id}
- reservation_id = self.create_test_server(
- scheduler_hints=hints, wait_until='ACTIVE', min_count=2,
- return_reservation_id=True)['reservation_id']
-
- # Get the servers using the reservation_id.
- servers = self.servers_client.list_servers(
- detail=True, reservation_id=reservation_id)['servers']
- self.assertEqual(2, len(servers))
-
- # Assert the servers are in the group.
- server_group = self.server_groups_client.show_server_group(
- group_id)['server_group']
- hosts = {}
- for server in servers:
- self.assertIn(server['id'], server_group['members'])
- hosts[server['id']] = self._get_host(server['id'])
-
- # Assert the servers are on same host.
+ hosts = self._create_servers_with_group('affinity')
hostnames = hosts.values()
self.assertEqual(hostnames[0], hostnames[1],
'Servers are on the different hosts: %s' % hosts)
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 0e8f681..7509ac6 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -185,7 +185,7 @@
@decorators.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
@utils.services('network')
- def test_create_list_show_delete_interfaces(self):
+ def test_create_list_show_delete_interfaces_by_network_port(self):
server, ifs = self._create_server_get_interfaces()
interface_count = len(ifs)
self.assertGreater(interface_count, 0)
@@ -206,6 +206,42 @@
iface = self._test_create_interface_by_port_id(server, ifs)
ifs.append(iface)
+ _ifs = (self.interfaces_client.list_interfaces(server['id'])
+ ['interfaceAttachments'])
+ self._compare_iface_list(ifs, _ifs)
+
+ self._test_show_interface(server, ifs)
+
+ _ifs = self._test_delete_interface(server, ifs)
+ self.assertEqual(len(ifs) - 1, len(_ifs))
+
+ @decorators.idempotent_id('d290c06c-f5b3-11e7-8ec8-002293781009')
+ @utils.services('network')
+ def test_create_list_show_delete_interfaces_by_fixed_ip(self):
+ # NOTE(zhufl) By default only project that is admin or network owner
+ # or project with role advsvc is authorised to create interfaces with
+ # fixed-ip, so if we don't create network for each project, do not
+ # test _test_create_interface_by_fixed_ips.
+ if not (CONF.auth.use_dynamic_credentials and
+ CONF.auth.create_isolated_networks and
+ not CONF.network.shared_physical_network):
+ raise self.skipException("Only owner network supports "
+ "creating interface by fixed ip.")
+
+ server, ifs = self._create_server_get_interfaces()
+ interface_count = len(ifs)
+ self.assertGreater(interface_count, 0)
+
+ try:
+ iface = self._test_create_interface(server)
+ except lib_exc.BadRequest as e:
+ msg = ('Multiple possible networks found, use a Network ID to be '
+ 'more specific.')
+ if not CONF.compute.fixed_network_name and six.text_type(e) == msg:
+ raise
+ else:
+ ifs.append(iface)
+
iface = self._test_create_interface_by_fixed_ips(server, ifs)
ifs.append(iface)
diff --git a/tempest/cmd/run.py b/tempest/cmd/run.py
index b8ae2ff..72ee715 100644
--- a/tempest/cmd/run.py
+++ b/tempest/cmd/run.py
@@ -153,7 +153,7 @@
if not os.path.isfile('.stestr.conf'):
self._create_stestr_conf()
# local execution with config file mode
- elif parsed_args.config_file:
+ elif parsed_args.config_file and not os.path.isfile('.stestr.conf'):
self._create_stestr_conf()
elif not os.path.isfile('.stestr.conf'):
print("No .stestr.conf file was found for local execution")
@@ -164,6 +164,7 @@
pass
regex = self._build_regex(parsed_args)
+ return_code = 0
if parsed_args.list_tests:
return_code = commands.list_command(
filters=regex, whitelist_file=parsed_args.whitelist_file,
diff --git a/tempest/config.py b/tempest/config.py
index 340a27e..8a6370a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -609,10 +609,14 @@
" for subnet creation"),
cfg.StrOpt('port_vnic_type',
choices=[None, 'normal', 'direct', 'macvtap'],
- help="vnic_type to use when Launching instances"
+ help="vnic_type to use when launching instances"
" with pre-configured ports."
" Supported ports are:"
" ['normal','direct','macvtap']"),
+ cfg.DictOpt('port_profile',
+ default={},
+ help="port profile to use when launching instances"
+ " with pre-configured ports."),
cfg.ListOpt('default_network',
default=["1.0.0.0/16", "2.0.0.0/16"],
help="List of ip pools"
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 06aa531..ef277fb 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -139,13 +139,15 @@
name = data_utils.rand_name(self.__class__.__name__ + "-server")
vnic_type = CONF.network.port_vnic_type
+ profile = CONF.network.port_profile
# If vnic_type is configured create port for
# every network
if vnic_type:
ports = []
- create_port_body = {'binding:vnic_type': vnic_type}
+ create_port_body = {'binding:vnic_type': vnic_type,
+ 'binding:profile': profile}
if kwargs:
# Convert security group names to security group ids
# to pass to create_port
diff --git a/tempest/tests/cmd/test_run.py b/tempest/tests/cmd/test_run.py
index bc10eb7..6cc356e 100644
--- a/tempest/tests/cmd/test_run.py
+++ b/tempest/tests/cmd/test_run.py
@@ -140,6 +140,11 @@
self.assertRunExit(['tempest', 'run', '--whitelist-file=%s' % path,
'--regex', 'fail'], 1)
+ def test_tempest_run_passes_with_config_file(self):
+ self.assertRunExit(['tempest', 'run',
+ '--config-file', self.stestr_conf_file,
+ '--regex', 'passing'], 0)
+
class TestTakeAction(base.TestCase):
def test_workspace_not_registered(self):
@@ -168,3 +173,27 @@
self.assertRaises(Exception_, tempest_run.take_action, parsed_args)
exit_msg = m_exit.call_args[0][0]
self.assertIn(workspace, exit_msg)
+
+ def test_config_file_specified(self):
+ # Setup test dirs
+ self.directory = tempfile.mkdtemp(prefix='tempest-unit')
+ self.addCleanup(shutil.rmtree, self.directory)
+ self.test_dir = os.path.join(self.directory, 'tests')
+ os.mkdir(self.test_dir)
+ # Change directory, run wrapper and check result
+ self.addCleanup(os.chdir, os.path.abspath(os.curdir))
+ os.chdir(self.directory)
+
+ tempest_run = run.TempestRun(app=mock.Mock(), app_args=mock.Mock())
+ parsed_args = mock.Mock()
+ parsed_args.config_file = []
+
+ parsed_args.workspace = None
+ parsed_args.state = None
+ parsed_args.list_tests = False
+ parsed_args.config_file = '.stestr.conf'
+
+ with mock.patch('stestr.commands.run_command') as m:
+ m.return_value = 0
+ self.assertEqual(0, tempest_run.take_action(parsed_args))
+ m.assert_called()