Adds "user-password-update" to v3/test_users

This submission is to verify user-password-update functionality
and also added required support functions in both XML/JSON
interfaces.

Change-Id: Ifcac99095fb4e07ccaa2b6f87ac836c3959ef37a
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 558575e..3c25819 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -65,6 +65,28 @@
         self.assertEqual('false', str(new_user_get['enabled']).lower())
 
     @test.attr(type='gate')
+    def test_update_user_password(self):
+        # Creating User to check password updation
+        u_name = data_utils.rand_name('user')
+        original_password = data_utils.rand_name('pass')
+        _, user = self.client.create_user(
+            u_name, password=original_password)
+        # Delete the User at the end all test methods
+        self.addCleanup(self.client.delete_user, user['id'])
+        # Update user with new password
+        new_password = data_utils.rand_name('pass1')
+        self.client.update_user_password(user['id'], new_password,
+                                         original_password)
+        resp, body = self.token.auth(user['id'], new_password)
+        self.assertEqual(201, resp.status)
+        subject_token = resp['x-subject-token']
+        # Perform GET Token to verify and confirm password is updated
+        _, token_details = self.client.get_token(subject_token)
+        self.assertEqual(resp['x-subject-token'], subject_token)
+        self.assertEqual(token_details['user']['id'], user['id'])
+        self.assertEqual(token_details['user']['name'], u_name)
+
+    @test.attr(type='gate')
     def test_list_user_projects(self):
         # List the projects that a user has access upon
         assigned_project_ids = list()
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 593bd15..0188c2a 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -77,6 +77,17 @@
         body = json.loads(body)
         return resp, body['user']
 
+    def update_user_password(self, user_id, password, original_password):
+        """Updates a user password."""
+        update_user = {
+            'password': password,
+            'original_password': original_password
+        }
+        update_user = json.dumps({'user': update_user})
+        resp, _ = self.post('users/%s/password' % user_id, update_user)
+        self.expected_success(204, resp.status)
+        return resp
+
     def list_user_projects(self, user_id):
         """Lists the projects on which a user has roles assigned."""
         resp, body = self.get('users/%s/projects' % user_id)
diff --git a/tempest/services/identity/v3/xml/identity_client.py b/tempest/services/identity/v3/xml/identity_client.py
index 3790f13..f3e084e 100644
--- a/tempest/services/identity/v3/xml/identity_client.py
+++ b/tempest/services/identity/v3/xml/identity_client.py
@@ -139,6 +139,17 @@
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
+    def update_user_password(self, user_id, password, original_password):
+        """Updates a user password."""
+        update_user = common.Element("user",
+                                     xmlns=XMLNS,
+                                     password=password,
+                                     original_password=original_password)
+        resp, _ = self.post('users/%s/password' % user_id,
+                            str(common.Document(update_user)))
+        self.expected_success(204, resp.status)
+        return resp
+
     def list_user_projects(self, user_id):
         """Lists the projects on which a user has roles assigned."""
         resp, body = self.get('users/%s/projects' % user_id)