Merge "Update volume and volume transfer schema"
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 0ed73a8..a69dbb3 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -43,7 +43,7 @@
super(ServerActionsTestJSON, self).setUp()
# Check if the server is in a clean state after test
try:
- validation_resources = self.get_class_validation_resources(
+ self.validation_resources = self.get_class_validation_resources(
self.os_primary)
# _test_rebuild_server test compares ip address attached to the
# server before and after the rebuild, in order to avoid
@@ -53,18 +53,18 @@
waiters.wait_for_server_floating_ip(
self.client,
self.client.show_server(self.server_id)['server'],
- validation_resources['floating_ip'])
+ self.validation_resources['floating_ip'])
waiters.wait_for_server_status(self.client,
self.server_id, 'ACTIVE')
except lib_exc.NotFound:
# The server was deleted by previous test, create a new one
# Use class level validation resources to avoid them being
# deleted once a test is over
- validation_resources = self.get_class_validation_resources(
+ self.validation_resources = self.get_class_validation_resources(
self.os_primary)
server = self.create_test_server(
validatable=True,
- validation_resources=validation_resources,
+ validation_resources=self.validation_resources,
wait_until='SSHABLE')
self.__class__.server_id = server['id']
except Exception:
@@ -106,11 +106,9 @@
"""
# Since this test messes with the password and makes the
# server unreachable, it should create its own server
- validation_resources = self.get_test_validation_resources(
- self.os_primary)
newserver = self.create_test_server(
validatable=True,
- validation_resources=validation_resources,
+ validation_resources=self.validation_resources,
wait_until='ACTIVE')
self.addCleanup(self.delete_server, newserver['id'])
# The server's password should be set to the provided password
@@ -122,7 +120,7 @@
# Verify that the user can authenticate with the new password
server = self.client.show_server(newserver['id'])['server']
linux_client = remote_client.RemoteClient(
- self.get_server_ip(server, validation_resources),
+ self.get_server_ip(server, self.validation_resources),
self.ssh_user,
new_password,
server=server,
@@ -131,15 +129,13 @@
def _test_reboot_server(self, reboot_type):
if CONF.validation.run_validation:
- validation_resources = self.get_class_validation_resources(
- self.os_primary)
# Get the time the server was last rebooted,
server = self.client.show_server(self.server_id)['server']
linux_client = remote_client.RemoteClient(
- self.get_server_ip(server, validation_resources),
+ self.get_server_ip(server, self.validation_resources),
self.ssh_user,
self.password,
- validation_resources['keypair']['private_key'],
+ self.validation_resources['keypair']['private_key'],
server=server,
servers_client=self.client)
boot_time = linux_client.get_boot_time()
@@ -153,10 +149,10 @@
if CONF.validation.run_validation:
# Log in and verify the boot time has changed
linux_client = remote_client.RemoteClient(
- self.get_server_ip(server, validation_resources),
+ self.get_server_ip(server, self.validation_resources),
self.ssh_user,
self.password,
- validation_resources['keypair']['private_key'],
+ self.validation_resources['keypair']['private_key'],
server=server,
servers_client=self.client)
new_boot_time = linux_client.get_boot_time()
@@ -185,10 +181,18 @@
server = self.client.show_server(server['id'])['server']
self.assertNotIn('security_groups', server)
- def _rebuild_server_and_check(self, image_ref):
- rebuilt_server = (self.client.rebuild_server(self.server_id, image_ref)
+ def _rebuild_server_and_check(self, image_ref, server):
+ rebuilt_server = (self.client.rebuild_server(server['id'], image_ref)
['server'])
- waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+ if CONF.validation.run_validation:
+ tenant_network = self.get_tenant_network()
+ compute.wait_for_ssh_or_ping(
+ server, self.os_primary, tenant_network,
+ True, self.validation_resources, "SSHABLE", True)
+ else:
+ waiters.wait_for_server_status(self.client, self.server['id'],
+ 'ACTIVE')
+
msg = ('Server was not rebuilt to the original image. '
'The original image: {0}. The current image: {1}'
.format(image_ref, rebuilt_server['image']['id']))
@@ -212,7 +216,8 @@
# If the server was rebuilt on a different image, restore it to the
# original image once the test ends
if self.image_ref_alt != self.image_ref:
- self.addCleanup(self._rebuild_server_and_check, self.image_ref)
+ self.addCleanup(self._rebuild_server_and_check, self.image_ref,
+ rebuilt_server)
# Verify the properties in the initial response are correct
self.assertEqual(self.server_id, rebuilt_server['id'])
@@ -230,8 +235,6 @@
self.assertEqual(original_addresses, server['addresses'])
if CONF.validation.run_validation:
- validation_resources = self.get_class_validation_resources(
- self.os_primary)
# Authentication is attempted in the following order of priority:
# 1.The key passed in, if one was passed in.
# 2.Any key we can find through an SSH agent (if allowed).
@@ -239,10 +242,10 @@
# ~/.ssh/ (if allowed).
# 4.Plain username/password auth, if a password was given.
linux_client = remote_client.RemoteClient(
- self.get_server_ip(rebuilt_server, validation_resources),
+ self.get_server_ip(rebuilt_server, self.validation_resources),
self.ssh_alt_user,
password,
- validation_resources['keypair']['private_key'],
+ self.validation_resources['keypair']['private_key'],
server=rebuilt_server,
servers_client=self.client)
linux_client.validate_authentication()
@@ -273,7 +276,7 @@
# If the server was rebuilt on a different image, restore it to the
# original image once the test ends
if self.image_ref_alt != self.image_ref:
- self.addCleanup(self._rebuild_server_and_check, old_image)
+ self.addCleanup(self._rebuild_server_and_check, old_image, server)
# Verify the properties in the initial response are correct
self.assertEqual(self.server_id, rebuilt_server['id'])
@@ -318,13 +321,11 @@
self.assertEqual(self.server_id,
vol_after_rebuild['attachments'][0]['server_id'])
if CONF.validation.run_validation:
- validation_resources = self.get_class_validation_resources(
- self.os_primary)
linux_client = remote_client.RemoteClient(
- self.get_server_ip(server, validation_resources),
+ self.get_server_ip(server, self.validation_resources),
self.ssh_alt_user,
password=None,
- pkey=validation_resources['keypair']['private_key'],
+ pkey=self.validation_resources['keypair']['private_key'],
server=server,
servers_client=self.client)
linux_client.validate_authentication()
@@ -376,10 +377,8 @@
kwargs = {'volume_backed': True,
'wait_until': 'ACTIVE'}
if CONF.validation.run_validation:
- validation_resources = self.get_test_validation_resources(
- self.os_primary)
kwargs.update({'validatable': True,
- 'validation_resources': validation_resources})
+ 'validation_resources': self.validation_resources})
server = self.create_test_server(**kwargs)
# NOTE(mgoddard): Get detailed server to ensure addresses are present
@@ -395,10 +394,10 @@
self.client.get_console_output(server['id'])
if CONF.validation.run_validation:
linux_client = remote_client.RemoteClient(
- self.get_server_ip(server, validation_resources),
+ self.get_server_ip(server, self.validation_resources),
self.ssh_user,
password=None,
- pkey=validation_resources['keypair']['private_key'],
+ pkey=self.validation_resources['keypair']['private_key'],
server=server,
servers_client=self.client)
linux_client.validate_authentication()
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index d283ab3..96031ac 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -131,7 +131,7 @@
# import image from web to backend
image_uri = CONF.image.http_image
self.client.image_import(image['id'], method='web-download',
- image_uri=image_uri)
+ import_params={'uri': image_uri})
waiters.wait_for_image_imported_to_stores(self.client, image['id'])
@decorators.idempotent_id('e04761a1-22af-42c2-b8bc-a34a3f12b585')
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index a3802a9..80c01a5 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -206,7 +206,7 @@
# import image from web to backend
image_uri = 'http://does-not.exist/no/possible/way'
self.client.image_import(image['id'], method='web-download',
- image_uri=image_uri,
+ import_params={'uri': image_uri},
stores=[stores[0]['id']])
start_time = int(time.time())
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 8d8039b..7107dc4 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -16,6 +16,7 @@
import time
from tempest.common import custom_matchers
+from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions as lib_exc
@@ -124,6 +125,9 @@
object_name,
data,
metadata=metadata)
+ waiters.wait_for_object_create(cls.object_client,
+ container_name,
+ object_name)
return object_name, data
# after bucket creation we might see Conflict
except lib_exc.Conflict as e:
diff --git a/tempest/api/object_storage/test_container_quotas.py b/tempest/api/object_storage/test_container_quotas.py
index 7977a7a..fb67fb4 100644
--- a/tempest/api/object_storage/test_container_quotas.py
+++ b/tempest/api/object_storage/test_container_quotas.py
@@ -15,6 +15,7 @@
from tempest.api.object_storage import base
from tempest.common import utils
+from tempest.common import waiters
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -91,6 +92,9 @@
for _ in range(QUOTA_COUNT):
name = data_utils.rand_name(name="TestObject")
self.object_client.create_object(self.container_name, name, "")
+ waiters.wait_for_object_create(self.object_client,
+ self.container_name,
+ name)
nbefore = self._get_object_count()
self.assertEqual(nbefore, QUOTA_COUNT)
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index a58da7e..b3a04f8 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -45,7 +45,7 @@
def test_snapshot_create_delete_with_volume_in_use(self):
"""Test create/delete snapshot from volume attached to server"""
# Create a test instance
- server = self.create_server()
+ server = self.create_server(wait_until='SSHABLE')
# NOTE(zhufl) Here we create volume from self.image_ref for adding
# coverage for "creating snapshot from non-blank volume".
volume = self.create_volume(imageRef=self.image_ref)
@@ -80,7 +80,7 @@
snapshot1 = self.create_snapshot(self.volume_origin['id'])
# Create a server and attach it
- server = self.create_server()
+ server = self.create_server(wait_until='SSHABLE')
self.attach_volume(server['id'], self.volume_origin['id'])
# Now that the volume is attached, create other snapshots
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 39a4e5d..f207066 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -612,3 +612,17 @@
if caller:
message = '(%s) %s' % (caller, message)
raise lib_exc.TimeoutException(message)
+
+
+def wait_for_object_create(object_client, container_name, object_name,
+ interval=1):
+ """Waits for created object to become available"""
+ start_time = time.time()
+ while time.time() - start_time < object_client.build_timeout:
+ try:
+ return object_client.get_object(container_name, object_name)
+ except lib_exc.NotFound:
+ time.sleep(interval)
+ message = ('Object %s failed to create within the required time (%s s).' %
+ (object_name, object_client.build_timeout))
+ raise lib_exc.TimeoutException(message)
diff --git a/tempest/config.py b/tempest/config.py
index 92fb31b..39e7fb3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1148,6 +1148,9 @@
help="One name of cluster which is set in the realm whose name "
"is set in 'realm_name' item in this file. Set the "
"same cluster name as Swift's container-sync-realms.conf"),
+ cfg.IntOpt('build_timeout',
+ default=10,
+ help="Timeout in seconds to wait for objects to create."),
]
object_storage_feature_group = cfg.OptGroup(
diff --git a/tempest/lib/services/image/v2/images_client.py b/tempest/lib/services/image/v2/images_client.py
index abf427c..ae6ce25 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -206,7 +206,7 @@
def image_import(self, image_id, method='glance-direct',
all_stores_must_succeed=None, all_stores=True,
- stores=None, image_uri=None):
+ stores=None, import_params=None):
"""Import data from staging area to glance store.
For a full list of available parameters, please refer to the official
@@ -222,9 +222,11 @@
all available stores (incompatible with stores)
:param stores: A list of destination store names for the import. Must
be None if server does not support multistore.
- :param image_uri: A URL to be used with the web-download method
+ :param import_params: A dict of import method parameters
"""
url = 'images/%s/import' % image_id
+ if import_params is None:
+ import_params = {}
data = {
"method": {
"name": method
@@ -237,8 +239,8 @@
if all_stores_must_succeed is not None:
data['all_stores_must_succeed'] = all_stores_must_succeed
- if image_uri:
- data['method']['uri'] = image_uri
+ if import_params:
+ data['method'].update(import_params)
data = json.dumps(data)
headers = {'Content-Type': 'application/json'}
resp, _ = self.post(url, data, headers=headers)