Merge "Scenario: Skip TestServerMultinode when only 1 compute node"
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 12d1d40..7e4503d 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -127,8 +127,11 @@
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
-git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1"
-html_last_updated_fmt = os.popen(git_cmd).read()
+git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local",
+ "-n1"]
+html_last_updated_fmt = subprocess.Popen(git_cmd,
+ stdout=subprocess.PIPE).\
+ communicate()[0]
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
diff --git a/requirements.txt b/requirements.txt
index 469b294..e5990ba 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -24,3 +24,4 @@
tempest-lib>=0.12.0
PyYAML>=3.1.0
stevedore>=1.5.0 # Apache-2.0
+PrettyTable<0.8,>=0.7
diff --git a/setup.cfg b/setup.cfg
index 4415063..b94a4f4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -36,6 +36,7 @@
init = tempest.cmd.init:TempestInit
cleanup = tempest.cmd.cleanup:TempestCleanup
run-stress = tempest.cmd.run_stress:TempestRunStress
+ list-plugins = tempest.cmd.list_plugins:TempestListPlugins
oslo.config.opts =
tempest.config = tempest.config:list_opts
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 4c7bab7..8a27929 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -70,7 +70,7 @@
cls.servers_client = cls.os.servers_client
cls.server_groups_client = cls.os.server_groups_client
cls.flavors_client = cls.os.flavors_client
- cls.images_client = cls.os.images_client
+ cls.compute_images_client = cls.os.compute_images_client
cls.extensions_client = cls.os.extensions_client
cls.floating_ip_pools_client = cls.os.floating_ip_pools_client
cls.floating_ips_client = cls.os.compute_floating_ips_client
@@ -178,7 +178,7 @@
LOG.debug('Clearing images: %s', ','.join(cls.images))
for image_id in cls.images:
try:
- cls.images_client.delete_image(image_id)
+ cls.compute_images_client.delete_image(image_id)
except lib_exc.NotFound:
# The image may have already been deleted which is OK.
pass
@@ -303,14 +303,14 @@
if 'name' in kwargs:
name = kwargs.pop('name')
- image = cls.images_client.create_image(server_id, name=name)
+ image = cls.compute_images_client.create_image(server_id, name=name)
image_id = data_utils.parse_image_id(image.response['location'])
cls.images.append(image_id)
if 'wait_until' in kwargs:
- waiters.wait_for_image_status(cls.images_client,
+ waiters.wait_for_image_status(cls.compute_images_client,
image_id, kwargs['wait_until'])
- image = cls.images_client.show_image(image_id)['image']
+ image = cls.compute_images_client.show_image(image_id)['image']
if kwargs['wait_until'] == 'ACTIVE':
if kwargs.get('wait_for_server', True):
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 975b850..0724566 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -37,7 +37,7 @@
def setup_clients(cls):
super(ImagesMetadataTestJSON, cls).setup_clients()
cls.glance_client = cls.os.image_client
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/compute/images/test_image_metadata_negative.py b/tempest/api/compute/images/test_image_metadata_negative.py
index 0f02166..85d137b 100644
--- a/tempest/api/compute/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/images/test_image_metadata_negative.py
@@ -25,7 +25,7 @@
@classmethod
def setup_clients(cls):
super(ImagesMetadataTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
@test.attr(type=['negative'])
@test.idempotent_id('94069db2-792f-4fa8-8bd3-2271a6e0c095')
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index dc62620..150e8af 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -37,7 +37,7 @@
@classmethod
def setup_clients(cls):
super(ImagesTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
cls.servers_client = cls.servers_client
@test.idempotent_id('aa06b52b-2db5-4807-b218-9441f75d74e3')
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 9197adf..8f6ede9 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -39,7 +39,7 @@
@classmethod
def setup_clients(cls):
super(ImagesNegativeTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
cls.servers_client = cls.servers_client
@test.attr(type=['negative'])
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 37c2bb6..7b978ab 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -62,7 +62,7 @@
@classmethod
def setup_clients(cls):
super(ImagesOneServerTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 9ea62fb..2fc9ef8 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -76,7 +76,7 @@
@classmethod
def setup_clients(cls):
super(ImagesOneServerNegativeTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 9f3ba71..49d9bc8 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -42,7 +42,7 @@
@classmethod
def setup_clients(cls):
super(ListImageFiltersTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
cls.glance_client = cls.os.image_client
@classmethod
diff --git a/tempest/api/compute/images/test_list_image_filters_negative.py b/tempest/api/compute/images/test_list_image_filters_negative.py
index 82062bd..34d26e2 100644
--- a/tempest/api/compute/images/test_list_image_filters_negative.py
+++ b/tempest/api/compute/images/test_list_image_filters_negative.py
@@ -34,7 +34,7 @@
@classmethod
def setup_clients(cls):
super(ListImageFiltersNegativeTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
@test.attr(type=['negative'])
@test.idempotent_id('391b0440-432c-4d4b-b5da-c5096aa247eb')
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index 6ca15d6..ae3667d 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -32,7 +32,7 @@
@classmethod
def setup_clients(cls):
super(ListImagesTestJSON, cls).setup_clients()
- cls.client = cls.images_client
+ cls.client = cls.compute_images_client
@test.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
def test_get_image(self):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index f51c2db..e1c22e5 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -262,13 +262,16 @@
'Instance validation tests are disabled.')
def test_verify_created_server_ephemeral_disk(self):
# Verify that the ephemeral disk is created when creating server
+ flavor_base = self.flavors_client.show_flavor(
+ self.flavor_ref)['flavor']
def create_flavor_with_extra_specs():
flavor_with_eph_disk_name = data_utils.rand_name('eph_flavor')
flavor_with_eph_disk_id = data_utils.rand_int_id(start=1000)
- ram = 64
- vcpus = 1
- disk = 0
+
+ ram = flavor_base['ram']
+ vcpus = flavor_base['vcpus']
+ disk = flavor_base['disk']
# Create a flavor with extra specs
flavor = (self.flavor_client.
@@ -284,9 +287,9 @@
flavor_no_eph_disk_name = data_utils.rand_name('no_eph_flavor')
flavor_no_eph_disk_id = data_utils.rand_int_id(start=1000)
- ram = 64
- vcpus = 1
- disk = 0
+ ram = flavor_base['ram']
+ vcpus = flavor_base['vcpus']
+ disk = flavor_base['disk']
# Create a flavor without extra specs
flavor = (self.flavor_client.
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 3acff98..d1ec064 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -43,7 +43,7 @@
super(ListServerFiltersTestJSON, cls).resource_setup()
# Check to see if the alternate image ref actually exists...
- images_client = cls.images_client
+ images_client = cls.compute_images_client
images = images_client.list_images()['images']
if cls.image_ref != cls.image_ref_alt and \
@@ -56,13 +56,13 @@
# Do some sanity checks here. If one of the images does
# not exist, fail early since the tests won't work...
try:
- cls.images_client.show_image(cls.image_ref)
+ cls.compute_images_client.show_image(cls.image_ref)
except lib_exc.NotFound:
raise RuntimeError("Image %s (image_ref) was not found!" %
cls.image_ref)
try:
- cls.images_client.show_image(cls.image_ref_alt)
+ cls.compute_images_client.show_image(cls.image_ref_alt)
except lib_exc.NotFound:
raise RuntimeError("Image %s (image_ref_alt) was not found!" %
cls.image_ref_alt)
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 71dfd96..d7f0d75 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -453,7 +453,7 @@
server = self.client.show_server(self.server_id)['server']
image_name = server['name'] + '-shelved'
params = {'name': image_name}
- images = self.images_client.list_images(**params)['images']
+ images = self.compute_images_client.list_images(**params)['images']
self.assertEqual(1, len(images))
self.assertEqual(image_name, images[0]['name'])
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index ed8484e..681b5db 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -490,7 +490,7 @@
server = self.client.show_server(self.server_id)['server']
image_name = server['name'] + '-shelved'
params = {'name': image_name}
- images = self.images_client.list_images(**params)['images']
+ images = self.compute_images_client.list_images(**params)['images']
self.assertEqual(1, len(images))
self.assertEqual(image_name, images[0]['name'])
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 67e6f4a..bf4396d 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -48,14 +48,14 @@
def setup_clients(cls):
super(AuthorizationTestJSON, cls).setup_clients()
cls.client = cls.os.servers_client
- cls.images_client = cls.os.images_client
+ cls.compute_images_client = cls.os.compute_images_client
cls.glance_client = cls.os.image_client
cls.keypairs_client = cls.os.keypairs_client
cls.security_client = cls.os.compute_security_groups_client
cls.rule_client = cls.os.compute_security_group_rules_client
cls.alt_client = cls.alt_manager.servers_client
- cls.alt_images_client = cls.alt_manager.images_client
+ cls.alt_compute_images_client = cls.alt_manager.compute_images_client
cls.alt_keypairs_client = cls.alt_manager.keypairs_client
cls.alt_security_client = (
cls.alt_manager.compute_security_groups_client)
@@ -78,7 +78,7 @@
body = cls.glance_client.update_image(image_id,
data=image_file)['image']
cls.glance_client.wait_for_image_status(image_id, 'active')
- cls.image = cls.images_client.show_image(image_id)['image']
+ cls.image = cls.compute_images_client.show_image(image_id)['image']
cls.keypairname = data_utils.rand_name('keypair')
cls.keypairs_client.create_keypair(name=cls.keypairname)
@@ -99,7 +99,7 @@
@classmethod
def resource_cleanup(cls):
if hasattr(cls, 'image'):
- cls.images_client.delete_image(cls.image['id'])
+ cls.compute_images_client.delete_image(cls.image['id'])
if hasattr(cls, 'keypairname'):
cls.keypairs_client.delete_keypair(cls.keypairname)
if hasattr(cls, 'security_group'):
@@ -176,7 +176,7 @@
def test_create_image_for_alt_account_fails(self):
# A create image request for another user's server should fail
self.assertRaises(lib_exc.NotFound,
- self.alt_images_client.create_image,
+ self.alt_compute_images_client.create_image,
self.server['id'], name='testImage')
@test.idempotent_id('95d445f6-babc-4f2e-aea3-aa24ec5e7f0d')
@@ -262,13 +262,14 @@
def test_get_image_for_alt_account_fails(self):
# A GET request for an image on another user's account should fail
self.assertRaises(lib_exc.NotFound,
- self.alt_images_client.show_image, self.image['id'])
+ self.alt_compute_images_client.show_image,
+ self.image['id'])
@test.idempotent_id('9facb962-f043-4a9d-b9ee-166a32dea098')
def test_delete_image_for_alt_account_fails(self):
# A DELETE request for another user's image should fail
self.assertRaises(lib_exc.NotFound,
- self.alt_images_client.delete_image,
+ self.alt_compute_images_client.delete_image,
self.image['id'])
@test.idempotent_id('752c917e-83be-499d-a422-3559127f7d3c')
@@ -391,7 +392,7 @@
# A set metadata for another user's image should fail
req_metadata = {'meta1': 'value1', 'meta2': 'value2'}
self.assertRaises(lib_exc.NotFound,
- self.alt_images_client.set_image_metadata,
+ self.alt_compute_images_client.set_image_metadata,
self.image['id'], req_metadata)
@test.idempotent_id('dea1936a-473d-49f2-92ad-97bb7aded22e')
@@ -409,13 +410,14 @@
def test_get_metadata_of_alt_account_image_fails(self):
# A get metadata for another user's image should fail
req_metadata = {'meta1': 'value1'}
- self.addCleanup(self.images_client.delete_image_metadata_item,
+ self.addCleanup(self.compute_images_client.delete_image_metadata_item,
self.image['id'], 'meta1')
- self.images_client.set_image_metadata(self.image['id'],
- req_metadata)
- self.assertRaises(lib_exc.NotFound,
- self.alt_images_client.show_image_metadata_item,
- self.image['id'], 'meta1')
+ self.compute_images_client.set_image_metadata(self.image['id'],
+ req_metadata)
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.alt_compute_images_client.show_image_metadata_item,
+ self.image['id'], 'meta1')
@test.idempotent_id('79531e2e-e721-493c-8b30-a35db36fdaa6')
def test_delete_metadata_of_alt_account_server_fails(self):
@@ -432,13 +434,14 @@
def test_delete_metadata_of_alt_account_image_fails(self):
# A delete metadata for another user's image should fail
req_metadata = {'meta1': 'data1'}
- self.addCleanup(self.images_client.delete_image_metadata_item,
+ self.addCleanup(self.compute_images_client.delete_image_metadata_item,
self.image['id'], 'meta1')
- self.images_client.set_image_metadata(self.image['id'],
- req_metadata)
- self.assertRaises(lib_exc.NotFound,
- self.alt_images_client.delete_image_metadata_item,
- self.image['id'], 'meta1')
+ self.compute_images_client.set_image_metadata(self.image['id'],
+ req_metadata)
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.alt_compute_images_client.delete_image_metadata_item,
+ self.image['id'], 'meta1')
@test.idempotent_id('b0c1e7a0-8853-40fd-8384-01f93d116cae')
def test_get_console_output_of_alt_account_server_fails(self):
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index b4837f7..468c79a 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -75,7 +75,7 @@
# Create a volume and wait for it to become ready
self.volume = self.volumes_client.create_volume(
- CONF.volume.volume_size, display_name='test')['volume']
+ size=CONF.volume.volume_size, display_name='test')['volume']
self.addCleanup(self._delete_volume)
self.volumes_client.wait_for_volume_status(self.volume['id'],
'available')
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index c3205ce..18d0446 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -62,18 +62,12 @@
@classmethod
def create_image(cls, **kwargs):
"""Wrapper that returns a test image."""
- name = data_utils.rand_name(cls.__name__ + "-instance")
- if 'name' in kwargs:
- name = kwargs.pop('name')
+ if 'name' not in kwargs:
+ name = data_utils.rand_name(cls.__name__ + "-instance")
+ kwargs['name'] = name
- container_format = kwargs.pop('container_format')
- disk_format = kwargs.pop('disk_format')
-
- image = cls.client.create_image(name=name,
- container_format=container_format,
- disk_format=disk_format,
- **kwargs)
+ image = cls.client.create_image(**kwargs)
# Image objects returned by the v1 client have the image
# data inside a dict that is keyed against 'image'.
if 'image' in image:
diff --git a/tempest/api/image/v1/test_images_negative.py b/tempest/api/image/v1/test_images_negative.py
index 3d94408..f16b80e 100644
--- a/tempest/api/image/v1/test_images_negative.py
+++ b/tempest/api/image/v1/test_images_negative.py
@@ -27,13 +27,17 @@
def test_register_with_invalid_container_format(self):
# Negative tests for invalid data supplied to POST /images
self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- 'test', 'wrong', 'vhd')
+ name='test',
+ container_format='wrong',
+ disk_format='vhd',)
@test.attr(type=['negative'])
@test.idempotent_id('993face5-921d-4e84-aabf-c1bba4234a67')
def test_register_with_invalid_disk_format(self):
self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- 'test', 'bare', 'wrong')
+ name='test',
+ container_format='bare',
+ disk_format='wrong',)
@test.attr(type=['negative'])
@test.idempotent_id('bb016f15-0820-4f27-a92d-09b2f67d2488')
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index 2e8fd50..c64cf77 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -14,9 +14,11 @@
from tempest.api.network import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import exceptions
from tempest import test
+CONF = config.CONF
AGENT_TYPE = 'L3 agent'
AGENT_MODES = (
'legacy',
@@ -80,6 +82,19 @@
cls.port = cls.create_port(cls.network)
cls.client.add_router_interface_with_port_id(
cls.router['id'], cls.port['id'])
+ # NOTE: Sometimes we have seen this test fail with dvr in,
+ # multinode tests, since the dhcp port is not created before
+ # the test gets executed and so the router is not scheduled
+ # on the given agent. By adding the external gateway info to
+ # the router, the router should be properly scheduled in the
+ # dvr_snat node.
+ # This is a temporary work around to prevent a race condition.
+ external_gateway_info = {
+ 'network_id': CONF.network.public_network_id,
+ 'enable_snat': True}
+ cls.admin_client.update_router_with_snat_gw_info(
+ cls.router['id'],
+ external_gateway_info=external_gateway_info)
@classmethod
def resource_cleanup(cls):
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index acb591d..c032d9c 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -70,7 +70,7 @@
# Update volume with new volume_type
self.volumes_client.retype_volume(volume['id'],
- volume_type=volume_types[1]['id'])
+ new_type=volume_types[1]['id'])
self.volumes_client.wait_for_volume_status(volume['id'], 'available')
# Get volume details and Verify
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 6c32321..253a3e1 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -48,12 +48,12 @@
def _reset_volume_status(self, volume_id, status):
# Reset the volume status
body = self.admin_volume_client.reset_volume_status(volume_id,
- status)
+ status=status)
return body
def tearDown(self):
# Set volume's status to available after test
- self._reset_volume_status(self.volume['id'], 'available')
+ self._reset_volume_status(self.volume['id'], status='available')
super(VolumesActionsV2Test, self).tearDown()
def _create_temp_volume(self):
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 5c4d0e1..dc53450 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -62,7 +62,7 @@
super(BaseVolumeTest, cls).setup_clients()
cls.servers_client = cls.os.servers_client
cls.compute_networks_client = cls.os.compute_networks_client
- cls.images_client = cls.os.images_client
+ cls.compute_images_client = cls.os.compute_images_client
if cls._api_version == 1:
cls.snapshots_client = cls.os.snapshots_client
@@ -106,14 +106,14 @@
super(BaseVolumeTest, cls).resource_cleanup()
@classmethod
- def create_volume(cls, size=None, **kwargs):
+ def create_volume(cls, **kwargs):
"""Wrapper utility that returns a test volume."""
name = data_utils.rand_name('Volume')
name_field = cls.special_fields['name_field']
kwargs[name_field] = name
- volume = cls.volumes_client.create_volume(size, **kwargs)['volume']
+ volume = cls.volumes_client.create_volume(**kwargs)['volume']
cls.volumes.append(volume)
cls.volumes_client.wait_for_volume_status(volume['id'], 'available')
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index c0b6b7e..7046dcf 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -47,7 +47,8 @@
self.addCleanup(self._delete_volume, volume['id'])
# Create a volume transfer
- transfer = self.client.create_volume_transfer(volume['id'])['transfer']
+ transfer = self.client.create_volume_transfer(
+ volume_id=volume['id'])['transfer']
transfer_id = transfer['id']
auth_key = transfer['auth_key']
self.client.wait_for_volume_status(volume['id'],
@@ -63,8 +64,8 @@
self.assertThat(len(body), matchers.GreaterThan(0))
# Accept a volume transfer by alt_tenant
- body = self.alt_client.accept_volume_transfer(transfer_id,
- auth_key)['transfer']
+ body = self.alt_client.accept_volume_transfer(
+ transfer_id, auth_key=auth_key)['transfer']
self.alt_client.wait_for_volume_status(volume['id'], 'available')
@test.idempotent_id('ab526943-b725-4c07-b875-8e8ef87a2c30')
@@ -74,7 +75,8 @@
self.addCleanup(self._delete_volume, volume['id'])
# Create a volume transfer
- body = self.client.create_volume_transfer(volume['id'])['transfer']
+ body = self.client.create_volume_transfer(
+ volume_id=volume['id'])['transfer']
transfer_id = body['id']
self.client.wait_for_volume_status(volume['id'],
'awaiting-transfer')
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index d4636ee..5f9ea7f 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -62,8 +62,8 @@
# Volume is attached and detached successfully from an instance
mountpoint = '/dev/vdc'
self.client.attach_volume(self.volume['id'],
- self.server['id'],
- mountpoint)
+ instance_uuid=self.server['id'],
+ mountpoint=mountpoint)
self.client.wait_for_volume_status(self.volume['id'], 'in-use')
self.client.detach_volume(self.volume['id'])
self.client.wait_for_volume_status(self.volume['id'], 'available')
@@ -74,7 +74,8 @@
def test_volume_bootable(self):
# Verify that a volume bootable flag is retrieved
for bool_bootable in [True, False]:
- self.client.set_bootable_volume(self.volume['id'], bool_bootable)
+ self.client.set_bootable_volume(self.volume['id'],
+ bootable=bool_bootable)
fetched_volume = self.client.show_volume(
self.volume['id'])['volume']
# Get Volume information
@@ -88,8 +89,8 @@
# Verify that a volume's attachment information is retrieved
mountpoint = '/dev/vdc'
self.client.attach_volume(self.volume['id'],
- self.server['id'],
- mountpoint)
+ instance_uuid=self.server['id'],
+ mountpoint=mountpoint)
self.client.wait_for_volume_status(self.volume['id'], 'in-use')
# NOTE(gfidente): added in reverse order because functions will be
# called in reverse order to the order they are added (LIFO)
@@ -114,8 +115,8 @@
# using the Glance image_client and from Cinder via tearDownClass.
image_name = data_utils.rand_name('Image')
body = self.client.upload_volume(
- self.volume['id'], image_name,
- CONF.volume.disk_format)['os-volume_upload_image']
+ self.volume['id'], image_name=image_name,
+ disk_format=CONF.volume.disk_format)['os-volume_upload_image']
image_id = body["image_id"]
self.addCleanup(self.image_client.delete_image, image_id)
self.image_client.wait_for_image_status(image_id, 'active')
@@ -142,7 +143,7 @@
# Update volume readonly true
readonly = True
self.client.update_volume_readonly(self.volume['id'],
- readonly)
+ readonly=readonly)
# Get Volume information
fetched_volume = self.client.show_volume(self.volume['id'])['volume']
bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
@@ -150,7 +151,8 @@
# Update volume readonly false
readonly = False
- self.client.update_volume_readonly(self.volume['id'], readonly)
+ self.client.update_volume_readonly(self.volume['id'],
+ readonly=readonly)
# Get Volume information
fetched_volume = self.client.show_volume(self.volume['id'])['volume']
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index 78f5571..ed1e5c5 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -32,7 +32,7 @@
# Extend Volume Test.
self.volume = self.create_volume()
extend_size = int(self.volume['size']) + 1
- self.client.extend_volume(self.volume['id'], extend_size)
+ self.client.extend_volume(self.volume['id'], new_size=extend_size)
self.client.wait_for_volume_status(self.volume['id'], 'available')
volume = self.client.show_volume(self.volume['id'])['volume']
self.assertEqual(int(volume['size']), extend_size)
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 35c8898..aa3ef2f 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -133,7 +133,8 @@
@test.idempotent_id('54a01030-c7fc-447c-86ee-c1182beae638')
@test.services('image')
def test_volume_create_get_update_delete_from_image(self):
- image = self.images_client.show_image(CONF.compute.image_ref)['image']
+ image = self.compute_images_client.show_image(
+ CONF.compute.image_ref)['image']
min_disk = image.get('minDisk')
disk_size = max(min_disk, CONF.volume.volume_size)
self._volume_create_get_update_delete(
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 0af40ea..ad6f556 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -190,8 +190,8 @@
self.assertRaises(lib_exc.NotFound,
self.client.attach_volume,
str(uuid.uuid4()),
- server['id'],
- self.mountpoint)
+ instance_uuid=server['id'],
+ mountpoint=self.mountpoint)
@test.attr(type=['negative'])
@test.idempotent_id('9f9c24e4-011d-46b5-b992-952140ce237a')
@@ -206,7 +206,7 @@
# Extend volume with smaller size than original size.
extend_size = 0
self.assertRaises(lib_exc.BadRequest, self.client.extend_volume,
- self.volume['id'], extend_size)
+ self.volume['id'], new_size=extend_size)
@test.attr(type=['negative'])
@test.idempotent_id('5d0b480d-e833-439f-8a5a-96ad2ed6f22f')
@@ -214,7 +214,7 @@
# Extend volume when size is non number.
extend_size = 'abc'
self.assertRaises(lib_exc.BadRequest, self.client.extend_volume,
- self.volume['id'], extend_size)
+ self.volume['id'], new_size=extend_size)
@test.attr(type=['negative'])
@test.idempotent_id('355218f1-8991-400a-a6bb-971239287d92')
@@ -222,7 +222,7 @@
# Extend volume with None size.
extend_size = None
self.assertRaises(lib_exc.BadRequest, self.client.extend_volume,
- self.volume['id'], extend_size)
+ self.volume['id'], new_size=extend_size)
@test.attr(type=['negative'])
@test.idempotent_id('8f05a943-013c-4063-ac71-7baf561e82eb')
@@ -230,7 +230,7 @@
# Extend volume size when volume is nonexistent.
extend_size = int(self.volume['size']) + 1
self.assertRaises(lib_exc.NotFound, self.client.extend_volume,
- str(uuid.uuid4()), extend_size)
+ str(uuid.uuid4()), new_size=extend_size)
@test.attr(type=['negative'])
@test.idempotent_id('aff8ba64-6d6f-4f2e-bc33-41a08ee9f115')
@@ -238,7 +238,7 @@
# Extend volume size when passing volume id is None.
extend_size = int(self.volume['size']) + 1
self.assertRaises(lib_exc.NotFound, self.client.extend_volume,
- None, extend_size)
+ None, new_size=extend_size)
@test.attr(type=['negative'])
@test.idempotent_id('ac6084c0-0546-45f9-b284-38a367e0e0e2')
diff --git a/tempest/clients.py b/tempest/clients.py
index 0496002..333852e 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -398,7 +398,8 @@
self.server_groups_client = ServerGroupsClient(
self.auth_provider, **params)
self.limits_client = LimitsClient(self.auth_provider, **params)
- self.images_client = ComputeImagesClient(self.auth_provider, **params)
+ self.compute_images_client = ComputeImagesClient(self.auth_provider,
+ **params)
self.keypairs_client = KeyPairsClient(self.auth_provider, **params)
self.quotas_client = QuotasClient(self.auth_provider, **params)
self.quota_classes_client = QuotaClassesClient(self.auth_provider,
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 2aeb5b1..8538509 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -775,7 +775,7 @@
class ImageService(BaseService):
def __init__(self, manager, **kwargs):
super(ImageService, self).__init__(kwargs)
- self.client = manager.images_client
+ self.client = manager.compute_images_client
def list(self):
client = self.client
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 6dfa0a7..9d889bd 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -1023,7 +1023,9 @@
server_id = _get_server_by_name(client, volume['server'])['id']
volume_id = _get_volume_by_name(client, volume['name'])['id']
device = volume['device']
- client.volumes.attach_volume(volume_id, server_id, device)
+ client.volumes.attach_volume(volume_id,
+ instance_uuid=server_id,
+ mountpoint=device)
#######################
diff --git a/tempest/cmd/list_plugins.py b/tempest/cmd/list_plugins.py
new file mode 100644
index 0000000..1f1ff1a
--- /dev/null
+++ b/tempest/cmd/list_plugins.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+# 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.
+
+"""
+Utility for listing all currently installed Tempest plugins.
+
+**Usage:** ``tempest list-plugins``.
+"""
+
+from cliff import command
+from oslo_log import log as logging
+import prettytable
+
+from tempest.test_discover.plugins import TempestTestPluginManager
+
+LOG = logging.getLogger(__name__)
+
+
+class TempestListPlugins(command.Command):
+ def take_action(self, parsed_args):
+ self._list_plugins()
+ return 0
+
+ def get_description(self):
+ return 'List all tempest plugins'
+
+ def _list_plugins(self):
+ plugins = TempestTestPluginManager()
+
+ output = prettytable.PrettyTable(["Name", "EntryPoint"])
+ for plugin in plugins.ext_plugins.extensions:
+ output.add_row([
+ plugin.name, plugin.entry_point_target])
+
+ print(output)
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 5a14fbe..6e6ada8 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -48,11 +48,7 @@
# TODO(jlanoux) add support of wait_until PINGABLE/SSHABLE
- if 'name' in kwargs:
- name = kwargs.pop('name')
- else:
- name = data_utils.rand_name(__name__ + "-instance")
-
+ name = kwargs.pop('name', data_utils.rand_name(__name__ + "-instance"))
flavor = kwargs.pop('flavor', CONF.compute.flavor_ref)
image_id = kwargs.pop('image_id', CONF.compute.image_ref)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index eb5ea16..bb4e521 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -49,10 +49,11 @@
cls.flavors_client = cls.manager.flavors_client
cls.compute_floating_ips_client = (
cls.manager.compute_floating_ips_client)
- # Glance image client v1
- cls.image_client = cls.manager.image_client
+ if CONF.service_available.glance:
+ # Glance image client v1
+ cls.image_client = cls.manager.image_client
# Compute image client
- cls.images_client = cls.manager.images_client
+ cls.compute_images_client = cls.manager.compute_images_client
cls.keypairs_client = cls.manager.keypairs_client
# Nova security groups client
cls.compute_security_groups_client = (
@@ -260,9 +261,13 @@
imageRef=None, volume_type=None, wait_on_delete=True):
if name is None:
name = data_utils.rand_name(self.__class__.__name__)
- volume = self.volumes_client.create_volume(
- size=size, display_name=name, snapshot_id=snapshot_id,
- imageRef=imageRef, volume_type=volume_type)['volume']
+ kwargs = {'display_name': name,
+ 'snapshot_id': snapshot_id,
+ 'imageRef': imageRef,
+ 'volume_type': volume_type}
+ if size is not None:
+ kwargs.update({'size': size})
+ volume = self.volumes_client.create_volume(**kwargs)['volume']
if wait_on_delete:
self.addCleanup(self.volumes_client.wait_for_resource_deletion,
@@ -344,17 +349,13 @@
return secgroup
- def get_remote_client(self, server_or_ip, username=None, private_key=None,
- log_console_of_servers=None):
+ def get_remote_client(self, server_or_ip, username=None, private_key=None):
"""Get a SSH client to a remote server
@param server_or_ip a server object as returned by Tempest compute
client or an IP address to connect to
@param username name of the Linux account on the remote server
@param private_key the SSH private key to use
- @param log_console_of_servers a list of server objects. Each server
- in the list will have its console printed in the logs in case the
- SSH connection failed to be established
@return a RemoteClient object
"""
if isinstance(server_or_ip, six.string_types):
@@ -391,10 +392,7 @@
if caller:
message = '(%s) %s' % (caller, message)
LOG.exception(message)
- # If we don't explicitly set for which servers we want to
- # log the console output then all the servers will be logged.
- # See the definition of _log_console_output()
- self._log_console_output(log_console_of_servers)
+ self._log_console_output()
raise
return linux_client
@@ -471,7 +469,7 @@
# Glance client
_image_client = self.image_client
# Compute client
- _images_client = self.images_client
+ _images_client = self.compute_images_client
if name is None:
name = data_utils.rand_name('scenario-snapshot')
LOG.debug("Creating a snapshot image for server: %s", server['name'])
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index fa7c0c9..3cbb3bc 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -40,11 +40,11 @@
self.non_ssh_image_pattern = \
CONF.input_scenario.non_ssh_image_regex
# Setup clients
- self.images_client = os.images_client
+ self.compute_images_client = os.compute_images_client
self.flavors_client = os.flavors_client
def ssh_user(self, image_id):
- _image = self.images_client.show_image(image_id)['image']
+ _image = self.compute_images_client.show_image(image_id)['image']
for regex, user in self.ssh_users:
# First match wins
if re.match(regex, _image['name']) is not None:
@@ -57,14 +57,14 @@
string=str(image['name']))
def is_sshable_image(self, image_id):
- _image = self.images_client.show_image(image_id)['image']
+ _image = self.compute_images_client.show_image(image_id)['image']
return self._is_sshable_image(_image)
def _is_flavor_enough(self, flavor, image):
return image['minDisk'] <= flavor['disk']
def is_flavor_enough(self, flavor_id, image_id):
- _image = self.images_client.show_image(image_id)['image']
+ _image = self.compute_images_client.show_image(image_id)['image']
_flavor = self.flavors_client.show_flavor(flavor_id)['flavor']
return self._is_flavor_enough(_flavor, _image)
@@ -108,7 +108,7 @@
identity_version=CONF.identity.auth_version,
network_resources=network_resources)
os = clients.Manager(self.cred_provider.get_primary_creds())
- self.images_client = os.images_client
+ self.compute_images_client = os.compute_images_client
self.flavors_client = os.flavors_client
self.image_pattern = CONF.input_scenario.image_regex
self.flavor_pattern = CONF.input_scenario.flavor_regex
@@ -128,7 +128,7 @@
return []
if not hasattr(self, '_scenario_images'):
try:
- images = self.images_client.list_images()['images']
+ images = self.compute_images_client.list_images()['images']
self._scenario_images = [
(self._normalize_name(i['name']), dict(image_ref=i['id']))
for i in images if re.search(self.image_pattern,
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index 3406db8..5b6a394 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -147,50 +147,29 @@
self._http = self._get_http()
return self._http
- def create_image(self, name, container_format, disk_format, **kwargs):
- params = {
- "name": name,
- "container_format": container_format,
- "disk_format": disk_format,
- }
-
+ def create_image(self, **kwargs):
headers = {}
+ data = kwargs.pop('data', None)
+ headers.update(self._image_meta_to_headers(kwargs))
- for option in ['is_public', 'location', 'properties',
- 'copy_from', 'min_ram']:
- if option in kwargs:
- params[option] = kwargs.get(option)
-
- headers.update(self._image_meta_to_headers(params))
-
- if 'data' in kwargs:
- return self._create_with_data(headers, kwargs.get('data'))
+ if data is not None:
+ return self._create_with_data(headers, data)
resp, body = self.post('v1/images', None, headers)
self.expected_success(201, resp.status)
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def update_image(self, image_id, name=None, container_format=None,
- data=None, properties=None):
- params = {}
+ def update_image(self, image_id, **kwargs):
headers = {}
- if name is not None:
- params['name'] = name
-
- if container_format is not None:
- params['container_format'] = container_format
-
- if properties is not None:
- params['properties'] = properties
-
- headers.update(self._image_meta_to_headers(params))
+ data = kwargs.pop('data', None)
+ headers.update(self._image_meta_to_headers(kwargs))
if data is not None:
return self._update_with_data(image_id, headers, data)
url = 'v1/images/%s' % image_id
- resp, body = self.put(url, data, headers)
+ resp, body = self.put(url, None, headers)
self.expected_success(200, resp.status)
body = json.loads(body)
return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/volume/base/base_volumes_client.py b/tempest/services/volume/base/base_volumes_client.py
index c7302e8..d4435bc 100644
--- a/tempest/services/volume/base/base_volumes_client.py
+++ b/tempest/services/volume/base/base_volumes_client.py
@@ -71,23 +71,15 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def create_volume(self, size=None, **kwargs):
+ def create_volume(self, **kwargs):
"""Creates a new Volume.
- size: Size of volume in GB.
- Following optional keyword arguments are accepted:
- display_name: Optional Volume Name(only for V1).
- name: Optional Volume Name(only for V2).
- metadata: A dictionary of values to be used as metadata.
- volume_type: Optional Name of volume_type for the volume
- snapshot_id: When specified the volume is created from this snapshot
- imageRef: When specified the volume is created from this image
+ Available params: see http://developer.openstack.org/
+ api-ref-blockstorage-v2.html#createVolume
"""
- if size is None:
- size = self.default_volume_size
- post_body = {'size': size}
- post_body.update(kwargs)
- post_body = json.dumps({'volume': post_body})
+ if 'size' not in kwargs:
+ kwargs['size'] = self.default_volume_size
+ post_body = json.dumps({'volume': kwargs})
resp, body = self.post('volumes', post_body)
body = json.loads(body)
self.expected_success(self.create_resp, resp.status)
@@ -107,35 +99,26 @@
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def upload_volume(self, volume_id, image_name, disk_format):
+ def upload_volume(self, volume_id, **kwargs):
"""Uploads a volume in Glance."""
- post_body = {
- 'image_name': image_name,
- 'disk_format': disk_format
- }
- post_body = json.dumps({'os-volume_upload_image': post_body})
+ post_body = json.dumps({'os-volume_upload_image': kwargs})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def attach_volume(self, volume_id, instance_uuid, mountpoint):
+ def attach_volume(self, volume_id, **kwargs):
"""Attaches a volume to a given instance on a given mountpoint."""
- post_body = {
- 'instance_uuid': instance_uuid,
- 'mountpoint': mountpoint,
- }
- post_body = json.dumps({'os-attach': post_body})
+ post_body = json.dumps({'os-attach': kwargs})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def set_bootable_volume(self, volume_id, bootable):
+ def set_bootable_volume(self, volume_id, **kwargs):
"""set a bootable flag for a volume - true or false."""
- post_body = {"bootable": bootable}
- post_body = json.dumps({'os-set_bootable': post_body})
+ post_body = json.dumps({'os-set_bootable': kwargs})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
self.expected_success(200, resp.status)
@@ -143,8 +126,7 @@
def detach_volume(self, volume_id):
"""Detaches a volume from an instance."""
- post_body = {}
- post_body = json.dumps({'os-detach': post_body})
+ post_body = json.dumps({'os-detach': {}})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
self.expected_success(202, resp.status)
@@ -152,8 +134,7 @@
def reserve_volume(self, volume_id):
"""Reserves a volume."""
- post_body = {}
- post_body = json.dumps({'os-reserve': post_body})
+ post_body = json.dumps({'os-reserve': {}})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
self.expected_success(202, resp.status)
@@ -161,8 +142,7 @@
def unreserve_volume(self, volume_id):
"""Restore a reserved volume ."""
- post_body = {}
- post_body = json.dumps({'os-unreserve': post_body})
+ post_body = json.dumps({'os-unreserve': {}})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
self.expected_success(202, resp.status)
@@ -184,20 +164,17 @@
"""Returns the primary type of resource this client works with."""
return 'volume'
- def extend_volume(self, volume_id, extend_size):
+ def extend_volume(self, volume_id, **kwargs):
"""Extend a volume."""
- post_body = {
- 'new_size': extend_size
- }
- post_body = json.dumps({'os-extend': post_body})
+ post_body = json.dumps({'os-extend': kwargs})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def reset_volume_status(self, volume_id, status):
+ def reset_volume_status(self, volume_id, **kwargs):
"""Reset the Specified Volume's Status."""
- post_body = json.dumps({'os-reset_status': {"status": status}})
+ post_body = json.dumps({'os-reset_status': kwargs})
resp, body = self.post('volumes/%s/action' % volume_id, post_body)
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
@@ -218,14 +195,9 @@
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def create_volume_transfer(self, vol_id, display_name=None):
+ def create_volume_transfer(self, **kwargs):
"""Create a volume transfer."""
- post_body = {
- 'volume_id': vol_id
- }
- if display_name:
- post_body['name'] = display_name
- post_body = json.dumps({'transfer': post_body})
+ post_body = json.dumps({'transfer': kwargs})
resp, body = self.post('os-volume-transfer', post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
@@ -239,7 +211,7 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def list_volume_transfers(self, params=None):
+ def list_volume_transfers(self, **params):
"""List all the volume transfers created."""
url = 'os-volume-transfer'
if params:
@@ -255,24 +227,18 @@
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def accept_volume_transfer(self, transfer_id, transfer_auth_key):
+ def accept_volume_transfer(self, transfer_id, **kwargs):
"""Accept a volume transfer."""
- post_body = {
- 'auth_key': transfer_auth_key,
- }
url = 'os-volume-transfer/%s/accept' % transfer_id
- post_body = json.dumps({'accept': post_body})
+ post_body = json.dumps({'accept': kwargs})
resp, body = self.post(url, post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
return service_client.ResponseBody(resp, body)
- def update_volume_readonly(self, volume_id, readonly):
+ def update_volume_readonly(self, volume_id, **kwargs):
"""Update the Specified Volume readonly."""
- post_body = {
- 'readonly': readonly
- }
- post_body = json.dumps({'os-update_readonly_flag': post_body})
+ post_body = json.dumps({'os-update_readonly_flag': kwargs})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
self.expected_success(202, resp.status)
@@ -327,10 +293,8 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def retype_volume(self, volume_id, volume_type, **kwargs):
+ def retype_volume(self, volume_id, **kwargs):
"""Updates volume with new volume type."""
- post_body = {'new_type': volume_type}
- post_body.update(kwargs)
- post_body = json.dumps({'os-retype': post_body})
+ post_body = json.dumps({'os-retype': kwargs})
resp, body = self.post('volumes/%s/action' % volume_id, post_body)
self.expected_success(202, resp.status)
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 56bc96c..62409bf 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -78,8 +78,8 @@
mocked_function = self.fake_client.volumes.attach_volume
mocked_function.assert_called_once_with(
self.fake_object.volume['id'],
- self.fake_object.server['id'],
- self.fake_object['device'])
+ instance_uuid=self.fake_object.server['id'],
+ mountpoint=self.fake_object['device'])
class TestCreateResources(JavelinUnitTest):
diff --git a/tempest/tests/cmd/test_list_plugins.py b/tempest/tests/cmd/test_list_plugins.py
new file mode 100644
index 0000000..17ddb18
--- /dev/null
+++ b/tempest/tests/cmd/test_list_plugins.py
@@ -0,0 +1,24 @@
+# Copyright 2015 Hewlett-Packard 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.
+
+import subprocess
+
+from tempest.tests import base
+
+
+class TestTempestListPlugins(base.TestCase):
+ def test_run_list_plugins(self):
+ return_code = subprocess.call(
+ ['tempest', 'list-plugins'], stdout=subprocess.PIPE)
+ self.assertEqual(return_code, 0)