Merge "Extend T110 check for lib's service clients"
diff --git a/HACKING.rst b/HACKING.rst
index 44519d4..b82f8c9 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -214,9 +214,9 @@
things to watch out for to try to avoid issues when running your tests in
parallel.
-- Resources outside of a tenant scope still have the potential to conflict. This
+- Resources outside of a project scope still have the potential to conflict. This
is a larger concern for the admin tests since most resources and actions that
- require admin privileges are outside of tenants.
+ require admin privileges are outside of projects.
- Races between methods in the same class are not a problem because
parallelization in tempest is at the test class level, but if there is a json
diff --git a/data/tempest-plugins-registry.header b/data/tempest-plugins-registry.header
new file mode 100644
index 0000000..9821e8e
--- /dev/null
+++ b/data/tempest-plugins-registry.header
@@ -0,0 +1,23 @@
+..
+ Note to patch submitters: this file is covered by a periodic proposal
+ job. You should edit the files data/tempest-plugins-registry.footer
+ and data/tempest-plugins-registry.header instead of this one.
+
+==========================
+ Tempest Plugin Registry
+==========================
+
+Since we've created the external plugin mechanism, it's gotten used by
+a lot of projects. The following is a list of plugins that currently
+exist.
+
+Detected Plugins
+================
+
+The following are plugins that a script has found in the openstack/
+namespace, which includes but is not limited to official OpenStack
+projects.
+
++----------------------------+-------------------------------------------------------------------------+
+|Plugin Name |URL |
++----------------------------+-------------------------------------------------------------------------+
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 367be41..245386b 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -17,7 +17,7 @@
in the tempest.conf file. These options are clearly labelled in the ``identity``
section and let you specify a set of credentials for a regular user, a global
admin user, and an alternate user, consisting of a username, password, and
-project/tenant name.
+project name.
The other method to provide credentials is using the accounts.yaml file. This
file is used to specify an arbitrary number of users available to run tests
@@ -59,13 +59,13 @@
Dynamic Credentials (formerly known as Tenant isolation) was originally created
to enable running Tempest in parallel. For each test class it creates a unique
set of user credentials to use for the tests in the class. It can create up to
-three sets of username, password, and tenant/project names for a primary user,
-an admin user, and an alternate user. To enable and use dynamic credentials you
+three sets of username, password, and project names for a primary user,
+an admin user, and an alternate user. To enable and use dynamic credentials you
only need to configure two things:
#. A set of admin credentials with permissions to create users and
- tenants/projects. This is specified in the ``auth`` section with the
- ``admin_username``, ``admin_tenant_name``, ``admin_domain_name`` and
+ projects. This is specified in the ``auth`` section with the
+ ``admin_username``, ``admin_project_name``, ``admin_domain_name`` and
``admin_password`` options
#. To enable dynamic credentials in the ``auth`` section with the
``use_dynamic_credentials`` option.
@@ -112,7 +112,7 @@
#. Set ``use_dynamic_credentials = False`` in the ``auth`` group
It is worth pointing out that each set of credentials in the accounts.yaml
-should have a unique tenant. This is required to provide proper isolation
+should have a unique project. This is required to provide proper isolation
to the tests using the credentials, and failure to do this will likely cause
unexpected failures in some tests.
@@ -123,7 +123,7 @@
removed in a future release.**
When Tempest was refactored to allow for locking test accounts, the original
-non-tenant isolated case was converted to internally work similarly to the
+non-project isolated case was converted to internally work similarly to the
accounts.yaml file. This mechanism was then called the legacy test accounts
provider. To use the legacy test accounts provider you can specify the sets of
credentials in the configuration file as detailed above with following nine
@@ -131,13 +131,13 @@
#. ``username``
#. ``password``
- #. ``tenant_name``
+ #. ``project_name``
#. ``admin_username``
#. ``admin_password``
- #. ``admin_tenant_name``
+ #. ``admin_project_name``
#. ``alt_username``
#. ``alt_password``
- #. ``alt_tenant_name``
+ #. ``alt_project_name``
If using Identity API v3, use the ``domain_name`` option to specify a
domain other than the default domain. The ``auth_version`` setting is
@@ -265,7 +265,7 @@
""""""""""""""""""
This is the simplest method of specifying how networks should be used. You can
just specify a single network name/label to use for all server creations. The
-limitation with this is that all tenants/projects and users must be able to see
+limitation with this is that all projects and users must be able to see
that network name/label if they are to perform a network list and be able to use
it.
@@ -287,10 +287,10 @@
"""""""""""""
If you are using an accounts file to provide credentials for running Tempest
then you can leverage it to also specify which network should be used with
-server creations on a per tenant/project and user pair basis. This provides
+server creations on a per project and user pair basis. This provides
the necessary flexibility to work with more intricate networking configurations
by enabling the user to specify exactly which network to use for which
-tenants/projects. You can refer to the accounts.yaml.sample file included in
+projects. You can refer to the accounts.yaml.sample file included in
the Tempest repo for the syntax around specifying networks in the file.
However, specifying a network is not required when using an accounts file. If
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 5f357b2..10364db 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -11,6 +11,7 @@
HACKING
REVIEWING
plugin
+ plugin-registry
library
microversion_testing
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
new file mode 100644
index 0000000..517e5b8
--- /dev/null
+++ b/doc/source/plugin-registry.rst
@@ -0,0 +1,23 @@
+..
+ Note to patch submitters: this file is covered by a periodic proposal
+ job. You should edit the files data/tempest-plugins-registry.footer
+ data/tempest-plugins-registry.header instead of this one.
+
+==========================
+ Tempest Plugin Registry
+==========================
+
+Since we've created the external plugin mechanism, it's gotten used by
+a lot of projects. The following is a list of plugins that currently
+exist.
+
+Detected Plugins
+================
+
+The following will list plugins that a script has found in the openstack/
+namespace, which includes but is not limited to official OpenStack
+projects.
+
++----------------------------+-------------------------------------------------------------------------+
+|Plugin Name |URL |
++----------------------------+-------------------------------------------------------------------------+
diff --git a/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml b/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml
new file mode 100644
index 0000000..09ff15d
--- /dev/null
+++ b/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml
@@ -0,0 +1,12 @@
+---
+prelude: >
+ This release is marking the start of Mitaka release support in tempest
+other:
+ - OpenStack Releases Supported at this time are **Kilo**, **Liberty**,
+ **Mitaka**
+
+ The release under current development as of this tag is Newton,
+ meaning that every Tempest commit is also tested against master during
+ the Newton cycle. However, this does not necessarily mean that using
+ Tempest as of this tag will work against a Newton (or future releases)
+ cloud.
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 5bd9176..b617b22 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -5,6 +5,7 @@
.. toctree::
:maxdepth: 1
+ v11.0.0
v10.0.0
unreleased
diff --git a/releasenotes/source/v11.0.0.rst b/releasenotes/source/v11.0.0.rst
new file mode 100644
index 0000000..84b145d
--- /dev/null
+++ b/releasenotes/source/v11.0.0.rst
@@ -0,0 +1,6 @@
+=====================
+v11.0.0 Release Notes
+=====================
+
+.. release-notes:: 11.0.0 Release Notes
+ :version: 11.0.0
diff --git a/requirements.txt b/requirements.txt
index 9dd57a9..7c426e6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,14 +12,14 @@
testrepository>=0.0.18 # Apache-2.0/BSD
pyOpenSSL>=0.14 # Apache-2.0
oslo.concurrency>=3.5.0 # Apache-2.0
-oslo.config>=3.7.0 # Apache-2.0
+oslo.config>=3.9.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0
oslo.log>=1.14.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.utils>=3.5.0 # Apache-2.0
six>=1.9.0 # MIT
iso8601>=0.1.9 # MIT
-fixtures>=1.3.1 # Apache-2.0/BSD
+fixtures<2.0,>=1.3.1 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
PyYAML>=3.1.0 # MIT
stevedore>=1.5.0 # Apache-2.0
diff --git a/tempest/api/baremetal/admin/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
index 8cc4d05..2c44665 100644
--- a/tempest/api/baremetal/admin/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -138,14 +138,14 @@
body = self.client.get_node_boot_device(self.node['uuid'])
self.assertIn('boot_device', body)
self.assertIn('persistent', body)
- self.assertTrue(isinstance(body['boot_device'], six.string_types))
- self.assertTrue(isinstance(body['persistent'], bool))
+ self.assertIsInstance(body['boot_device'], six.string_types)
+ self.assertIsInstance(body['persistent'], bool)
@test.idempotent_id('3622bc6f-3589-4bc2-89f3-50419c66b133')
def test_get_node_supported_boot_devices(self):
body = self.client.get_node_supported_boot_devices(self.node['uuid'])
self.assertIn('supported_boot_devices', body)
- self.assertTrue(isinstance(body['supported_boot_devices'], list))
+ self.assertIsInstance(body['supported_boot_devices'], list)
@test.idempotent_id('f63b6288-1137-4426-8cfe-0d5b7eb87c06')
def test_get_console(self):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index f719bfc..87f3c86 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -38,7 +38,6 @@
def setup_clients(cls):
super(ServersTestJSON, cls).setup_clients()
cls.client = cls.servers_client
- cls.network_client = cls.os.network_client
cls.networks_client = cls.os.networks_client
cls.subnets_client = cls.os.subnets_client
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 0df6ead..8f0e430 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -29,8 +29,6 @@
class ServersNegativeTestJSON(base.BaseV2ComputeTest):
- credentials = ['primary', 'alt']
-
def setUp(self):
super(ServersNegativeTestJSON, self).setUp()
try:
@@ -47,7 +45,6 @@
def setup_clients(cls):
super(ServersNegativeTestJSON, cls).setup_clients()
cls.client = cls.servers_client
- cls.alt_client = cls.os_alt.servers_client
@classmethod
def resource_setup(cls):
@@ -271,16 +268,6 @@
self.server_id, name=new_name)
@test.attr(type=['negative'])
- @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
- def test_update_server_of_another_tenant(self):
- # Update name of a server that belongs to another tenant
-
- new_name = self.server_id + '_new'
- self.assertRaises(lib_exc.NotFound,
- self.alt_client.update_server, self.server_id,
- name=new_name)
-
- @test.attr(type=['negative'])
@test.idempotent_id('5c8e244c-dada-4590-9944-749c455b431f')
def test_update_server_name_length_exceeds_256(self):
# Update name of server exceed the name length limit
@@ -301,14 +288,6 @@
nonexistent_server)
@test.attr(type=['negative'])
- @test.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
- def test_delete_a_server_of_another_tenant(self):
- # Delete a server that belongs to another tenant
- self.assertRaises(lib_exc.NotFound,
- self.alt_client.delete_server,
- self.server_id)
-
- @test.attr(type=['negative'])
@test.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
def test_delete_server_pass_negative_id(self):
# Pass an invalid string parameter to delete server
@@ -519,3 +498,45 @@
self.assertRaises(lib_exc.Conflict,
self.client.unshelve_server,
self.server_id)
+
+
+class ServersNegativeTestMultiTenantJSON(base.BaseV2ComputeTest):
+
+ credentials = ['primary', 'alt']
+
+ def setUp(self):
+ super(ServersNegativeTestMultiTenantJSON, self).setUp()
+ try:
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'ACTIVE')
+ except Exception:
+ self.__class__.server_id = self.rebuild_server(self.server_id)
+
+ @classmethod
+ def setup_clients(cls):
+ super(ServersNegativeTestMultiTenantJSON, cls).setup_clients()
+ cls.alt_client = cls.os_alt.servers_client
+
+ @classmethod
+ def resource_setup(cls):
+ super(ServersNegativeTestMultiTenantJSON, cls).resource_setup()
+ server = cls.create_test_server(wait_until='ACTIVE')
+ cls.server_id = server['id']
+
+ @test.attr(type=['negative'])
+ @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
+ def test_update_server_of_another_tenant(self):
+ # Update name of a server that belongs to another tenant
+
+ new_name = self.server_id + '_new'
+ self.assertRaises(lib_exc.NotFound,
+ self.alt_client.update_server, self.server_id,
+ name=new_name)
+
+ @test.attr(type=['negative'])
+ @test.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
+ def test_delete_a_server_of_another_tenant(self):
+ # Delete a server that belongs to another tenant
+ self.assertRaises(lib_exc.NotFound,
+ self.alt_client.delete_server,
+ self.server_id)
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
index f75b867..bdb4383 100644
--- a/tempest/api/database/flavors/test_flavors.py
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.database import base
+from tempest.lib import decorators
from tempest import test
@@ -58,6 +59,7 @@
@test.attr(type='smoke')
@test.idempotent_id('afb2667f-4ec2-4925-bcb7-313fdcffb80d')
@test.services('compute')
+ @decorators.skip_because(bug='1567134')
def test_compare_db_flavors_with_os(self):
db_flavors = self.client.list_db_flavors()['flavors']
os_flavors = (self.os_flavors_client.list_flavors(detail=True)
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 010e4a0..a3ada21 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -20,12 +20,18 @@
class GroupsV3TestJSON(base.BaseIdentityV3AdminTest):
+ @classmethod
+ def resource_setup(cls):
+ super(GroupsV3TestJSON, cls).resource_setup()
+ cls.data.setup_test_domain()
+
@test.idempotent_id('2e80343b-6c81-4ac3-88c7-452f3e9d5129')
def test_group_create_update_get(self):
name = data_utils.rand_name('Group')
description = data_utils.rand_name('Description')
group = self.groups_client.create_group(
- name=name, description=description)['group']
+ name=name, domain_id=self.data.domain['id'],
+ description=description)['group']
self.addCleanup(self.groups_client.delete_group, group['id'])
self.assertEqual(group['name'], name)
self.assertEqual(group['description'], description)
@@ -47,7 +53,8 @@
name = data_utils.rand_name('Group')
old_description = data_utils.rand_name('Description')
group = self.groups_client.create_group(
- name=name, description=old_description)['group']
+ name=name, domain_id=self.data.domain['id'],
+ description=old_description)['group']
self.addCleanup(self.groups_client.delete_group, group['id'])
new_name = data_utils.rand_name('UpdateGroup')
@@ -61,7 +68,8 @@
@test.idempotent_id('1598521a-2f36-4606-8df9-30772bd51339')
def test_group_users_add_list_delete(self):
name = data_utils.rand_name('Group')
- group = self.groups_client.create_group(name=name)['group']
+ group = self.groups_client.create_group(
+ name=name, domain_id=self.data.domain['id'])['group']
self.addCleanup(self.groups_client.delete_group, group['id'])
# add user into group
users = []
@@ -94,7 +102,8 @@
groups = []
for i in range(2):
name = data_utils.rand_name('Group')
- group = self.groups_client.create_group(name=name)['group']
+ group = self.groups_client.create_group(
+ name=name, domain_id=self.data.domain['id'])['group']
groups.append(group)
self.addCleanup(self.groups_client.delete_group, group['id'])
self.groups_client.add_group_user(group['id'], user['id'])
@@ -112,7 +121,8 @@
name = data_utils.rand_name('Group')
description = data_utils.rand_name('Description')
group = self.groups_client.create_group(
- name=name, description=description)['group']
+ name=name, domain_id=self.data.domain['id'],
+ description=description)['group']
self.addCleanup(self.groups_client.delete_group, group['id'])
group_ids.append(group['id'])
# List and Verify Groups
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index 6ad374b..baeaa0c 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -28,7 +28,6 @@
@classmethod
def setup_clients(cls):
super(FloatingIPAdminTestJSON, cls).setup_clients()
- cls.alt_client = cls.alt_manager.network_client
cls.alt_floating_ips_client = cls.alt_manager.floating_ips_client
@classmethod
@@ -68,7 +67,7 @@
body = self.floating_ips_client.list_floatingips()
floating_ip_ids = [f['id'] for f in body['floatingips']]
# Check that nonadmin user doesn't see floating ip created from admin
- # and floating ip that is created in another tenant (alt user)
+ # and floating ip that is created in another project (alt user)
self.assertIn(self.floating_ip['id'], floating_ip_ids)
self.assertNotIn(floating_ip_admin['floatingip']['id'],
floating_ip_ids)
diff --git a/tempest/api/network/admin/test_negative_quotas.py b/tempest/api/network/admin/test_negative_quotas.py
index c1cdbf2..7b037d5 100644
--- a/tempest/api/network/admin/test_negative_quotas.py
+++ b/tempest/api/network/admin/test_negative_quotas.py
@@ -24,7 +24,7 @@
set network quota and exceed this quota
v2.0 of the API is assumed.
- It is also assumed that the per-tenant quota extension API is configured
+ It is also assumed that the per-project quota extension API is configured
in /etc/neutron/neutron.conf as follows:
quota_driver = neutron.db.quota_db.DbQuotaDriver
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index d72e960..ea3d59a 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -24,13 +24,13 @@
class QuotasTest(base.BaseAdminNetworkTest):
"""Tests the following operations in the Neutron API:
- list quotas for tenants who have non-default quota values
- show quotas for a specified tenant
- update quotas for a specified tenant
- reset quotas to default values for a specified tenant
+ list quotas for projects who have non-default quota values
+ show quotas for a specified project
+ update quotas for a specified project
+ reset quotas to default values for a specified project
v2.0 of the API is assumed.
- It is also assumed that the per-tenant quota extension API is configured
+ It is also assumed that the per-project quota extension API is configured
in /etc/neutron/neutron.conf as follows:
quota_driver = neutron.db.quota_db.DbQuotaDriver
@@ -49,7 +49,7 @@
cls.identity_admin_client = cls.os_adm.identity_client
def _check_quotas(self, new_quotas):
- # Add a tenant to conduct the test
+ # Add a project to conduct the test
project = data_utils.rand_name('test_project_')
description = data_utils.rand_name('desc_')
project = self.identity_utils.create_project(name=project,
@@ -57,14 +57,14 @@
project_id = project['id']
self.addCleanup(self.identity_utils.delete_project, project_id)
- # Change quotas for tenant
+ # Change quotas for project
quota_set = self.admin_quotas_client.update_quotas(
project_id, **new_quotas)['quota']
self.addCleanup(self._cleanup_quotas, project_id)
for key, value in six.iteritems(new_quotas):
self.assertEqual(value, quota_set[key])
- # Confirm our tenant is listed among tenants with non default quotas
+ # Confirm our project is listed among projects with non default quotas
non_default_quotas = self.admin_quotas_client.list_quotas()
found = False
for qs in non_default_quotas['quotas']:
@@ -72,7 +72,7 @@
found = True
self.assertTrue(found)
- # Confirm from API quotas were changed as requested for tenant
+ # Confirm from API quotas were changed as requested for project
quota_set = self.admin_quotas_client.show_quotas(project_id)
quota_set = quota_set['quota']
for key, value in six.iteritems(new_quotas):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 71edf74..9823345 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -32,11 +32,11 @@
Therefore, v2.x of the Neutron API is assumed. It is also assumed that the
following options are defined in the [network] section of etc/tempest.conf:
- tenant_network_cidr with a block of cidr's from which smaller blocks
- can be allocated for tenant networks
+ project_network_cidr with a block of cidr's from which smaller blocks
+ can be allocated for project networks
- tenant_network_mask_bits with the mask bits to be used to partition the
- block defined by tenant-network_cidr
+ project_network_mask_bits with the mask bits to be used to partition
+ the block defined by project-network_cidr
Finally, it is assumed that the following option is defined in the
[service_available] section of etc/tempest.conf
@@ -67,7 +67,6 @@
@classmethod
def setup_clients(cls):
super(BaseNetworkTest, cls).setup_clients()
- cls.client = cls.os.network_client
cls.agents_client = cls.os.network_agents_client
cls.network_extensions_client = cls.os.network_extensions_client
cls.networks_client = cls.os.networks_client
@@ -176,12 +175,12 @@
ip_version = ip_version if ip_version is not None else cls._ip_version
gateway_not_set = gateway == ''
if ip_version == 4:
- cidr = cidr or netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- mask_bits = mask_bits or CONF.network.tenant_network_mask_bits
+ cidr = cidr or netaddr.IPNetwork(CONF.network.project_network_cidr)
+ mask_bits = mask_bits or CONF.network.project_network_mask_bits
elif ip_version == 6:
- cidr = (
- cidr or netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr))
- mask_bits = mask_bits or CONF.network.tenant_network_v6_mask_bits
+ cidr = (cidr or
+ netaddr.IPNetwork(CONF.network.project_network_v6_cidr))
+ mask_bits = mask_bits or CONF.network.project_network_v6_mask_bits
# Find a cidr that is not in use yet and create a subnet with it
for subnet_cidr in cidr.subnet(mask_bits):
if gateway_not_set:
@@ -276,7 +275,6 @@
@classmethod
def setup_clients(cls):
super(BaseAdminNetworkTest, cls).setup_clients()
- cls.admin_client = cls.os_adm.network_client
cls.admin_agents_client = cls.os_adm.network_agents_client
cls.admin_networks_client = cls.os_adm.networks_client
cls.admin_routers_client = cls.os_adm.routers_client
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index 394aec1..b2892e5 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -100,7 +100,7 @@
@test.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
def test_update_port_with_cidr_address_pair(self):
# Update allowed address pair with cidr
- cidr = str(netaddr.IPNetwork(CONF.network.tenant_network_cidr))
+ cidr = str(netaddr.IPNetwork(CONF.network.project_network_cidr))
self._update_port_with_address(cidr)
@test.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index d71d600..2c981a1 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -31,7 +31,7 @@
@test.attr(type='smoke')
@test.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
def test_list_show_extensions(self):
- # List available extensions for the tenant
+ # List available extensions for the project
expected_alias = ['security-group', 'l3_agent_scheduler',
'ext-gw-mode', 'binding', 'quotas',
'agent', 'dhcp_agent_scheduler', 'provider',
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index fa1ed6a..b6f9da7 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -29,12 +29,12 @@
class NetworksTest(base.BaseNetworkTest):
"""Tests the following operations in the Neutron API:
- create a network for a tenant
- list tenant's networks
- show a tenant network details
- create a subnet for a tenant
- list tenant's subnets
- show a tenant subnet details
+ create a network for a project
+ list project's networks
+ show a project network details
+ create a subnet for a project
+ list project's subnets
+ show a project subnet details
network update
subnet update
delete a network also deletes its subnets
@@ -45,15 +45,15 @@
v2.0 of the Neutron API is assumed. It is also assumed that the following
options are defined in the [network] section of etc/tempest.conf:
- tenant_network_cidr with a block of cidr's from which smaller blocks
- can be allocated for tenant ipv4 subnets
+ project_network_cidr with a block of cidr's from which smaller blocks
+ can be allocated for project ipv4 subnets
- tenant_network_v6_cidr is the equivalent for ipv6 subnets
+ project_network_v6_cidr is the equivalent for ipv6 subnets
- tenant_network_mask_bits with the mask bits to be used to partition the
- block defined by tenant_network_cidr
+ project_network_mask_bits with the mask bits to be used to partition
+ the block defined by project_network_cidr
- tenant_network_v6_mask_bits is the equivalent for ipv6 subnets
+ project_network_v6_mask_bits is the equivalent for ipv6 subnets
"""
@classmethod
@@ -92,14 +92,14 @@
@classmethod
def _create_subnet_with_last_subnet_block(cls, network, ip_version):
- # Derive last subnet CIDR block from tenant CIDR and
+ # Derive last subnet CIDR block from project CIDR and
# create the subnet with that derived CIDR
if ip_version == 4:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- mask_bits = CONF.network.tenant_network_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ mask_bits = CONF.network.project_network_mask_bits
elif ip_version == 6:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
- mask_bits = CONF.network.tenant_network_v6_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+ mask_bits = CONF.network.project_network_v6_mask_bits
subnet_cidr = list(cidr.subnet(mask_bits))[-1]
gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
@@ -110,11 +110,11 @@
def _get_gateway_from_tempest_conf(cls, ip_version):
"""Return first subnet gateway for configured CIDR """
if ip_version == 4:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- mask_bits = CONF.network.tenant_network_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ mask_bits = CONF.network.project_network_mask_bits
elif ip_version == 6:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
- mask_bits = CONF.network.tenant_network_v6_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+ mask_bits = CONF.network.project_network_v6_mask_bits
if mask_bits >= cidr.prefixlen:
return netaddr.IPAddress(cidr) + 1
@@ -403,16 +403,16 @@
bulk network creation
bulk subnet creation
bulk port creation
- list tenant's networks
+ list project's networks
v2.0 of the Neutron API is assumed. It is also assumed that the following
options are defined in the [network] section of etc/tempest.conf:
- tenant_network_cidr with a block of cidr's from which smaller blocks
- can be allocated for tenant networks
+ project_network_cidr with a block of cidr's from which smaller blocks
+ can be allocated for project networks
- tenant_network_mask_bits with the mask bits to be used to partition the
- block defined by tenant-network_cidr
+ project_network_mask_bits with the mask bits to be used to partition
+ the block defined by project-network_cidr
"""
def _delete_networks(self, created_networks):
@@ -464,11 +464,11 @@
networks = [self.create_network(), self.create_network()]
# Creates 2 subnets in one request
if self._ip_version == 4:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- mask_bits = CONF.network.tenant_network_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ mask_bits = CONF.network.project_network_mask_bits
else:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
- mask_bits = CONF.network.tenant_network_v6_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+ mask_bits = CONF.network.project_network_v6_mask_bits
cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
@@ -529,7 +529,7 @@
@test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
def test_create_delete_subnet_with_gw(self):
- net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+ net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
gateway = str(netaddr.IPAddress(net.first + 2))
name = data_utils.rand_name('network-')
network = self.create_network(network_name=name)
@@ -539,7 +539,7 @@
@test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
def test_create_delete_subnet_with_default_gw(self):
- net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+ net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
gateway_ip = str(netaddr.IPAddress(net.first + 1))
name = data_utils.rand_name('network-')
network = self.create_network(network_name=name)
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index e302284..caf7f14 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -90,12 +90,12 @@
def _get_ipaddress_from_tempest_conf(cls):
"""Return subnet with mask bits for configured CIDR """
if cls._ip_version == 4:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- cidr.prefixlen = CONF.network.tenant_network_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ cidr.prefixlen = CONF.network.project_network_mask_bits
elif cls._ip_version == 6:
- cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
- cidr.prefixlen = CONF.network.tenant_network_v6_mask_bits
+ cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
+ cidr.prefixlen = CONF.network.project_network_v6_mask_bits
return cidr
@@ -428,11 +428,7 @@
class PortsIpV6TestJSON(PortsTestJSON):
_ip_version = 6
- _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
- _tenant_network_mask_bits = CONF.network.tenant_network_v6_mask_bits
class PortsAdminExtendedAttrsIpV6TestJSON(PortsAdminExtendedAttrsTestJSON):
_ip_version = 6
- _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
- _tenant_network_mask_bits = CONF.network.tenant_network_v6_mask_bits
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 11f7fc6..3654b2e 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -41,9 +41,9 @@
@classmethod
def resource_setup(cls):
super(RoutersTest, cls).resource_setup()
- cls.tenant_cidr = (CONF.network.tenant_network_cidr
+ cls.tenant_cidr = (CONF.network.project_network_cidr
if cls._ip_version == 4 else
- CONF.network.tenant_network_v6_cidr)
+ CONF.network.project_network_v6_cidr)
@test.attr(type='smoke')
@test.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
@@ -274,7 +274,7 @@
@test.requires_ext(extension='extraroute', service='network')
def test_update_delete_extra_route(self):
# Create different cidr for each subnet to avoid cidr duplicate
- # The cidr starts from tenant_cidr
+ # The cidr starts from project_cidr
next_cidr = netaddr.IPNetwork(self.tenant_cidr)
# Prepare to build several routes
test_routes = []
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 36aaf2d..cd9f6ad 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -39,9 +39,9 @@
cls.router = cls.create_router(data_utils.rand_name('router-'))
cls.network = cls.create_network()
cls.subnet = cls.create_subnet(cls.network)
- cls.tenant_cidr = (CONF.network.tenant_network_cidr
+ cls.tenant_cidr = (CONF.network.project_network_cidr
if cls._ip_version == 4 else
- CONF.network.tenant_network_v6_cidr)
+ CONF.network.project_network_v6_cidr)
@test.attr(type=['negative'])
@test.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 7d0765e..5312979 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -24,7 +24,7 @@
class SecGroupTest(base.BaseSecGroupTest):
- _tenant_network_cidr = CONF.network.tenant_network_cidr
+ _project_network_cidr = CONF.network.project_network_cidr
@classmethod
def skip_checks(cls):
@@ -71,7 +71,7 @@
@test.attr(type='smoke')
@test.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
def test_list_security_groups(self):
- # Verify the that security group belonging to tenant exist in list
+ # Verify the that security group belonging to project exist in list
body = self.security_groups_client.list_security_groups()
security_groups = body['security_groups']
found = None
@@ -210,7 +210,7 @@
protocol = 'tcp'
port_range_min = 76
port_range_max = 77
- ip_prefix = self._tenant_network_cidr
+ ip_prefix = self._project_network_cidr
self._create_verify_security_group_rule(sg_id, direction,
self.ethertype, protocol,
port_range_min,
@@ -239,4 +239,4 @@
class SecGroupIPv6Test(SecGroupTest):
_ip_version = 6
- _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
+ _project_network_cidr = CONF.network.project_network_v6_cidr
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index 401fa3b..86d0b46 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -24,7 +24,7 @@
class NegativeSecGroupTest(base.BaseSecGroupTest):
- _tenant_network_cidr = CONF.network.tenant_network_cidr
+ _project_network_cidr = CONF.network.project_network_cidr
@classmethod
def skip_checks(cls):
@@ -110,7 +110,7 @@
sg2_body, _ = self._create_security_group()
# Create rule specifying both remote_ip_prefix and remote_group_id
- prefix = self._tenant_network_cidr
+ prefix = self._project_network_cidr
self.assertRaises(
lib_exc.BadRequest,
self.security_group_rules_client.create_security_group_rule,
@@ -214,7 +214,7 @@
class NegativeSecGroupIPv6Test(NegativeSecGroupTest):
_ip_version = 6
- _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
+ _project_network_cidr = CONF.network.project_network_v6_cidr
@test.attr(type=['negative'])
@test.idempotent_id('7607439c-af73-499e-bf64-f687fd12a842')
@@ -223,9 +223,9 @@
# Create rule with bad remote_ip_prefix
pairs = ({'ethertype': 'IPv6',
- 'ip_prefix': CONF.network.tenant_network_cidr},
+ 'ip_prefix': CONF.network.project_network_cidr},
{'ethertype': 'IPv4',
- 'ip_prefix': CONF.network.tenant_network_v6_cidr})
+ 'ip_prefix': CONF.network.project_network_v6_cidr})
for pair in pairs:
self.assertRaisesRegex(
lib_exc.BadRequest,
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 26ace81..d813263 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -46,7 +46,6 @@
cls.client = cls.orchestration_client
cls.servers_client = cls.os.servers_client
cls.keypairs_client = cls.os.keypairs_client
- cls.network_client = cls.os.network_client
cls.networks_client = cls.os.networks_client
cls.volumes_client = cls.os.volumes_client
cls.images_v2_client = cls.os.image_client_v2
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 5483361..3f45634 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -44,7 +44,6 @@
@classmethod
def setup_clients(cls):
super(NeutronResourcesTestJSON, cls).setup_clients()
- cls.network_client = cls.os.network_client
cls.subnets_client = cls.os.subnets_client
cls.ports_client = cls.os.ports_client
@@ -58,8 +57,8 @@
cls._create_keypair()['name'])
cls.external_network_id = CONF.network.public_network_id
- tenant_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- mask_bits = CONF.network.tenant_network_mask_bits
+ tenant_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ mask_bits = CONF.network.project_network_mask_bits
cls.subnet_cidr = tenant_cidr.subnet(mask_bits).next()
# create the stack
diff --git a/tempest/clients.py b/tempest/clients.py
index fc0cc89..141d1c6 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -132,7 +132,6 @@
UsersClient as UsersV3Client
from tempest.services.image.v1.json.images_client import ImagesClient
from tempest.services.image.v2.json.images_client import ImagesClientV2
-from tempest.services.network.json.network_client import NetworkClient
from tempest.services.network.json.routers_client import RoutersClient
from tempest.services.object_storage.account_client import AccountClient
from tempest.services.object_storage.container_client import ContainerClient
@@ -237,14 +236,6 @@
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**self.default_params)
- self.network_client = NetworkClient(
- self.auth_provider,
- CONF.network.catalog_type,
- CONF.network.region or CONF.identity.region,
- endpoint_type=CONF.network.endpoint_type,
- build_interval=CONF.network.build_interval,
- build_timeout=CONF.network.build_timeout,
- **self.default_params)
self.networks_client = NetworksClient(
self.auth_provider,
CONF.network.catalog_type,
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 6124676..a154d0b 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -103,7 +103,6 @@
from tempest.services.identity.v2.json import roles_client
from tempest.services.identity.v2.json import tenants_client
from tempest.services.identity.v2.json import users_client
-from tempest.services.network.json import network_client
from tempest.services.network.json import routers_client
LOG = None
@@ -170,7 +169,6 @@
endpoint_type='adminURL',
**params
)
- network_admin = None
networks_admin = None
routers_admin = None
subnets_admin = None
@@ -178,12 +176,6 @@
if (CONF.service_available.neutron and
CONF.auth.create_isolated_networks):
neutron_iso_networks = True
- network_admin = network_client.NetworkClient(
- _auth,
- CONF.network.catalog_type,
- CONF.network.region or CONF.identity.region,
- endpoint_type='adminURL',
- **params)
networks_admin = networks_client.NetworksClient(
_auth,
CONF.network.catalog_type,
@@ -203,13 +195,13 @@
endpoint_type='adminURL',
**params)
return (identity_admin, tenants_admin, roles_admin, users_admin,
- neutron_iso_networks, network_admin, networks_admin, routers_admin,
+ neutron_iso_networks, networks_admin, routers_admin,
subnets_admin)
def create_resources(opts, resources):
(identity_admin, tenants_admin, roles_admin, users_admin,
- neutron_iso_networks, network_admin, networks_admin, routers_admin,
+ neutron_iso_networks, networks_admin, routers_admin,
subnets_admin) = get_admin_clients(opts)
roles = roles_admin.list_roles()['roles']
for u in resources['users']:
@@ -255,7 +247,7 @@
for u in resources['users']:
tenant = identity.get_tenant_by_name(tenants_admin, u['tenant'])
network_name, router_name = create_network_resources(
- network_admin, networks_admin, routers_admin, subnets_admin,
+ networks_admin, routers_admin, subnets_admin,
tenant['id'], u['name'])
u['network'] = network_name
u['router'] = router_name
@@ -282,7 +274,7 @@
LOG.info('Resources deployed successfully!')
-def create_network_resources(network_admin_client, networks_admin_client,
+def create_network_resources(networks_admin_client,
routers_admin_client, subnets_admin_client,
tenant_id, name):
@@ -292,8 +284,8 @@
return resp_body['network']
def _create_subnet(subnet_name, network_id):
- base_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- mask_bits = CONF.network.tenant_network_mask_bits
+ base_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ mask_bits = CONF.network.project_network_mask_bits
for subnet_cidr in base_cidr.subnet(mask_bits):
try:
resp_body = subnets_admin_client.\
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 99933dd..3c09600 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -382,7 +382,6 @@
class NetworkService(BaseService):
def __init__(self, manager, **kwargs):
super(NetworkService, self).__init__(kwargs)
- self.client = manager.network_client
self.networks_client = manager.networks_client
self.subnets_client = manager.subnets_client
self.ports_client = manager.ports_client
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index e3c1c64..2a4e314 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -127,6 +127,7 @@
from tempest.lib.services.compute import security_group_rules_client
from tempest.lib.services.compute import security_groups_client
from tempest.lib.services.compute import servers_client
+from tempest.lib.services.network import networks_client
from tempest.lib.services.network import ports_client
from tempest.lib.services.network import subnets_client
from tempest.services.identity.v2.json import identity_client
@@ -134,7 +135,6 @@
from tempest.services.identity.v2.json import tenants_client
from tempest.services.identity.v2.json import users_client
from tempest.services.image.v2.json import images_client
-from tempest.services.network.json import network_client
from tempest.services.network.json import routers_client
from tempest.services.object_storage import container_client
from tempest.services.object_storage import object_client
@@ -264,7 +264,7 @@
build_interval=CONF.volume.build_interval,
build_timeout=CONF.volume.build_timeout,
**default_params)
- self.networks = network_client.NetworkClient(
+ self.networks = networks_client.NetworksClient(
_auth,
CONF.network.catalog_type,
CONF.network.region or CONF.identity.region,
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 0ca14a9..58157ef 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -256,7 +256,7 @@
if credential_type not in CREDENTIAL_TYPES:
raise exceptions.InvalidCredentials()
- conf_attributes = ['username', 'password', 'tenant_name']
+ conf_attributes = ['username', 'password', 'project_name']
if identity_version == 'v3':
conf_attributes.append('domain_name')
@@ -269,6 +269,11 @@
params[attr] = getattr(_section, attr)
else:
params[attr] = getattr(_section, prefix + "_" + attr)
+ # NOTE(andreaf) v2 API still uses tenants, so we must translate project
+ # to tenant before building the Credentials object
+ if identity_version == 'v2':
+ params['tenant_name'] = params.get('project_name')
+ params.pop('project_name', None)
# Build and validate credentials. We are reading configured credentials,
# so validate them even if fill_in is False
credentials = get_credentials(fill_in=fill_in,
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 5f6c8b8..d374be4 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -62,7 +62,6 @@
self.users_admin_client,
self.roles_admin_client,
self.domains_admin_client,
- self.network_admin_client,
self.networks_admin_client,
self.routers_admin_client,
self.subnets_admin_client,
@@ -93,13 +92,13 @@
os = clients.Manager(self.default_admin_creds)
if self.identity_version == 'v2':
return (os.identity_client, os.tenants_client, os.users_client,
- os.roles_client, None, os.network_client,
+ os.roles_client, None,
os.networks_client, os.routers_client, os.subnets_client,
os.ports_client, os.security_groups_client)
else:
return (os.identity_v3_client, os.projects_client,
os.users_v3_client, os.roles_v3_client, os.domains_client,
- os.network_client, os.networks_client, os.routers_client,
+ os.networks_client, os.routers_client,
os.subnets_client, os.ports_client,
os.security_groups_client)
@@ -208,8 +207,8 @@
return resp_body['network']
def _create_subnet(self, subnet_name, tenant_id, network_id):
- base_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- mask_bits = CONF.network.tenant_network_mask_bits
+ base_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ mask_bits = CONF.network.project_network_mask_bits
for subnet_cidr in base_cidr.subnet(mask_bits):
try:
if self.network_resources:
diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py
index 97cc2ec..f3df387 100644
--- a/tempest/common/preprov_creds.py
+++ b/tempest/common/preprov_creds.py
@@ -331,6 +331,7 @@
def _wrap_creds_with_network(self, hash):
creds_dict = self.hash_dict['creds'][hash]
# Make sure a domain scope if defined for users in case of V3
+ # Make sure a tenant is available in case of V2
creds_dict = self._extend_credentials(creds_dict)
# This just builds a Credentials object, it does not validate
# nor fill with missing fields.
@@ -356,4 +357,17 @@
user_domain_fields = set(['user_domain_name', 'user_domain_id'])
if not user_domain_fields.intersection(set(creds_dict.keys())):
creds_dict['user_domain_name'] = self.credentials_domain
+ # NOTE(andreaf) In case of v2, replace project with tenant if project
+ # is provided and tenant is not
+ if self.identity_version == 'v2':
+ if ('project_name' in creds_dict and
+ 'tenant_name' in creds_dict and
+ creds_dict['project_name'] != creds_dict['tenant_name']):
+ clean_creds = self._sanitize_creds(creds_dict)
+ msg = 'Cannot specify project and tenant at the same time %s'
+ raise exceptions.InvalidCredentials(msg % clean_creds)
+ if ('project_name' in creds_dict and
+ 'tenant_name' not in creds_dict):
+ creds_dict['tenant_name'] = creds_dict['project_name']
+ creds_dict.pop('project_name')
return creds_dict
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 36e3e3a..3a215a0 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -118,7 +118,7 @@
def assign_static_ip(self, nic, addr):
cmd = "sudo ip addr add {ip}/{mask} dev {nic}".format(
- ip=addr, mask=CONF.network.tenant_network_mask_bits,
+ ip=addr, mask=CONF.network.project_network_mask_bits,
nic=nic
)
return self.exec_command(cmd)
diff --git a/tempest/config.py b/tempest/config.py
index 4c3b04b..b787b19 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -56,7 +56,7 @@
"number of concurrent test processes."),
cfg.BoolOpt('use_dynamic_credentials',
default=True,
- help="Allows test cases to create/destroy tenants and "
+ help="Allows test cases to create/destroy projects and "
"users. This option requires that OpenStack Identity "
"API admin credentials are known. If false, isolated "
"test cases and parallel execution, can still be "
@@ -81,23 +81,26 @@
default=True,
help="If use_dynamic_credentials is set to True and Neutron "
"is enabled Tempest will try to create a usable network, "
- "subnet, and router when needed for each tenant it "
+ "subnet, and router when needed for each project it "
"creates. However in some neutron configurations, like "
"with VLAN provider networks, this doesn't work. So if "
"set to False the isolated networks will not be created"),
cfg.StrOpt('admin_username',
help="Username for an administrative user. This is needed for "
- "authenticating requests made by tenant isolation to "
+ "authenticating requests made by project isolation to "
"create users and projects",
deprecated_group='identity'),
- cfg.StrOpt('admin_tenant_name',
- help="Tenant name to use for an administrative user. This is "
- "needed for authenticating requests made by tenant "
+ cfg.StrOpt('admin_project_name',
+ help="Project name to use for an administrative user. This is "
+ "needed for authenticating requests made by project "
"isolation to create users and projects",
- deprecated_group='identity'),
+ deprecated_opts=[cfg.DeprecatedOpt('admin_tenant_name',
+ group='auth'),
+ cfg.DeprecatedOpt('admin_tenant_name',
+ group='identity')]),
cfg.StrOpt('admin_password',
help="Password to use for an administrative user. This is "
- "needed for authenticating requests made by tenant "
+ "needed for authenticating requests made by project "
"isolation to create users and projects",
secret=True,
deprecated_group='identity'),
@@ -158,8 +161,9 @@
cfg.StrOpt('username',
help="Username to use for Nova API requests.",
deprecated_for_removal=True),
- cfg.StrOpt('tenant_name',
- help="Tenant name to use for Nova API requests.",
+ cfg.StrOpt('project_name',
+ deprecated_name='tenant_name',
+ help="Project name to use for Nova API requests.",
deprecated_for_removal=True),
cfg.StrOpt('admin_role',
default='admin',
@@ -176,8 +180,9 @@
help="Username of alternate user to use for Nova API "
"requests.",
deprecated_for_removal=True),
- cfg.StrOpt('alt_tenant_name',
- help="Alternate user's Tenant name to use for Nova API "
+ cfg.StrOpt('alt_project_name',
+ deprecated_name='alt_tenant_name',
+ help="Alternate user's Project name to use for Nova API "
"requests.",
deprecated_for_removal=True),
cfg.StrOpt('alt_password',
@@ -246,10 +251,10 @@
"no OS-EXT-STS extension available"),
cfg.StrOpt('fixed_network_name',
help="Name of the fixed network that is visible to all test "
- "tenants. If multiple networks are available for a tenant"
- " this is the network which will be used for creating "
- "servers if tempest does not create a network or a "
- "network is not specified elsewhere. It may be used for "
+ "projects. If multiple networks are available for a "
+ "project, this is the network which will be used for "
+ "creating servers if tempest does not create a network or "
+ "s network is not specified elsewhere. It may be used for "
"ssh validation only if floating IPs are disabled."),
cfg.StrOpt('catalog_type',
default='compute',
@@ -493,21 +498,26 @@
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The endpoint type to use for the network service."),
- cfg.StrOpt('tenant_network_cidr',
+ cfg.StrOpt('project_network_cidr',
+ deprecated_name='tenant_network_cidr',
default="10.100.0.0/16",
- help="The cidr block to allocate tenant ipv4 subnets from"),
- cfg.IntOpt('tenant_network_mask_bits',
+ help="The cidr block to allocate project ipv4 subnets from"),
+ cfg.IntOpt('project_network_mask_bits',
+ deprecated_name='tenant_network_mask_bits',
default=28,
- help="The mask bits for tenant ipv4 subnets"),
- cfg.StrOpt('tenant_network_v6_cidr',
+ help="The mask bits for project ipv4 subnets"),
+ cfg.StrOpt('project_network_v6_cidr',
+ deprecated_name='tenant_network_v6_cidr',
default="2003::/48",
- help="The cidr block to allocate tenant ipv6 subnets from"),
- cfg.IntOpt('tenant_network_v6_mask_bits',
+ help="The cidr block to allocate project ipv6 subnets from"),
+ cfg.IntOpt('project_network_v6_mask_bits',
+ deprecated_name='tenant_network_v6_mask_bits',
default=64,
- help="The mask bits for tenant ipv6 subnets"),
- cfg.BoolOpt('tenant_networks_reachable',
+ help="The mask bits for project ipv6 subnets"),
+ cfg.BoolOpt('project_networks_reachable',
+ deprecated_name='tenant_networks_reachable',
default=False,
- help="Whether tenant networks can be reached directly from "
+ help="Whether project networks can be reached directly from "
"the test client. This must be set to True when the "
"'fixed' ssh_connect_method is selected."),
cfg.StrOpt('public_network_id',
@@ -1003,7 +1013,7 @@
default=False,
help='Allows a full cleaning process after a stress test.'
' Caution : this cleanup will remove every objects of'
- ' every tenant.')
+ ' every project.')
]
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index 5d3fc93..380c173 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -4,5 +4,4 @@
./tempest/services/volume/base/base_qos_client.py
./tempest/services/volume/base/base_backups_client.py
./tempest/services/baremetal/base.py
-./tempest/services/network/json/network_client.py
./tempest/services/network/json/routers_client.py
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index 7d2eda0..d001d27 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -248,10 +248,10 @@
:param str url: the relative url to send the post request to
:param dict body: the request body
:param dict headers: The headers to use for the request
- :param dict extra_headers: If the headers returned by the get_headers()
- method are to be used but additional headers
- are needed in the request pass them in as a
- dict
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:return: a tuple with the first entry containing the response headers
and the second the response body
:rtype: tuple
@@ -263,10 +263,10 @@
:param str url: the relative url to send the post request to
:param dict headers: The headers to use for the request
- :param dict extra_headers: If the headers returned by the get_headers()
- method are to be used but additional headers
- are needed in the request pass them in as a
- dict
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:return: a tuple with the first entry containing the response headers
and the second the response body
:rtype: tuple
@@ -279,10 +279,10 @@
:param str url: the relative url to send the post request to
:param dict headers: The headers to use for the request
:param dict body: the request body
- :param dict extra_headers: If the headers returned by the get_headers()
- method are to be used but additional headers
- are needed in the request pass them in as a
- dict
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:return: a tuple with the first entry containing the response headers
and the second the response body
:rtype: tuple
@@ -295,10 +295,10 @@
:param str url: the relative url to send the post request to
:param dict body: the request body
:param dict headers: The headers to use for the request
- :param dict extra_headers: If the headers returned by the get_headers()
- method are to be used but additional headers
- are needed in the request pass them in as a
- dict
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:return: a tuple with the first entry containing the response headers
and the second the response body
:rtype: tuple
@@ -311,10 +311,10 @@
:param str url: the relative url to send the post request to
:param dict body: the request body
:param dict headers: The headers to use for the request
- :param dict extra_headers: If the headers returned by the get_headers()
- method are to be used but additional headers
- are needed in the request pass them in as a
- dict
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:return: a tuple with the first entry containing the response headers
and the second the response body
:rtype: tuple
@@ -326,10 +326,10 @@
:param str url: the relative url to send the post request to
:param dict headers: The headers to use for the request
- :param dict extra_headers: If the headers returned by the get_headers()
- method are to be used but additional headers
- are needed in the request pass them in as a
- dict
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:return: a tuple with the first entry containing the response headers
and the second the response body
:rtype: tuple
@@ -341,10 +341,10 @@
:param str url: the relative url to send the post request to
:param dict headers: The headers to use for the request
- :param dict extra_headers: If the headers returned by the get_headers()
- method are to be used but additional headers
- are needed in the request pass them in as a
- dict
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:return: a tuple with the first entry containing the response headers
and the second the response body
:rtype: tuple
@@ -576,10 +576,10 @@
:param str method: The HTTP verb to use for the request
:param str url: Relative url to send the request to
- :param dict extra_headers: If specified without the headers kwarg the
- headers sent with the request will be the
- combination from the get_headers() method
- and this kwarg
+ :param bool extra_headers: Boolean value than indicates if the headers
+ returned by the get_headers() method are to
+ be used but additional headers are needed in
+ the request pass them in as a dict.
:param dict headers: Headers to use for the request if none are
specifed the headers returned from the
get_headers() method are used. If the request
@@ -620,7 +620,6 @@
headers = self.get_headers()
elif extra_headers:
try:
- headers = headers.copy()
headers.update(self.get_headers())
except (ValueError, TypeError):
headers = self.get_headers()
diff --git a/tempest/lib/services/network/ports_client.py b/tempest/lib/services/network/ports_client.py
index 1793d6a..eba11d3 100644
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib import exceptions as lib_exc
from tempest.lib.services.network import base
@@ -45,3 +46,10 @@
"""
uri = '/ports'
return self.create_resource(uri, kwargs)
+
+ def is_resource_deleted(self, id):
+ try:
+ self.show_port(id)
+ except lib_exc.NotFound:
+ return True
+ return False
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 1217dc9..988ee1a 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -63,7 +63,6 @@
cls.servers_client = cls.manager.servers_client
cls.interface_client = cls.manager.interfaces_client
# Neutron network client
- cls.network_client = cls.manager.network_client
cls.networks_client = cls.manager.networks_client
cls.ports_client = cls.manager.ports_client
cls.routers_client = cls.manager.routers_client
@@ -217,7 +216,7 @@
networks = kwargs.pop('networks')
# If there are no networks passed to us we look up
- # for the tenant's private networks and create a port
+ # for the project's private networks and create a port
# if there is only one private network. The same behaviour
# as we would expect when passing the call to the clients
# with no networks
@@ -687,17 +686,15 @@
super(NetworkScenarioTest, cls).resource_setup()
cls.tenant_id = cls.manager.identity_client.tenant_id
- def _create_network(self, client=None, networks_client=None,
+ def _create_network(self, networks_client=None,
routers_client=None, tenant_id=None,
namestart='network-smoke-'):
- if not client:
- client = self.network_client
if not networks_client:
networks_client = self.networks_client
if not routers_client:
routers_client = self.routers_client
if not tenant_id:
- tenant_id = client.tenant_id
+ tenant_id = networks_client.tenant_id
name = data_utils.rand_name(namestart)
result = networks_client.create_network(name=name, tenant_id=tenant_id)
network = net_resources.DeletableNetwork(
@@ -737,15 +734,13 @@
*args, **kwargs)
return agents_list['agents']
- def _create_subnet(self, network, client=None, subnets_client=None,
+ def _create_subnet(self, network, subnets_client=None,
routers_client=None, namestart='subnet-smoke',
**kwargs):
"""Create a subnet for the given network
within the cidr block configured for tenant networks.
"""
- if not client:
- client = self.network_client
if not subnets_client:
subnets_client = self.subnets_client
if not routers_client:
@@ -764,11 +759,11 @@
if ip_version == 6:
tenant_cidr = netaddr.IPNetwork(
- CONF.network.tenant_network_v6_cidr)
- num_bits = CONF.network.tenant_network_v6_mask_bits
+ CONF.network.project_network_v6_cidr)
+ num_bits = CONF.network.project_network_v6_mask_bits
else:
- tenant_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
- num_bits = CONF.network.tenant_network_mask_bits
+ tenant_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
+ num_bits = CONF.network.project_network_mask_bits
result = None
str_cidr = None
@@ -796,7 +791,7 @@
raise
self.assertIsNotNone(result, 'Unable to allocate tenant network')
subnet = net_resources.DeletableSubnet(
- network_client=client, subnets_client=subnets_client,
+ subnets_client=subnets_client,
routers_client=routers_client, **result['subnet'])
self.assertEqual(subnet.cidr, str_cidr)
self.addCleanup(self.delete_wrapper, subnet.delete)
@@ -908,7 +903,7 @@
private_key,
should_connect=True,
servers_for_debug=None):
- if not CONF.network.tenant_networks_reachable:
+ if not CONF.network.project_networks_reachable:
msg = 'Tenant networks not configured to be reachable.'
LOG.info(msg)
return
@@ -1169,7 +1164,7 @@
router.update(admin_state_up=admin_state_up)
self.assertEqual(admin_state_up, router.admin_state_up)
- def create_networks(self, client=None, networks_client=None,
+ def create_networks(self, networks_client=None,
routers_client=None, subnets_client=None,
tenant_id=None, dns_nameservers=None):
"""Create a network with a subnet connected to a router.
@@ -1177,7 +1172,6 @@
The baremetal driver is a special case since all nodes are
on the same shared network.
- :param client: network client to create resources with.
:param tenant_id: id of tenant to create resources in.
:param dns_nameservers: list of dns servers to send to subnet.
:returns: network, subnet, router
@@ -1197,12 +1191,12 @@
subnet = None
else:
network = self._create_network(
- client=client, networks_client=networks_client,
+ networks_client=networks_client,
tenant_id=tenant_id)
router = self._get_router(client=routers_client,
tenant_id=tenant_id)
- subnet_kwargs = dict(network=network, client=client,
+ subnet_kwargs = dict(network=network,
subnets_client=subnets_client,
routers_client=routers_client)
# use explicit check because empty list is a valid option
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 2cbe6dc..4c2d31b 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -38,9 +38,9 @@
@classmethod
def skip_checks(cls):
super(TestNetworkAdvancedServerOps, cls).skip_checks()
- if not (CONF.network.tenant_networks_reachable
+ if not (CONF.network.project_networks_reachable
or CONF.network.public_network_id):
- msg = ('Either tenant_networks_reachable must be "true", or '
+ msg = ('Either project_networks_reachable must be "true", or '
'public_network_id must be defined.')
raise cls.skipException(msg)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 9e2477e..dfa4815 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -59,7 +59,7 @@
Determine which types of networks to test as follows:
* Configure tenant network checks (via the
- 'tenant_networks_reachable' key) if the Tempest host should
+ 'project_networks_reachable' key) if the Tempest host should
have direct connectivity to tenant networks. This is likely to
be the case if Tempest is running on the same host as a
single-node devstack installation with IP namespaces disabled.
@@ -81,9 +81,9 @@
@classmethod
def skip_checks(cls):
super(TestNetworkBasicOps, cls).skip_checks()
- if not (CONF.network.tenant_networks_reachable
+ if not (CONF.network.project_networks_reachable
or CONF.network.public_network_id):
- msg = ('Either tenant_networks_reachable must be "true", or '
+ msg = ('Either project_networks_reachable must be "true", or '
'public_network_id must be defined.')
raise cls.skipException(msg)
for ext in ['router', 'security-group']:
@@ -250,9 +250,8 @@
interface = self.interface_client.create_interface(
server_id=server['id'],
net_id=self.new_net.id)['interfaceAttachment']
- self.addCleanup(self.network_client.wait_for_resource_deletion,
- 'port',
- interface['port_id'], client=self.ports_client)
+ self.addCleanup(self.ports_client.wait_for_resource_deletion,
+ interface['port_id'])
self.addCleanup(self.delete_wrapper,
self.interface_client.delete_interface,
server['id'], interface['port_id'])
@@ -692,7 +691,7 @@
self._setup_network_and_servers()
# NOTE(kevinbenton): we have to use the admin credentials to check
- # for the distributed flag because self.router only has a tenant view.
+ # for the distributed flag because self.router only has a project view.
admin = self.admin_manager.routers_client.show_router(self.router.id)
if admin['router'].get('distributed', False):
msg = "Rescheduling test does not apply to distributed routers."
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 66c8ade..a52d8f9 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -44,9 +44,9 @@
if not (CONF.network_feature_enabled.ipv6
and CONF.network_feature_enabled.ipv6_subnet_attributes):
raise cls.skipException('IPv6 or its attributes not supported')
- if not (CONF.network.tenant_networks_reachable
+ if not (CONF.network.project_networks_reachable
or CONF.network.public_network_id):
- msg = ('Either tenant_networks_reachable must be "true", or '
+ msg = ('Either project_networks_reachable must be "true", or '
'public_network_id must be defined.')
raise cls.skipException(msg)
if CONF.baremetal.driver_enabled:
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 058f43b..d3f45c7 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -130,9 +130,9 @@
msg = ('Not currently supported when using vnic_type'
' direct or macvtap')
raise cls.skipException(msg)
- if not (CONF.network.tenant_networks_reachable or
+ if not (CONF.network.project_networks_reachable or
CONF.network.public_network_id):
- msg = ('Either tenant_networks_reachable must be "true", or '
+ msg = ('Either project_networks_reachable must be "true", or '
'public_network_id must be defined.')
raise cls.skipException(msg)
if not test.is_extension_enabled('security-group', 'network'):
@@ -194,7 +194,7 @@
client=tenant.manager.security_groups_client
)
- # don't use default secgroup since it allows in-tenant traffic
+ # don't use default secgroup since it allows in-project traffic
def_sg = self._create_empty_security_group(
namestart='secgroup_general-',
tenant_id=tenant.creds.tenant_id,
@@ -301,7 +301,7 @@
def _set_access_point(self, tenant):
# creates a server in a secgroup with rule allowing external ssh
- # in order to access tenant internal network
+ # in order to access project internal network
# workaround ip namespace
secgroups = tenant.security_groups.values()
name = 'server-{tenant}-access_point'.format(
@@ -321,7 +321,6 @@
def _create_tenant_network(self, tenant):
network, subnet, router = self.create_networks(
- client=tenant.manager.network_client,
networks_client=tenant.manager.networks_client,
routers_client=tenant.manager.routers_client,
subnets_client=tenant.manager.subnets_client)
@@ -468,7 +467,7 @@
if not self.credentials_provider.is_multi_tenant():
raise self.skipException("No secondary tenant defined")
try:
- # deploy new tenant
+ # deploy new project
self._deploy_tenant(self.alt_tenant)
self._verify_network_details(self.alt_tenant)
self._verify_mac_addr(self.alt_tenant)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
deleted file mode 100644
index 5080657..0000000
--- a/tempest/services/network/json/network_client.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# 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.
-
-import time
-
-from tempest import exceptions
-from tempest.lib import exceptions as lib_exc
-from tempest.lib.services.network import base
-
-
-class NetworkClient(base.BaseNetworkClient):
-
- """Tempest REST client for Neutron.
-
- Uses v2 of the Neutron API, since the V1 API has been removed from the
- code base.
-
- Implements create, delete, update, list and show for the basic Neutron
- abstractions (networks, sub-networks, routers, ports and floating IP):
-
- Implements add/remove interface to router using subnet ID / port ID
-
- It also implements list, show, update and reset for OpenStack Networking
- quotas
- """
-
- def wait_for_resource_deletion(self, resource_type, id, client=None):
- """Waits for a resource to be deleted."""
- start_time = int(time.time())
- while True:
- if self.is_resource_deleted(resource_type, id, client=client):
- return
- if int(time.time()) - start_time >= self.build_timeout:
- raise exceptions.TimeoutException
- time.sleep(self.build_interval)
-
- def is_resource_deleted(self, resource_type, id, client=None):
- if client is None:
- client = self
- method = 'show_' + resource_type
- try:
- getattr(client, method)(id)
- except AttributeError:
- raise Exception("Unknown resource type %s " % resource_type)
- except lib_exc.NotFound:
- return True
- return False
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index e78fcfe..329c54d 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -41,7 +41,6 @@
def __init__(self, *args, **kwargs):
self.client = kwargs.pop('client', None)
- self.network_client = kwargs.pop('network_client', None)
self.networks_client = kwargs.pop('networks_client', None)
self.routers_client = kwargs.pop('routers_client', None)
self.subnets_client = kwargs.pop('subnets_client', None)
diff --git a/tempest/tests/common/test_admin_available.py b/tempest/tests/common/test_admin_available.py
index 75401db..98e76b9 100644
--- a/tempest/tests/common/test_admin_available.py
+++ b/tempest/tests/common/test_admin_available.py
@@ -36,19 +36,19 @@
dynamic_creds, group='auth')
if use_accounts_file:
accounts = [{'username': 'u1',
- 'tenant_name': 't1',
+ 'project_name': 't1',
'password': 'p'},
{'username': 'u2',
- 'tenant_name': 't2',
+ 'project_name': 't2',
'password': 'p'}]
if admin_creds == 'role':
accounts.append({'username': 'admin',
- 'tenant_name': 'admin',
+ 'project_name': 'admin',
'password': 'p',
'roles': ['admin']})
elif admin_creds == 'type':
accounts.append({'username': 'admin',
- 'tenant_name': 'admin',
+ 'project_name': 'admin',
'password': 'p',
'types': ['admin']})
self.useFixture(mockpatch.Patch(
@@ -63,17 +63,17 @@
return_value=False))
if admin_creds:
username = 'u'
- tenant = 't'
+ project = 't'
password = 'p'
domain = 'd'
else:
username = None
- tenant = None
+ project = None
password = None
domain = None
cfg.CONF.set_default('admin_username', username, group='auth')
- cfg.CONF.set_default('admin_tenant_name', tenant, group='auth')
+ cfg.CONF.set_default('admin_project_name', project, group='auth')
cfg.CONF.set_default('admin_password', password, group='auth')
cfg.CONF.set_default('admin_domain_name', domain, group='auth')
diff --git a/tempest/tests/common/test_alt_available.py b/tempest/tests/common/test_alt_available.py
index db3f5ec..48e4a3e 100644
--- a/tempest/tests/common/test_alt_available.py
+++ b/tempest/tests/common/test_alt_available.py
@@ -36,7 +36,7 @@
dynamic_creds, group='auth')
if use_accounts_file:
accounts = [dict(username="u%s" % ii,
- tenant_name="t%s" % ii,
+ project_name="t%s" % ii,
password="p") for ii in creds]
self.useFixture(mockpatch.Patch(
'tempest.common.preprov_creds.read_accounts_yaml',
@@ -52,19 +52,19 @@
for ii in range(0, 2):
if len(creds) > ii:
username = 'u%s' % creds[ii]
- tenant = 't%s' % creds[ii]
+ project = 't%s' % creds[ii]
password = 'p'
domain = 'd'
else:
username = None
- tenant = None
+ project = None
password = None
domain = None
cfg.CONF.set_default('%susername' % cred_prefix[ii], username,
group='identity')
- cfg.CONF.set_default('%stenant_name' % cred_prefix[ii], tenant,
- group='identity')
+ cfg.CONF.set_default('%sproject_name' % cred_prefix[ii],
+ project, group='identity')
cfg.CONF.set_default('%spassword' % cred_prefix[ii], password,
group='identity')
cfg.CONF.set_default('%sdomain_name' % cred_prefix[ii], domain,
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index be4a6ee..a49612d 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -30,7 +30,6 @@
json_tenants_client
from tempest.services.identity.v2.json import users_client as \
json_users_client
-from tempest.services.network.json import network_client as json_network_client
from tempest.services.network.json import routers_client
from tempest.tests import base
from tempest.tests import fake_config
@@ -59,10 +58,8 @@
def test_tempest_client(self):
creds = dynamic_creds.DynamicCredentialProvider(**self.fixed_params)
- self.assertTrue(isinstance(creds.identity_admin_client,
- json_iden_client.IdentityClient))
- self.assertTrue(isinstance(creds.network_admin_client,
- json_network_client.NetworkClient))
+ self.assertIsInstance(creds.identity_admin_client,
+ json_iden_client.IdentityClient)
def _get_fake_admin_creds(self):
return credentials.get_credentials(
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index 7188e5f..7af8654 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -325,7 +325,7 @@
'id': 'fake-id',
'label': 'network-2'}]}):
creds = test_accounts_class.get_creds_by_roles(['role-7'])
- self.assertTrue(isinstance(creds, cred_provider.TestResources))
+ self.assertIsInstance(creds, cred_provider.TestResources)
network = creds.network
self.assertIsNotNone(network)
self.assertIn('name', network)
diff --git a/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index c45f6da..edd7186 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -46,7 +46,7 @@
lock_path=str(os.environ.get('OS_TEST_LOCK_PATH')),
)
self.conf.set_default('auth_version', 'v2', group='identity')
- for config_option in ['username', 'password', 'tenant_name']:
+ for config_option in ['username', 'password', 'project_name']:
# Identity group items
for prefix in ['', 'alt_', 'admin_']:
if prefix == 'admin_':
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index 98b045a..da5e2d7 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -201,7 +201,13 @@
if expected_to_skip:
self.assertRaises(testtools.TestCase.skipException, t.test_bar)
else:
- self.assertEqual(t.test_bar(), 0)
+ try:
+ self.assertEqual(t.test_bar(), 0)
+ except testtools.TestCase.skipException:
+ # We caught a skipException but we didn't expect to skip
+ # this test so raise a hard test failure instead.
+ raise testtools.TestCase.failureException(
+ "Not supposed to skip")
def test_requires_ext_decorator(self):
self._test_requires_ext_helper(expected_to_skip=False,
@@ -213,7 +219,7 @@
service='compute')
def test_requires_ext_decorator_with_all_ext_enabled(self):
- cfg.CONF.set_default('api_extensions', 'all',
+ cfg.CONF.set_default('api_extensions', ['all'],
group='compute-feature-enabled')
self._test_requires_ext_helper(expected_to_skip=False,
extension='random_ext',
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index 1811141..f6076ca 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -93,29 +93,29 @@
self.assertEqual(httplib.HTTPConnection, conn_class)
def test_get_connection_http(self):
- self.assertTrue(isinstance(self.client._get_connection(),
- httplib.HTTPConnection))
+ self.assertIsInstance(self.client._get_connection(),
+ httplib.HTTPConnection)
def test_get_connection_https(self):
endpoint = 'https://fake_url.com'
self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
self.client = glance_http.HTTPClient(self.fake_auth, {})
- self.assertTrue(isinstance(self.client._get_connection(),
- glance_http.VerifiedHTTPSConnection))
+ self.assertIsInstance(self.client._get_connection(),
+ glance_http.VerifiedHTTPSConnection)
def test_get_connection_ipv4_https(self):
endpoint = 'https://127.0.0.1'
self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
self.client = glance_http.HTTPClient(self.fake_auth, {})
- self.assertTrue(isinstance(self.client._get_connection(),
- glance_http.VerifiedHTTPSConnection))
+ self.assertIsInstance(self.client._get_connection(),
+ glance_http.VerifiedHTTPSConnection)
def test_get_connection_ipv6_https(self):
endpoint = 'https://[::1]'
self.fake_auth.base_url = mock.MagicMock(return_value=endpoint)
self.client = glance_http.HTTPClient(self.fake_auth, {})
- self.assertTrue(isinstance(self.client._get_connection(),
- glance_http.VerifiedHTTPSConnection))
+ self.assertIsInstance(self.client._get_connection(),
+ glance_http.VerifiedHTTPSConnection)
def test_get_connection_url_not_fount(self):
self.useFixture(mockpatch.PatchObject(self.client, 'connection_class',
diff --git a/test-requirements.txt b/test-requirements.txt
index be3a4f1..bb4b27f 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -6,7 +6,7 @@
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
python-subunit>=0.0.18 # Apache-2.0/BSD
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
-reno>=0.1.1 # Apache2
+reno>=1.6.2 # Apache2
mox>=0.5.3 # Apache-2.0
mock>=1.2 # BSD
coverage>=3.6 # Apache-2.0
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
new file mode 100644
index 0000000..03dbd9b
--- /dev/null
+++ b/tools/generate-tempest-plugins-list.py
@@ -0,0 +1,70 @@
+#! /usr/bin/env python
+
+# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
+#
+# 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.
+
+# This script is intended to be run as part of a periodic proposal bot
+# job in OpenStack infrastructure.
+#
+# In order to function correctly, the environment in which the
+# script runs must have
+# * network access to the review.openstack.org Gerrit API
+# working directory
+# * network access to https://git.openstack.org/cgit
+
+import json
+import re
+import requests
+
+url = 'https://review.openstack.org/projects/'
+
+# This is what a project looks like
+'''
+ "openstack-attic/akanda": {
+ "id": "openstack-attic%2Fakanda",
+ "state": "READ_ONLY"
+ },
+'''
+
+
+def is_in_openstack_namespace(proj):
+ return proj.startswith('openstack/')
+
+# Rather than returning a 404 for a nonexistent file, cgit delivers a
+# 0-byte response to a GET request. It also does not provide a
+# Content-Length in a HEAD response, so the way we tell if a file exists
+# is to check the length of the entire GET response body.
+
+
+def has_tempest_plugin(proj):
+ r = requests.get(
+ "https://git.openstack.org/cgit/%s/plain/setup.cfg" % proj)
+ p = re.compile('^tempest\.test_plugins', re.M)
+ if p.findall(r.text):
+ return True
+ else:
+ False
+
+r = requests.get(url)
+# Gerrit prepends 4 garbage octets to the JSON, in order to counter
+# cross-site scripting attacks. Therefore we must discard it so the
+# json library won't choke.
+projects = sorted(filter(is_in_openstack_namespace, json.loads(r.text[4:])))
+
+found_plugins = filter(has_tempest_plugin, projects)
+
+# Every element of the found_plugins list begins with "openstack/".
+# We drop those initial 10 octets when printing the list.
+for project in found_plugins:
+ print(project[10:])
diff --git a/tools/generate-tempest-plugins-list.sh b/tools/generate-tempest-plugins-list.sh
new file mode 100755
index 0000000..ecff508
--- /dev/null
+++ b/tools/generate-tempest-plugins-list.sh
@@ -0,0 +1,64 @@
+#!/bin/bash -ex
+
+# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
+#
+# 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.
+
+# This script is intended to be run as a periodic proposal bot job
+# in OpenStack infrastructure, though you can run it as a one-off.
+#
+# In order to function correctly, the environment in which the
+# script runs must have
+# * a writable doc/source directory relative to the current
+# working directory
+# AND ( (
+# * git
+# * all git repos meant to be searched for plugins cloned and
+# at the desired level of up-to-datedness
+# * the environment variable git_dir pointing to the location
+# * of said git repositories
+# ) OR (
+# * network access to the review.openstack.org Gerrit API
+# working directory
+# * network access to https://git.openstack.org/cgit
+# ))
+#
+# If a file named data/tempest-plugins-registry.header or
+# data/tempest-plugins-registry.footer is found relative to the
+# current working directory, it will be prepended or appended to
+# the generated reStructuredText plugins table respectively.
+
+(
+declare -A plugins
+
+if [[ -r data/tempest-plugins-registry.header ]]; then
+ cat data/tempest-plugins-registry.header
+fi
+
+sorted_plugins=$(python tools/generate-tempest-plugins-list.py)
+
+for k in ${sorted_plugins}; do
+ project=${k:0:28}
+ giturl="git://git.openstack.org/openstack/${k:0:26}"
+ printf "|%-28s|%-73s|\n" "${project}" "${giturl}"
+ printf "+----------------------------+-------------------------------------------------------------------------+\n"
+done
+
+if [[ -r data/tempest-plugins-registry.footer ]]; then
+ cat data/tempest-plugins-registry.footer
+fi
+) > doc/source/plugin-registry.rst
+
+if [[ -n ${1} ]]; then
+ cp doc/source/plugin-registry.rst ${1}/doc/source/plugin-registry.rst
+fi