Merge "Adding server evacuate client"
diff --git a/HACKING.rst b/HACKING.rst
index 910a977..f97f97a 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -170,7 +170,7 @@
All negative tests should be based on `API-WG guideline`_ . Such negative
tests can block any changes from accurate failure code to invalid one.
-.. _API-WG guideline: https://github.com/openstack/api-wg/blob/master/guidelines/http.rst#failure-code-clarifications
+.. _API-WG guideline: http://specs.openstack.org/openstack/api-wg/guidelines/http.html#failure-code-clarifications
If facing some gray area which is not clarified on the above guideline, propose
a new guideline to the API-WG. With a proposal to the API-WG we will be able to
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 04ddfdf..2597f04 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -140,9 +140,8 @@
git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local",
"-n1"]
try:
- html_last_updated_fmt = subprocess.Popen(git_cmd,
- stdout=subprocess.PIPE).\
- communicate()[0]
+ html_last_updated_fmt = str(
+ subprocess.Popen(git_cmd, stdout=subprocess.PIPE).communicate()[0])
except Exception:
warnings.warn('Cannot get last updated time from git repository. '
'Not setting "html_last_updated_fmt".')
@@ -184,123 +183,5 @@
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Tempestdoc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
- ('index', 'Tempest.tex', u'Tempest Documentation',
- u'OpenStack QA Team', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'tempest', u'Tempest Documentation',
- [u'OpenStack QA Team'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output ------------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- ('index', 'Tempest', u'Tempest Documentation',
- u'OpenStack QA Team', 'Tempest', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
-
-
-# -- Options for Epub output ---------------------------------------------------
-
-# Bibliographic Dublin Core info.
-epub_title = u'Tempest'
-epub_author = u'Sean Dague'
-epub_publisher = u'OpenStack QA Team'
-epub_copyright = u'2013, OpenStack QA Team'
-
-# The language of the text. It defaults to the language option
-# or en if the language is not set.
-#epub_language = ''
-
-# The scheme of the identifier. Typical schemes are ISBN or URL.
-#epub_scheme = ''
-
-# The unique identifier of the text. This can be a ISBN number
-# or the project homepage.
-#epub_identifier = ''
-
-# A unique identification for the text.
-#epub_uid = ''
-
-# A tuple containing the cover image and cover page html template filenames.
-#epub_cover = ()
-
-# HTML files that should be inserted before the pages created by sphinx.
-# The format is a list of tuples containing the path and title.
-#epub_pre_files = []
-
-# HTML files shat should be inserted after the pages created by sphinx.
-# The format is a list of tuples containing the path and title.
-#epub_post_files = []
-
-# A list of files that should not be packed into the epub file.
-#epub_exclude_files = []
-
-# The depth of the table of contents in toc.ncx.
-#epub_tocdepth = 3
-
-# Allow duplicate toc entries.
-#epub_tocdup = True
+# A list of warning types to suppress arbitrary warning messages.
+suppress_warnings = ['image.nonlocal_uri']
diff --git a/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml b/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml
new file mode 100644
index 0000000..233cc28
--- /dev/null
+++ b/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add versions_client module for volume service.
+ This new module provides list_versions() method which shows API versions
+ from Volume service.
diff --git a/releasenotes/notes/deprecate-deactivate_image-config-7a282c471937bbcb.yaml b/releasenotes/notes/deprecate-deactivate_image-config-7a282c471937bbcb.yaml
new file mode 100644
index 0000000..69c6bb6
--- /dev/null
+++ b/releasenotes/notes/deprecate-deactivate_image-config-7a282c471937bbcb.yaml
@@ -0,0 +1,6 @@
+---
+deprecations:
+ - |
+ The ``deactivate_image`` configuration switch from the ``config`` module
+ is deprecated. It was added to support the older-than-kilo releases
+ which we don't support anymore.
diff --git a/releasenotes/notes/deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml b/releasenotes/notes/deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml
new file mode 100644
index 0000000..0660d9c
--- /dev/null
+++ b/releasenotes/notes/deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml
@@ -0,0 +1,12 @@
+---
+deprecations:
+ - |
+ Volume v1 API is deprecated and the v3 are CURRENT.
+ Tempest doesn't need to test the v1 API as the default.
+ The volume config option 'api_v1' has been marked as
+ deprecated.
+upgrade:
+ - |
+ The volume config option 'api_v1' default is changed to
+ ``False`` because the volume v1 API has been deprecated
+ since Juno release.
diff --git a/releasenotes/notes/remove-cinder-v1-api-tests-71e266b8d55d475f.yaml b/releasenotes/notes/remove-cinder-v1-api-tests-71e266b8d55d475f.yaml
new file mode 100644
index 0000000..710ad9e
--- /dev/null
+++ b/releasenotes/notes/remove-cinder-v1-api-tests-71e266b8d55d475f.yaml
@@ -0,0 +1,5 @@
+upgrade:
+ - Remove Cinder v1 API tests.
+ Cinder v1 API has been deprecated since Juno release, and Juno is
+ not supported by current Tempest. Then Cinder v1 API tests are
+ removed from Tempest.
diff --git a/setup.cfg b/setup.cfg
index 96313fd..b2035bc 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -45,12 +45,10 @@
tempest.config = tempest.config:list_opts
[build_sphinx]
-all_files = 1
+all-files = 1
+warning-is-error = 1
build-dir = doc/build
source-dir = doc/source
-[pbr]
-warnerrors = True
-
[wheel]
universal = 1
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index ceac56b..29bd6da 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -17,6 +17,7 @@
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
+import testtools
CONF = config.CONF
@@ -66,6 +67,8 @@
self.assertEqual(snapshot_name, image['name'])
@decorators.idempotent_id('71bcb732-0261-11e7-9086-fa163e4fa634')
+ @testtools.skipUnless(CONF.compute_feature_enabled.pause,
+ 'Pause is not available.')
def test_create_image_from_paused_server(self):
server = self.create_test_server(wait_until='ACTIVE')
self.servers_client.pause_server(server['id'])
@@ -82,6 +85,8 @@
self.assertEqual(snapshot_name, image['name'])
@decorators.idempotent_id('8ca07fec-0262-11e7-907e-fa163e4fa634')
+ @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
+ 'Suspend is not available.')
def test_create_image_from_suspended_server(self):
server = self.create_test_server(wait_until='ACTIVE')
self.servers_client.suspend_server(server['id'])
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index 87265ec..7cbb513 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -22,9 +22,12 @@
@decorators.idempotent_id('61e03386-89c3-449c-9bb1-a06f423fd9d1')
def test_multiple_create(self):
- body, servers = compute.create_test_server(self.os,
- wait_until='ACTIVE',
- min_count=2)
+ tenant_network = self.get_tenant_network()
+ body, servers = compute.create_test_server(
+ self.os,
+ wait_until='ACTIVE',
+ min_count=2,
+ tenant_network=tenant_network)
for server in servers:
self.addCleanup(self.servers_client.delete_server, server['id'])
# NOTE(maurosr): do status response check and also make sure that
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index 3f6abab..a72df5e 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -87,29 +87,48 @@
'Token must be invalid because the connection '
'closed.')
# Parse the RFB version from the data to make sure it is valid
- # and greater than or equal to 3.3
+ # and belong to the known supported RFB versions.
version = float("%d.%d" % (int(data[4:7], base=10),
int(data[8:11], base=10)))
- self.assertTrue(version >= 3.3, 'Bad RFB Version: ' + str(version))
- # Send our RFB version to the server, which we will just go with 3.3
+ # Add the max RFB versions supported
+ supported_versions = [3.3, 3.8]
+ self.assertIn(version, supported_versions,
+ 'Bad RFB Version: ' + str(version))
+ # Send our RFB version to the server
self._websocket.send_frame(data)
# Get the sever authentication type and make sure None is supported
data = self._websocket.receive_frame()
self.assertIsNotNone(data, 'Expected authentication type None.')
- self.assertGreaterEqual(
- len(data), 2, 'Expected authentication type None.')
- self.assertIn(
- 1, [ord_func(data[i + 1]) for i in range(ord_func(data[0]))],
- 'Expected authentication type None.')
- # Send to the server that we only support authentication type None
- self._websocket.send_frame(six.int2byte(1))
- # The server should send 4 bytes of 0's if security handshake succeeded
- data = self._websocket.receive_frame()
- self.assertEqual(
- len(data), 4, 'Server did not think security was successful.')
- self.assertEqual(
- [ord_func(i) for i in data], [0, 0, 0, 0],
- 'Server did not think security was successful.')
+ data_length = len(data)
+ if version == 3.3:
+ # For RFB 3.3: in the security handshake, rather than a two-way
+ # negotiation, the server decides the security type and sends a
+ # single word(4 bytes).
+ self.assertEqual(
+ data_length, 4, 'Expected authentication type None.')
+ self.assertIn(1, [ord_func(data[i]) for i in (0, 3)],
+ 'Expected authentication type None.')
+ else:
+ self.assertGreaterEqual(
+ len(data), 2, 'Expected authentication type None.')
+ self.assertIn(
+ 1,
+ [ord_func(data[i + 1]) for i in range(ord_func(data[0]))],
+ 'Expected authentication type None.')
+ # Send to the server that we only support authentication
+ # type None
+ self._websocket.send_frame(six.int2byte(1))
+
+ # The server should send 4 bytes of 0's if security
+ # handshake succeeded
+ data = self._websocket.receive_frame()
+ self.assertEqual(
+ len(data), 4,
+ 'Server did not think security was successful.')
+ self.assertEqual(
+ [ord_func(i) for i in data], [0, 0, 0, 0],
+ 'Server did not think security was successful.')
+
# Say to leave the desktop as shared as part of client initialization
self._websocket.send_frame(six.int2byte(1))
# Get the server initialization packet back and make sure it is the
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 4a46adc..eea918a 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -36,7 +36,6 @@
# read backend name from a list .
backend_names = set(CONF.volume.backend_names)
- cls.name_field = cls.special_fields['name_field']
cls.volume_id_list_with_prefix = []
cls.volume_id_list_without_prefix = []
@@ -65,7 +64,7 @@
cls.create_volume_type(name=type_name,
extra_specs=extra_specs)
- params = {cls.name_field: vol_name, 'volume_type': type_name,
+ params = {'name': vol_name, 'volume_type': type_name,
'size': CONF.volume.volume_size}
cls.volume = cls.admin_volume_client.create_volume(
**params)['volume']
@@ -140,7 +139,3 @@
msg = ("volumes %s were created in the same backend" % ", "
.join(volume_hosts))
six.assertCountEqual(self, volume_hosts, set(volume_hosts), msg)
-
-
-class VolumeMultiBackendV1Test(VolumeMultiBackendV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_qos.py b/tempest/api/volume/admin/test_qos.py
index 7a91985..aa6aa98 100644
--- a/tempest/api/volume/admin/test_qos.py
+++ b/tempest/api/volume/admin/test_qos.py
@@ -157,7 +157,3 @@
operation = 'disassociate-all'
waiters.wait_for_qos_operations(self.admin_volume_qos_client,
self.created_qos['id'], operation)
-
-
-class QosSpecsV1TestJSON(QosSpecsV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index e1c9492..4d8e5bf 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -107,7 +107,3 @@
def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
# test force delete when status of snapshot is error_deleting
self._create_reset_and_force_delete_temp_snapshot('error_deleting')
-
-
-class SnapshotsActionsV1Test(SnapshotsActionsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 73c927a..1686582 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -24,7 +24,3 @@
hosts = self.admin_hosts_client.list_hosts()['hosts']
self.assertGreaterEqual(len(hosts), 2, "No. of hosts are < 2,"
"response of list hosts is: % s" % hosts)
-
-
-class VolumeHostsAdminV1TestsJSON(VolumeHostsAdminV2TestsJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 3fd9b01..97f61c1 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -169,7 +169,3 @@
self.assertEqual(primary_quota['gigabytes']['in_use'] -
volume['size'],
new_primary_quota['gigabytes']['in_use'])
-
-
-class VolumeQuotasAdminV1TestJSON(BaseVolumeQuotasAdminV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index 8170626..1051445 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -70,7 +70,3 @@
self.assertRaises(lib_exc.OverLimit,
self.volumes_client.create_volume,
size=CONF.volume.volume_size)
-
-
-class VolumeQuotasNegativeV1TestJSON(BaseVolumeQuotasNegativeV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 5dfdfce..aa5145d 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -80,7 +80,3 @@
self.assertNotEqual(0, len(services))
self.assertEqual(self.host_name, _get_host(services[0]['host']))
self.assertEqual(self.binary_name, services[0]['binary'])
-
-
-class VolumesServicesV1TestJSON(VolumesServicesV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
index 90a0022..6320fb1 100644
--- a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
@@ -75,7 +75,3 @@
self.assertRaises(lib_exc.OverLimit,
self.snapshots_client.create_snapshot,
volume_id=self.volume['id'])
-
-
-class VolumeSnapshotNegativeV1TestJSON(VolumeSnapshotQuotasNegativeV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 6e56be9..fd333eb 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -36,7 +36,6 @@
# Create/update/get/delete volume with volume_type and extra spec.
volume_types = list()
vol_name = data_utils.rand_name(self.__class__.__name__ + '-volume')
- name_field = self.special_fields['name_field']
proto = CONF.volume.storage_protocol
vendor = CONF.volume.vendor_name
extra_specs = {"storage_protocol": proto,
@@ -46,14 +45,14 @@
vol_type = self.create_volume_type(
extra_specs=extra_specs)
volume_types.append(vol_type)
- params = {name_field: vol_name,
+ params = {'name': vol_name,
'volume_type': volume_types[0]['id'],
'size': CONF.volume.volume_size}
# Create volume
volume = self.create_volume(**params)
self.assertEqual(volume_types[0]['name'], volume["volume_type"])
- self.assertEqual(volume[name_field], vol_name,
+ self.assertEqual(volume['name'], vol_name,
"The created volume name is not equal "
"to the requested name")
self.assertIsNotNone(volume['id'],
@@ -74,7 +73,7 @@
fetched_volume['volume_type'],
'The fetched Volume type is different '
'from updated volume type')
- self.assertEqual(vol_name, fetched_volume[name_field],
+ self.assertEqual(vol_name, fetched_volume['name'],
'The fetched Volume is different '
'from the created Volume')
self.assertEqual(volume['id'], fetched_volume['id'],
@@ -183,7 +182,3 @@
self.assertEqual(name, updated_vol_type['name'])
self.assertEqual(description, updated_vol_type['description'])
self.assertEqual(is_public, updated_vol_type['is_public'])
-
-
-class VolumeTypesV1Test(VolumeTypesV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 1729d06..6a7ee3b 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -77,7 +77,3 @@
lib_exc.NotFound,
self.admin_volume_types_client.show_volume_type_extra_specs,
self.volume_type['id'], spec_key)
-
-
-class VolumeTypesExtraSpecsV1Test(VolumeTypesExtraSpecsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index d491f23..37422ca 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -136,7 +136,3 @@
lib_exc.NotFound,
self.admin_volume_types_client.show_volume_type_extra_specs,
self.volume_type['id'], data_utils.rand_uuid())
-
-
-class ExtraSpecsNegativeV1Test(ExtraSpecsNegativeV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index 69e9cc0..4017de6 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -26,8 +26,7 @@
@decorators.idempotent_id('b48c98f2-e662-4885-9b71-032256906314')
def test_create_with_nonexistent_volume_type(self):
# Should not be able to create volume with nonexistent volume_type.
- name_field = self.special_fields['name_field']
- params = {name_field: data_utils.rand_uuid(),
+ params = {'name': data_utils.rand_uuid(),
'volume_type': data_utils.rand_uuid()}
self.assertRaises(lib_exc.NotFound,
self.volumes_client.create_volume, **params)
@@ -64,7 +63,3 @@
volume_type = self.create_volume_type(**params)
self.assertRaises(lib_exc.NotFound,
self.create_volume, volume_type=volume_type['id'])
-
-
-class VolumeTypesNegativeV1Test(VolumeTypesNegativeV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 693ffe7..02b10f9 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -53,7 +53,3 @@
def test_volume_force_delete_when_volume_is_error(self):
# test force delete when status of volume is error
self._create_reset_and_force_delete_temp_volume('error')
-
-
-class VolumesActionsV1Test(VolumesActionsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index b771d8a..29c79f9 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -136,7 +136,3 @@
status="error")
waiters.wait_for_volume_resource_status(self.admin_backups_client,
backup['id'], 'error')
-
-
-class VolumesBackupsAdminV1Test(VolumesBackupsAdminV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 496594c..5e4fada 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -37,11 +37,7 @@
if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
- if cls._api_version == 1:
- if not CONF.volume_feature_enabled.api_v1:
- msg = "Volume API v1 is disabled"
- raise cls.skipException(msg)
- elif cls._api_version == 2:
+ if cls._api_version == 2:
if not CONF.volume_feature_enabled.api_v2:
msg = "Volume API v2 is disabled"
raise cls.skipException(msg)
@@ -65,23 +61,13 @@
cls.compute_networks_client = cls.os.compute_networks_client
cls.compute_images_client = cls.os.compute_images_client
- if cls._api_version == 1:
- cls.snapshots_client = cls.os.snapshots_client
- cls.volumes_client = cls.os.volumes_client
- cls.backups_client = cls.os.backups_client
- cls.volume_services_client = cls.os.volume_services_client
- cls.volumes_extension_client = cls.os.volumes_extension_client
- cls.availability_zone_client = (
- cls.os.volume_availability_zone_client)
- cls.volume_limits_client = cls.os.volume_limits_client
- else:
- cls.snapshots_client = cls.os.snapshots_v2_client
- cls.volumes_client = cls.os.volumes_v2_client
- cls.backups_client = cls.os.backups_v2_client
- cls.volumes_extension_client = cls.os.volumes_v2_extension_client
- cls.availability_zone_client = (
- cls.os.volume_v2_availability_zone_client)
- cls.volume_limits_client = cls.os.volume_v2_limits_client
+ cls.snapshots_client = cls.os.snapshots_v2_client
+ cls.volumes_client = cls.os.volumes_v2_client
+ cls.backups_client = cls.os.backups_v2_client
+ cls.volumes_extension_client = cls.os.volumes_v2_extension_client
+ cls.availability_zone_client = (
+ cls.os.volume_v2_availability_zone_client)
+ cls.volume_limits_client = cls.os.volume_v2_limits_client
@classmethod
def resource_setup(cls):
@@ -94,15 +80,6 @@
cls.build_interval = CONF.volume.build_interval
cls.build_timeout = CONF.volume.build_timeout
- if cls._api_version == 1:
- # Special fields and resp code for cinder v1
- cls.special_fields = {'name_field': 'display_name',
- 'descrip_field': 'display_description'}
- else:
- # Special fields and resp code for cinder v2
- cls.special_fields = {'name_field': 'name',
- 'descrip_field': 'description'}
-
@classmethod
def resource_cleanup(cls):
cls.clear_snapshots()
@@ -124,10 +101,9 @@
min_disk = image.get('minDisk')
kwargs['size'] = max(kwargs['size'], min_disk)
- name_field = cls.special_fields['name_field']
- if name_field not in kwargs:
+ if 'name' not in kwargs:
name = data_utils.rand_name(cls.__name__ + '-Volume')
- kwargs[name_field] = name
+ kwargs['name'] = name
volume = cls.volumes_client.create_volume(**kwargs)['volume']
cls.volumes.append(volume)
@@ -138,10 +114,9 @@
@classmethod
def create_snapshot(cls, volume_id=1, **kwargs):
"""Wrapper utility that returns a test snapshot."""
- name_field = cls.special_fields['name_field']
- if name_field not in kwargs:
+ if 'name' not in kwargs:
name = data_utils.rand_name(cls.__name__ + '-Snapshot')
- kwargs[name_field] = name
+ kwargs['name'] = name
snapshot = cls.snapshots_client.create_snapshot(
volume_id=volume_id, **kwargs)['snapshot']
@@ -246,38 +221,24 @@
def setup_clients(cls):
super(BaseVolumeAdminTest, cls).setup_clients()
- if cls._api_version == 1:
- cls.admin_volume_qos_client = cls.os_adm.volume_qos_client
- cls.admin_volume_services_client = \
- cls.os_adm.volume_services_client
- cls.admin_volume_types_client = cls.os_adm.volume_types_client
- cls.admin_volume_client = cls.os_adm.volumes_client
- cls.admin_hosts_client = cls.os_adm.volume_hosts_client
- cls.admin_snapshots_client = cls.os_adm.snapshots_client
- cls.admin_backups_client = cls.os_adm.backups_client
- cls.admin_encryption_types_client = \
- cls.os_adm.encryption_types_client
- cls.admin_quotas_client = cls.os_adm.volume_quotas_client
- cls.admin_volume_limits_client = cls.os_adm.volume_limits_client
- elif cls._api_version == 2:
- cls.admin_volume_qos_client = cls.os_adm.volume_qos_v2_client
- cls.admin_volume_services_client = \
- cls.os_adm.volume_services_v2_client
- cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
- cls.admin_volume_client = cls.os_adm.volumes_v2_client
- cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client
- cls.admin_snapshot_manage_client = \
- cls.os_adm.snapshot_manage_v2_client
- cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
- cls.admin_backups_client = cls.os_adm.backups_v2_client
- cls.admin_encryption_types_client = \
- cls.os_adm.encryption_types_v2_client
- cls.admin_quotas_client = cls.os_adm.volume_quotas_v2_client
- cls.admin_volume_limits_client = cls.os_adm.volume_v2_limits_client
- cls.admin_capabilities_client = \
- cls.os_adm.volume_capabilities_v2_client
- cls.admin_scheduler_stats_client = \
- cls.os_adm.volume_scheduler_stats_v2_client
+ cls.admin_volume_qos_client = cls.os_adm.volume_qos_v2_client
+ cls.admin_volume_services_client = \
+ cls.os_adm.volume_services_v2_client
+ cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
+ cls.admin_volume_client = cls.os_adm.volumes_v2_client
+ cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client
+ cls.admin_snapshot_manage_client = \
+ cls.os_adm.snapshot_manage_v2_client
+ cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
+ cls.admin_backups_client = cls.os_adm.backups_v2_client
+ cls.admin_encryption_types_client = \
+ cls.os_adm.encryption_types_v2_client
+ cls.admin_quotas_client = cls.os_adm.volume_quotas_v2_client
+ cls.admin_volume_limits_client = cls.os_adm.volume_v2_limits_client
+ cls.admin_capabilities_client = \
+ cls.os_adm.volume_capabilities_v2_client
+ cls.admin_scheduler_stats_client = \
+ cls.os_adm.volume_scheduler_stats_v2_client
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/volume/test_availability_zone.py b/tempest/api/volume/test_availability_zone.py
index 25fe5ad..f0d653f 100644
--- a/tempest/api/volume/test_availability_zone.py
+++ b/tempest/api/volume/test_availability_zone.py
@@ -31,7 +31,3 @@
availability_zone = (self.client.list_availability_zones()
['availabilityZoneInfo'])
self.assertGreater(len(availability_zone), 0)
-
-
-class AvailabilityZoneV1TestJSON(AvailabilityZoneV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index ca86748..ac3742c 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -43,7 +43,3 @@
self.assertIn(ext, map(lambda x: x['alias'], extensions))
else:
raise self.skipException('There are not any extensions configured')
-
-
-class ExtensionsV1TestJSON(ExtensionsV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index d5ad8d2..c1d4e05 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -102,7 +102,3 @@
body = self.snapshots_client.show_snapshot_metadata(
self.snapshot['id'])['metadata']
self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
-
-
-class SnapshotV1MetadataTestJSON(SnapshotV2MetadataTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_volume_absolute_limits.py b/tempest/api/volume/test_volume_absolute_limits.py
index 36445b9..8e3c343 100644
--- a/tempest/api/volume/test_volume_absolute_limits.py
+++ b/tempest/api/volume/test_volume_absolute_limits.py
@@ -46,7 +46,3 @@
self.assertEqual(absolute_limits['totalSnapshotsUsed'], 0)
self.assertEqual(absolute_limits['totalBackupsUsed'], 0)
self.assertEqual(absolute_limits['totalBackupGigabytesUsed'], 0)
-
-
-class AbsoluteLimitsV1Tests(AbsoluteLimitsV2Tests):
- _api_version = 1
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 9e7b0a7..bbe1765 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -89,7 +89,3 @@
body = self.volumes_client.show_volume_metadata(
self.volume['id'])['metadata']
self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
-
-
-class VolumesV1MetadataTest(VolumesV2MetadataTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 9f63b14..22cbd85 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -86,7 +86,3 @@
self.client.delete_volume_transfer(transfer_id)
waiters.wait_for_volume_resource_status(
self.client, volume['id'], 'available')
-
-
-class VolumesV1TransfersTest(VolumesV2TransfersTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index d39b07a..4fc1a69 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -153,7 +153,3 @@
# to compare here.
self.assertEqual(str(readonly),
fetched_volume['metadata']['readonly'])
-
-
-class VolumesV1ActionsTest(VolumesV2ActionsTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 83006c0..e0b54b5 100644
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -134,7 +134,3 @@
restored_volume_id)['volume']
self.assertEqual('true', restored_volume_info['bootable'])
-
-
-class VolumesBackupsV1Test(VolumesBackupsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_clone.py b/tempest/api/volume/test_volumes_clone.py
index d653808..620f3d4 100644
--- a/tempest/api/volume/test_volumes_clone.py
+++ b/tempest/api/volume/test_volumes_clone.py
@@ -60,7 +60,3 @@
self.assertEqual('true', cloned_vol_details['bootable'])
self.assertEqual(src_vol['id'], cloned_vol_details['source_volid'])
self.assertEqual(src_vol['size'], cloned_vol_details['size'])
-
-
-class VolumesV1CloneTest(VolumesV2CloneTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_clone_negative.py b/tempest/api/volume/test_volumes_clone_negative.py
index 5331243..28327f4 100644
--- a/tempest/api/volume/test_volumes_clone_negative.py
+++ b/tempest/api/volume/test_volumes_clone_negative.py
@@ -43,7 +43,3 @@
self.volumes_client.create_volume,
size=src_size - 1,
source_volid=src_vol['id'])
-
-
-class VolumesV1CloneNegativeTest(VolumesV2CloneNegativeTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index 3df9b00..3b09b60 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -31,7 +31,3 @@
volume['id'], 'available')
volume = self.volumes_client.show_volume(volume['id'])['volume']
self.assertEqual(volume['size'], extend_size)
-
-
-class VolumesV1ExtendTest(VolumesV2ExtendTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index d870534..9eff97a 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -29,22 +29,19 @@
class VolumesV2GetTest(base.BaseVolumeTest):
def _volume_create_get_update_delete(self, **kwargs):
- name_field = self.special_fields['name_field']
- descrip_field = self.special_fields['descrip_field']
-
# Create a volume, Get it's details and Delete the volume
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
metadata = {'Type': 'Test'}
# Create a volume
- kwargs[name_field] = v_name
+ kwargs['name'] = v_name
kwargs['metadata'] = metadata
volume = self.volumes_client.create_volume(**kwargs)['volume']
self.assertIn('id', volume)
self.addCleanup(self.delete_volume, self.volumes_client, volume['id'])
waiters.wait_for_volume_resource_status(self.volumes_client,
volume['id'], 'available')
- self.assertIn(name_field, volume)
- self.assertEqual(volume[name_field], v_name,
+ self.assertIn('name', volume)
+ self.assertEqual(volume['name'], v_name,
"The created volume name is not equal "
"to the requested name")
@@ -52,7 +49,7 @@
fetched_volume = self.volumes_client.show_volume(
volume['id'])['volume']
self.assertEqual(v_name,
- fetched_volume[name_field],
+ fetched_volume['name'],
'The fetched Volume name is different '
'from the created Volume')
self.assertEqual(volume['id'],
@@ -71,25 +68,25 @@
# Update Volume
# Test volume update when display_name is same with original value
- params = {name_field: v_name}
+ params = {'name': v_name}
self.volumes_client.update_volume(volume['id'], **params)
# Test volume update when display_name is new
new_v_name = data_utils.rand_name(
self.__class__.__name__ + '-new-Volume')
new_desc = 'This is the new description of volume'
- params = {name_field: new_v_name,
- descrip_field: new_desc}
+ params = {'name': new_v_name,
+ 'description': new_desc}
update_volume = self.volumes_client.update_volume(
volume['id'], **params)['volume']
# Assert response body for update_volume method
- self.assertEqual(new_v_name, update_volume[name_field])
- self.assertEqual(new_desc, update_volume[descrip_field])
+ self.assertEqual(new_v_name, update_volume['name'])
+ self.assertEqual(new_desc, update_volume['description'])
# Assert response body for show_volume method
updated_volume = self.volumes_client.show_volume(
volume['id'])['volume']
self.assertEqual(volume['id'], updated_volume['id'])
- self.assertEqual(new_v_name, updated_volume[name_field])
- self.assertEqual(new_desc, updated_volume[descrip_field])
+ self.assertEqual(new_v_name, updated_volume['name'])
+ self.assertEqual(new_desc, updated_volume['description'])
self.assertThat(updated_volume['metadata'].items(),
matchers.ContainsAll(metadata.items()),
'The fetched Volume metadata misses data '
@@ -99,7 +96,7 @@
# contains specific characters,
# then test volume update if display_name is duplicated
new_v_desc = data_utils.rand_name('@#$%^* description')
- params = {descrip_field: new_v_desc,
+ params = {'description': new_v_desc,
'availability_zone': volume['availability_zone'],
'size': CONF.volume.volume_size}
new_volume = self.volumes_client.create_volume(**params)['volume']
@@ -109,8 +106,8 @@
waiters.wait_for_volume_resource_status(self.volumes_client,
new_volume['id'], 'available')
- params = {name_field: volume[name_field],
- descrip_field: volume[descrip_field]}
+ params = {'name': volume['name'],
+ 'description': volume['description']}
self.volumes_client.update_volume(new_volume['id'], **params)
if 'imageRef' in kwargs:
@@ -141,7 +138,3 @@
origin = self.create_volume()
self._volume_create_get_update_delete(source_volid=origin['id'],
size=CONF.volume.volume_size)
-
-
-class VolumesV1GetTest(VolumesV2GetTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 1d6d35f..a852cea 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -221,8 +221,3 @@
params = {self.name: volume[self.name],
'status': 'available'}
self._list_by_param_value_and_assert(params, with_detail=True)
-
-
-class VolumesV1ListTestJSON(VolumesV2ListTestJSON):
- _api_version = 1
- VOLUME_FIELDS = ('id', 'display_name')
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 76ffc03..8990a15 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -26,8 +26,6 @@
def resource_setup(cls):
super(VolumesV2NegativeTest, cls).resource_setup()
- cls.name_field = cls.special_fields['name_field']
-
# Create a test shared instance and volume for attach/detach tests
cls.volume = cls.create_volume()
cls.mountpoint = "/dev/vdc"
@@ -52,7 +50,7 @@
# Should not be able to create volume with invalid size
# in request
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume,
size='#$%', params=params)
@@ -63,7 +61,7 @@
# Should not be able to create volume without passing size
# in request
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume,
size='', params=params)
@@ -73,7 +71,7 @@
def test_create_volume_with_size_zero(self):
# Should not be able to create volume with size zero
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume,
size='0', params=params)
@@ -83,7 +81,7 @@
def test_create_volume_with_size_negative(self):
# Should not be able to create volume with size negative
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.BadRequest,
self.volumes_client.create_volume,
size='-1', params=params)
@@ -93,7 +91,7 @@
def test_create_volume_with_nonexistent_volume_type(self):
# Should not be able to create volume with non-existent volume type
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
size='1', volume_type=data_utils.rand_uuid(),
params=params)
@@ -103,7 +101,7 @@
def test_create_volume_with_nonexistent_snapshot_id(self):
# Should not be able to create volume with non-existent snapshot
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
size='1', snapshot_id=data_utils.rand_uuid(),
params=params)
@@ -113,7 +111,7 @@
def test_create_volume_with_nonexistent_source_volid(self):
# Should not be able to create volume with non-existent source volume
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
size='1', source_volid=data_utils.rand_uuid(),
params=params)
@@ -122,7 +120,7 @@
@decorators.idempotent_id('0186422c-999a-480e-a026-6a665744c30c')
def test_update_volume_with_nonexistent_volume_id(self):
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
volume_id=data_utils.rand_uuid(), params=params)
@@ -130,7 +128,7 @@
@decorators.idempotent_id('e66e40d6-65e6-4e75-bdc7-636792fa152d')
def test_update_volume_with_invalid_volume_id(self):
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
volume_id=data_utils.rand_name('invalid'),
params=params)
@@ -139,7 +137,7 @@
@decorators.idempotent_id('72aeca85-57a5-4c1f-9057-f320f9ea575b')
def test_update_volume_with_empty_volume_id(self):
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
volume_id='', params=params)
@@ -263,7 +261,7 @@
@decorators.idempotent_id('0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f')
def test_list_volumes_with_nonexistent_name(self):
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
fetched_volume = self.volumes_client.list_volumes(
params=params)['volumes']
self.assertEqual(0, len(fetched_volume))
@@ -272,7 +270,7 @@
@decorators.idempotent_id('9ca17820-a0e7-4cbd-a7fa-f4468735e359')
def test_list_volumes_detail_with_nonexistent_name(self):
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
- params = {self.name_field: v_name}
+ params = {'name': v_name}
fetched_volume = \
self.volumes_client.list_volumes(
detail=True, params=params)['volumes']
@@ -294,7 +292,3 @@
self.volumes_client.list_volumes(detail=True,
params=params)['volumes']
self.assertEqual(0, len(fetched_volume))
-
-
-class VolumesV1NegativeTest(VolumesV2NegativeTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 82b4fc2..82f456b 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -33,8 +33,6 @@
def resource_setup(cls):
super(VolumesV2SnapshotTestJSON, cls).resource_setup()
cls.volume_origin = cls.create_volume()
- cls.name_field = cls.special_fields['name_field']
- cls.descrip_field = cls.special_fields['descrip_field']
@decorators.idempotent_id('b467b54c-07a4-446d-a1cf-651dedcc3ff1')
@test.services('compute')
@@ -110,27 +108,27 @@
matchers.ContainsAll(metadata.items()))
# Compare also with the output from the list action
- tracking_data = (snapshot['id'], snapshot[self.name_field])
+ tracking_data = (snapshot['id'], snapshot['name'])
snaps_list = self.snapshots_client.list_snapshots()['snapshots']
- snaps_data = [(f['id'], f[self.name_field]) for f in snaps_list]
+ snaps_data = [(f['id'], f['name']) for f in snaps_list]
self.assertIn(tracking_data, snaps_data)
# Updates snapshot with new values
new_s_name = data_utils.rand_name(
self.__class__.__name__ + '-new-snap')
new_desc = 'This is the new description of snapshot.'
- params = {self.name_field: new_s_name,
- self.descrip_field: new_desc}
+ params = {'name': new_s_name,
+ 'description': new_desc}
update_snapshot = self.snapshots_client.update_snapshot(
snapshot['id'], **params)['snapshot']
# Assert response body for update_snapshot method
- self.assertEqual(new_s_name, update_snapshot[self.name_field])
- self.assertEqual(new_desc, update_snapshot[self.descrip_field])
+ self.assertEqual(new_s_name, update_snapshot['name'])
+ self.assertEqual(new_desc, update_snapshot['description'])
# Assert response body for show_snapshot method
updated_snapshot = self.snapshots_client.show_snapshot(
snapshot['id'])['snapshot']
- self.assertEqual(new_s_name, updated_snapshot[self.name_field])
- self.assertEqual(new_desc, updated_snapshot[self.descrip_field])
+ self.assertEqual(new_s_name, updated_snapshot['name'])
+ self.assertEqual(new_desc, updated_snapshot['description'])
# Delete the snapshot
self.delete_snapshot(snapshot['id'])
@@ -158,7 +156,3 @@
# Should allow
self.assertEqual(volume['snapshot_id'], src_snap['id'])
self.assertEqual(volume['size'], src_size + 1)
-
-
-class VolumesV1SnapshotTestJSON(VolumesV2SnapshotTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_snapshots_list.py b/tempest/api/volume/test_volumes_snapshots_list.py
index a0eaa00..0ea8ec7 100644
--- a/tempest/api/volume/test_volumes_snapshots_list.py
+++ b/tempest/api/volume/test_volumes_snapshots_list.py
@@ -29,7 +29,6 @@
def resource_setup(cls):
super(VolumesV2SnapshotListTestJSON, cls).resource_setup()
volume_origin = cls.create_volume()
- cls.name_field = cls.special_fields['name_field']
# Create snapshots with params
for _ in range(2):
cls.snapshot = cls.create_snapshot(volume_origin['id'])
@@ -59,7 +58,7 @@
def test_snapshots_list_with_params(self):
"""list snapshots with params."""
# Verify list snapshots by display_name filter
- params = {self.name_field: self.snapshot[self.name_field]}
+ params = {'name': self.snapshot['name']}
self._list_by_param_values_and_assert(**params)
# Verify list snapshots by status filter
@@ -68,21 +67,21 @@
# Verify list snapshots by status and display name filter
params = {'status': 'available',
- self.name_field: self.snapshot[self.name_field]}
+ 'name': self.snapshot['name']}
self._list_by_param_values_and_assert(**params)
@decorators.idempotent_id('220a1022-1fcd-4a74-a7bd-6b859156cda2')
def test_snapshots_list_details_with_params(self):
"""list snapshot details with params."""
# Verify list snapshot details by display_name filter
- params = {self.name_field: self.snapshot[self.name_field]}
+ params = {'name': self.snapshot['name']}
self._list_by_param_values_and_assert(with_detail=True, **params)
# Verify list snapshot details by status filter
params = {'status': 'available'}
self._list_by_param_values_and_assert(with_detail=True, **params)
# Verify list snapshot details by status and display name filter
params = {'status': 'available',
- self.name_field: self.snapshot[self.name_field]}
+ 'name': self.snapshot['name']}
self._list_by_param_values_and_assert(with_detail=True, **params)
@decorators.idempotent_id('db4d8e0a-7a2e-41cc-a712-961f6844e896')
@@ -103,7 +102,3 @@
def test_snapshot_list_param_limit_equals_zero(self):
# List returns zero elements
self._list_snapshots_by_param_limit(limit=0, expected_elements=0)
-
-
-class VolumesV1SnapshotLimitTestJSON(VolumesV2SnapshotListTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index d3e3c9b..285d3f5 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -68,7 +68,3 @@
self.assertRaises(lib_exc.BadRequest,
self.snapshots_client.list_snapshots,
limit='invalid')
-
-
-class VolumesV1SnapshotNegativeTestJSON(VolumesV2SnapshotNegativeTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/v3/base.py b/tempest/api/volume/v3/base.py
index 31fc1eb..7f76e6f 100644
--- a/tempest/api/volume/v3/base.py
+++ b/tempest/api/volume/v3/base.py
@@ -45,6 +45,7 @@
def setup_clients(cls):
super(VolumesV3Test, cls).setup_clients()
cls.messages_client = cls.os.volume_v3_messages_client
+ cls.versions_client = cls.os.volume_v3_versions_client
def setUp(self):
super(VolumesV3Test, self).setUp()
diff --git a/tempest/api/volume/v3/test_versions.py b/tempest/api/volume/v3/test_versions.py
new file mode 100644
index 0000000..20f1657
--- /dev/null
+++ b/tempest/api/volume/v3/test_versions.py
@@ -0,0 +1,28 @@
+# Copyright 2017 NEC Corporation. All rights reserved.
+#
+# 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.
+
+from tempest.api.volume.v3 import base
+from tempest.lib import decorators
+from tempest import test
+
+
+class VersionsTest(base.VolumesV3Test):
+
+ @decorators.idempotent_id('77838fc4-b49b-4c64-9533-166762517369')
+ @test.attr(type='smoke')
+ def test_list_versions(self):
+ # NOTE: The version data is checked on service client side
+ # with JSON-Schema validation. It is enough to just call
+ # the API here.
+ self.versions_client.list_versions()['versions']
diff --git a/tempest/clients.py b/tempest/clients.py
index e75fa79..0654110 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -265,6 +265,7 @@
self.volumes_client = self.volume_v1.VolumesClient()
self.volumes_v2_client = self.volume_v2.VolumesClient()
self.volume_v3_messages_client = self.volume_v3.MessagesClient()
+ self.volume_v3_versions_client = self.volume_v3.VersionsClient()
self.volume_types_client = self.volume_v1.TypesClient()
self.volume_types_v2_client = self.volume_v2.TypesClient()
self.volume_hosts_client = self.volume_v1.HostsClient()
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 9a483bb..b2667e5 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import base64
+import textwrap
+
from oslo_log import log as logging
from oslo_utils import excutils
@@ -113,6 +116,19 @@
if wait_until is None:
wait_until = 'ACTIVE'
+ if 'user_data' not in kwargs:
+ # If nothing overrides the default user data script then run
+ # a simple script on the host to print networking info. This is
+ # to aid in debugging ssh failures.
+ script = '''
+ #!/bin/sh
+ echo "Printing {user} user authorized keys"
+ cat ~{user}/.ssh/authorized_keys || true
+ '''.format(user=CONF.validation.image_ssh_user)
+ script_clean = textwrap.dedent(script).lstrip().encode('utf8')
+ script_b64 = base64.b64encode(script_clean)
+ kwargs['user_data'] = script_b64
+
if volume_backed:
volume_name = data_utils.rand_name(__name__ + '-volume')
volumes_client = clients.volumes_v2_client
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 6dfc579..414c016 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -50,6 +50,8 @@
ping_count=CONF.validation.ping_count,
ping_size=CONF.validation.ping_size)
+ # Note that this method will not work on SLES11 guests, as they do
+ # not support the TYPE column on lsblk
def get_disks(self):
# Select root disk devices as shown by lsblk
command = 'lsblk -lb --nodeps'
diff --git a/tempest/config.py b/tempest/config.py
index d5c8ea9..93b8ab2 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -223,8 +223,8 @@
default=True,
help='Does the environment support reseller?',
deprecated_for_removal=True,
- deprecated_reason="All supported version of OpenStack now "
- "supports the 'reseller' feature"),
+ deprecated_reason="All supported versions of OpenStack now "
+ "support the 'reseller' feature"),
# TODO(rodrigods): This is a feature flag for bug 1590578 which is fixed
# in Newton and Ocata. This option can be removed after Mitaka is end of
# life.
@@ -531,7 +531,10 @@
cfg.BoolOpt('deactivate_image',
default=False,
help="Is the deactivate-image feature enabled."
- " The feature has been integrated since Kilo."),
+ " The feature has been integrated since Kilo.",
+ deprecated_for_removal=True,
+ deprecated_reason="All supported versions of OpenStack now "
+ "support the 'deactivate_image' feature"),
]
network_group = cfg.OptGroup(name='network',
@@ -812,8 +815,12 @@
'entry all which indicates every extension is enabled. '
'Empty list indicates all extensions are disabled'),
cfg.BoolOpt('api_v1',
- default=True,
- help="Is the v1 volume API enabled"),
+ default=False,
+ help="Is the v1 volume API enabled",
+ deprecated_for_removal=True,
+ deprecated_reason="The v1 volume API has been deprecated "
+ "since Juno release, and the API will be "
+ "removed."),
cfg.BoolOpt('api_v2',
default=True,
help="Is the v2 volume API enabled"),
diff --git a/tempest/lib/api_schema/response/volume/__init__.py b/tempest/lib/api_schema/response/volume/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/__init__.py
diff --git a/tempest/lib/api_schema/response/volume/versions.py b/tempest/lib/api_schema/response/volume/versions.py
new file mode 100644
index 0000000..2391a8c
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/versions.py
@@ -0,0 +1,60 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# 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.
+
+
+list_versions = {
+ 'status_code': [300],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'versions': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'status': {'type': 'string'},
+ 'updated': {'type': 'string'},
+ 'id': {'type': 'string'},
+ 'links': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'href': {'type': 'string',
+ 'format': 'uri'},
+ 'rel': {'type': 'string'},
+ 'type': {'type': 'string'},
+ },
+ 'required': ['href', 'rel']
+ }
+ },
+ 'min_version': {'type': 'string'},
+ 'version': {'type': 'string'},
+ 'media-types': {
+ 'type': 'array',
+ 'properties': {
+ 'base': {'type': 'string'},
+ 'type': {'type': 'string'}
+ },
+ 'required': ['base', 'type']
+ }
+ },
+ 'required': ['status', 'updated', 'id', 'links',
+ 'min_version', 'version', 'media-types']
+ }
+ }
+ },
+ 'required': ['versions'],
+ }
+}
diff --git a/tempest/lib/common/cred_client.py b/tempest/lib/common/cred_client.py
index ea06011..a81f53c 100644
--- a/tempest/lib/common/cred_client.py
+++ b/tempest/lib/common/cred_client.py
@@ -59,7 +59,8 @@
def _check_role_exists(self, role_name):
try:
roles = self._list_roles()
- role = next(r for r in roles if r['name'] == role_name)
+ lc_role_name = role_name.lower()
+ role = next(r for r in roles if r['name'].lower() == lc_role_name)
except StopIteration:
return None
return role
diff --git a/tempest/lib/services/volume/v3/__init__.py b/tempest/lib/services/volume/v3/__init__.py
index a4600a8..72ab785 100644
--- a/tempest/lib/services/volume/v3/__init__.py
+++ b/tempest/lib/services/volume/v3/__init__.py
@@ -14,5 +14,6 @@
from tempest.lib.services.volume.v3.base_client import BaseClient
from tempest.lib.services.volume.v3.messages_client import MessagesClient
+from tempest.lib.services.volume.v3.versions_client import VersionsClient
-__all__ = ['MessagesClient', 'BaseClient']
+__all__ = ['MessagesClient', 'BaseClient', 'VersionsClient']
diff --git a/tempest/lib/services/volume/v3/versions_client.py b/tempest/lib/services/volume/v3/versions_client.py
new file mode 100644
index 0000000..e2941c4
--- /dev/null
+++ b/tempest/lib/services/volume/v3/versions_client.py
@@ -0,0 +1,47 @@
+# Copyright 2017 NEC Corporation. All rights reserved.
+#
+# 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 oslo_serialization import jsonutils as json
+
+from tempest.lib.api_schema.response.volume import versions as schema
+from tempest.lib.common import rest_client
+from tempest.lib.services.volume.v3 import base_client
+
+
+class VersionsClient(base_client.BaseClient):
+
+ def list_versions(self):
+ """List API versions
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v3/#list-all-api-versions
+ """
+ version_url = self._get_base_version_url()
+
+ start = time.time()
+ resp, body = self.raw_request(version_url, 'GET')
+ end = time.time()
+ # NOTE: We need a raw_request() here instead of request() call because
+ # "list API versions" API doesn't require an authentication and we can
+ # skip it with raw_request() call.
+ self._log_request('GET', version_url, resp, secs=(end - start),
+ resp_body=body)
+ self._error_checker(resp, body)
+
+ body = json.loads(body)
+ self.validate_response(schema.list_versions, resp, body)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 727afd6..d4f0e13 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -79,13 +79,8 @@
cls.security_groups_client = cls.manager.security_groups_client
cls.security_group_rules_client = (
cls.manager.security_group_rules_client)
-
- if CONF.volume_feature_enabled.api_v2:
- cls.volumes_client = cls.manager.volumes_v2_client
- cls.snapshots_client = cls.manager.snapshots_v2_client
- else:
- cls.volumes_client = cls.manager.volumes_client
- cls.snapshots_client = cls.manager.snapshots_client
+ cls.volumes_client = cls.manager.volumes_v2_client
+ cls.snapshots_client = cls.manager.snapshots_v2_client
# ## Test functions library
#
@@ -235,12 +230,7 @@
volume['id'])
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.volumes_client.delete_volume, volume['id'])
-
- # NOTE(e0ne): Cinder API v2 uses name instead of display_name
- if 'display_name' in volume:
- self.assertEqual(name, volume['display_name'])
- else:
- self.assertEqual(name, volume['name'])
+ self.assertEqual(name, volume['name'])
waiters.wait_for_volume_resource_status(self.volumes_client,
volume['id'], 'available')
# The volume retrieved on creation has a non-up-to-date status.
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 96b423d..5f5d701 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -68,10 +68,7 @@
volume['id'], 'available')
waiters.wait_for_volume_resource_status(self.snapshots_client,
snapshot['id'], 'available')
- if 'display_name' in snapshot:
- self.assertEqual(snapshot_name, snapshot['display_name'])
- else:
- self.assertEqual(snapshot_name, snapshot['name'])
+ self.assertEqual(snapshot_name, snapshot['name'])
return snapshot
def _wait_for_volume_available_on_the_system(self, ip_address,
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index ae0230e..888bff2 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -81,13 +81,7 @@
self.addCleanup(self.snapshots_client.delete_snapshot, snap['id'])
waiters.wait_for_volume_resource_status(self.snapshots_client,
snap['id'], 'available')
-
- # NOTE(e0ne): Cinder API v2 uses name instead of display_name
- if 'display_name' in snap:
- self.assertEqual(snap_name, snap['display_name'])
- else:
- self.assertEqual(snap_name, snap['name'])
-
+ self.assertEqual(snap_name, snap['name'])
return snap
def _delete_server(self, server):
diff --git a/tempest/test_discover/plugins.py b/tempest/test_discover/plugins.py
index 276cf3c..613ab92 100644
--- a/tempest/test_discover/plugins.py
+++ b/tempest/test_discover/plugins.py
@@ -102,11 +102,10 @@
in any ServiceClients object instantiated by tests.
The default implementation returns an empty list.
- :return list of dictionaries. Each element of the list represents
- the service client for an API. Each dict must define all
- parameters required for the invocation of
- `service_clients.ServiceClients.register_service_client_module`.
- :rtype: list
+ :returns: Each element of the list represents the service client for an
+ API. Each dict must define all parameters required for the invocation
+ of `service_clients.ServiceClients.register_service_client_module`.
+ :rtype: list of dictionaries
Example:
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 1af0d95..98bf145 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -192,7 +192,7 @@
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, '_get_unversioned_endpoint',
return_value='http://fake_endpoint:5000'))
- fake_resp = {'versions': [{'id': 'v1.0'}, {'id': 'v2.0'}]}
+ fake_resp = {'versions': [{'id': 'v2.0'}]}
fake_resp = json.dumps(fake_resp)
mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
@@ -206,7 +206,7 @@
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, '_get_unversioned_endpoint',
return_value='http://fake_endpoint:5000'))
- fake_resp = {'versions': [{'id': 'v1.0'}, {'id': 'v3.0'}]}
+ fake_resp = {'versions': [{'id': 'v3.0'}]}
fake_resp = json.dumps(fake_resp)
mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
@@ -231,11 +231,9 @@
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_cinder_api_versions(fake_os, True)
- print_mock.assert_any_call('api_v1', 'volume-feature-enabled',
- False, True)
print_mock.assert_any_call('api_v3', 'volume-feature-enabled',
True, True)
- self.assertEqual(2, print_mock.call_count)
+ self.assertEqual(1, print_mock.call_count)
def test_verify_glance_version_no_v2_with_v1_1(self):
def fake_get_versions():
diff --git a/tempest/tests/lib/services/volume/v3/test_versions_client.py b/tempest/tests/lib/services/volume/v3/test_versions_client.py
new file mode 100644
index 0000000..9627b9a
--- /dev/null
+++ b/tempest/tests/lib/services/volume/v3/test_versions_client.py
@@ -0,0 +1,91 @@
+# Copyright 2017 NEC Corporation. All rights reserved.
+#
+# 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.
+
+from tempest.lib.services.volume.v3 import versions_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestVersionsClient(base.BaseServiceTest):
+
+ FAKE_VERSIONS_INFO = {
+ "versions": [
+ {
+ "status": "DEPRECATED", "updated": "2016-05-02T20:25:19Z",
+ "links": [
+ {"href": "http://docs.openstack.org/", "type": "text/html",
+ "rel": "describedby"},
+ {"href": "https://10.30.197.39:8776/v1/", "rel": "self"}
+ ],
+ "min_version": "",
+ "version": "",
+ "media-types": [
+ {"base": "application/json",
+ "type": "application/vnd.openstack.volume+json;version=1"}
+ ],
+ "id": "v1.0"
+ },
+ {
+ "status": "DEPRECATED", "updated": "2017-02-25T12:00:00Z",
+ "links": [
+ {"href": "http://docs.openstack.org/", "type": "text/html",
+ "rel": "describedby"},
+ {"href": "https://10.30.197.39:8776/v2/", "rel": "self"}
+ ],
+ "min_version": "",
+ "version": "",
+ "media-types": [
+ {"base": "application/json",
+ "type": "application/vnd.openstack.volume+json;version=1"}
+ ],
+ "id": "v2.0"
+ },
+ {
+ "status": "CURRENT", "updated": "2016-02-08T12:20:21Z",
+ "links": [
+ {"href": "http://docs.openstack.org/", "type": "text/html",
+ "rel": "describedby"},
+ {"href": "https://10.30.197.39:8776/v3/", "rel": "self"}
+ ],
+ "min_version": "3.0",
+ "version": "3.28",
+ "media-types": [
+ {"base": "application/json",
+ "type": "application/vnd.openstack.volume+json;version=1"}
+ ],
+ "id": "v3.0"
+ }
+ ]
+ }
+
+ def setUp(self):
+ super(TestVersionsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = versions_client.VersionsClient(fake_auth,
+ 'volume',
+ 'regionOne')
+
+ def _test_list_versions(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_versions,
+ 'tempest.lib.common.rest_client.RestClient.raw_request',
+ self.FAKE_VERSIONS_INFO,
+ bytes_body,
+ 300)
+
+ def test_list_versions_with_str_body(self):
+ self._test_list_versions()
+
+ def test_list_versions_with_bytes_body(self):
+ self._test_list_versions(bytes_body=True)
diff --git a/tox.ini b/tox.ini
index dfa8332..e2a9b3f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -11,7 +11,6 @@
BRANCH_NAME=master
CLIENT_NAME=tempest
deps =
- setuptools
-r{toxinidir}/requirements.txt
[testenv]