Merge "Allow free-form image import parameters"
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/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/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(