Hello community,

here is the log from the commit of package python-tempest-lib for 
openSUSE:Factory checked in at 2015-10-30 13:42:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tempest-lib (Old)
 and      /work/SRC/openSUSE:Factory/.python-tempest-lib.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tempest-lib"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tempest-lib/python-tempest-lib.changes    
2015-08-27 08:55:13.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-tempest-lib.new/python-tempest-lib.changes   
    2015-10-30 13:42:31.000000000 +0100
@@ -1,0 +2,20 @@
+Mon Sep 21 14:00:26 UTC 2015 - [email protected]
+
+- update to 0.9.0:
+  * Migrated agents_client.py, test_agents_client.py, agents.py from tempest
+  * Write the latest change_id on migration commit
+  * Keep original pathes of source files
+
+-------------------------------------------------------------------
+Wed Sep  9 09:03:52 UTC 2015 - [email protected]
+
+- update to 0.8.0:
+  * Add HTTP30X checks for validate_response(
+  * Make TokenClientJSON deprecated
+  * Add the resp to RestClientExceptions
+  * Add std out to ssh exception
+  * Properly decode body before calling json.loads()
+  * Updated from global requirements
+- Adjust Requires according to requirements.txt
+
+-------------------------------------------------------------------

Old:
----
  tempest-lib-0.6.1.tar.gz

New:
----
  tempest-lib-0.9.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tempest-lib.spec ++++++
--- /var/tmp/diff_new_pack.ITUeEb/_old  2015-10-30 13:42:31.000000000 +0100
+++ /var/tmp/diff_new_pack.ITUeEb/_new  2015-10-30 13:42:31.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           python-tempest-lib
-Version:        0.6.1
+Version:        0.9.0
 Release:        0
 Summary:        OpenStack Functional Testing Library
 License:        Apache-2.0
@@ -45,12 +45,13 @@
 BuildRequires:  python-testtools
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 Requires:       python-Babel >= 1.3
-Requires:       python-fixtures >= 0.3.14
+Requires:       python-fixtures >= 1.3.1
 Requires:       python-httplib2 >= 0.7.5
 Requires:       python-iso8601 >= 0.1.9
-Requires:       python-jsonschema >= 2
-Requires:       python-oslo.log >= 0.4.0
-Requires:       python-six >= 1.9
+Requires:       python-jsonschema >= 2.0.0
+Requires:       python-os-testr >= 0.1.0
+Requires:       python-oslo.log >= 1.8.0
+Requires:       python-six >= 1.9.0
 %if 0%{?suse_version} && 0%{?suse_version} <= 1110
 %{!?python_sitelib: %global python_sitelib %(python -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib()")}
 %else

++++++ tempest-lib-0.6.1.tar.gz -> tempest-lib-0.9.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/AUTHORS 
new/tempest-lib-0.9.0/AUTHORS
--- old/tempest-lib-0.6.1/AUTHORS       2015-06-24 07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/AUTHORS       2015-09-16 12:30:44.000000000 +0200
@@ -29,6 +29,7 @@
 Joe Gordon <[email protected]>
 JordanP <[email protected]>
 Katherine Elliott <[email protected]>
+Ken'ichi Ohmichi <[email protected]>
 Ken'ichi Ohmichi <[email protected]>
 Lilywei123 <[email protected]>
 Marc Koderer <[email protected]>
@@ -42,8 +43,10 @@
 Matthew Treinish <[email protected]>
 Mauro S. M. Rodrigues <[email protected]>
 Mehdi Abaakouk <[email protected]>
+Mehdi Abaakouk <[email protected]>
 Mikhail S Medvedev <[email protected]>
 Mitsuhiko Yamazaki <[email protected]>
+Paul Glass <[email protected]>
 Pavel Sedlák <[email protected]>
 Rohan Kanade <[email protected]>
 Ryan Hsu <[email protected]>
@@ -63,6 +66,7 @@
 Yuxing wang <[email protected]>
 Zhi Kun Liu <[email protected]>
 ZhiQiang Fan <[email protected]>
+afazekas <[email protected]>
 andreaf <[email protected]>
 ekhugen <[email protected]>
 ghanshyam <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/ChangeLog 
new/tempest-lib-0.9.0/ChangeLog
--- old/tempest-lib-0.6.1/ChangeLog     2015-06-24 07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/ChangeLog     2015-09-16 12:30:44.000000000 +0200
@@ -1,6 +1,33 @@
 CHANGES
 =======
 
+0.9.0
+-----
+
+* Migrated agents_client.py, test_agents_client.py, agents.py from tempest
+* Write the latest change_id on migration commit
+* Keep original pathes of source files
+
+0.8.0
+-----
+
+* Add HTTP30X checks for validate_response(
+* Make TokenClientJSON deprecated
+* Fix cli.base.execute with py34
+* Updated from global requirements
+* Updated from global requirements
+* Updated from global requirements
+* Add the resp to RestClientExceptions
+* Add std out to ssh exception
+* Updated from global requirements
+
+0.7.0
+-----
+
+* Updated from global requirements
+* Properly decode body before calling json.loads()
+* Updated from global requirements
+
 0.6.1
 -----
 
@@ -11,6 +38,7 @@
 
 * Revert "Adding support for neutron-debug CLI."
 * Updated from global requirements
+* Categorize rest client exceptions
 * Remove unnecessary oslo-incubator code
 * Allows any valid ISO8601 timestamp in token expiry time format
 * Explicitly add json schema validator for schema validation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/PKG-INFO 
new/tempest-lib-0.9.0/PKG-INFO
--- old/tempest-lib-0.6.1/PKG-INFO      2015-06-24 07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/PKG-INFO      2015-09-16 12:30:44.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: tempest-lib
-Version: 0.6.1
+Version: 0.9.0
 Summary: OpenStack Functional Testing Library
 Home-page: http://www.openstack.org/
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/requirements.txt 
new/tempest-lib-0.9.0/requirements.txt
--- old/tempest-lib-0.6.1/requirements.txt      2015-06-24 07:55:34.000000000 
+0200
+++ new/tempest-lib-0.9.0/requirements.txt      2015-09-16 12:29:59.000000000 
+0200
@@ -1,13 +1,13 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-pbr<2.0,>=0.11
+pbr<2.0,>=1.6
 Babel>=1.3
-fixtures>=0.3.14
+fixtures>=1.3.1
 iso8601>=0.1.9
 jsonschema!=2.5.0,<3.0.0,>=2.0.0
 httplib2>=0.7.5
 paramiko>=1.13.0
 six>=1.9.0
-oslo.log>=1.2.0 # Apache-2.0
+oslo.log>=1.8.0 # Apache-2.0
 os-testr>=0.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/setup.cfg 
new/tempest-lib-0.9.0/setup.cfg
--- old/tempest-lib-0.6.1/setup.cfg     2015-06-24 07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/setup.cfg     2015-09-16 12:30:44.000000000 +0200
@@ -50,7 +50,7 @@
 output_file = tempest_lib/locale/tempest-lib.pot
 
 [egg_info]
-tag_build = 
-tag_date = 0
 tag_svn_revision = 0
+tag_date = 0
+tag_build = 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/setup.py 
new/tempest-lib-0.9.0/setup.py
--- old/tempest-lib-0.6.1/setup.py      2015-06-24 07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/setup.py      2015-09-16 12:29:59.000000000 +0200
@@ -25,5 +25,5 @@
     pass
 
 setuptools.setup(
-    setup_requires=['pbr'],
+    setup_requires=['pbr>=1.3'],
     pbr=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/api_schema/response/compute/v2_1/agents.py 
new/tempest-lib-0.9.0/tempest_lib/api_schema/response/compute/v2_1/agents.py
--- 
old/tempest-lib-0.6.1/tempest_lib/api_schema/response/compute/v2_1/agents.py    
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/tempest-lib-0.9.0/tempest_lib/api_schema/response/compute/v2_1/agents.py    
    2015-09-16 12:30:00.000000000 +0200
@@ -0,0 +1,60 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    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.
+
+common_agent_info = {
+    'type': 'object',
+    'properties': {
+        'agent_id': {'type': ['integer', 'string']},
+        'hypervisor': {'type': 'string'},
+        'os': {'type': 'string'},
+        'architecture': {'type': 'string'},
+        'version': {'type': 'string'},
+        'url': {'type': 'string', 'format': 'uri'},
+        'md5hash': {'type': 'string'}
+    },
+    'additionalProperties': False,
+    'required': ['agent_id', 'hypervisor', 'os', 'architecture',
+                 'version', 'url', 'md5hash']
+}
+
+list_agents = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'agents': {
+                'type': 'array',
+                'items': common_agent_info
+            }
+        },
+        'additionalProperties': False,
+        'required': ['agents']
+    }
+}
+
+create_agent = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'agent': common_agent_info
+        },
+        'additionalProperties': False,
+        'required': ['agent']
+    }
+}
+
+delete_agent = {
+    'status_code': [200]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib/auth.py 
new/tempest-lib-0.9.0/tempest_lib/auth.py
--- old/tempest-lib-0.6.1/tempest_lib/auth.py   2015-06-24 07:55:34.000000000 
+0200
+++ new/tempest-lib-0.9.0/tempest_lib/auth.py   2015-09-16 12:29:59.000000000 
+0200
@@ -248,7 +248,7 @@
 class KeystoneV2AuthProvider(KeystoneAuthProvider):
 
     def _auth_client(self, auth_url):
-        return json_v2id.TokenClientJSON(
+        return json_v2id.TokenClient(
             auth_url, disable_ssl_certificate_validation=self.dsvm,
             ca_certs=self.ca_certs, trace_requests=self.trace_requests)
 
@@ -326,7 +326,7 @@
 class KeystoneV3AuthProvider(KeystoneAuthProvider):
 
     def _auth_client(self, auth_url):
-        return json_v3id.V3TokenClientJSON(
+        return json_v3id.V3TokenClient(
             auth_url, disable_ssl_certificate_validation=self.dsvm,
             ca_certs=self.ca_certs, trace_requests=self.trace_requests)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib/cli/base.py 
new/tempest-lib-0.9.0/tempest_lib/cli/base.py
--- old/tempest-lib-0.6.1/tempest_lib/cli/base.py       2015-06-24 
07:55:35.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/cli/base.py       2015-09-16 
12:30:00.000000000 +0200
@@ -16,6 +16,7 @@
 import logging
 import os
 import shlex
+import six
 import subprocess
 
 from tempest_lib import base
@@ -50,7 +51,9 @@
     cmd = ' '.join([os.path.join(cli_dir, cmd),
                     flags, action, params])
     LOG.info("running: '%s'" % cmd)
-    cmd = shlex.split(cmd.encode('utf-8'))
+    if six.PY2:
+        cmd = cmd.encode('utf-8')
+    cmd = shlex.split(cmd)
     result = ''
     result_err = ''
     stdout = subprocess.PIPE
@@ -62,7 +65,10 @@
                                        cmd,
                                        result,
                                        result_err)
-    return result
+    if six.PY2:
+        return result
+    else:
+        return os.fsdecode(result)
 
 
 class CLIClient(object):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib/common/rest_client.py 
new/tempest-lib-0.9.0/tempest_lib/common/rest_client.py
--- old/tempest-lib-0.6.1/tempest_lib/common/rest_client.py     2015-06-24 
07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/common/rest_client.py     2015-09-16 
12:29:59.000000000 +0200
@@ -34,6 +34,9 @@
 # All the successful HTTP status codes from RFC 7231 & 4918
 HTTP_SUCCESS = (200, 201, 202, 203, 204, 205, 206, 207)
 
+# All the redirection HTTP status codes from RFC 7231 & 4918
+HTTP_REDIRECTION = (300, 301, 302, 303, 304, 305, 306, 307)
+
 # JSON Schema validator and format checker used for JSON Schema validation
 JSONSCHEMA_VALIDATOR = jsonschema.Draft4Validator
 FORMAT_CHECKER = jsonschema.draft4_format_checker
@@ -223,9 +226,9 @@
                       ).format(expected_code)
         if isinstance(expected_code, list):
             for code in expected_code:
-                assert code in HTTP_SUCCESS, assert_msg
+                assert code in HTTP_SUCCESS + HTTP_REDIRECTION, assert_msg
         else:
-            assert expected_code in HTTP_SUCCESS, assert_msg
+            assert expected_code in HTTP_SUCCESS + HTTP_REDIRECTION, assert_msg
 
         # NOTE(afazekas): the http status code above 400 is processed by
         # the _error_checker method
@@ -439,9 +442,16 @@
             self._log_request_full(method, req_url, resp, secs, req_headers,
                                    req_body, resp_body, caller_name, extra)
 
+    def _json_loads(self, resp_body):
+        if isinstance(resp_body, bytes):
+            resp_body = json.loads(resp_body.decode('utf8'))
+        else:
+            resp_body = json.loads(resp_body)
+        return resp_body
+
     def _parse_resp(self, body):
         try:
-            body = json.loads(body)
+            body = self._json_loads(body)
         except ValueError:
             return body
 
@@ -583,9 +593,8 @@
         :rtype: tuple
         :return: a tuple with the first entry containing the response headers
                  and the second the response body
-        :raises InvalidContentType: If the content-type of the response isn't
-                                    an expect type or a 415 response code is
-                                    received
+        :raises UnexpectedContentType: If the content-type of the response
+                                       isn't an expect type
         :raises Unauthorized: If a 401 response code is received
         :raises Forbidden: If a 403 response code is received
         :raises NotFound: If a 404 response code is received
@@ -595,6 +604,7 @@
                           not in the response body
         :raises RateLimitExceeded: If a 413 response code is received and
                                    over_limit is in the response body
+        :raises InvalidContentType: If a 415 response code is received
         :raises UnprocessableEntity: If a 422 response code is received
         :raises InvalidHTTPResponseBody: The response body wasn't valid JSON
                                          and couldn't be parsed
@@ -670,50 +680,51 @@
         elif ctype.lower() in TXT_ENC:
             parse_resp = False
         else:
-            raise exceptions.InvalidContentType(str(resp.status))
+            raise exceptions.UnexpectedContentType(str(resp.status),
+                                                   resp=resp)
 
         if resp.status == 401:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.Unauthorized(resp_body)
+            raise exceptions.Unauthorized(resp_body, resp=resp)
 
         if resp.status == 403:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.Forbidden(resp_body)
+            raise exceptions.Forbidden(resp_body, resp=resp)
 
         if resp.status == 404:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.NotFound(resp_body)
+            raise exceptions.NotFound(resp_body, resp=resp)
 
         if resp.status == 400:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.BadRequest(resp_body)
+            raise exceptions.BadRequest(resp_body, resp=resp)
 
         if resp.status == 409:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.Conflict(resp_body)
+            raise exceptions.Conflict(resp_body, resp=resp)
 
         if resp.status == 413:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
             if self.is_absolute_limit(resp, resp_body):
-                raise exceptions.OverLimit(resp_body)
+                raise exceptions.OverLimit(resp_body, resp=resp)
             else:
-                raise exceptions.RateLimitExceeded(resp_body)
+                raise exceptions.RateLimitExceeded(resp_body, resp=resp)
 
         if resp.status == 415:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.InvalidContentType(resp_body)
+            raise exceptions.InvalidContentType(resp_body, resp=resp)
 
         if resp.status == 422:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
-            raise exceptions.UnprocessableEntity(resp_body)
+            raise exceptions.UnprocessableEntity(resp_body, resp=resp)
 
         if resp.status in (500, 501):
             message = resp_body
@@ -742,12 +753,15 @@
                         message = resp_body
 
             if resp.status == 501:
-                raise exceptions.NotImplemented(message)
+                raise exceptions.NotImplemented(resp_body, resp=resp,
+                                                message=message)
             else:
-                raise exceptions.ServerFault(resp_body, message=message)
+                raise exceptions.ServerFault(resp_body, resp=resp,
+                                             message=message)
 
         if resp.status >= 400:
-            raise exceptions.UnexpectedResponseCode(str(resp.status))
+            raise exceptions.UnexpectedResponseCode(str(resp.status),
+                                                    resp=resp)
 
     def is_absolute_limit(self, resp, resp_body):
         if (not isinstance(resp_body, collections.Mapping) or
@@ -802,7 +816,7 @@
         # code if it exists is something that we expect. This is explicitly
         # declared in the V3 API and so we should be able to export this in
         # the response schema. For now we'll ignore it.
-        if resp.status in HTTP_SUCCESS:
+        if resp.status in HTTP_SUCCESS + HTTP_REDIRECTION:
             cls.expected_success(schema['status_code'], resp.status)
 
             # Check the body of a response
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib/common/ssh.py 
new/tempest-lib-0.9.0/tempest_lib/common/ssh.py
--- old/tempest-lib-0.6.1/tempest_lib/common/ssh.py     2015-06-24 
07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/common/ssh.py     2015-09-16 
12:29:59.000000000 +0200
@@ -143,7 +143,7 @@
         if 0 != exit_status:
             raise exceptions.SSHExecCommandFailed(
                 command=cmd, exit_status=exit_status,
-                strerror=''.join(err_data))
+                stderr=err_data, stdout=out_data)
         return ''.join(out_data)
 
     def test_connection_auth(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib/exceptions.py 
new/tempest-lib-0.9.0/tempest_lib/exceptions.py
--- old/tempest-lib-0.6.1/tempest_lib/exceptions.py     2015-06-24 
07:55:35.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/exceptions.py     2015-09-16 
12:29:59.000000000 +0200
@@ -48,82 +48,100 @@
 class RestClientException(TempestException,
                           testtools.TestCase.failureException):
     def __init__(self, resp_body=None, *args, **kwargs):
+        if 'resp' in kwargs:
+            self.resp = kwargs.get('resp')
         self.resp_body = resp_body
         message = kwargs.get("message", resp_body)
         super(RestClientException, self).__init__(message, *args, **kwargs)
 
 
-class InvalidHttpSuccessCode(RestClientException):
+class OtherRestClientException(RestClientException):
+    pass
+
+
+class ServerRestClientException(RestClientException):
+    pass
+
+
+class ClientRestClientException(RestClientException):
+    pass
+
+
+class InvalidHttpSuccessCode(OtherRestClientException):
     message = "The success code is different than the expected one"
 
 
-class NotFound(RestClientException):
+class NotFound(ClientRestClientException):
     message = "Object not found"
 
 
-class Unauthorized(RestClientException):
+class Unauthorized(ClientRestClientException):
     message = 'Unauthorized'
 
 
-class Forbidden(RestClientException):
+class Forbidden(ClientRestClientException):
     message = "Forbidden"
 
 
-class TimeoutException(RestClientException):
+class TimeoutException(OtherRestClientException):
     message = "Request timed out"
 
 
-class BadRequest(RestClientException):
+class BadRequest(ClientRestClientException):
     message = "Bad request"
 
 
-class UnprocessableEntity(RestClientException):
+class UnprocessableEntity(ClientRestClientException):
     message = "Unprocessable entity"
 
 
-class RateLimitExceeded(RestClientException):
+class RateLimitExceeded(ClientRestClientException):
     message = "Rate limit exceeded"
 
 
-class OverLimit(RestClientException):
+class OverLimit(ClientRestClientException):
     message = "Quota exceeded"
 
 
-class ServerFault(RestClientException):
+class ServerFault(ServerRestClientException):
     message = "Got server fault"
 
 
-class NotImplemented(RestClientException):
+class NotImplemented(ServerRestClientException):
     message = "Got NotImplemented error"
 
 
-class Conflict(RestClientException):
+class Conflict(ClientRestClientException):
     message = "An object with that identifier already exists"
 
 
-class ResponseWithNonEmptyBody(RestClientException):
+class ResponseWithNonEmptyBody(OtherRestClientException):
     message = ("RFC Violation! Response with %(status)d HTTP Status Code "
                "MUST NOT have a body")
 
 
-class ResponseWithEntity(RestClientException):
+class ResponseWithEntity(OtherRestClientException):
     message = ("RFC Violation! Response with 205 HTTP Status Code "
                "MUST NOT have an entity")
 
 
-class InvalidHTTPResponseBody(RestClientException):
+class InvalidHTTPResponseBody(OtherRestClientException):
     message = "HTTP response body is invalid json or xml"
 
 
-class InvalidHTTPResponseHeader(RestClientException):
+class InvalidHTTPResponseHeader(OtherRestClientException):
     message = "HTTP response header is invalid"
 
 
-class InvalidContentType(RestClientException):
+class InvalidContentType(ClientRestClientException):
     message = "Invalid content type provided"
 
 
-class UnexpectedResponseCode(RestClientException):
+class UnexpectedContentType(OtherRestClientException):
+    message = "Unexpected content type provided"
+
+
+class UnexpectedResponseCode(OtherRestClientException):
     message = "Unexpected response code received"
 
 
@@ -168,4 +186,5 @@
 class SSHExecCommandFailed(TempestException):
     """Raised when remotely executed command returns nonzero status."""
     message = ("Command '%(command)s', exit status: %(exit_status)d, "
-               "Error:\n%(strerror)s")
+               "stderr:\n%(stderr)s\n"
+               "stdout:\n%(stdout)s")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/services/compute/agents_client.py 
new/tempest-lib-0.9.0/tempest_lib/services/compute/agents_client.py
--- old/tempest-lib-0.6.1/tempest_lib/services/compute/agents_client.py 
1970-01-01 01:00:00.000000000 +0100
+++ new/tempest-lib-0.9.0/tempest_lib/services/compute/agents_client.py 
2015-09-16 12:30:00.000000000 +0200
@@ -0,0 +1,54 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    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.
+
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest_lib.api_schema.response.compute.v2_1 import agents as schema
+from tempest_lib.common import rest_client
+
+
+class AgentsClient(rest_client.RestClient):
+    """Tests Agents API"""
+
+    def list_agents(self, **params):
+        """List all agent builds."""
+        url = 'os-agents'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.validate_response(schema.list_agents, resp, body)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_agent(self, **kwargs):
+        """Create an agent build."""
+        post_body = json.dumps({'agent': kwargs})
+        resp, body = self.post('os-agents', post_body)
+        body = json.loads(body)
+        self.validate_response(schema.create_agent, resp, body)
+        return rest_client.ResponseBody(resp, body)
+
+    def delete_agent(self, agent_id):
+        """Delete an existing agent build."""
+        resp, body = self.delete("os-agents/%s" % agent_id)
+        self.validate_response(schema.delete_agent, resp, body)
+        return rest_client.ResponseBody(resp, body)
+
+    def update_agent(self, agent_id, **kwargs):
+        """Update an agent build."""
+        put_body = json.dumps({'para': kwargs})
+        resp, body = self.put('os-agents/%s' % agent_id, put_body)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/services/identity/v2/token_client.py 
new/tempest-lib-0.9.0/tempest_lib/services/identity/v2/token_client.py
--- old/tempest-lib-0.6.1/tempest_lib/services/identity/v2/token_client.py      
2015-06-24 07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/services/identity/v2/token_client.py      
2015-09-16 12:29:59.000000000 +0200
@@ -13,16 +13,19 @@
 #    under the License.
 
 import json
+
+from oslo_log import log as logging
+
 from tempest_lib.common import rest_client
 from tempest_lib import exceptions
 
 
-class TokenClientJSON(rest_client.RestClient):
+class TokenClient(rest_client.RestClient):
 
     def __init__(self, auth_url, disable_ssl_certificate_validation=None,
                  ca_certs=None, trace_requests=None):
         dscv = disable_ssl_certificate_validation
-        super(TokenClientJSON, self).__init__(
+        super(TokenClient, self).__init__(
             None, None, None, disable_ssl_certificate_validation=dscv,
             ca_certs=ca_certs, trace_requests=trace_requests)
 
@@ -85,15 +88,13 @@
         self._log_request(method, url, resp)
 
         if resp.status in [401, 403]:
-            resp_body = json.loads(resp_body)
+            resp_body = self._json_loads(resp_body)
             raise exceptions.Unauthorized(resp_body['error']['message'])
         elif resp.status not in [200, 201]:
             raise exceptions.IdentityError(
                 'Unexpected status code {0}'.format(resp.status))
 
-        if isinstance(resp_body, str):
-            resp_body = json.loads(resp_body)
-        return resp, resp_body
+        return resp, self._json_loads(resp_body)
 
     def get_token(self, user, password, tenant, auth_data=False):
         """Returns (token id, token data) for supplied credentials."""
@@ -103,3 +104,15 @@
             return body['token']['id'], body
         else:
             return body['token']['id']
+
+
+class TokenClientJSON(TokenClient):
+    LOG = logging.getLogger(__name__)
+
+    def _warn(self):
+        self.LOG.warning("%s class was deprecated and renamed to %s" %
+                         (self.__class__.__name__, 'TokenClient'))
+
+    def __init__(self, *args, **kwargs):
+        self._warn()
+        super(TokenClientJSON, self).__init__(*args, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/services/identity/v3/token_client.py 
new/tempest-lib-0.9.0/tempest_lib/services/identity/v3/token_client.py
--- old/tempest-lib-0.6.1/tempest_lib/services/identity/v3/token_client.py      
2015-06-24 07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/services/identity/v3/token_client.py      
2015-09-16 12:29:59.000000000 +0200
@@ -13,16 +13,19 @@
 #    under the License.
 
 import json
+
+from oslo_log import log as logging
+
 from tempest_lib.common import rest_client
 from tempest_lib import exceptions
 
 
-class V3TokenClientJSON(rest_client.RestClient):
+class V3TokenClient(rest_client.RestClient):
 
     def __init__(self, auth_url, disable_ssl_certificate_validation=None,
                  ca_certs=None, trace_requests=None):
         dscv = disable_ssl_certificate_validation
-        super(V3TokenClientJSON, self).__init__(
+        super(V3TokenClient, self).__init__(
             None, None, None, disable_ssl_certificate_validation=dscv,
             ca_certs=ca_certs, trace_requests=trace_requests)
 
@@ -135,13 +138,13 @@
         self._log_request(method, url, resp)
 
         if resp.status in [401, 403]:
-            resp_body = json.loads(resp_body)
+            resp_body = self._json_loads(resp_body)
             raise exceptions.Unauthorized(resp_body['error']['message'])
         elif resp.status not in [200, 201, 204]:
             raise exceptions.IdentityError(
                 'Unexpected status code {0}'.format(resp.status))
 
-        return resp, json.loads(resp_body)
+        return resp, self._json_loads(resp_body)
 
     def get_token(self, **kwargs):
         """Returns (token id, token data) for supplied credentials"""
@@ -163,3 +166,15 @@
             return token, body['token']
         else:
             return token
+
+
+class V3TokenClientJSON(V3TokenClient):
+    LOG = logging.getLogger(__name__)
+
+    def _warn(self):
+        self.LOG.warning("%s class was deprecated and renamed to %s" %
+                         (self.__class__.__name__, 'V3TokenClient'))
+
+    def __init__(self, *args, **kwargs):
+        self._warn()
+        super(V3TokenClientJSON, self).__init__(*args, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/tests/cli/test_execute.py 
new/tempest-lib-0.9.0/tempest_lib/tests/cli/test_execute.py
--- old/tempest-lib-0.6.1/tempest_lib/tests/cli/test_execute.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/tempest-lib-0.9.0/tempest_lib/tests/cli/test_execute.py 2015-09-16 
12:30:00.000000000 +0200
@@ -0,0 +1,31 @@
+#
+#    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.
+
+
+from tempest_lib.cli import base as cli_base
+from tempest_lib.tests import base
+
+
+class TestExecute(base.TestCase):
+    def test_execute_success(self):
+        result = cli_base.execute("/bin/ls", action="tempest_lib",
+                                  flags="-l -a")
+        self.assertIsInstance(result, str)
+        self.assertIn("__init__.py", result)
+
+    def test_execute_failure(self):
+        result = cli_base.execute("/bin/ls", action="tempest_lib",
+                                  flags="--foobar", merge_stderr=True,
+                                  fail_ok=True)
+        self.assertIsInstance(result, str)
+        self.assertIn("--foobar", result)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/tests/services/compute/base.py 
new/tempest-lib-0.9.0/tempest_lib/tests/services/compute/base.py
--- old/tempest-lib-0.6.1/tempest_lib/tests/services/compute/base.py    
1970-01-01 01:00:00.000000000 +0100
+++ new/tempest-lib-0.9.0/tempest_lib/tests/services/compute/base.py    
2015-09-16 12:30:00.000000000 +0200
@@ -0,0 +1,43 @@
+# Copyright 2015 Deutsche Telekom AG.  All rights reserved.
+#
+#    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 httplib2
+
+from oslo_serialization import jsonutils as json
+from oslotest import mockpatch
+
+from tempest_lib.tests import base
+
+
+class BaseComputeServiceTest(base.TestCase):
+    def create_response(self, body, to_utf=False, status=200):
+        json_body = {}
+        if body:
+            json_body = json.dumps(body)
+            if to_utf:
+                json_body = json_body.encode('utf-8')
+        response = (httplib2.Response({'status': status}), json_body)
+        return response
+
+    def check_service_client_function(self, function, function2mock,
+                                      body, to_utf=False, status=200,
+                                      **kwargs):
+        mocked_response = self.create_response(body, to_utf, status)
+        self.useFixture(mockpatch.Patch(
+            function2mock, return_value=mocked_response))
+        if kwargs:
+            resp = function(**kwargs)
+        else:
+            resp = function()
+        self.assertEqual(body, resp)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/tests/services/compute/test_agents_client.py 
new/tempest-lib-0.9.0/tempest_lib/tests/services/compute/test_agents_client.py
--- 
old/tempest-lib-0.6.1/tempest_lib/tests/services/compute/test_agents_client.py  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/tempest-lib-0.9.0/tempest_lib/tests/services/compute/test_agents_client.py  
    2015-09-16 12:30:00.000000000 +0200
@@ -0,0 +1,106 @@
+# Copyright 2015 NEC Corporation.  All rights reserved.
+#
+#    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.
+
+from tempest_lib.services.compute import agents_client
+from tempest_lib.tests import fake_auth_provider
+from tempest_lib.tests.services.compute import base
+
+
+class TestAgentsClient(base.BaseComputeServiceTest):
+    FAKE_CREATE_AGENT = {
+        "agent": {
+            "url": "http://foo.com";,
+            "hypervisor": "kvm",
+            "md5hash": "md5",
+            "version": "2",
+            "architecture": "x86_64",
+            "os": "linux",
+            "agent_id": 1
+        }
+    }
+
+    FAKE_UPDATE_AGENT = {
+        "agent": {
+            "url": "http://foo.com";,
+            "hypervisor": "kvm",
+            "md5hash": "md5",
+            "version": "2",
+            "architecture": "x86_64",
+            "os": "linux",
+            "agent_id": 1
+        }
+    }
+
+    def setUp(self):
+        super(TestAgentsClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = agents_client.AgentsClient(fake_auth,
+                                                 'compute', 'regionOne')
+
+    def _test_list_agents(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_agents,
+            'tempest_lib.common.rest_client.RestClient.get',
+            {"agents": []},
+            bytes_body)
+        self.check_service_client_function(
+            self.client.list_agents,
+            'tempest_lib.common.rest_client.RestClient.get',
+            {"agents": []},
+            bytes_body,
+            hypervisor="kvm")
+
+    def _test_create_agent(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.create_agent,
+            'tempest_lib.common.rest_client.RestClient.post',
+            self.FAKE_CREATE_AGENT,
+            bytes_body,
+            url="http://foo.com";, hypervisor="kvm", md5hash="md5",
+            version="2", architecture="x86_64", os="linux")
+
+    def _test_delete_agent(self):
+        self.check_service_client_function(
+            self.client.delete_agent,
+            'tempest_lib.common.rest_client.RestClient.delete',
+            {}, agent_id="1")
+
+    def _test_update_agent(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.update_agent,
+            'tempest_lib.common.rest_client.RestClient.put',
+            self.FAKE_UPDATE_AGENT,
+            bytes_body,
+            agent_id="1", url="http://foo.com";, md5hash="md5", version="2")
+
+    def test_list_agents_with_str_body(self):
+        self._test_list_agents()
+
+    def test_list_agents_with_bytes_body(self):
+        self._test_list_agents(bytes_body=True)
+
+    def test_create_agent_with_str_body(self):
+        self._test_create_agent()
+
+    def test_create_agent_with_bytes_body(self):
+        self._test_create_agent(bytes_body=True)
+
+    def test_delete_agent(self):
+        self._test_delete_agent()
+
+    def test_update_agent_with_str_body(self):
+        self._test_update_agent()
+
+    def test_update_agent_with_bytes_body(self):
+        self._test_update_agent(bytes_body=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/tests/services/identity/v2/test_token_client.py
 
new/tempest-lib-0.9.0/tempest_lib/tests/services/identity/v2/test_token_client.py
--- 
old/tempest-lib-0.6.1/tempest_lib/tests/services/identity/v2/test_token_client.py
   2015-06-24 07:55:34.000000000 +0200
+++ 
new/tempest-lib-0.9.0/tempest_lib/tests/services/identity/v2/test_token_client.py
   2015-09-16 12:29:59.000000000 +0200
@@ -14,6 +14,7 @@
 
 import json
 
+import httplib2
 from oslotest import mockpatch
 
 from tempest_lib.common import rest_client
@@ -29,7 +30,7 @@
         self.fake_200_http = fake_http.fake_httplib2(return_type=200)
 
     def test_auth(self):
-        token_client_v2 = token_client.TokenClientJSON('fake_url')
+        token_client_v2 = token_client.TokenClient('fake_url')
         post_mock = self.useFixture(mockpatch.PatchObject(
             token_client_v2, 'post', return_value=self.fake_200_http.request(
                 'fake_url', body={'access': {'token': 'fake_token'}})))
@@ -47,7 +48,7 @@
                                                body=req_dict)
 
     def test_auth_with_tenant(self):
-        token_client_v2 = token_client.TokenClientJSON('fake_url')
+        token_client_v2 = token_client.TokenClient('fake_url')
         post_mock = self.useFixture(mockpatch.PatchObject(
             token_client_v2, 'post', return_value=self.fake_200_http.request(
                 'fake_url', body={'access': {'token': 'fake_token'}})))
@@ -64,3 +65,23 @@
         })
         post_mock.mock.assert_called_once_with('fake_url/tokens',
                                                body=req_dict)
+
+    def test_request_with_str_body(self):
+        token_client_v2 = token_client.TokenClient('fake_url')
+        self.useFixture(mockpatch.PatchObject(
+            token_client_v2, 'raw_request', return_value=(
+                httplib2.Response({'status': '200'}),
+                str('{"access": {"token": "fake_token"}}'))))
+        resp, body = token_client_v2.request('GET', 'fake_uri')
+        self.assertIsInstance(resp, httplib2.Response)
+        self.assertIsInstance(body, dict)
+
+    def test_request_with_bytes_body(self):
+        token_client_v2 = token_client.TokenClient('fake_url')
+        self.useFixture(mockpatch.PatchObject(
+            token_client_v2, 'raw_request', return_value=(
+                httplib2.Response({'status': '200'}),
+                bytes(b'{"access": {"token": "fake_token"}}'))))
+        resp, body = token_client_v2.request('GET', 'fake_uri')
+        self.assertIsInstance(resp, httplib2.Response)
+        self.assertIsInstance(body, dict)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/tests/services/identity/v3/test_token_client.py
 
new/tempest-lib-0.9.0/tempest_lib/tests/services/identity/v3/test_token_client.py
--- 
old/tempest-lib-0.6.1/tempest_lib/tests/services/identity/v3/test_token_client.py
   2015-06-24 07:55:34.000000000 +0200
+++ 
new/tempest-lib-0.9.0/tempest_lib/tests/services/identity/v3/test_token_client.py
   2015-09-16 12:29:59.000000000 +0200
@@ -14,6 +14,7 @@
 
 import json
 
+import httplib2
 from oslotest import mockpatch
 
 from tempest_lib.common import rest_client
@@ -29,7 +30,7 @@
         self.fake_201_http = fake_http.fake_httplib2(return_type=201)
 
     def test_auth(self):
-        token_client_v3 = token_client.V3TokenClientJSON('fake_url')
+        token_client_v3 = token_client.V3TokenClient('fake_url')
         post_mock = self.useFixture(mockpatch.PatchObject(
             token_client_v3, 'post', return_value=self.fake_201_http.request(
                 'fake_url', body={'access': {'token': 'fake_token'}})))
@@ -52,7 +53,7 @@
                                                body=req_dict)
 
     def test_auth_with_tenant(self):
-        token_client_v2 = token_client.V3TokenClientJSON('fake_url')
+        token_client_v2 = token_client.V3TokenClient('fake_url')
         post_mock = self.useFixture(mockpatch.PatchObject(
             token_client_v2, 'post', return_value=self.fake_201_http.request(
                 'fake_url', body={'access': {'token': 'fake_token'}})))
@@ -79,3 +80,23 @@
 
         post_mock.mock.assert_called_once_with('fake_url/auth/tokens',
                                                body=req_dict)
+
+    def test_request_with_str_body(self):
+        token_client_v3 = token_client.V3TokenClient('fake_url')
+        self.useFixture(mockpatch.PatchObject(
+            token_client_v3, 'raw_request', return_value=(
+                httplib2.Response({"status": "200"}),
+                str('{"access": {"token": "fake_token"}}'))))
+        resp, body = token_client_v3.request('GET', 'fake_uri')
+        self.assertIsInstance(resp, httplib2.Response)
+        self.assertIsInstance(body, dict)
+
+    def test_request_with_bytes_body(self):
+        token_client_v3 = token_client.V3TokenClient('fake_url')
+        self.useFixture(mockpatch.PatchObject(
+            token_client_v3, 'raw_request', return_value=(
+                httplib2.Response({"status": "200"}),
+                bytes(b'{"access": {"token": "fake_token"}}'))))
+        resp, body = token_client_v3.request('GET', 'fake_uri')
+        self.assertIsInstance(resp, httplib2.Response)
+        self.assertIsInstance(body, dict)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib/tests/test_auth.py 
new/tempest-lib-0.9.0/tempest_lib/tests/test_auth.py
--- old/tempest-lib-0.6.1/tempest_lib/tests/test_auth.py        2015-06-24 
07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/tests/test_auth.py        2015-09-16 
12:29:59.000000000 +0200
@@ -120,7 +120,7 @@
 
     def setUp(self):
         super(TestKeystoneV2AuthProvider, self).setUp()
-        self.stubs.Set(v2_client.TokenClientJSON, 'raw_request',
+        self.stubs.Set(v2_client.TokenClient, 'raw_request',
                        fake_identity._fake_v2_response)
         self.target_url = 'test_api'
 
@@ -341,7 +341,7 @@
 
     def setUp(self):
         super(TestKeystoneV3AuthProvider, self).setUp()
-        self.stubs.Set(v3_client.V3TokenClientJSON, 'raw_request',
+        self.stubs.Set(v3_client.V3TokenClient, 'raw_request',
                        fake_identity._fake_v3_response)
 
     def _get_fake_alt_identity(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/tests/test_credentials.py 
new/tempest-lib-0.9.0/tempest_lib/tests/test_credentials.py
--- old/tempest-lib-0.6.1/tempest_lib/tests/test_credentials.py 2015-06-24 
07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/tests/test_credentials.py 2015-09-16 
12:29:59.000000000 +0200
@@ -67,7 +67,7 @@
 
     identity_response = fake_identity._fake_v2_response
     credentials_class = auth.KeystoneV2Credentials
-    tokenclient_class = v2_client.TokenClientJSON
+    tokenclient_class = v2_client.TokenClient
     identity_version = 'v2'
 
     def setUp(self):
@@ -147,7 +147,7 @@
 
     credentials_class = auth.KeystoneV3Credentials
     identity_response = fake_identity._fake_v3_response
-    tokenclient_class = v3_client.V3TokenClientJSON
+    tokenclient_class = v3_client.V3TokenClient
     identity_version = 'v3'
 
     def test_is_not_valid(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tempest-lib-0.6.1/tempest_lib/tests/test_rest_client.py 
new/tempest-lib-0.9.0/tempest_lib/tests/test_rest_client.py
--- old/tempest-lib-0.6.1/tempest_lib/tests/test_rest_client.py 2015-06-24 
07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib/tests/test_rest_client.py 2015-09-16 
12:29:59.000000000 +0200
@@ -12,6 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import copy
 import json
 
 import httplib2
@@ -306,67 +307,56 @@
     def test_response_less_than_400(self):
         self.rest_client._error_checker(**self.set_data("399"))
 
+    def _test_error_checker(self, exception_type, data):
+        e = self.assertRaises(exception_type,
+                              self.rest_client._error_checker,
+                              **data)
+        self.assertEqual(e.resp, data['resp'])
+        self.assertTrue(hasattr(e, 'resp_body'))
+        return e
+
     def test_response_400(self):
-        self.assertRaises(exceptions.BadRequest,
-                          self.rest_client._error_checker,
-                          **self.set_data("400"))
+        self._test_error_checker(exceptions.BadRequest, self.set_data("400"))
 
     def test_response_401(self):
-        self.assertRaises(exceptions.Unauthorized,
-                          self.rest_client._error_checker,
-                          **self.set_data("401"))
+        self._test_error_checker(exceptions.Unauthorized, self.set_data("401"))
 
     def test_response_403(self):
-        self.assertRaises(exceptions.Forbidden,
-                          self.rest_client._error_checker,
-                          **self.set_data("403"))
+        self._test_error_checker(exceptions.Forbidden, self.set_data("403"))
 
     def test_response_404(self):
-        self.assertRaises(exceptions.NotFound,
-                          self.rest_client._error_checker,
-                          **self.set_data("404"))
+        self._test_error_checker(exceptions.NotFound, self.set_data("404"))
 
     def test_response_409(self):
-        self.assertRaises(exceptions.Conflict,
-                          self.rest_client._error_checker,
-                          **self.set_data("409"))
+        self._test_error_checker(exceptions.Conflict, self.set_data("409"))
 
     def test_response_413(self):
-        self.assertRaises(exceptions.OverLimit,
-                          self.rest_client._error_checker,
-                          **self.set_data("413"))
+        self._test_error_checker(exceptions.OverLimit, self.set_data("413"))
 
     def test_response_413_without_absolute_limit(self):
-        self.assertRaises(exceptions.RateLimitExceeded,
-                          self.rest_client._error_checker,
-                          **self.set_data("413", absolute_limit=False))
+        self._test_error_checker(exceptions.RateLimitExceeded,
+                                 self.set_data("413", absolute_limit=False))
 
     def test_response_415(self):
-        self.assertRaises(exceptions.InvalidContentType,
-                          self.rest_client._error_checker,
-                          **self.set_data("415"))
+        self._test_error_checker(exceptions.InvalidContentType,
+                                 self.set_data("415"))
 
     def test_response_422(self):
-        self.assertRaises(exceptions.UnprocessableEntity,
-                          self.rest_client._error_checker,
-                          **self.set_data("422"))
+        self._test_error_checker(exceptions.UnprocessableEntity,
+                                 self.set_data("422"))
 
     def test_response_500_with_text(self):
         # _parse_resp is expected to return 'str'
-        self.assertRaises(exceptions.ServerFault,
-                          self.rest_client._error_checker,
-                          **self.set_data("500"))
+        self._test_error_checker(exceptions.ServerFault, self.set_data("500"))
 
     def test_response_501_with_text(self):
-        self.assertRaises(exceptions.NotImplemented,
-                          self.rest_client._error_checker,
-                          **self.set_data("501"))
+        self._test_error_checker(exceptions.NotImplemented,
+                                 self.set_data("501"))
 
     def test_response_400_with_dict(self):
         r_body = '{"resp_body": {"err": "fake_resp_body"}}'
-        e = self.assertRaises(exceptions.BadRequest,
-                              self.rest_client._error_checker,
-                              **self.set_data("400", r_body=r_body))
+        e = self._test_error_checker(exceptions.BadRequest,
+                                     self.set_data("400", r_body=r_body))
 
         if self.c_type == 'application/json':
             expected = {"err": "fake_resp_body"}
@@ -376,9 +366,8 @@
 
     def test_response_401_with_dict(self):
         r_body = '{"resp_body": {"err": "fake_resp_body"}}'
-        e = self.assertRaises(exceptions.Unauthorized,
-                              self.rest_client._error_checker,
-                              **self.set_data("401", r_body=r_body))
+        e = self._test_error_checker(exceptions.Unauthorized,
+                                     self.set_data("401", r_body=r_body))
 
         if self.c_type == 'application/json':
             expected = {"err": "fake_resp_body"}
@@ -388,9 +377,8 @@
 
     def test_response_403_with_dict(self):
         r_body = '{"resp_body": {"err": "fake_resp_body"}}'
-        e = self.assertRaises(exceptions.Forbidden,
-                              self.rest_client._error_checker,
-                              **self.set_data("403", r_body=r_body))
+        e = self._test_error_checker(exceptions.Forbidden,
+                                     self.set_data("403", r_body=r_body))
 
         if self.c_type == 'application/json':
             expected = {"err": "fake_resp_body"}
@@ -400,9 +388,8 @@
 
     def test_response_404_with_dict(self):
         r_body = '{"resp_body": {"err": "fake_resp_body"}}'
-        e = self.assertRaises(exceptions.NotFound,
-                              self.rest_client._error_checker,
-                              **self.set_data("404", r_body=r_body))
+        e = self._test_error_checker(exceptions.NotFound,
+                                     self.set_data("404", r_body=r_body))
 
         if self.c_type == 'application/json':
             expected = {"err": "fake_resp_body"}
@@ -412,18 +399,16 @@
 
     def test_response_404_with_invalid_dict(self):
         r_body = '{"foo": "bar"]'
-        e = self.assertRaises(exceptions.NotFound,
-                              self.rest_client._error_checker,
-                              **self.set_data("404", r_body=r_body))
+        e = self._test_error_checker(exceptions.NotFound,
+                                     self.set_data("404", r_body=r_body))
 
         expected = r_body
         self.assertEqual(expected, e.resp_body)
 
     def test_response_409_with_dict(self):
         r_body = '{"resp_body": {"err": "fake_resp_body"}}'
-        e = self.assertRaises(exceptions.Conflict,
-                              self.rest_client._error_checker,
-                              **self.set_data("409", r_body=r_body))
+        e = self._test_error_checker(exceptions.Conflict,
+                                     self.set_data("409", r_body=r_body))
 
         if self.c_type == 'application/json':
             expected = {"err": "fake_resp_body"}
@@ -433,9 +418,8 @@
 
     def test_response_500_with_dict(self):
         r_body = '{"resp_body": {"err": "fake_resp_body"}}'
-        e = self.assertRaises(exceptions.ServerFault,
-                              self.rest_client._error_checker,
-                              **self.set_data("500", r_body=r_body))
+        e = self._test_error_checker(exceptions.ServerFault,
+                                     self.set_data("500", r_body=r_body))
 
         if self.c_type == 'application/json':
             expected = {"err": "fake_resp_body"}
@@ -445,16 +429,14 @@
 
     def test_response_501_with_dict(self):
         r_body = '{"resp_body": {"err": "fake_resp_body"}}'
-        self.assertRaises(exceptions.NotImplemented,
-                          self.rest_client._error_checker,
-                          **self.set_data("501", r_body=r_body))
+        self._test_error_checker(exceptions.NotImplemented,
+                                 self.set_data("501", r_body=r_body))
 
     def test_response_bigger_than_400(self):
         # Any response code, that bigger than 400, and not in
         # (401, 403, 404, 409, 413, 422, 500, 501)
-        self.assertRaises(exceptions.UnexpectedResponseCode,
-                          self.rest_client._error_checker,
-                          **self.set_data("402"))
+        self._test_error_checker(exceptions.UnexpectedResponseCode,
+                                 self.set_data("402"))
 
 
 class TestRestClientErrorCheckerTEXT(TestRestClientErrorCheckerJSON):
@@ -464,9 +446,8 @@
         # This test is required only in one exemplar
         # Any response code, that bigger than 400, and not in
         # (401, 403, 404, 409, 413, 422, 500, 501)
-        self.assertRaises(exceptions.InvalidContentType,
-                          self.rest_client._error_checker,
-                          **self.set_data("405", enc="fake_enc"))
+        self._test_error_checker(exceptions.UnexpectedContentType,
+                                 self.set_data("405", enc="fake_enc"))
 
     def test_response_413_without_absolute_limit(self):
         # Skip this test because rest_client cannot get overLimit message
@@ -691,9 +672,15 @@
         }
     }
 
-    def test_validate_pass(self):
+    def test_validate_pass_with_http_success_code(self):
+        body = {'foo': 12}
+        self._test_validate_pass(self.schema, body, status=200)
+
+    def test_validate_pass_with_http_redirect_code(self):
         body = {'foo': 12}
-        self._test_validate_pass(self.schema, body)
+        schema = copy.deepcopy(self.schema)
+        schema['status_code'] = 300
+        self._test_validate_pass(schema, body, status=300)
 
     def test_validate_not_http_success_code(self):
         schema = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib.egg-info/PKG-INFO 
new/tempest-lib-0.9.0/tempest_lib.egg-info/PKG-INFO
--- old/tempest-lib-0.6.1/tempest_lib.egg-info/PKG-INFO 2015-06-24 
07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib.egg-info/PKG-INFO 2015-09-16 
12:30:44.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: tempest-lib
-Version: 0.6.1
+Version: 0.9.0
 Summary: OpenStack Functional Testing Library
 Home-page: http://www.openstack.org/
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib.egg-info/SOURCES.txt 
new/tempest-lib-0.9.0/tempest_lib.egg-info/SOURCES.txt
--- old/tempest-lib-0.6.1/tempest_lib.egg-info/SOURCES.txt      2015-06-24 
07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib.egg-info/SOURCES.txt      2015-09-16 
12:30:44.000000000 +0200
@@ -37,6 +37,11 @@
 tempest_lib.egg-info/pbr.json
 tempest_lib.egg-info/requires.txt
 tempest_lib.egg-info/top_level.txt
+tempest_lib/api_schema/__init__.py
+tempest_lib/api_schema/response/__init__.py
+tempest_lib/api_schema/response/compute/__init__.py
+tempest_lib/api_schema/response/compute/v2_1/__init__.py
+tempest_lib/api_schema/response/compute/v2_1/agents.py
 tempest_lib/cli/__init__.py
 tempest_lib/cli/base.py
 tempest_lib/cli/output_parser.py
@@ -50,6 +55,8 @@
 tempest_lib/common/utils/data_utils.py
 tempest_lib/common/utils/misc.py
 tempest_lib/services/__init__.py
+tempest_lib/services/compute/__init__.py
+tempest_lib/services/compute/agents_client.py
 tempest_lib/services/identity/__init__.py
 tempest_lib/services/identity/v2/__init__.py
 tempest_lib/services/identity/v2/token_client.py
@@ -70,12 +77,16 @@
 tempest_lib/tests/test_tempest_lib.py
 tempest_lib/tests/cli/__init__.py
 tempest_lib/tests/cli/test_command_failed.py
+tempest_lib/tests/cli/test_execute.py
 tempest_lib/tests/cli/test_output_parser.py
 tempest_lib/tests/common/__init__.py
 tempest_lib/tests/common/utils/__init__.py
 tempest_lib/tests/common/utils/test_data_utils.py
 tempest_lib/tests/common/utils/test_misc.py
 tempest_lib/tests/services/__init__.py
+tempest_lib/tests/services/compute/__init__.py
+tempest_lib/tests/services/compute/base.py
+tempest_lib/tests/services/compute/test_agents_client.py
 tempest_lib/tests/services/identity/v2/__init__.py
 tempest_lib/tests/services/identity/v2/test_token_client.py
 tempest_lib/tests/services/identity/v3/__init__.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib.egg-info/pbr.json 
new/tempest-lib-0.9.0/tempest_lib.egg-info/pbr.json
--- old/tempest-lib-0.6.1/tempest_lib.egg-info/pbr.json 2015-06-24 
07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib.egg-info/pbr.json 2015-09-16 
12:30:44.000000000 +0200
@@ -1 +1 @@
-{"is_release": true, "git_version": "31662ca"}
\ No newline at end of file
+{"git_version": "b501a03", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tempest_lib.egg-info/requires.txt 
new/tempest-lib-0.9.0/tempest_lib.egg-info/requires.txt
--- old/tempest-lib-0.6.1/tempest_lib.egg-info/requires.txt     2015-06-24 
07:56:19.000000000 +0200
+++ new/tempest-lib-0.9.0/tempest_lib.egg-info/requires.txt     2015-09-16 
12:30:44.000000000 +0200
@@ -1,10 +1,10 @@
-pbr<2.0,>=0.11
+pbr<2.0,>=1.6
 Babel>=1.3
-fixtures>=0.3.14
+fixtures>=1.3.1
 iso8601>=0.1.9
 jsonschema!=2.5.0,<3.0.0,>=2.0.0
 httplib2>=0.7.5
 paramiko>=1.13.0
 six>=1.9.0
-oslo.log>=1.2.0 # Apache-2.0
+oslo.log>=1.8.0
 os-testr>=0.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/test-requirements.txt 
new/tempest-lib-0.9.0/test-requirements.txt
--- old/tempest-lib-0.6.1/test-requirements.txt 2015-06-24 07:55:34.000000000 
+0200
+++ new/tempest-lib-0.9.0/test-requirements.txt 2015-09-16 12:29:59.000000000 
+0200
@@ -9,9 +9,9 @@
 python-subunit>=0.0.18
 sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
 oslosphinx>=2.5.0 # Apache-2.0
-oslotest>=1.5.1 # Apache-2.0
+oslotest>=1.10.0 # Apache-2.0
 testrepository>=0.0.18
 testscenarios>=0.4
 testtools>=1.4.0
-mock>=1.0
+mock>=1.2
 ddt>=0.7.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tempest-lib-0.6.1/tools/migrate_from_tempest.sh 
new/tempest-lib-0.9.0/tools/migrate_from_tempest.sh
--- old/tempest-lib-0.6.1/tools/migrate_from_tempest.sh 2015-06-24 
07:55:34.000000000 +0200
+++ new/tempest-lib-0.9.0/tools/migrate_from_tempest.sh 2015-09-16 
12:30:00.000000000 +0200
@@ -49,28 +49,23 @@
 cd $tmpdir
 
 for file in $files; do
-    # get only commits that touch our files
-    commits="$commits $(git log --format=format:%h --no-merges --follow -- 
$file)"
-    # then their merge commits - which works fina since we merge commits
-    # individually.
-    merge_commits="$merge_commits $(git log --format=format:%h --merges 
--first-parent -- $file)"
+    # Get the latest change-id for each file
+    change_id=`git log -n1 --grep "Change-Id: " -- $file | grep "Change-Id: " 
| awk '{print $2}'`
+    CHANGE_LIST=`echo -e "$CHANGE_LIST\n * $file: $change_id"`
 done
 
-pattern="\n$(echo $commits $merge_commits | sed -e 's/ /\\|/g')"
-
-# order them by filtering each one in the order it appears on rev-list
-SHA1_LIST=$(git rev-list --oneline HEAD | grep $pattern)
-
 # Move files and commit
 cd -
 file_list=''
 for file in $files; do
     filename=`basename $file`
+    dirname=`dirname $file`
     if [ -n "$output_dir" ]; then
-        dest_file="$output_dir/$filename"
+        dirname="$output_dir"
     else
-        dest_file="tempest_lib/$filename"
+        dirname=`echo $dirname | sed s@tempest\/@tempest_lib/\@`
     fi
+    dest_file="$dirname/$filename"
     cp -r "$tmpdir/$file" "$dest_file"
     git add "$dest_file"
     if [[ -z "$file_list" ]]; then
@@ -86,4 +81,4 @@
 commit_message="Migrated $file_list from tempest"
 pre_list=$"This migrates the above files from tempest. This includes tempest 
commits:"
 post_list=$"to see the commit history for these files refer to the above sha1s 
in the tempest repository"
-git commit -m "$commit_message" -m "$pre_list" -m "$SHA1_LIST" -m "$post_list"
+git commit -m "$commit_message" -m "$pre_list" -m "$CHANGE_LIST" -m 
"$post_list"


Reply via email to