Merge "Addition of XML support to test_console_output.py"
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 884d147..c96fc4f 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -212,8 +212,8 @@
         #TODO(afazekas): Make sure we can validate all responses, and the
         #http library does not do any action automatically
         if (resp.status in set((204, 205, 304)) or resp.status < 200 or
-            method.upper() == 'HEAD') and resp_body:
-            raise exceptions.ResponseWithNonEmptyBody(status=resp.status)
+                method.upper() == 'HEAD') and resp_body:
+                raise exceptions.ResponseWithNonEmptyBody(status=resp.status)
 
         #NOTE(afazekas):
         # If the HTTP Status Code is 205
@@ -226,8 +226,8 @@
 
         if (resp.status == 205 and
             0 != len(set(resp.keys()) - set(('status',)) -
-            self.response_header_lc - self.general_header_lc)):
-            raise exceptions.ResponseWithEntity()
+                     self.response_header_lc - self.general_header_lc)):
+                        raise exceptions.ResponseWithEntity()
 
         #NOTE(afazekas)
         # Now the swift sometimes (delete not empty container)
@@ -264,7 +264,7 @@
             self._log(req_url, body, resp, resp_body)
             if 'overLimit' in resp_body:
                 raise exceptions.OverLimit(resp_body['overLimit']['message'])
-            elif 'limit' in resp_body['message']:
+            elif 'exceeded' in resp_body['message']:
                 raise exceptions.OverLimit(resp_body['message'])
             elif depth < MAX_RECURSION_DEPTH:
                 delay = resp['Retry-After'] if 'Retry-After' in resp else 60
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index 5bf8de0..0047b50 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -19,6 +19,7 @@
 import json
 import re
 from tempest.common.rest_client import RestClient
+from tempest import exceptions
 
 
 class ObjectClient(RestClient):
@@ -141,12 +142,11 @@
         req_url = "%s/%s" % (self.base_url, url)
         resp, resp_body = self.http_obj.request(req_url, method,
                                                 headers=headers, body=body)
-        if resp.status in (401, 403):
-            try:
-                resp_body = json.loads(resp_body)
-                raise exceptions.Unauthorized(resp_body['error']['message'])
-            except ValueError:
-                pass
+
+        if resp.status == 401 or resp.status == 403:
+            self._log(req_url, body, resp, resp_body)
+            raise exceptions.Unauthorized()
+
         return resp, resp_body
 
     def get_object(self, container, object_name, metadata=None):
@@ -159,3 +159,22 @@
         url = "{0}/{1}".format(container, object_name)
         resp, body = self.get(url, headers=headers)
         return resp, body
+
+    def create_object(self, container, object_name, data, metadata=None):
+        """Create storage object"""
+
+        headers = {}
+        if metadata:
+            for key in metadata:
+                headers[str(key)] = metadata[key]
+
+        url = "%s/%s" % (str(container), str(object_name))
+        resp, body = self.put(url, data, headers=headers)
+        return resp, body
+
+    def delete_object(self, container, object_name):
+        """Delete storage object"""
+
+        url = "%s/%s" % (str(container), str(object_name))
+        resp, body = self.delete(url)
+        return resp, body
diff --git a/tempest/tests/object_storage/test_object_services.py b/tempest/tests/object_storage/test_object_services.py
index 807a99e..43af072 100644
--- a/tempest/tests/object_storage/test_object_services.py
+++ b/tempest/tests/object_storage/test_object_services.py
@@ -19,6 +19,7 @@
 
 from tempest.common.utils.data_utils import arbitrary_string
 from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 from tempest.tests.object_storage import base
 
 
@@ -265,34 +266,104 @@
                 dst_container_name)
 
     @attr(type='smoke')
-    def test_access_object_without_using_creds(self):
+    def test_access_public_container_object_without_using_creds(self):
         """Make container public-readable, and access the object
            anonymously, e.g. without using credentials"""
 
-        # Update Container Metadata to make public readable
-        headers = {'X-Container-Read': '.r:*,.rlistings'}
-        resp, body = \
-            self.container_client.update_container_metadata(
-                self.container_name, metadata=headers, metadata_prefix='')
-        self.assertIn(resp['status'], '204')
+        try:
+            resp_meta = None
+            # Update Container Metadata to make public readable
+            cont_headers = {'X-Container-Read': '.r:*,.rlistings'}
+            resp_meta, body = \
+                self.container_client.update_container_metadata(
+                    self.container_name, metadata=cont_headers,
+                    metadata_prefix='')
+            self.assertEqual(resp_meta['status'], '204')
+
+            # Create Object
+            object_name = rand_name(name='Object')
+            data = arbitrary_string(size=len(object_name),
+                                    base_text=object_name)
+            resp, _ = self.object_client.create_object(self.container_name,
+                                                       object_name, data)
+            self.assertEqual(resp['status'], '201')
+
+            # List container metadata
+            resp_meta, _ = \
+                self.container_client.list_container_metadata(
+                    self.container_name)
+            self.assertEqual(resp_meta['status'], '204')
+            self.assertIn('x-container-read', resp_meta)
+            self.assertEqual(resp_meta['x-container-read'], '.r:*,.rlistings')
+
+            # Trying to Get Object with empty Headers as it is public readable
+            resp, body = \
+                self.custom_object_client.get_object(self.container_name,
+                                                     object_name, metadata={})
+            self.assertEqual(body, data)
+        finally:
+            if resp_meta['status'] == '204':
+                # Delete updated container metadata, to revert back.
+                resp, body = \
+                    self.container_client.delete_container_metadata(
+                        self.container_name, metadata=cont_headers,
+                        metadata_prefix='')
+
+                resp, _ = \
+                    self.container_client.list_container_metadata(
+                        self.container_name)
+                self.assertEqual(resp['status'], '204')
+                self.assertIn('x-container-read', resp)
+                self.assertEqual(resp['x-container-read'], 'x')
+
+    @attr(type='negative')
+    def test_access_object_without_using_creds(self):
+        """Attempt to access the object anonymously, e.g.
+        not using any credentials"""
 
         # Create Object
         object_name = rand_name(name='Object')
-        data = arbitrary_string(size=len(object_name) * 1,
+        data = arbitrary_string(size=len(object_name),
                                 base_text=object_name)
         resp, _ = self.object_client.create_object(self.container_name,
                                                    object_name, data)
         self.assertEqual(resp['status'], '201')
 
-        # List container metadata
-        resp, _ = \
-            self.container_client.list_container_metadata(self.container_name)
-        self.assertEqual(resp['status'], '204')
-        self.assertIn('x-container-read', resp)
-        self.assertEqual(resp['x-container-read'], '.r:*,.rlistings')
+        # Trying to Get Object with empty Headers
+        self.assertRaises(exceptions.Unauthorized,
+                          self.custom_object_client.get_object,
+                          self.container_name, object_name, metadata={})
 
-        # Trying to Get Object with empty Headers as it is public readable
-        resp, body = \
-            self.custom_object_client.get_object(self.container_name,
-                                                 object_name, metadata={})
-        self.assertEqual(body, data)
+    @attr(type='negative')
+    def test_write_object_without_using_creds(self):
+        """Attempt to write to the object anonymously, e.g.
+        not using any credentials"""
+
+        # Trying to Create Object with empty Headers
+        object_name = rand_name(name='Object')
+        data = arbitrary_string(size=len(object_name),
+                                base_text=object_name)
+        obj_headers = {'Content-Type': 'application/json',
+                       'Accept': 'application/json'}
+
+        self.assertRaises(exceptions.Unauthorized,
+                          self.custom_object_client.create_object,
+                          self.container_name, object_name, data,
+                          metadata=obj_headers)
+
+    @attr(type='negative')
+    def test_delete_object_without_using_creds(self):
+        """Attempt to delete the object anonymously,
+        e.g. not using any credentials"""
+
+        # Create Object
+        object_name = rand_name(name='Object')
+        data = arbitrary_string(size=len(object_name),
+                                base_text=object_name)
+        resp, _ = self.object_client.create_object(self.container_name,
+                                                   object_name, data)
+
+        # Trying to Delete Object with empty Headers
+        self.assertRaises(exceptions.Unauthorized,
+                          self.custom_object_client.delete_object,
+                          self.container_name, object_name)