Merge "Use addClassResourceCleanup for cleanup in test_regions"
diff --git a/.zuul.yaml b/.zuul.yaml
index ec6c59a..9f91455 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -14,6 +14,19 @@
post-run: playbooks/post-tempest.yaml
- job:
+ name: tempest-full
+ parent: devstack-tempest
+ description: |
+ Base integration test with Neutron networking and py27.
+ Former names for this job where:
+ * legacy-tempest-dsvm-neutron-full
+ * gate-tempest-dsvm-neutron-full-ubuntu-xenial
+ vars:
+ tox_venvlist: full
+ devstack_localrc:
+ ENABLE_FILE_INJECTION: True
+
+- job:
name: tempest-tox-plugin-sanity-check
parent: tox
description: |
@@ -98,4 +111,15 @@
- ^playbooks/
- ^roles/
- ^.zuul.yaml$
+ - tempest-full:
+ voting: false
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^.*\.rst$
+ - ^doc/.*$
+ - ^etc/.*$
+ - ^releasenotes/.*$
+ - ^setup.cfg$
+ - ^tempest/hacking/.*$
+ - ^tempest/tests/.*$
- tempest-tox-plugin-sanity-check
diff --git a/tempest/README.rst b/tempest/README.rst
index 663653e..62821de 100644
--- a/tempest/README.rst
+++ b/tempest/README.rst
@@ -12,10 +12,12 @@
and guidelines. Below is the overview of the Tempest respository structure
to make this clear.
-| tempest/
-| api/ - API tests
-| scenario/ - complex scenario tests
-| tests/ - unit tests for Tempest internals
+ .. code-block:: console
+
+ tempest/
+ api/ - API tests
+ scenario/ - complex scenario tests
+ tests/ - unit tests for Tempest internals
Each of these directories contains different types of tests. What
belongs in each directory, the rules and examples for good tests, are
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 9ee8858..ac03cdc 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -439,7 +439,7 @@
# is already detached.
pass
- def attach_volume(self, server, volume, device=None, check_reserved=False):
+ def attach_volume(self, server, volume, device=None):
"""Attaches volume to server and waits for 'in-use' volume status.
The volume will be detached when the test tears down.
@@ -448,15 +448,10 @@
:param volume: The volume to attach.
:param device: Optional mountpoint for the attached volume. Note that
this is not guaranteed for all hypervisors and is not recommended.
- :param check_reserved: Consider a status of reserved as valid for
- completion. This is to handle new Cinder attach where we more
- accurately use 'reserved' for things like attaching to a shelved
- server.
"""
attach_kwargs = dict(volumeId=volume['id'])
if device:
attach_kwargs['device'] = device
-
attachment = self.servers_client.attach_volume(
server['id'], **attach_kwargs)['volumeAttachment']
# On teardown detach the volume and wait for it to be available. This
@@ -467,11 +462,8 @@
# Ignore 404s on detach in case the server is deleted or the volume
# is already detached.
self.addCleanup(self._detach_volume, server, volume)
- statuses = ['in-use']
- if check_reserved:
- statuses.append('reserved')
waiters.wait_for_volume_resource_status(self.volumes_client,
- volume['id'], statuses)
+ volume['id'], 'in-use')
return attachment
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 9bef80f..297e8a8 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -223,8 +223,7 @@
num_vol = self._count_volumes(server, validation_resources)
self._shelve_server(server, validation_resources)
attachment = self.attach_volume(server, volume,
- device=('/dev/%s' % self.device),
- check_reserved=True)
+ device=('/dev/%s' % self.device))
# Unshelve the instance and check that attached volume exists
self._unshelve_server_and_check_volumes(
@@ -250,8 +249,7 @@
self._shelve_server(server, validation_resources)
# Attach and then detach the volume
- self.attach_volume(server, volume, device=('/dev/%s' % self.device),
- check_reserved=True)
+ self.attach_volume(server, volume, device=('/dev/%s' % self.device))
self.servers_client.detach_volume(server['id'], volume['id'])
waiters.wait_for_volume_resource_status(self.volumes_client,
volume['id'], 'available')
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 70dd7b5..d54e222 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -30,7 +30,6 @@
@classmethod
def resource_setup(cls):
super(EndpointsNegativeTestJSON, cls).resource_setup()
- cls.service_ids = list()
s_name = data_utils.rand_name('service')
s_type = data_utils.rand_name('type')
s_description = data_utils.rand_name('description')
@@ -38,14 +37,10 @@
cls.services_client.create_service(name=s_name, type=s_type,
description=s_description)
['service'])
- cls.service_id = service_data['id']
- cls.service_ids.append(cls.service_id)
+ cls.addClassResourceCleanup(cls.services_client.delete_service,
+ service_data['id'])
- @classmethod
- def resource_cleanup(cls):
- for s in cls.service_ids:
- cls.services_client.delete_service(s)
- super(EndpointsNegativeTestJSON, cls).resource_cleanup()
+ cls.service_id = service_data['id']
@decorators.attr(type=['negative'])
@decorators.idempotent_id('ac6c137e-4d3d-448f-8c83-4f13d0942651')
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index e7b005c..7cd41e9 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -32,6 +32,8 @@
for _ in range(3):
role_name = data_utils.rand_name(name='role')
role = cls.roles_client.create_role(name=role_name)['role']
+ cls.addClassResourceCleanup(cls.roles_client.delete_role,
+ role['id'])
cls.roles.append(role)
u_name = data_utils.rand_name('user')
u_desc = '%s description' % u_name
@@ -42,25 +44,23 @@
data_utils.rand_name('project'),
description=data_utils.rand_name('project-desc'),
domain_id=cls.domain['id'])['project']
+ cls.addClassResourceCleanup(cls.projects_client.delete_project,
+ cls.project['id'])
cls.group_body = cls.groups_client.create_group(
name=data_utils.rand_name('Group'), project_id=cls.project['id'],
domain_id=cls.domain['id'])['group']
+ cls.addClassResourceCleanup(cls.groups_client.delete_group,
+ cls.group_body['id'])
cls.user_body = cls.users_client.create_user(
name=u_name, description=u_desc, password=cls.u_password,
email=u_email, project_id=cls.project['id'],
domain_id=cls.domain['id'])['user']
+ cls.addClassResourceCleanup(cls.users_client.delete_user,
+ cls.user_body['id'])
cls.role = cls.roles_client.create_role(
name=data_utils.rand_name('Role'))['role']
-
- @classmethod
- def resource_cleanup(cls):
- cls.roles_client.delete_role(cls.role['id'])
- cls.groups_client.delete_group(cls.group_body['id'])
- cls.users_client.delete_user(cls.user_body['id'])
- cls.projects_client.delete_project(cls.project['id'])
- for role in cls.roles:
- cls.roles_client.delete_role(role['id'])
- super(RolesV3TestJSON, cls).resource_cleanup()
+ cls.addClassResourceCleanup(cls.roles_client.delete_role,
+ cls.role['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('18afc6c0-46cf-4911-824e-9989cc056c3a')
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 10afee0..08e2a12 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -179,15 +179,13 @@
raise lib_exc.TimeoutException(message)
-def wait_for_volume_resource_status(client, resource_id, statuses):
- """Waits for a volume resource to reach any of the specified statuses.
+def wait_for_volume_resource_status(client, resource_id, status):
+ """Waits for a volume resource to reach a given status.
This function is a common function for volume, snapshot and backup
resources. The function extracts the name of the desired resource from
the client class name of the resource.
"""
- if not isinstance(statuses, list):
- statuses = [statuses]
resource_name = re.findall(
r'(volume|group-snapshot|snapshot|backup|group)',
client.resource_type)[-1].replace('-', '_')
@@ -195,11 +193,11 @@
resource_status = show_resource(resource_id)[resource_name]['status']
start = int(time.time())
- while resource_status not in statuses:
+ while resource_status != status:
time.sleep(client.build_interval)
resource_status = show_resource(resource_id)[
'{}'.format(resource_name)]['status']
- if resource_status == 'error' and resource_status not in statuses:
+ if resource_status == 'error' and resource_status != status:
raise exceptions.VolumeResourceBuildErrorException(
resource_name=resource_name, resource_id=resource_id)
if resource_name == 'volume' and resource_status == 'error_restoring':
@@ -208,11 +206,11 @@
if int(time.time()) - start >= client.build_timeout:
message = ('%s %s failed to reach %s status (current %s) '
'within the required time (%s s).' %
- (resource_name, resource_id, statuses, resource_status,
+ (resource_name, resource_id, status, resource_status,
client.build_timeout))
raise lib_exc.TimeoutException(message)
LOG.info('%s %s reached %s after waiting for %f seconds',
- resource_name, resource_id, statuses, time.time() - start)
+ resource_name, resource_id, status, time.time() - start)
def wait_for_volume_retype(client, volume_id, new_volume_type):
diff --git a/tempest/config.py b/tempest/config.py
index b14d4fd..5eee86d 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -312,9 +312,9 @@
default=0,
help='Time in seconds before a shelved instance is eligible '
'for removing from a host. -1 never offload, 0 offload '
- 'when shelved. This time should be the same as the time '
- 'of nova.conf, and some tests will run for as long as the '
- 'time.'),
+ 'when shelved. This configuration value should be same as '
+ '[nova.DEFAULT]->shelved_offload_time in nova.conf, and '
+ 'some tests will run for as long as the time.'),
cfg.IntOpt('min_compute_nodes',
default=1,
help=('The minimum number of compute nodes expected. This will '
diff --git a/tox.ini b/tox.ini
index 21696eb..db5976f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -36,7 +36,17 @@
commands = oslo-config-generator --config-file tempest/cmd/config-generator.tempest.conf
[testenv:cover]
-commands = python setup.py testr --coverage --testr-arg='tempest\.tests {posargs}'
+setenv =
+ {[testenv]setenv}
+ PYTHON=coverage run --source tempest --parallel-mode
+commands =
+ coverage erase
+ find . -type f -name "*.pyc" -delete
+ stestr --test-path ./tempest/tests run {posargs}
+ coverage combine
+ coverage html -d cover
+ coverage xml -o cover/coverage.xml
+ coverage report
[testenv:all]
envdir = .tox/tempest
@@ -50,17 +60,6 @@
find . -type f -name "*.pyc" -delete
tempest run --regex {posargs}
-[testenv:ostestr]
-sitepackages = {[tempestenv]sitepackages}
-# 'all' includes slow tests
-setenv =
- {[tempestenv]setenv}
- OS_TEST_TIMEOUT={env:OS_TEST_TIMEOUT:1200}
-deps = {[tempestenv]deps}
-commands =
- find . -type f -name "*.pyc" -delete
- ostestr {posargs}
-
[testenv:all-plugin]
sitepackages = True
# 'all' includes slow tests