Merge "Rename get_image_meta method into check_image for Glance V1 client"
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f01657b..5ce41c8 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -226,6 +226,35 @@
 
         self.client.start_server(self.server_id)
 
+    @test.idempotent_id('b68bd8d6-855d-4212-b59b-2e704044dace')
+    @test.services('volume')
+    def test_rebuild_server_with_volume_attached(self):
+        # create a new volume and attach it to the server
+        volume = self.volumes_client.create_volume(
+            size=CONF.volume.volume_size)
+        volume = volume['volume']
+        self.addCleanup(self.volumes_client.delete_volume, volume['id'])
+        waiters.wait_for_volume_status(self.volumes_client, volume['id'],
+                                       'available')
+
+        self.client.attach_volume(self.server_id, volumeId=volume['id'])
+        self.addCleanup(waiters.wait_for_volume_status, self.volumes_client,
+                        volume['id'], 'available')
+        self.addCleanup(self.client.detach_volume,
+                        self.server_id, volume['id'])
+        waiters.wait_for_volume_status(self.volumes_client, volume['id'],
+                                       'in-use')
+
+        # run general rebuild test
+        self.test_rebuild_server()
+
+        # make sure the volume is attached to the instance after rebuild
+        vol_after_rebuild = self.volumes_client.show_volume(volume['id'])
+        vol_after_rebuild = vol_after_rebuild['volume']
+        self.assertEqual('in-use', vol_after_rebuild['status'])
+        self.assertEqual(self.server_id,
+                         vol_after_rebuild['attachments'][0]['server_id'])
+
     def _test_resize_server_confirm(self, stop=False):
         # The server's RAM and disk space should be modified to that of
         # the provided flavor
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
index 62ddead..79f2576 100644
--- a/tempest/api/identity/v2/test_users.py
+++ b/tempest/api/identity/v2/test_users.py
@@ -13,13 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import copy
 import time
 
 from tempest.api.identity import base
 from tempest.lib.common.utils import data_utils
 from tempest.lib import exceptions
-from tempest import manager
 from tempest import test
 
 
@@ -35,23 +33,26 @@
 
     @test.idempotent_id('165859c9-277f-4124-9479-a7d1627b0ca7')
     def test_user_update_own_password(self):
-        self.new_creds = copy.copy(self.creds.credentials)
-        self.new_creds.password = data_utils.rand_password()
-        # we need new non-admin Identity Client with new credentials, since
-        # current non_admin_client token will be revoked after updating
-        # password
-        self.non_admin_users_client_for_cleanup = copy.copy(
-            self.non_admin_users_client)
-        self.non_admin_users_client_for_cleanup.auth_provider = (
-            manager.get_auth_provider(self.new_creds))
-        user_id = self.creds.credentials.user_id
-        old_pass = self.creds.credentials.password
-        new_pass = self.new_creds.password
 
+        def _restore_password(client, user_id, old_pass, new_pass):
+            # Reset auth to get a new token with the new password
+            client.auth_provider.clear_auth()
+            client.auth_provider.credentials.password = new_pass
+            client.update_user_own_password(user_id, password=old_pass,
+                                            original_password=new_pass)
+            # Reset auth again to verify the password restore does work.
+            # Clear auth restores the original credentials and deletes
+            # cached auth data
+            client.auth_provider.clear_auth()
+            client.auth_provider.set_auth()
+
+        old_pass = self.creds.credentials.password
+        new_pass = data_utils.rand_password()
+        user_id = self.creds.credentials.user_id
         # to change password back. important for allow_tenant_isolation = false
-        self.addCleanup(
-            self.non_admin_users_client_for_cleanup.update_user_own_password,
-            user_id, original_password=new_pass, password=old_pass)
+        self.addCleanup(_restore_password, self.non_admin_users_client,
+                        user_id, old_pass=old_pass, new_pass=new_pass)
+
         # user updates own password
         self.non_admin_users_client.update_user_own_password(
             user_id, password=new_pass, original_password=old_pass)
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index 60fbe12..76b46c0 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -13,13 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import copy
 import time
 
 from tempest.api.identity import base
 from tempest.lib.common.utils import data_utils
 from tempest.lib import exceptions
-from tempest import manager
 from tempest import test
 
 
@@ -35,24 +33,25 @@
 
     @test.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
     def test_user_update_own_password(self):
-        self.new_creds = copy.copy(self.creds.credentials)
-        self.new_creds.password = data_utils.rand_password()
-        # we need new non-admin Identity V3 Client with new credentials, since
-        # current non_admin_users_client token will be revoked after updating
-        # password
-        self.non_admin_users_client_for_cleanup = (
-            copy.copy(self.non_admin_users_client))
-        self.non_admin_users_client_for_cleanup.auth_provider = (
-            manager.get_auth_provider(self.new_creds))
-        user_id = self.creds.credentials.user_id
+
+        def _restore_password(client, user_id, old_pass, new_pass):
+            # Reset auth to get a new token with the new password
+            client.auth_provider.clear_auth()
+            client.auth_provider.credentials.password = new_pass
+            client.update_user_password(user_id, password=old_pass,
+                                        original_password=new_pass)
+            # Reset auth again to verify the password restore does work.
+            # Clear auth restores the original credentials and deletes
+            # cached auth data
+            client.auth_provider.clear_auth()
+            client.auth_provider.set_auth()
+
         old_pass = self.creds.credentials.password
-        new_pass = self.new_creds.password
+        new_pass = data_utils.rand_password()
+        user_id = self.creds.credentials.user_id
         # to change password back. important for allow_tenant_isolation = false
-        self.addCleanup(
-            self.non_admin_users_client_for_cleanup.update_user_password,
-            user_id,
-            password=old_pass,
-            original_password=new_pass)
+        self.addCleanup(_restore_password, self.non_admin_users_client,
+                        user_id, old_pass=old_pass, new_pass=new_pass)
 
         # user updates own password
         self.non_admin_users_client.update_user_password(
diff --git a/tempest/services/identity/v3/json/projects_client.py b/tempest/services/identity/v3/json/projects_client.py
index dc553d0..97e43df 100644
--- a/tempest/services/identity/v3/json/projects_client.py
+++ b/tempest/services/identity/v3/json/projects_client.py
@@ -23,17 +23,15 @@
     api_version = "v3"
 
     def create_project(self, name, **kwargs):
-        """Creates a project."""
-        description = kwargs.get('description', None)
-        en = kwargs.get('enabled', True)
-        domain_id = kwargs.get('domain_id', 'default')
-        post_body = {
-            'description': description,
-            'domain_id': domain_id,
-            'enabled': en,
-            'name': name
-        }
-        post_body = json.dumps({'project': post_body})
+        """Create a Project.
+
+        Available params: see http://developer.openstack.org/
+                          api-ref-identity-v3.html#createProject
+
+        """
+        # Include the project name to the kwargs parameters
+        kwargs['name'] = name
+        post_body = json.dumps({'project': kwargs})
         resp, body = self.post('projects', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
@@ -49,19 +47,13 @@
         return rest_client.ResponseBody(resp, body)
 
     def update_project(self, project_id, **kwargs):
-        body = self.show_project(project_id)['project']
-        name = kwargs.get('name', body['name'])
-        desc = kwargs.get('description', body['description'])
-        en = kwargs.get('enabled', body['enabled'])
-        domain_id = kwargs.get('domain_id', body['domain_id'])
-        post_body = {
-            'id': project_id,
-            'name': name,
-            'description': desc,
-            'enabled': en,
-            'domain_id': domain_id,
-        }
-        post_body = json.dumps({'project': post_body})
+        """Update a Project.
+
+        Available params: see http://developer.openstack.org/
+                          api-ref-identity-v3.html#updateProject
+
+        """
+        post_body = json.dumps({'project': kwargs})
         resp, body = self.patch('projects/%s' % project_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
diff --git a/tools/check_logs.py b/tools/check_logs.py
index fa7129d..e34dec3 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -54,7 +54,6 @@
     'q-meta',
     'q-metering',
     'q-svc',
-    'q-vpn',
     's-proxy'])