additional tests
[pithos] / snf-pithos-tools / pithos / tools / test.py
index 35d5e9c..85c1f55 100755 (executable)
@@ -2,20 +2,20 @@
 #coding=utf8
 
 # Copyright 2011-2012 GRNET S.A. All rights reserved.
 #coding=utf8
 
 # Copyright 2011-2012 GRNET S.A. All rights reserved.
-# 
+#
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
 # conditions are met:
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
 # conditions are met:
-# 
+#
 #   1. Redistributions of source code must retain the above
 #      copyright notice, this list of conditions and the following
 #      disclaimer.
 #   1. Redistributions of source code must retain the above
 #      copyright notice, this list of conditions and the following
 #      disclaimer.
-# 
+#
 #   2. Redistributions in binary form must reproduce the above
 #      copyright notice, this list of conditions and the following
 #      disclaimer in the documentation and/or other materials
 #      provided with the distribution.
 #   2. Redistributions in binary form must reproduce the above
 #      copyright notice, this list of conditions and the following
 #      disclaimer in the documentation and/or other materials
 #      provided with the distribution.
-# 
+#
 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
-# 
+#
 # The views and conclusions contained in the software and
 # documentation are those of the authors and should not be
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
 # The views and conclusions contained in the software and
 # documentation are those of the authors and should not be
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from pithos.lib.client import Pithos_Client, Fault
-from pithos.lib.util import get_user, get_auth, get_server, get_api
+from pithos.tools.lib.client import Pithos_Client, Fault
+from pithos.tools.lib.util import get_user, get_auth, get_url
 
 from xml.dom import minidom
 from StringIO import StringIO
 from hashlib import new as newhasher
 from binascii import hexlify
 
 from xml.dom import minidom
 from StringIO import StringIO
 from hashlib import new as newhasher
 from binascii import hexlify
+from httplib import HTTPConnection
+from urlparse import urlparse
 
 import json
 import unittest
 
 import json
 import unittest
@@ -71,18 +73,16 @@ OTHER_ACCOUNTS = {
 class BaseTestCase(unittest.TestCase):
     #TODO unauthorized request
     def setUp(self):
 class BaseTestCase(unittest.TestCase):
     #TODO unauthorized request
     def setUp(self):
-        self.client = Pithos_Client(get_server(), get_auth(), get_user(),
-                                    get_api())
+        self.client = Pithos_Client(get_url(), get_auth(), get_user())
         self._clean_account()
         self._clean_account()
-        self.invalid_client = Pithos_Client(get_server(), get_auth(), 'invalid',
-                                            get_api())
-        
+        self.invalid_client = Pithos_Client(get_url(), get_auth(), 'invalid')
+
         #keep track of initial account groups
         self.initial_groups = self.client.retrieve_account_groups()
         #keep track of initial account groups
         self.initial_groups = self.client.retrieve_account_groups()
-        
+
         #keep track of initial account meta
         self.initial_meta = self.client.retrieve_account_metadata(restricted=True)
         #keep track of initial account meta
         self.initial_meta = self.client.retrieve_account_metadata(restricted=True)
-        
+
         self.extended = {
             'container':(
                 'name',
         self.extended = {
             'container':(
                 'name',
@@ -98,7 +98,7 @@ class BaseTestCase(unittest.TestCase):
                 'content_encoding',
                 'last_modified',)}
         self.return_codes = (400, 401, 403, 404, 503,)
                 'content_encoding',
                 'last_modified',)}
         self.return_codes = (400, 401, 403, 404, 503,)
-    
+
     def tearDown(self):
         #delete additionally created meta
         l = []
     def tearDown(self):
         #delete additionally created meta
         l = []
@@ -106,7 +106,7 @@ class BaseTestCase(unittest.TestCase):
             if m not in self.initial_meta:
                 l.append(m)
         self.client.delete_account_metadata(l)
             if m not in self.initial_meta:
                 l.append(m)
         self.client.delete_account_metadata(l)
-        
+
         #delete additionally created groups
         l = []
         for g in self.client.retrieve_account_groups():
         #delete additionally created groups
         l = []
         for g in self.client.retrieve_account_groups():
@@ -114,7 +114,7 @@ class BaseTestCase(unittest.TestCase):
                 l.append(g)
         self.client.unset_account_groups(l)
         self._clean_account()
                 l.append(g)
         self.client.unset_account_groups(l)
         self._clean_account()
-    
+
     def _clean_account(self):
         for c in self.client.list_containers():
             while True:
     def _clean_account(self):
         for c in self.client.list_containers():
             while True:
@@ -126,7 +126,7 @@ class BaseTestCase(unittest.TestCase):
                 for o in objects:
                     self.client.delete_object(c, o)
             self.client.delete_container(c)
                 for o in objects:
                     self.client.delete_object(c, o)
             self.client.delete_container(c)
-    
+
     def assert_status(self, status, codes):
         l = [elem for elem in self.return_codes]
         if type(codes) == types.ListType:
     def assert_status(self, status, codes):
         l = [elem for elem in self.return_codes]
         if type(codes) == types.ListType:
@@ -134,13 +134,13 @@ class BaseTestCase(unittest.TestCase):
         else:
             l.append(codes)
         self.assertTrue(status in l)
         else:
             l.append(codes)
         self.assertTrue(status in l)
-    
+
     def assert_extended(self, data, format, type, size=10000):
         if format == 'xml':
             self._assert_xml(data, type, size)
         elif format == 'json':
             self._assert_json(data, type, size)
     def assert_extended(self, data, format, type, size=10000):
         if format == 'xml':
             self._assert_xml(data, type, size)
         elif format == 'json':
             self._assert_json(data, type, size)
-    
+
     def _assert_json(self, data, type, size):
         convert = lambda s: s.lower()
         info = [convert(elem) for elem in self.extended[type]]
     def _assert_json(self, data, type, size):
         convert = lambda s: s.lower()
         info = [convert(elem) for elem in self.extended[type]]
@@ -150,7 +150,7 @@ class BaseTestCase(unittest.TestCase):
                 if 'subdir' in i.keys():
                     continue
                 self.assertTrue(item in i.keys())
                 if 'subdir' in i.keys():
                     continue
                 self.assertTrue(item in i.keys())
-    
+
     def _assert_xml(self, data, type, size):
         convert = lambda s: s.lower()
         info = [convert(elem) for elem in self.extended[type]]
     def _assert_xml(self, data, type, size):
         convert = lambda s: s.lower()
         info = [convert(elem) for elem in self.extended[type]]
@@ -164,7 +164,7 @@ class BaseTestCase(unittest.TestCase):
         for e in entities:
             for item in info:
                 self.assertTrue(e.getElementsByTagName(item))
         for e in entities:
             for item in info:
                 self.assertTrue(e.getElementsByTagName(item))
-    
+
     def assert_raises_fault(self, status, callableObj, *args, **kwargs):
         """
         asserts that a Fault with a specific status is raised
     def assert_raises_fault(self, status, callableObj, *args, **kwargs):
         """
         asserts that a Fault with a specific status is raised
@@ -178,7 +178,7 @@ class BaseTestCase(unittest.TestCase):
                 self.failUnless(f.status in status)
             else:
                 self.failUnless(f.status == status)
                 self.failUnless(f.status in status)
             else:
                 self.failUnless(f.status == status)
-    
+
     def assert_not_raises_fault(self, status, callableObj, *args, **kwargs):
         """
         asserts that a Fault with a specific status is not raised
     def assert_not_raises_fault(self, status, callableObj, *args, **kwargs):
         """
         asserts that a Fault with a specific status is not raised
@@ -188,7 +188,7 @@ class BaseTestCase(unittest.TestCase):
             r = callableObj(*args, **kwargs)
         except Fault, f:
             self.failIfEqual(f.status, status)
             r = callableObj(*args, **kwargs)
         except Fault, f:
             self.failIfEqual(f.status, status)
-    
+
     def assert_container_exists(self, container):
         """
         asserts the existence of a container
     def assert_container_exists(self, container):
         """
         asserts the existence of a container
@@ -197,14 +197,14 @@ class BaseTestCase(unittest.TestCase):
             self.client.retrieve_container_metadata(container)
         except Fault, f:
             self.failIf(f.status == 404)
             self.client.retrieve_container_metadata(container)
         except Fault, f:
             self.failIf(f.status == 404)
-    
+
     def assert_container_not_exists(self, container):
         """
         asserts there is no such a container
         """
         self.assert_raises_fault(404, self.client.retrieve_container_metadata,
                                  container)
     def assert_container_not_exists(self, container):
         """
         asserts there is no such a container
         """
         self.assert_raises_fault(404, self.client.retrieve_container_metadata,
                                  container)
-    
+
     def assert_object_exists(self, container, object):
         """
         asserts the existence of an object
     def assert_object_exists(self, container, object):
         """
         asserts the existence of an object
@@ -213,25 +213,25 @@ class BaseTestCase(unittest.TestCase):
             self.client.retrieve_object_metadata(container, object)
         except Fault, f:
             self.failIf(f.status == 404)
             self.client.retrieve_object_metadata(container, object)
         except Fault, f:
             self.failIf(f.status == 404)
-    
+
     def assert_object_not_exists(self, container, object):
         """
         asserts there is no such an object
         """
         self.assert_raises_fault(404, self.client.retrieve_object_metadata,
                                  container, object)
     def assert_object_not_exists(self, container, object):
         """
         asserts there is no such an object
         """
         self.assert_raises_fault(404, self.client.retrieve_object_metadata,
                                  container, object)
-    
+
     def assert_versionlist_structure(self, versionlist):
         self.assertTrue(type(versionlist) == types.ListType)
         for elem in versionlist:
             self.assertTrue(type(elem) == types.ListType)
             self.assertEqual(len(elem), 2)
     def assert_versionlist_structure(self, versionlist):
         self.assertTrue(type(versionlist) == types.ListType)
         for elem in versionlist:
             self.assertTrue(type(elem) == types.ListType)
             self.assertEqual(len(elem), 2)
-    
+
     def upload_random_data(self, container, name, length=1024, type=None,
                            enc=None, **meta):
         data = get_random_data(length)
         return self.upload_data(container, name, data, type, enc, **meta)
     def upload_random_data(self, container, name, length=1024, type=None,
                            enc=None, **meta):
         data = get_random_data(length)
         return self.upload_data(container, name, data, type, enc, **meta)
-    
+
     def upload_data(self, container, name, data, type=None, enc=None, etag=None,
                     **meta):
         obj = {}
     def upload_data(self, container, name, data, type=None, enc=None, etag=None,
                     **meta):
         obj = {}
@@ -239,10 +239,10 @@ class BaseTestCase(unittest.TestCase):
         try:
             obj['data'] = data
             obj['hash'] = compute_md5_hash(obj['data'])
         try:
             obj['data'] = data
             obj['hash'] = compute_md5_hash(obj['data'])
-            
+
             args = {}
             args['etag'] = etag if etag else obj['hash']
             args = {}
             args['etag'] = etag if etag else obj['hash']
-            
+
             try:
                 guess = mimetypes.guess_type(name)
                 type = type if type else guess[0]
             try:
                 guess = mimetypes.guess_type(name)
                 type = type if type else guess[0]
@@ -251,13 +251,13 @@ class BaseTestCase(unittest.TestCase):
                 pass
             args['content_type'] = type if type else 'plain/text'
             args['content_encoding'] = enc if enc else None
                 pass
             args['content_type'] = type if type else 'plain/text'
             args['content_encoding'] = enc if enc else None
-            
+
             obj['meta'] = args
             obj['meta'] = args
-            
+
             path = '/%s/%s' % (container, name)
             self.client.create_object(container, name, f=StringIO(obj['data']),
                                       meta=meta, **args)
             path = '/%s/%s' % (container, name)
             self.client.create_object(container, name, f=StringIO(obj['data']),
                                       meta=meta, **args)
-            
+
             return obj
         except IOError:
             return
             return obj
         except IOError:
             return
@@ -268,14 +268,14 @@ class AccountHead(BaseTestCase):
         self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
         for item in self.containers:
             self.client.create_container(item)
         self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
         for item in self.containers:
             self.client.create_container(item)
-        
+
         meta = {'foo':'bar'}
         self.client.update_account_metadata(**meta)
         #self.updated_meta = self.initial_meta.update(meta)
         meta = {'foo':'bar'}
         self.client.update_account_metadata(**meta)
         #self.updated_meta = self.initial_meta.update(meta)
-    
+
     def test_get_account_meta(self):
         meta = self.client.retrieve_account_metadata()
     def test_get_account_meta(self):
         meta = self.client.retrieve_account_metadata()
-        
+
         containers = self.client.list_containers()
         l = str(len(containers))
         self.assertEqual(meta['x-account-container-count'], l)
         containers = self.client.list_containers()
         l = str(len(containers))
         self.assertEqual(meta['x-account-container-count'], l)
@@ -284,32 +284,32 @@ class AccountHead(BaseTestCase):
             m = self.client.retrieve_container_metadata(c)
             size = size + int(m['x-container-bytes-used'])
         self.assertEqual(meta['x-account-bytes-used'], str(size))
             m = self.client.retrieve_container_metadata(c)
             size = size + int(m['x-container-bytes-used'])
         self.assertEqual(meta['x-account-bytes-used'], str(size))
-    
+
     def test_get_account_403(self):
         self.assert_raises_fault(403,
                                  self.invalid_client.retrieve_account_metadata)
     def test_get_account_403(self):
         self.assert_raises_fault(403,
                                  self.invalid_client.retrieve_account_metadata)
-    
+
     def test_get_account_meta_until(self):
         t = datetime.datetime.utcnow()
         past = t - datetime.timedelta(minutes=-15)
         past = int(_time.mktime(past.timetuple()))
     def test_get_account_meta_until(self):
         t = datetime.datetime.utcnow()
         past = t - datetime.timedelta(minutes=-15)
         past = int(_time.mktime(past.timetuple()))
-        
+
         meta = {'premium':True}
         self.client.update_account_metadata(**meta)
         meta = self.client.retrieve_account_metadata(restricted=True,
                                                      until=past)
         self.assertTrue('premium' not in meta)
         meta = {'premium':True}
         self.client.update_account_metadata(**meta)
         meta = self.client.retrieve_account_metadata(restricted=True,
                                                      until=past)
         self.assertTrue('premium' not in meta)
-        
+
         meta = self.client.retrieve_account_metadata(restricted=True)
         self.assertTrue('premium' in meta)
         meta = self.client.retrieve_account_metadata(restricted=True)
         self.assertTrue('premium' in meta)
-    
+
     def test_get_account_meta_until_invalid_date(self):
         meta = {'premium':True}
         self.client.update_account_metadata(**meta)
         meta = self.client.retrieve_account_metadata(restricted=True,
                                                      until='kshfksfh')
         self.assertTrue('premium' in meta)
     def test_get_account_meta_until_invalid_date(self):
         meta = {'premium':True}
         self.client.update_account_metadata(**meta)
         meta = self.client.retrieve_account_metadata(restricted=True,
                                                      until='kshfksfh')
         self.assertTrue('premium' in meta)
-    
+
 class AccountGet(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
 class AccountGet(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
@@ -317,33 +317,33 @@ class AccountGet(BaseTestCase):
         self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
         for item in self.containers:
             self.client.create_container(item)
         self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
         for item in self.containers:
             self.client.create_container(item)
-    
+
     def test_list(self):
         #list containers
         containers = self.client.list_containers()
         self.assertEquals(self.containers, containers)
     def test_list(self):
         #list containers
         containers = self.client.list_containers()
         self.assertEquals(self.containers, containers)
-    
+
     def test_list_403(self):
         self.assert_raises_fault(403, self.invalid_client.list_containers)
     def test_list_403(self):
         self.assert_raises_fault(403, self.invalid_client.list_containers)
-    
+
     def test_list_with_limit(self):
         limit = 2
         containers = self.client.list_containers(limit=limit)
         self.assertEquals(len(containers), limit)
         self.assertEquals(self.containers[:2], containers)
     def test_list_with_limit(self):
         limit = 2
         containers = self.client.list_containers(limit=limit)
         self.assertEquals(len(containers), limit)
         self.assertEquals(self.containers[:2], containers)
-    
+
     def test_list_with_marker(self):
         l = 2
         m = 'bananas'
         containers = self.client.list_containers(limit=l, marker=m)
         i = self.containers.index(m) + 1
         self.assertEquals(self.containers[i:(i+l)], containers)
     def test_list_with_marker(self):
         l = 2
         m = 'bananas'
         containers = self.client.list_containers(limit=l, marker=m)
         i = self.containers.index(m) + 1
         self.assertEquals(self.containers[i:(i+l)], containers)
-        
+
         m = 'oranges'
         containers = self.client.list_containers(limit=l, marker=m)
         i = self.containers.index(m) + 1
         self.assertEquals(self.containers[i:(i+l)], containers)
         m = 'oranges'
         containers = self.client.list_containers(limit=l, marker=m)
         i = self.containers.index(m) + 1
         self.assertEquals(self.containers[i:(i+l)], containers)
-    
+
     def test_list_json_with_marker(self):
         l = 2
         m = 'bananas'
     def test_list_json_with_marker(self):
         l = 2
         m = 'bananas'
@@ -351,7 +351,7 @@ class AccountGet(BaseTestCase):
         self.assert_extended(containers, 'json', 'container', l)
         self.assertEqual(containers[0]['name'], 'kiwis')
         self.assertEqual(containers[1]['name'], 'oranges')
         self.assert_extended(containers, 'json', 'container', l)
         self.assertEqual(containers[0]['name'], 'kiwis')
         self.assertEqual(containers[1]['name'], 'oranges')
-    
+
     def test_list_xml_with_marker(self):
         l = 2
         m = 'oranges'
     def test_list_xml_with_marker(self):
         l = 2
         m = 'oranges'
@@ -360,14 +360,14 @@ class AccountGet(BaseTestCase):
         nodes = xml.getElementsByTagName('name')
         self.assertEqual(len(nodes), 1)
         self.assertEqual(nodes[0].childNodes[0].data, 'pears')
         nodes = xml.getElementsByTagName('name')
         self.assertEqual(len(nodes), 1)
         self.assertEqual(nodes[0].childNodes[0].data, 'pears')
-    
+
     def test_if_modified_since(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
     def test_if_modified_since(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
-        
+
         #add a new container
         self.client.create_container('dummy')
         #add a new container
         self.client.create_container('dummy')
-        
+
         for f in DATE_FORMATS:
             past = t2.strftime(f)
             try:
         for f in DATE_FORMATS:
             past = t2.strftime(f)
             try:
@@ -375,142 +375,142 @@ class AccountGet(BaseTestCase):
                 self.assertEqual(len(c), len(self.containers) + 1)
             except Fault, f:
                 self.failIf(f.status == 304) #fail if not modified
                 self.assertEqual(len(c), len(self.containers) + 1)
             except Fault, f:
                 self.failIf(f.status == 304) #fail if not modified
-    
+
     def test_if_modified_since_invalid_date(self):
         c = self.client.list_containers(if_modified_since='')
         self.assertEqual(len(c), len(self.containers))
     def test_if_modified_since_invalid_date(self):
         c = self.client.list_containers(if_modified_since='')
         self.assertEqual(len(c), len(self.containers))
-    
+
     def test_if_not_modified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
     def test_if_not_modified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
-        
+
         for f in DATE_FORMATS:
             args = {'if_modified_since':'%s' %since.strftime(f)}
         for f in DATE_FORMATS:
             args = {'if_modified_since':'%s' %since.strftime(f)}
-            
+
             #assert not modified
             self.assert_raises_fault(304, self.client.list_containers, **args)
             #assert not modified
             self.assert_raises_fault(304, self.client.list_containers, **args)
-    
+
     def test_if_unmodified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
     def test_if_unmodified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
-        
+
         for f in DATE_FORMATS:
             c = self.client.list_containers(if_unmodified_since=since.strftime(f))
         for f in DATE_FORMATS:
             c = self.client.list_containers(if_unmodified_since=since.strftime(f))
-            
+
             #assert success
             self.assertEqual(self.containers, c)
             #assert success
             self.assertEqual(self.containers, c)
-    
+
     def test_if_unmodified_since_precondition_failed(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
     def test_if_unmodified_since_precondition_failed(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
-        
+
         #add a new container
         self.client.create_container('dummy')
         #add a new container
         self.client.create_container('dummy')
-        
+
         for f in DATE_FORMATS:
             past = t2.strftime(f)
         for f in DATE_FORMATS:
             past = t2.strftime(f)
-            
+
             args = {'if_unmodified_since':'%s' %past}
             args = {'if_unmodified_since':'%s' %past}
-            
+
             #assert precondition failed
             self.assert_raises_fault(412, self.client.list_containers, **args)
             #assert precondition failed
             self.assert_raises_fault(412, self.client.list_containers, **args)
-    
+
 class AccountPost(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
         self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
         for item in self.containers:
             self.client.create_container(item)
 class AccountPost(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
         self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
         for item in self.containers:
             self.client.create_container(item)
-        
+
         meta = {'foo':'bar'}
         self.client.update_account_metadata(**meta)
         self.updated_meta = self.initial_meta.update(meta)
         meta = {'foo':'bar'}
         self.client.update_account_metadata(**meta)
         self.updated_meta = self.initial_meta.update(meta)
-    
+
     def test_update_meta(self):
         with AssertMappingInvariant(self.client.retrieve_account_groups):
             meta = {'test':'test', 'tost':'tost'}
             self.client.update_account_metadata(**meta)
     def test_update_meta(self):
         with AssertMappingInvariant(self.client.retrieve_account_groups):
             meta = {'test':'test', 'tost':'tost'}
             self.client.update_account_metadata(**meta)
-            
+
             meta.update(self.initial_meta)
             self.assertEqual(meta,
                              self.client.retrieve_account_metadata(
                                 restricted=True))
             meta.update(self.initial_meta)
             self.assertEqual(meta,
                              self.client.retrieve_account_metadata(
                                 restricted=True))
-        
+
     def test_invalid_account_update_meta(self):
         meta = {'test':'test', 'tost':'tost'}
         self.assert_raises_fault(403,
                                  self.invalid_client.update_account_metadata,
                                  **meta)
     def test_invalid_account_update_meta(self):
         meta = {'test':'test', 'tost':'tost'}
         self.assert_raises_fault(403,
                                  self.invalid_client.update_account_metadata,
                                  **meta)
-    
+
     def test_reset_meta(self):
         with AssertMappingInvariant(self.client.retrieve_account_groups):
             meta = {'test':'test', 'tost':'tost'}
             self.client.update_account_metadata(**meta)
     def test_reset_meta(self):
         with AssertMappingInvariant(self.client.retrieve_account_groups):
             meta = {'test':'test', 'tost':'tost'}
             self.client.update_account_metadata(**meta)
-            
+
             meta = {'test':'test33'}
             self.client.reset_account_metadata(**meta)
             meta = {'test':'test33'}
             self.client.reset_account_metadata(**meta)
-            
+
             self.assertEqual(meta, self.client.retrieve_account_metadata(restricted=True))
             self.assertEqual(meta, self.client.retrieve_account_metadata(restricted=True))
-    
+
     def test_delete_meta(self):
         with AssertMappingInvariant(self.client.retrieve_account_groups):
             meta = {'test':'test', 'tost':'tost'}
             self.client.update_account_metadata(**meta)
     def test_delete_meta(self):
         with AssertMappingInvariant(self.client.retrieve_account_groups):
             meta = {'test':'test', 'tost':'tost'}
             self.client.update_account_metadata(**meta)
-            
+
             self.client.delete_account_metadata(meta.keys())
             self.client.delete_account_metadata(meta.keys())
-            
+
             account_meta = self.client.retrieve_account_metadata(restricted=True)
             for m in meta:
                 self.assertTrue(m not in account_meta.keys())
             account_meta = self.client.retrieve_account_metadata(restricted=True)
             for m in meta:
                 self.assertTrue(m not in account_meta.keys())
-    
+
     def test_set_account_groups(self):
         with AssertMappingInvariant(self.client.retrieve_account_metadata):
             groups = {'pithosdev':'verigak,gtsouk,chazapis'}
             self.client.set_account_groups(**groups)
     def test_set_account_groups(self):
         with AssertMappingInvariant(self.client.retrieve_account_metadata):
             groups = {'pithosdev':'verigak,gtsouk,chazapis'}
             self.client.set_account_groups(**groups)
-            
+
             self.assertEqual(set(groups['pithosdev']),
                              set(self.client.retrieve_account_groups()['pithosdev']))
             self.assertEqual(set(groups['pithosdev']),
                              set(self.client.retrieve_account_groups()['pithosdev']))
-            
+
             more_groups = {'clientsdev':'pkanavos,mvasilak'}
             self.client.set_account_groups(**more_groups)
             more_groups = {'clientsdev':'pkanavos,mvasilak'}
             self.client.set_account_groups(**more_groups)
-            
+
             groups.update(more_groups)
             self.assertEqual(set(groups['clientsdev']),
                              set(self.client.retrieve_account_groups()['clientsdev']))
             groups.update(more_groups)
             self.assertEqual(set(groups['clientsdev']),
                              set(self.client.retrieve_account_groups()['clientsdev']))
-    
+
     def test_reset_account_groups(self):
         with AssertMappingInvariant(self.client.retrieve_account_metadata):
             groups = {'pithosdev':'verigak,gtsouk,chazapis',
                       'clientsdev':'pkanavos,mvasilak'}
             self.client.set_account_groups(**groups)
     def test_reset_account_groups(self):
         with AssertMappingInvariant(self.client.retrieve_account_metadata):
             groups = {'pithosdev':'verigak,gtsouk,chazapis',
                       'clientsdev':'pkanavos,mvasilak'}
             self.client.set_account_groups(**groups)
-            
+
             self.assertEqual(set(groups['pithosdev'].split(',')),
                              set(self.client.retrieve_account_groups()['pithosdev'].split(',')))
             self.assertEqual(set(groups['clientsdev'].split(',')),
                              set(self.client.retrieve_account_groups()['clientsdev'].split(',')))
             self.assertEqual(set(groups['pithosdev'].split(',')),
                              set(self.client.retrieve_account_groups()['pithosdev'].split(',')))
             self.assertEqual(set(groups['clientsdev'].split(',')),
                              set(self.client.retrieve_account_groups()['clientsdev'].split(',')))
-            
+
             groups = {'pithosdev':'verigak,gtsouk,chazapis,papagian'}
             self.client.reset_account_groups(**groups)
             groups = {'pithosdev':'verigak,gtsouk,chazapis,papagian'}
             self.client.reset_account_groups(**groups)
-            
+
             self.assertEqual(set(groups['pithosdev'].split(',')),
                              set(self.client.retrieve_account_groups()['pithosdev'].split(',')))
             self.assertEqual(set(groups['pithosdev'].split(',')),
                              set(self.client.retrieve_account_groups()['pithosdev'].split(',')))
-    
+
     def test_delete_account_groups(self):
         with AssertMappingInvariant(self.client.retrieve_account_metadata):
             groups = {'pithosdev':'verigak,gtsouk,chazapis',
                       'clientsdev':'pkanavos,mvasilak'}
             self.client.set_account_groups(**groups)
     def test_delete_account_groups(self):
         with AssertMappingInvariant(self.client.retrieve_account_metadata):
             groups = {'pithosdev':'verigak,gtsouk,chazapis',
                       'clientsdev':'pkanavos,mvasilak'}
             self.client.set_account_groups(**groups)
-            
+
             self.client.unset_account_groups(groups.keys())
             self.client.unset_account_groups(groups.keys())
-            
+
             self.assertEqual({}, self.client.retrieve_account_groups())
             self.assertEqual({}, self.client.retrieve_account_groups())
-    
+
 class ContainerHead(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
         self.container = 'apples'
         self.client.create_container(self.container)
 class ContainerHead(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
         self.container = 'apples'
         self.client.create_container(self.container)
-    
+
     def test_get_meta(self):
         meta = {'trash':'true'}
         t1 = datetime.datetime.utcnow()
     def test_get_meta(self):
         meta = {'trash':'true'}
         t1 = datetime.datetime.utcnow()
@@ -521,7 +521,7 @@ class ContainerHead(BaseTestCase):
             self.assertEqual(headers['x-container-bytes-used'], str(len(o['data'])))
             t2 = datetime.datetime.strptime(headers['last-modified'], DATE_FORMATS[2])
             delta = (t2 - t1)
             self.assertEqual(headers['x-container-bytes-used'], str(len(o['data'])))
             t2 = datetime.datetime.strptime(headers['last-modified'], DATE_FORMATS[2])
             delta = (t2 - t1)
-            threashold = datetime.timedelta(seconds=1) 
+            threashold = datetime.timedelta(seconds=1)
             self.assertTrue(delta < threashold)
             self.assertTrue(headers['x-container-object-meta'])
             self.assertTrue('Trash' in headers['x-container-object-meta'])
             self.assertTrue(delta < threashold)
             self.assertTrue(headers['x-container-object-meta'])
             self.assertTrue('Trash' in headers['x-container-object-meta'])
@@ -537,23 +537,23 @@ class ContainerGet(BaseTestCase):
             self.obj.append(self.upload_random_data(self.container[0], o))
         for o in o_names[8:]:
             self.obj.append(self.upload_random_data(self.container[1], o))
             self.obj.append(self.upload_random_data(self.container[0], o))
         for o in o_names[8:]:
             self.obj.append(self.upload_random_data(self.container[1], o))
-    
+
     def test_list_objects(self):
         objects = self.client.list_objects(self.container[0])
         l = [elem['name'] for elem in self.obj[:8]]
         l.sort()
         self.assertEqual(objects, l)
     def test_list_objects(self):
         objects = self.client.list_objects(self.container[0])
         l = [elem['name'] for elem in self.obj[:8]]
         l.sort()
         self.assertEqual(objects, l)
-    
+
     def test_list_objects_containing_slash(self):
         self.client.create_container('test')
         self.upload_random_data('test', '/objectname')
     def test_list_objects_containing_slash(self):
         self.client.create_container('test')
         self.upload_random_data('test', '/objectname')
-        
+
         objects = self.client.list_objects('test')
         self.assertEqual(objects, ['/objectname'])
         objects = self.client.list_objects('test')
         self.assertEqual(objects, ['/objectname'])
-        
+
         objects = self.client.list_objects('test', format='json')
         self.assertEqual(objects[0]['name'], '/objectname')
         objects = self.client.list_objects('test', format='json')
         self.assertEqual(objects[0]['name'], '/objectname')
-        
+
         objects = self.client.list_objects('test', format='xml')
         self.assert_extended(objects, 'xml', 'object')
         node_name = objects.getElementsByTagName('name')[0]
         objects = self.client.list_objects('test', format='xml')
         self.assert_extended(objects, 'xml', 'object')
         node_name = objects.getElementsByTagName('name')[0]
@@ -564,7 +564,7 @@ class ContainerGet(BaseTestCase):
         l = [elem['name'] for elem in self.obj[:8]]
         l.sort()
         self.assertEqual(objects, l[:2])
         l = [elem['name'] for elem in self.obj[:8]]
         l.sort()
         self.assertEqual(objects, l[:2])
-        
+
         markers = ['How To Win Friends And Influence People.pdf',
                    'moms_birthday.jpg']
         limit = 4
         markers = ['How To Win Friends And Influence People.pdf',
                    'moms_birthday.jpg']
         limit = 4
@@ -577,45 +577,45 @@ class ContainerGet(BaseTestCase):
             end = start + limit
             end = end if len(l) >= end else len(l)
             self.assertEqual(objects, l[start:end])
             end = start + limit
             end = end if len(l) >= end else len(l)
             self.assertEqual(objects, l[start:end])
-    
+
     #takes too long
     def _test_list_limit_exceeds(self):
         self.client.create_container('pithos')
     #takes too long
     def _test_list_limit_exceeds(self):
         self.client.create_container('pithos')
-        
+
         for i in range(10001):
             self.client.create_zero_length_object('pithos', i)
         for i in range(10001):
             self.client.create_zero_length_object('pithos', i)
-        
+
         self.assertEqual(10000, len(self.client.list_objects('pithos')))
         self.assertEqual(10000, len(self.client.list_objects('pithos')))
-    
+
     def test_list_empty_params(self):
         objects = self.client.get('/%s/%s' % (get_user(), self.container[0]))[2]
         if objects:
             objects = objects.strip().split('\n')
         self.assertEqual(objects,
                          self.client.list_objects(self.container[0]))
     def test_list_empty_params(self):
         objects = self.client.get('/%s/%s' % (get_user(), self.container[0]))[2]
         if objects:
             objects = objects.strip().split('\n')
         self.assertEqual(objects,
                          self.client.list_objects(self.container[0]))
-    
+
     def test_list_pseudo_hierarchical_folders(self):
         objects = self.client.list_objects(self.container[1], prefix='photos',
                                            delimiter='/')
         self.assertEquals(['photos/animals/', 'photos/me.jpg',
                            'photos/plants/'], objects)
     def test_list_pseudo_hierarchical_folders(self):
         objects = self.client.list_objects(self.container[1], prefix='photos',
                                            delimiter='/')
         self.assertEquals(['photos/animals/', 'photos/me.jpg',
                            'photos/plants/'], objects)
-        
+
         objects = self.client.list_objects(self.container[1],
                                            prefix='photos/animals',
                                            delimiter='/')
         l = ['photos/animals/cats/', 'photos/animals/dogs/']
         self.assertEquals(l, objects)
         objects = self.client.list_objects(self.container[1],
                                            prefix='photos/animals',
                                            delimiter='/')
         l = ['photos/animals/cats/', 'photos/animals/dogs/']
         self.assertEquals(l, objects)
-        
+
         objects = self.client.list_objects(self.container[1], path='photos')
         self.assertEquals(['photos/me.jpg'], objects)
         objects = self.client.list_objects(self.container[1], path='photos')
         self.assertEquals(['photos/me.jpg'], objects)
-    
+
     def test_extended_list_json(self):
         objects = self.client.list_objects(self.container[1], format='json',
                                            limit=2, prefix='photos/animals',
                                            delimiter='/')
         self.assertEqual(objects[0]['subdir'], 'photos/animals/cats/')
         self.assertEqual(objects[1]['subdir'], 'photos/animals/dogs/')
     def test_extended_list_json(self):
         objects = self.client.list_objects(self.container[1], format='json',
                                            limit=2, prefix='photos/animals',
                                            delimiter='/')
         self.assertEqual(objects[0]['subdir'], 'photos/animals/cats/')
         self.assertEqual(objects[1]['subdir'], 'photos/animals/dogs/')
-    
+
     def test_extended_list_xml(self):
         xml = self.client.list_objects(self.container[1], format='xml', limit=4,
                                        prefix='photos', delimiter='/')
     def test_extended_list_xml(self):
         xml = self.client.list_objects(self.container[1], format='xml', limit=4,
                                        prefix='photos', delimiter='/')
@@ -624,11 +624,11 @@ class ContainerGet(BaseTestCase):
         self.assertEqual(len(dirs), 2)
         self.assertEqual(dirs[0].attributes['name'].value, 'photos/animals/')
         self.assertEqual(dirs[1].attributes['name'].value, 'photos/plants/')
         self.assertEqual(len(dirs), 2)
         self.assertEqual(dirs[0].attributes['name'].value, 'photos/animals/')
         self.assertEqual(dirs[1].attributes['name'].value, 'photos/plants/')
-        
+
         objects = xml.getElementsByTagName('name')
         self.assertEqual(len(objects), 1)
         self.assertEqual(objects[0].childNodes[0].data, 'photos/me.jpg')
         objects = xml.getElementsByTagName('name')
         self.assertEqual(len(objects), 1)
         self.assertEqual(objects[0].childNodes[0].data, 'photos/me.jpg')
-    
+
     def test_list_meta_double_matching(self):
         meta = {'quality':'aaa', 'stock':'true'}
         self.client.update_object_metadata(self.container[0],
     def test_list_meta_double_matching(self):
         meta = {'quality':'aaa', 'stock':'true'}
         self.client.update_object_metadata(self.container[0],
@@ -636,7 +636,7 @@ class ContainerGet(BaseTestCase):
         obj = self.client.list_objects(self.container[0], meta='Quality,Stock')
         self.assertEqual(len(obj), 1)
         self.assertTrue(obj, self.obj[0]['name'])
         obj = self.client.list_objects(self.container[0], meta='Quality,Stock')
         self.assertEqual(len(obj), 1)
         self.assertTrue(obj, self.obj[0]['name'])
-    
+
     def test_list_using_meta(self):
         meta = {'quality':'aaa'}
         for o in self.obj[:2]:
     def test_list_using_meta(self):
         meta = {'quality':'aaa'}
         for o in self.obj[:2]:
@@ -646,33 +646,33 @@ class ContainerGet(BaseTestCase):
         for o in self.obj[3:5]:
             self.client.update_object_metadata(self.container[0], o['name'],
                                                **meta)
         for o in self.obj[3:5]:
             self.client.update_object_metadata(self.container[0], o['name'],
                                                **meta)
-        
+
         obj = self.client.list_objects(self.container[0], meta='Quality')
         self.assertEqual(len(obj), 2)
         self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
         obj = self.client.list_objects(self.container[0], meta='Quality')
         self.assertEqual(len(obj), 2)
         self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
-        
+
         # test case insensitive
         obj = self.client.list_objects(self.container[0], meta='quality')
         self.assertEqual(len(obj), 2)
         self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
         # test case insensitive
         obj = self.client.list_objects(self.container[0], meta='quality')
         self.assertEqual(len(obj), 2)
         self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
-        
+
         # test multiple matches
         obj = self.client.list_objects(self.container[0], meta='Quality,Stock')
         self.assertEqual(len(obj), 4)
         self.assertTrue(obj, [o['name'] for o in self.obj[:4]])
         # test multiple matches
         obj = self.client.list_objects(self.container[0], meta='Quality,Stock')
         self.assertEqual(len(obj), 4)
         self.assertTrue(obj, [o['name'] for o in self.obj[:4]])
-        
+
         # test non 1-1 multiple match
         obj = self.client.list_objects(self.container[0], meta='Quality,aaaa')
         self.assertEqual(len(obj), 2)
         self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
         # test non 1-1 multiple match
         obj = self.client.list_objects(self.container[0], meta='Quality,aaaa')
         self.assertEqual(len(obj), 2)
         self.assertTrue(obj, [o['name'] for o in self.obj[:2]])
-    
+
     def test_if_modified_since(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
     def test_if_modified_since(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
-        
+
         #add a new object
         self.upload_random_data(self.container[0], o_names[0])
         #add a new object
         self.upload_random_data(self.container[0], o_names[0])
-        
+
         for f in DATE_FORMATS:
             past = t2.strftime(f)
             try:
         for f in DATE_FORMATS:
             past = t2.strftime(f)
             try:
@@ -682,46 +682,46 @@ class ContainerGet(BaseTestCase):
                                  self.client.list_objects(self.container[0]))
             except Fault, f:
                 self.failIf(f.status == 304) #fail if not modified
                                  self.client.list_objects(self.container[0]))
             except Fault, f:
                 self.failIf(f.status == 304) #fail if not modified
-    
+
     def test_if_modified_since_invalid_date(self):
         headers = {'if-modified-since':''}
         o = self.client.list_objects(self.container[0], if_modified_since='')
         self.assertEqual(o, self.client.list_objects(self.container[0]))
     def test_if_modified_since_invalid_date(self):
         headers = {'if-modified-since':''}
         o = self.client.list_objects(self.container[0], if_modified_since='')
         self.assertEqual(o, self.client.list_objects(self.container[0]))
-    
+
     def test_if_not_modified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
     def test_if_not_modified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
-        
+
         for f in DATE_FORMATS:
             args = {'if_modified_since':'%s' %since.strftime(f)}
         for f in DATE_FORMATS:
             args = {'if_modified_since':'%s' %since.strftime(f)}
-            
+
             #assert not modified
             self.assert_raises_fault(304, self.client.list_objects,
                                      self.container[0], **args)
             #assert not modified
             self.assert_raises_fault(304, self.client.list_objects,
                                      self.container[0], **args)
-    
+
     def test_if_unmodified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
     def test_if_unmodified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
-        
+
         for f in DATE_FORMATS:
             obj = self.client.list_objects(self.container[0],
                                            if_unmodified_since=since.strftime(f))
         for f in DATE_FORMATS:
             obj = self.client.list_objects(self.container[0],
                                            if_unmodified_since=since.strftime(f))
-            
+
             #assert unmodified
             self.assertEqual(obj, self.client.list_objects(self.container[0]))
             #assert unmodified
             self.assertEqual(obj, self.client.list_objects(self.container[0]))
-    
+
     def test_if_unmodified_since_precondition_failed(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
     def test_if_unmodified_since_precondition_failed(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
-        
+
         #add a new container
         self.client.create_container('dummy')
         #add a new container
         self.client.create_container('dummy')
-        
+
         for f in DATE_FORMATS:
             past = t2.strftime(f)
         for f in DATE_FORMATS:
             past = t2.strftime(f)
-            
+
             args = {'if_unmodified_since':'%s' %past}
             args = {'if_unmodified_since':'%s' %past}
-            
+
             #assert precondition failed
             self.assert_raises_fault(412, self.client.list_objects,
                                      self.container[0], **args)
             #assert precondition failed
             self.assert_raises_fault(412, self.client.list_objects,
                                      self.container[0], **args)
@@ -730,41 +730,41 @@ class ContainerPut(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
         self.containers = ['c1', 'c2']
     def setUp(self):
         BaseTestCase.setUp(self)
         self.containers = ['c1', 'c2']
-    
+
     def test_create(self):
         self.client.create_container(self.containers[0])
         containers = self.client.list_containers()
         self.assertTrue(self.containers[0] in containers)
         self.assert_container_exists(self.containers[0])
     def test_create(self):
         self.client.create_container(self.containers[0])
         containers = self.client.list_containers()
         self.assertTrue(self.containers[0] in containers)
         self.assert_container_exists(self.containers[0])
-    
+
     def test_create_twice(self):
         self.client.create_container(self.containers[0])
         self.assertTrue(not self.client.create_container(self.containers[0]))
     def test_create_twice(self):
         self.client.create_container(self.containers[0])
         self.assertTrue(not self.client.create_container(self.containers[0]))
-    
+
     def test_quota(self):
         self.client.create_container(self.containers[0])
     def test_quota(self):
         self.client.create_container(self.containers[0])
-        
+
         policy = {'quota':100}
         self.client.set_container_policies('c1', **policy)
         policy = {'quota':100}
         self.client.set_container_policies('c1', **policy)
-        
+
         meta = self.client.retrieve_container_metadata('c1')
         self.assertTrue('x-container-policy-quota' in meta)
         self.assertEqual(meta['x-container-policy-quota'], '100')
         meta = self.client.retrieve_container_metadata('c1')
         self.assertTrue('x-container-policy-quota' in meta)
         self.assertEqual(meta['x-container-policy-quota'], '100')
-        
+
         args = ['c1', 'o1']
         kwargs = {'length':101}
         self.assert_raises_fault(413, self.upload_random_data, *args, **kwargs)
         args = ['c1', 'o1']
         kwargs = {'length':101}
         self.assert_raises_fault(413, self.upload_random_data, *args, **kwargs)
-        
+
         #reset quota
         policy = {'quota':0}
         self.client.set_container_policies('c1', **policy)
         #reset quota
         policy = {'quota':0}
         self.client.set_container_policies('c1', **policy)
-    
+
 class ContainerPost(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
         self.container = 'apples'
         self.client.create_container(self.container)
 class ContainerPost(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
         self.container = 'apples'
         self.client.create_container(self.container)
-    
+
     def test_update_meta(self):
         meta = {'test':'test33',
                 'tost':'tost22'}
     def test_update_meta(self):
         meta = {'test':'test33',
                 'tost':'tost22'}
@@ -781,16 +781,16 @@ class ContainerDelete(BaseTestCase):
         self.containers = ['c1', 'c2']
         for c in self.containers:
             self.client.create_container(c)
         self.containers = ['c1', 'c2']
         for c in self.containers:
             self.client.create_container(c)
-    
+
     def test_delete(self):
         status = self.client.delete_container(self.containers[0])[0]
         self.assertEqual(status, 204)
     def test_delete(self):
         status = self.client.delete_container(self.containers[0])[0]
         self.assertEqual(status, 204)
-    
+
     def test_delete_non_empty(self):
         self.upload_random_data(self.containers[1], o_names[0])
         self.assert_raises_fault(409, self.client.delete_container,
                                  self.containers[1])
     def test_delete_non_empty(self):
         self.upload_random_data(self.containers[1], o_names[0])
         self.assert_raises_fault(409, self.client.delete_container,
                                  self.containers[1])
-    
+
     def test_delete_invalid(self):
         self.assert_raises_fault(404, self.client.delete_container, 'c3')
 
     def test_delete_invalid(self):
         self.assert_raises_fault(404, self.client.delete_container, 'c3')
 
@@ -801,28 +801,28 @@ class ObjectGet(BaseTestCase):
         #create some containers
         for c in self.containers:
             self.client.create_container(c)
         #create some containers
         for c in self.containers:
             self.client.create_container(c)
-        
+
         #upload a file
         names = ('obj1', 'obj2')
         self.objects = []
         for n in names:
             self.objects.append(self.upload_random_data(self.containers[1], n))
         #upload a file
         names = ('obj1', 'obj2')
         self.objects = []
         for n in names:
             self.objects.append(self.upload_random_data(self.containers[1], n))
-    
+
     def test_versions(self):
         c = self.containers[1]
         o = self.objects[0]
         b = self.client.retrieve_object_versionlist(c, o['name'])['versions']
         self.assert_versionlist_structure(b)
     def test_versions(self):
         c = self.containers[1]
         o = self.objects[0]
         b = self.client.retrieve_object_versionlist(c, o['name'])['versions']
         self.assert_versionlist_structure(b)
-        
+
         #update meta
         meta = {'quality':'AAA', 'stock':True}
         self.client.update_object_metadata(c, o['name'], **meta)
         #update meta
         meta = {'quality':'AAA', 'stock':True}
         self.client.update_object_metadata(c, o['name'], **meta)
-        
+
         a = self.client.retrieve_object_versionlist(c, o['name'])['versions']
         self.assert_versionlist_structure(a)
         self.assertEqual(len(b)+1, len(a))
         self.assertEqual(b, a[:-1])
         a = self.client.retrieve_object_versionlist(c, o['name'])['versions']
         self.assert_versionlist_structure(a)
         self.assertEqual(len(b)+1, len(a))
         self.assertEqual(b, a[:-1])
-        
+
         #get exact previous version metadata
         v = a[-2][0]
         v_meta = self.client.retrieve_object_metadata(c, o['name'],
         #get exact previous version metadata
         v = a[-2][0]
         v_meta = self.client.retrieve_object_metadata(c, o['name'],
@@ -830,30 +830,30 @@ class ObjectGet(BaseTestCase):
                                                       version=v)
         for k in meta.keys():
             self.assertTrue(k not in v_meta)
                                                       version=v)
         for k in meta.keys():
             self.assertTrue(k not in v_meta)
-        
+
         #update obejct
         data = get_random_data()
         self.client.update_object(c, o['name'], StringIO(data))
         #update obejct
         data = get_random_data()
         self.client.update_object(c, o['name'], StringIO(data))
-        
+
         aa = self.client.retrieve_object_versionlist(c, o['name'])['versions']
         self.assert_versionlist_structure(aa)
         self.assertEqual(len(a)+1, len(aa))
         self.assertEqual(a, aa[:-1])
         aa = self.client.retrieve_object_versionlist(c, o['name'])['versions']
         self.assert_versionlist_structure(aa)
         self.assertEqual(len(a)+1, len(aa))
         self.assertEqual(a, aa[:-1])
-        
+
         #get exact previous version
         v = aa[-3][0]
         v_data = self.client.retrieve_object_version(c, o['name'], version=v)
         self.assertEqual(o['data'], v_data)
         self.assertEqual(self.client.retrieve_object(c, o['name']),
                          '%s%s' %(v_data, data))
         #get exact previous version
         v = aa[-3][0]
         v_data = self.client.retrieve_object_version(c, o['name'], version=v)
         self.assertEqual(o['data'], v_data)
         self.assertEqual(self.client.retrieve_object(c, o['name']),
                          '%s%s' %(v_data, data))
-    
+
     def test_get(self):
         #perform get
         o = self.client.retrieve_object(self.containers[1],
                                         self.objects[0]['name'],
                                         self.objects[0]['meta'])
         self.assertEqual(o, self.objects[0]['data'])
     def test_get(self):
         #perform get
         o = self.client.retrieve_object(self.containers[1],
                                         self.objects[0]['name'],
                                         self.objects[0]['meta'])
         self.assertEqual(o, self.objects[0]['data'])
-    
+
     def test_objects_with_trailing_spaces(self):
         self.client.create_container('test')
         #create 'a' object
     def test_objects_with_trailing_spaces(self):
         self.client.create_container('test')
         #create 'a' object
@@ -861,90 +861,90 @@ class ObjectGet(BaseTestCase):
         #look for 'a ' object
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  'test', 'a ')
         #look for 'a ' object
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  'test', 'a ')
-        
+
         #delete 'a' object
         self.client.delete_object('test', 'a')
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  'test', 'a')
         #delete 'a' object
         self.client.delete_object('test', 'a')
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  'test', 'a')
-        
+
         #create 'a ' object
         self.upload_random_data('test', 'a ')
         #look for 'a' object
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  'test', 'a')
         #create 'a ' object
         self.upload_random_data('test', 'a ')
         #look for 'a' object
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  'test', 'a')
-    
+
     def test_get_invalid(self):
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  self.containers[0], self.objects[0]['name'])
     def test_get_invalid(self):
         self.assert_raises_fault(404, self.client.retrieve_object,
                                  self.containers[0], self.objects[0]['name'])
-    
+
     def test_get_partial(self):
         #perform get with range
         status, headers, data = self.client.request_object(self.containers[1],
                                                             self.objects[0]['name'],
                                                             range='bytes=0-499')
     def test_get_partial(self):
         #perform get with range
         status, headers, data = self.client.request_object(self.containers[1],
                                                             self.objects[0]['name'],
                                                             range='bytes=0-499')
-        
+
         #assert successful partial content
         self.assertEqual(status, 206)
         #assert successful partial content
         self.assertEqual(status, 206)
-        
+
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
-        
+
         #assert content length
         self.assertEqual(int(headers['content-length']), 500)
         #assert content length
         self.assertEqual(int(headers['content-length']), 500)
-        
+
         #assert content
         self.assertEqual(self.objects[0]['data'][:500], data)
         #assert content
         self.assertEqual(self.objects[0]['data'][:500], data)
-    
+
     def test_get_final_500(self):
         #perform get with range
         headers = {'range':'bytes=-500'}
         status, headers, data = self.client.request_object(self.containers[1],
                                                             self.objects[0]['name'],
                                                             range='bytes=-500')
     def test_get_final_500(self):
         #perform get with range
         headers = {'range':'bytes=-500'}
         status, headers, data = self.client.request_object(self.containers[1],
                                                             self.objects[0]['name'],
                                                             range='bytes=-500')
-        
+
         #assert successful partial content
         self.assertEqual(status, 206)
         #assert successful partial content
         self.assertEqual(status, 206)
-        
+
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
-        
+
         #assert content length
         self.assertEqual(int(headers['content-length']), 500)
         #assert content length
         self.assertEqual(int(headers['content-length']), 500)
-        
+
         #assert content
         self.assertTrue(self.objects[0]['data'][-500:], data)
         #assert content
         self.assertTrue(self.objects[0]['data'][-500:], data)
-    
+
     def test_get_rest(self):
         #perform get with range
         offset = len(self.objects[0]['data']) - 500
         status, headers, data = self.client.request_object(self.containers[1],
                                                 self.objects[0]['name'],
                                                 range='bytes=%s-' %offset)
     def test_get_rest(self):
         #perform get with range
         offset = len(self.objects[0]['data']) - 500
         status, headers, data = self.client.request_object(self.containers[1],
                                                 self.objects[0]['name'],
                                                 range='bytes=%s-' %offset)
-        
+
         #assert successful partial content
         self.assertEqual(status, 206)
         #assert successful partial content
         self.assertEqual(status, 206)
-        
+
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
-        
+
         #assert content length
         self.assertEqual(int(headers['content-length']), 500)
         #assert content length
         self.assertEqual(int(headers['content-length']), 500)
-        
+
         #assert content
         self.assertTrue(self.objects[0]['data'][-500:], data)
         #assert content
         self.assertTrue(self.objects[0]['data'][-500:], data)
-    
+
     def test_get_range_not_satisfiable(self):
         #perform get with range
         offset = len(self.objects[0]['data']) + 1
     def test_get_range_not_satisfiable(self):
         #perform get with range
         offset = len(self.objects[0]['data']) + 1
-        
+
         #assert range not satisfiable
         self.assert_raises_fault(416, self.client.retrieve_object,
                                  self.containers[1], self.objects[0]['name'],
                                  range='bytes=0-%s' %offset)
         #assert range not satisfiable
         self.assert_raises_fault(416, self.client.retrieve_object,
                                  self.containers[1], self.objects[0]['name'],
                                  range='bytes=0-%s' %offset)
-    
+
     def test_multiple_range(self):
         #perform get with multiple range
         ranges = ['0-499', '-500', '1000-']
     def test_multiple_range(self):
         #perform get with multiple range
         ranges = ['0-499', '-500', '1000-']
@@ -952,21 +952,21 @@ class ObjectGet(BaseTestCase):
         status, headers, data = self.client.request_object(self.containers[1],
                                                            self.objects[0]['name'],
                                                            range=bytes)
         status, headers, data = self.client.request_object(self.containers[1],
                                                            self.objects[0]['name'],
                                                            range=bytes)
-        
+
         # assert partial content
         self.assertEqual(status, 206)
         # assert partial content
         self.assertEqual(status, 206)
-        
+
         # assert Content-Type of the reply will be multipart/byteranges
         self.assertTrue(headers['content-type'])
         content_type_parts = headers['content-type'].split()
         self.assertEqual(content_type_parts[0], ('multipart/byteranges;'))
         # assert Content-Type of the reply will be multipart/byteranges
         self.assertTrue(headers['content-type'])
         content_type_parts = headers['content-type'].split()
         self.assertEqual(content_type_parts[0], ('multipart/byteranges;'))
-        
+
         boundary = '--%s' %content_type_parts[1].split('=')[-1:][0]
         cparts = data.split(boundary)[1:-1]
         boundary = '--%s' %content_type_parts[1].split('=')[-1:][0]
         cparts = data.split(boundary)[1:-1]
-        
+
         # assert content parts are exactly 2
         self.assertEqual(len(cparts), len(ranges))
         # assert content parts are exactly 2
         self.assertEqual(len(cparts), len(ranges))
-        
+
         # for each content part assert headers
         i = 0
         for cpart in cparts:
         # for each content part assert headers
         i = 0
         for cpart in cparts:
@@ -974,7 +974,7 @@ class ObjectGet(BaseTestCase):
             headers = content[1:3]
             content_range = headers[0].split(': ')
             self.assertEqual(content_range[0], 'Content-Range')
             headers = content[1:3]
             content_range = headers[0].split(': ')
             self.assertEqual(content_range[0], 'Content-Range')
-            
+
             r = ranges[i].split('-')
             if not r[0] and not r[1]:
                 pass
             r = ranges[i].split('-')
             if not r[0] and not r[1]:
                 pass
@@ -992,18 +992,18 @@ class ObjectGet(BaseTestCase):
             self.assertEqual(len(fdata), len(sdata))
             self.assertEquals(fdata, sdata)
             i+=1
             self.assertEqual(len(fdata), len(sdata))
             self.assertEquals(fdata, sdata)
             i+=1
-    
+
     def test_multiple_range_not_satisfiable(self):
         #perform get with multiple range
         out_of_range = len(self.objects[0]['data']) + 1
         ranges = ['0-499', '-500', '%d-' %out_of_range]
         bytes = 'bytes=%s' % ','.join(ranges)
     def test_multiple_range_not_satisfiable(self):
         #perform get with multiple range
         out_of_range = len(self.objects[0]['data']) + 1
         ranges = ['0-499', '-500', '%d-' %out_of_range]
         bytes = 'bytes=%s' % ','.join(ranges)
-        
+
         # assert partial content
         self.assert_raises_fault(416, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'], range=bytes)
         # assert partial content
         self.assert_raises_fault(416, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'], range=bytes)
-    
+
     def test_get_with_if_match(self):
         #perform get with If-Match
         etag = self.objects[0]['hash']
     def test_get_with_if_match(self):
         #perform get with If-Match
         etag = self.objects[0]['hash']
@@ -1012,14 +1012,14 @@ class ObjectGet(BaseTestCase):
                                                            if_match=etag)
         #assert get success
         self.assertEqual(status, 200)
                                                            if_match=etag)
         #assert get success
         self.assertEqual(status, 200)
-        
+
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
-        
+
         #assert response content
         self.assertEqual(self.objects[0]['data'], data)
         #assert response content
         self.assertEqual(self.objects[0]['data'], data)
-    
+
     def test_get_with_if_match_star(self):
         #perform get with If-Match *
         headers = {'if-match':'*'}
     def test_get_with_if_match_star(self):
         #perform get with If-Match *
         headers = {'if-match':'*'}
@@ -1028,14 +1028,14 @@ class ObjectGet(BaseTestCase):
                                                 **headers)
         #assert get success
         self.assertEqual(status, 200)
                                                 **headers)
         #assert get success
         self.assertEqual(status, 200)
-        
+
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
-        
+
         #assert response content
         self.assertEqual(self.objects[0]['data'], data)
         #assert response content
         self.assertEqual(self.objects[0]['data'], data)
-    
+
     def test_get_with_multiple_if_match(self):
         #perform get with If-Match
         etags = [i['hash'] for i in self.objects if i]
     def test_get_with_multiple_if_match(self):
         #perform get with If-Match
         etags = [i['hash'] for i in self.objects if i]
@@ -1045,67 +1045,67 @@ class ObjectGet(BaseTestCase):
                                                            if_match=etags)
         #assert get success
         self.assertEqual(status, 200)
                                                            if_match=etags)
         #assert get success
         self.assertEqual(status, 200)
-        
+
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
-        
+
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content-type'],
                          self.objects[0]['meta']['content_type'])
-        
+
         #assert response content
         self.assertEqual(self.objects[0]['data'], data)
         #assert response content
         self.assertEqual(self.objects[0]['data'], data)
-    
+
     def test_if_match_precondition_failed(self):
         #assert precondition failed
         self.assert_raises_fault(412, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'], if_match='123')
     def test_if_match_precondition_failed(self):
         #assert precondition failed
         self.assert_raises_fault(412, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'], if_match='123')
-    
+
     def test_if_none_match(self):
         #perform get with If-None-Match
         status, headers, data = self.client.request_object(self.containers[1],
                                                            self.objects[0]['name'],
                                                            if_none_match='123')
     def test_if_none_match(self):
         #perform get with If-None-Match
         status, headers, data = self.client.request_object(self.containers[1],
                                                            self.objects[0]['name'],
                                                            if_none_match='123')
-        
+
         #assert get success
         self.assertEqual(status, 200)
         #assert get success
         self.assertEqual(status, 200)
-        
+
         #assert content-type
         self.assertEqual(headers['content_type'],
                          self.objects[0]['meta']['content_type'])
         #assert content-type
         self.assertEqual(headers['content_type'],
                          self.objects[0]['meta']['content_type'])
-    
+
     def test_if_none_match(self):
         #perform get with If-None-Match * and assert not modified
         self.assert_raises_fault(304, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'],
                                  if_none_match='*')
     def test_if_none_match(self):
         #perform get with If-None-Match * and assert not modified
         self.assert_raises_fault(304, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'],
                                  if_none_match='*')
-    
+
     def test_if_none_match_not_modified(self):
         #perform get with If-None-Match and assert not modified
         self.assert_raises_fault(304, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'],
                                  if_none_match=self.objects[0]['hash'])
     def test_if_none_match_not_modified(self):
         #perform get with If-None-Match and assert not modified
         self.assert_raises_fault(304, self.client.retrieve_object,
                                  self.containers[1],
                                  self.objects[0]['name'],
                                  if_none_match=self.objects[0]['hash'])
-        
+
         meta = self.client.retrieve_object_metadata(self.containers[1],
                                                     self.objects[0]['name'])
         self.assertEqual(meta['etag'], self.objects[0]['hash'])
         meta = self.client.retrieve_object_metadata(self.containers[1],
                                                     self.objects[0]['name'])
         self.assertEqual(meta['etag'], self.objects[0]['hash'])
-    
+
     def test_if_modified_since(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
     def test_if_modified_since(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
-        
+
         #modify the object
         self.upload_data(self.containers[1],
                            self.objects[0]['name'],
                            self.objects[0]['data'][:200])
         #modify the object
         self.upload_data(self.containers[1],
                            self.objects[0]['name'],
                            self.objects[0]['data'][:200])
-        
+
         for f in DATE_FORMATS:
             past = t2.strftime(f)
         for f in DATE_FORMATS:
             past = t2.strftime(f)
-            
+
             headers = {'if-modified-since':'%s' %past}
             try:
                 o = self.client.retrieve_object(self.containers[1],
             headers = {'if-modified-since':'%s' %past}
             try:
                 o = self.client.retrieve_object(self.containers[1],
@@ -1116,28 +1116,28 @@ class ObjectGet(BaseTestCase):
                                                              self.objects[0]['name']))
             except Fault, f:
                 self.failIf(f.status == 304)
                                                              self.objects[0]['name']))
             except Fault, f:
                 self.failIf(f.status == 304)
-    
+
     def test_if_modified_since_invalid_date(self):
         o = self.client.retrieve_object(self.containers[1],
                                         self.objects[0]['name'],
                                         if_modified_since='')
         self.assertEqual(o, self.client.retrieve_object(self.containers[1],
                                                         self.objects[0]['name']))
     def test_if_modified_since_invalid_date(self):
         o = self.client.retrieve_object(self.containers[1],
                                         self.objects[0]['name'],
                                         if_modified_since='')
         self.assertEqual(o, self.client.retrieve_object(self.containers[1],
                                                         self.objects[0]['name']))
-            
+
     def test_if_not_modified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
     def test_if_not_modified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
-        
+
         for f in DATE_FORMATS:
             #assert not modified
             self.assert_raises_fault(304, self.client.retrieve_object,
                                      self.containers[1], self.objects[0]['name'],
                                      if_modified_since=since.strftime(f))
         for f in DATE_FORMATS:
             #assert not modified
             self.assert_raises_fault(304, self.client.retrieve_object,
                                      self.containers[1], self.objects[0]['name'],
                                      if_modified_since=since.strftime(f))
-    
+
     def test_if_unmodified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
     def test_if_unmodified_since(self):
         now = datetime.datetime.utcnow()
         since = now + datetime.timedelta(1)
-        
+
         for f in DATE_FORMATS:
             t = since.strftime(f)
             status, headers, data = self.client.request_object(self.containers[1],
         for f in DATE_FORMATS:
             t = since.strftime(f)
             status, headers, data = self.client.request_object(self.containers[1],
@@ -1146,27 +1146,27 @@ class ObjectGet(BaseTestCase):
             #assert success
             self.assertEqual(status, 200)
             self.assertEqual(self.objects[0]['data'], data)
             #assert success
             self.assertEqual(status, 200)
             self.assertEqual(self.objects[0]['data'], data)
-            
+
             #assert content-type
             self.assertEqual(headers['content-type'],
                              self.objects[0]['meta']['content_type'])
             #assert content-type
             self.assertEqual(headers['content-type'],
                              self.objects[0]['meta']['content_type'])
-    
+
     def test_if_unmodified_since_precondition_failed(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
     def test_if_unmodified_since_precondition_failed(self):
         t = datetime.datetime.utcnow()
         t2 = t - datetime.timedelta(minutes=10)
-        
+
         #modify the object
         self.upload_data(self.containers[1],
                            self.objects[0]['name'],
                            self.objects[0]['data'][:200])
         #modify the object
         self.upload_data(self.containers[1],
                            self.objects[0]['name'],
                            self.objects[0]['data'][:200])
-        
+
         for f in DATE_FORMATS:
             past = t2.strftime(f)
             #assert precondition failed
             self.assert_raises_fault(412, self.client.retrieve_object,
                                      self.containers[1], self.objects[0]['name'],
                                      if_unmodified_since=past)
         for f in DATE_FORMATS:
             past = t2.strftime(f)
             #assert precondition failed
             self.assert_raises_fault(412, self.client.retrieve_object,
                                      self.containers[1], self.objects[0]['name'],
                                      if_unmodified_since=past)
-    
+
     def test_hashes(self):
         l = 8388609
         fname = 'largefile'
     def test_hashes(self):
         l = 8388609
         fname = 'largefile'
@@ -1192,26 +1192,26 @@ class ObjectPut(BaseTestCase):
         BaseTestCase.setUp(self)
         self.container = 'c1'
         self.client.create_container(self.container)
         BaseTestCase.setUp(self)
         self.container = 'c1'
         self.client.create_container(self.container)
-    
+
     def test_upload(self):
         name = o_names[0]
         meta = {'test':'test1'}
         o = self.upload_random_data(self.container, name, **meta)
     def test_upload(self):
         name = o_names[0]
         meta = {'test':'test1'}
         o = self.upload_random_data(self.container, name, **meta)
-        
+
         headers = self.client.retrieve_object_metadata(self.container,
                                                        name,
                                                        restricted=True)
         self.assertTrue('test' in headers.keys())
         self.assertEqual(headers['test'], meta['test'])
         headers = self.client.retrieve_object_metadata(self.container,
                                                        name,
                                                        restricted=True)
         self.assertTrue('test' in headers.keys())
         self.assertEqual(headers['test'], meta['test'])
-        
+
         #assert uploaded content
         status, h, data = self.client.request_object(self.container, name)
         self.assertEqual(len(o['data']), int(h['content-length']))
         self.assertEqual(o['data'], data)
         #assert uploaded content
         status, h, data = self.client.request_object(self.container, name)
         self.assertEqual(len(o['data']), int(h['content-length']))
         self.assertEqual(o['data'], data)
-        
+
         #assert content-type
         self.assertEqual(h['content-type'], o['meta']['content_type'])
         #assert content-type
         self.assertEqual(h['content-type'], o['meta']['content_type'])
-    
+
     def _test_maximum_upload_size_exceeds(self):
         name = o_names[0]
         meta = {'test':'test1'}
     def _test_maximum_upload_size_exceeds(self):
         name = o_names[0]
         meta = {'test':'test1'}
@@ -1219,17 +1219,17 @@ class ObjectPut(BaseTestCase):
         length=1024*1024*100
         self.assert_raises_fault(400, self.upload_random_data, self.container,
                                  name, length, **meta)
         length=1024*1024*100
         self.assert_raises_fault(400, self.upload_random_data, self.container,
                                  name, length, **meta)
-    
+
     def test_upload_with_name_containing_slash(self):
         name = '/%s' % o_names[0]
         meta = {'test':'test1'}
         o = self.upload_random_data(self.container, name, **meta)
     def test_upload_with_name_containing_slash(self):
         name = '/%s' % o_names[0]
         meta = {'test':'test1'}
         o = self.upload_random_data(self.container, name, **meta)
-        
+
         self.assertEqual(o['data'],
                          self.client.retrieve_object(self.container, name))
         self.assertEqual(o['data'],
                          self.client.retrieve_object(self.container, name))
-        
+
         self.assertTrue(name in self.client.list_objects(self.container))
         self.assertTrue(name in self.client.list_objects(self.container))
-    
+
     def test_create_directory_marker(self):
         self.client.create_directory_marker(self.container, 'foo')
         meta = self.client.retrieve_object_metadata(self.container, 'foo')
     def test_create_directory_marker(self):
         self.client.create_directory_marker(self.container, 'foo')
         meta = self.client.retrieve_object_metadata(self.container, 'foo')
@@ -1238,20 +1238,20 @@ class ObjectPut(BaseTestCase):
 
     def test_upload_unprocessable_entity(self):
         meta={'etag':'123', 'test':'test1'}
 
     def test_upload_unprocessable_entity(self):
         meta={'etag':'123', 'test':'test1'}
-        
+
         #assert unprocessable entity
         self.assert_raises_fault(422, self.upload_random_data, self.container,
                                  o_names[0], **meta)
         #assert unprocessable entity
         self.assert_raises_fault(422, self.upload_random_data, self.container,
                                  o_names[0], **meta)
-    
+
     def test_chunked_transfer(self):
         data = get_random_data()
         objname = 'object'
         self.client.create_object_using_chunks(self.container, objname,
                                                StringIO(data))
     def test_chunked_transfer(self):
         data = get_random_data()
         objname = 'object'
         self.client.create_object_using_chunks(self.container, objname,
                                                StringIO(data))
-        
+
         uploaded_data = self.client.retrieve_object(self.container, objname)
         self.assertEqual(data, uploaded_data)
         uploaded_data = self.client.retrieve_object(self.container, objname)
         self.assertEqual(data, uploaded_data)
-    
+
     def test_manifestation(self):
         prefix = 'myobject/'
         data = ''
     def test_manifestation(self):
         prefix = 'myobject/'
         data = ''
@@ -1259,20 +1259,28 @@ class ObjectPut(BaseTestCase):
             part = '%s%d' %(prefix, i)
             o = self.upload_random_data(self.container, part)
             data += o['data']
             part = '%s%d' %(prefix, i)
             o = self.upload_random_data(self.container, part)
             data += o['data']
-        
+
         manifest = '%s/%s' %(self.container, prefix)
         self.client.create_manifestation(self.container, 'large-object', manifest)
         manifest = '%s/%s' %(self.container, prefix)
         self.client.create_manifestation(self.container, 'large-object', manifest)
-        
+
         self.assert_object_exists(self.container, 'large-object')
         self.assertEqual(data, self.client.retrieve_object(self.container,
                                                            'large-object'))
         
         self.assert_object_exists(self.container, 'large-object')
         self.assertEqual(data, self.client.retrieve_object(self.container,
                                                            'large-object'))
         
+        r = self.client.retrieve_object_hashmap(self.container,'large-object')
+        hashes = r['hashes']
+        block_size = int(r['block_size'])
+        block_hash = r['block_hash']
+        l = len(data)
+        block_num = l/block_size if l/block_size != 0 else l/block_size + 1
+        self.assertEqual(block_num, len(hashes))
+        
         #wrong manifestation
         self.client.create_manifestation(self.container, 'large-object',
                                          '%s/invalid' % self.container)
         self.assertEqual('', self.client.retrieve_object(self.container,
                                                          'large-object'))
         #wrong manifestation
         self.client.create_manifestation(self.container, 'large-object',
                                          '%s/invalid' % self.container)
         self.assertEqual('', self.client.retrieve_object(self.container,
                                                          'large-object'))
-    
+
     def test_create_zero_length_object(self):
         c = self.container
         o = 'object'
     def test_create_zero_length_object(self):
         c = self.container
         o = 'object'
@@ -1280,14 +1288,14 @@ class ObjectPut(BaseTestCase):
         zero_meta = self.client.retrieve_object_metadata(c, o)
         zero_hash = self.client.retrieve_object_hashmap(c, o)["hashes"]
         zero_data = self.client.retrieve_object(c, o)
         zero_meta = self.client.retrieve_object_metadata(c, o)
         zero_hash = self.client.retrieve_object_hashmap(c, o)["hashes"]
         zero_data = self.client.retrieve_object(c, o)
-        
+
         self.assertEqual(int(zero_meta['content-length']), 0)
         hasher = newhasher('sha256')
         hasher.update("")
         emptyhash = hasher.digest()
         self.assertEqual(zero_hash, [hexlify(emptyhash)])
         self.assertEqual(zero_data, '')
         self.assertEqual(int(zero_meta['content-length']), 0)
         hasher = newhasher('sha256')
         hasher.update("")
         emptyhash = hasher.digest()
         self.assertEqual(zero_hash, [hexlify(emptyhash)])
         self.assertEqual(zero_data, '')
-    
+
     def test_create_object_by_hashmap(self):
         c = self.container
         o = 'object'
     def test_create_object_by_hashmap(self):
         c = self.container
         o = 'object'
@@ -1305,7 +1313,7 @@ class ObjectCopy(BaseTestCase):
         for c in self.containers:
             self.client.create_container(c)
         self.obj = self.upload_random_data(self.containers[0], o_names[0])
         for c in self.containers:
             self.client.create_container(c)
         self.obj = self.upload_random_data(self.containers[0], o_names[0])
-        
+
     def test_copy(self):
         with AssertMappingInvariant(self.client.retrieve_object_metadata,
                              self.containers[0], self.obj['name']):
     def test_copy(self):
         with AssertMappingInvariant(self.client.retrieve_object_metadata,
                              self.containers[0], self.obj['name']):
@@ -1316,22 +1324,22 @@ class ObjectCopy(BaseTestCase):
                                               self.containers[0],
                                               'testcopy',
                                               meta)[0]
                                               self.containers[0],
                                               'testcopy',
                                               meta)[0]
-            
+
             #assert copy success
             self.assertEqual(status, 201)
             #assert copy success
             self.assertEqual(status, 201)
-            
+
             #assert access the new object
             headers = self.client.retrieve_object_metadata(self.containers[0],
                                                            'testcopy')
             self.assertTrue('x-object-meta-test' in headers.keys())
             self.assertTrue(headers['x-object-meta-test'], 'testcopy')
             #assert access the new object
             headers = self.client.retrieve_object_metadata(self.containers[0],
                                                            'testcopy')
             self.assertTrue('x-object-meta-test' in headers.keys())
             self.assertTrue(headers['x-object-meta-test'], 'testcopy')
-            
+
             #assert etag is the same
             self.assertEqual(headers['etag'], self.obj['hash'])
             #assert etag is the same
             self.assertEqual(headers['etag'], self.obj['hash'])
-            
+
             #assert src object still exists
             self.assert_object_exists(self.containers[0], self.obj['name'])
             #assert src object still exists
             self.assert_object_exists(self.containers[0], self.obj['name'])
-    
+
     def test_copy_from_different_container(self):
         with AssertMappingInvariant(self.client.retrieve_object_metadata,
                              self.containers[0], self.obj['name']):
     def test_copy_from_different_container(self):
         with AssertMappingInvariant(self.client.retrieve_object_metadata,
                              self.containers[0], self.obj['name']):
@@ -1342,23 +1350,23 @@ class ObjectCopy(BaseTestCase):
                                              'testcopy',
                                              meta)[0]
             self.assertEqual(status, 201)
                                              'testcopy',
                                              meta)[0]
             self.assertEqual(status, 201)
-            
+
             # assert updated metadata
             meta = self.client.retrieve_object_metadata(self.containers[1],
                                                            'testcopy',
                                                            restricted=True)
             self.assertTrue('test' in meta.keys())
             self.assertTrue(meta['test'], 'testcopy')
             # assert updated metadata
             meta = self.client.retrieve_object_metadata(self.containers[1],
                                                            'testcopy',
                                                            restricted=True)
             self.assertTrue('test' in meta.keys())
             self.assertTrue(meta['test'], 'testcopy')
-            
+
             #assert src object still exists
             self.assert_object_exists(self.containers[0], self.obj['name'])
             #assert src object still exists
             self.assert_object_exists(self.containers[0], self.obj['name'])
-    
+
     def test_copy_invalid(self):
         #copy from invalid object
         meta = {'test':'testcopy'}
         self.assert_raises_fault(404, self.client.copy_object, self.containers[0],
                                  'test.py', self.containers[1], 'testcopy', meta)
     def test_copy_invalid(self):
         #copy from invalid object
         meta = {'test':'testcopy'}
         self.assert_raises_fault(404, self.client.copy_object, self.containers[0],
                                  'test.py', self.containers[1], 'testcopy', meta)
-        
+
         #copy from invalid container
         meta = {'test':'testcopy'}
         self.assert_raises_fault(404, self.client.copy_object, self.containers[1],
         #copy from invalid container
         meta = {'test':'testcopy'}
         self.assert_raises_fault(404, self.client.copy_object, self.containers[1],
@@ -1372,32 +1380,32 @@ class ObjectMove(BaseTestCase):
         for c in self.containers:
             self.client.create_container(c)
         self.obj = self.upload_random_data(self.containers[0], o_names[0])
         for c in self.containers:
             self.client.create_container(c)
         self.obj = self.upload_random_data(self.containers[0], o_names[0])
-    
+
     def test_move(self):
         meta = self.client.retrieve_object_metadata(self.containers[0],
                                                     self.obj['name'])
         self.assertTrue('x-object-uuid' in meta)
         uuid = meta['x-object-uuid']
     def test_move(self):
         meta = self.client.retrieve_object_metadata(self.containers[0],
                                                     self.obj['name'])
         self.assertTrue('x-object-uuid' in meta)
         uuid = meta['x-object-uuid']
-        
+
         #perform move
         meta = {'test':'testcopy'}
         src_path = '/'.join(('/', self.containers[0], self.obj['name']))
         status = self.client.move_object(self.containers[0], self.obj['name'],
                                          self.containers[0], 'testcopy',
                                          meta)[0]
         #perform move
         meta = {'test':'testcopy'}
         src_path = '/'.join(('/', self.containers[0], self.obj['name']))
         status = self.client.move_object(self.containers[0], self.obj['name'],
                                          self.containers[0], 'testcopy',
                                          meta)[0]
-        
+
         #assert successful move
         self.assertEqual(status, 201)
         #assert successful move
         self.assertEqual(status, 201)
-        
+
         #assert updated metadata
         meta = self.client.retrieve_object_metadata(self.containers[0],
                                                     'testcopy')
         self.assertTrue('x-object-meta-test' in meta.keys())
         self.assertTrue(meta['x-object-meta-test'], 'testcopy')
         #assert updated metadata
         meta = self.client.retrieve_object_metadata(self.containers[0],
                                                     'testcopy')
         self.assertTrue('x-object-meta-test' in meta.keys())
         self.assertTrue(meta['x-object-meta-test'], 'testcopy')
-        
+
         #assert same uuid
         self.assertTrue(meta['x-object-uuid'], uuid)
         #assert same uuid
         self.assertTrue(meta['x-object-uuid'], uuid)
-        
+
         #assert src object no more exists
         self.assert_object_not_exists(self.containers[0], self.obj['name'])
 
         #assert src object no more exists
         self.assert_object_not_exists(self.containers[0], self.obj['name'])
 
@@ -1410,13 +1418,37 @@ class ObjectPost(BaseTestCase):
         self.obj = []
         for i in range(2):
             self.obj.append(self.upload_random_data(self.containers[0], o_names[i]))
         self.obj = []
         for i in range(2):
             self.obj.append(self.upload_random_data(self.containers[0], o_names[i]))
-    
+
     def test_update_meta(self):
         with AssertUUidInvariant(self.client.retrieve_object_metadata,
                                  self.containers[0],
                                  self.obj[0]['name']):
             #perform update metadata
     def test_update_meta(self):
         with AssertUUidInvariant(self.client.retrieve_object_metadata,
                                  self.containers[0],
                                  self.obj[0]['name']):
             #perform update metadata
-            more = {'foo':'foo', 'bar':'bar'}
+            more = {'foo': 'foo', 'bar': 'bar', 'f' * 114: 'b' * 256}
+            status = self.client.update_object_metadata(self.containers[0],
+                                                        self.obj[0]['name'],
+                                                        **more)[0]
+            #assert request accepted
+            self.assertEqual(status, 202)
+
+            #assert old metadata are still there
+            headers = self.client.retrieve_object_metadata(self.containers[0],
+                                                           self.obj[0]['name'],
+                                                           restricted=True)
+            #assert new metadata have been updated
+            for k,v in more.items():
+                self.assertTrue(k in headers.keys())
+                self.assertTrue(headers[k], v)
+
+            #out of limits
+            more = {'f' * 114: 'b' * 257}
+            self.assert_raises_fault(400, self.client.update_object_metadata,
+                                                        self.containers[0],
+                                                        self.obj[0]['name'],
+                                                        **more)
+            
+            #perform update metadata
+            more = {'α': 'β' * 256}
             status = self.client.update_object_metadata(self.containers[0],
                                                         self.obj[0]['name'],
                                                         **more)[0]
             status = self.client.update_object_metadata(self.containers[0],
                                                         self.obj[0]['name'],
                                                         **more)[0]
@@ -1431,6 +1463,13 @@ class ObjectPost(BaseTestCase):
             for k,v in more.items():
                 self.assertTrue(k in headers.keys())
                 self.assertTrue(headers[k], v)
             for k,v in more.items():
                 self.assertTrue(k in headers.keys())
                 self.assertTrue(headers[k], v)
+            
+            #out of limits
+            more = {'α': 'β' * 257}
+            self.assert_raises_fault(400, self.client.update_object_metadata,
+                                                        self.containers[0],
+                                                        self.obj[0]['name'],
+                                                        **more)
     
     def test_update_object(self,
                            first_byte_pos=0,
     
     def test_update_object(self,
                            first_byte_pos=0,
@@ -1451,24 +1490,26 @@ class ObjectPost(BaseTestCase):
                     'content_range':'%s' %range}
             if content_length:
                 args['content_length'] = content_length
                     'content_range':'%s' %range}
             if content_length:
                 args['content_length'] = content_length
-            
-            status = self.client.update_object(self.containers[0], self.obj[0]['name'],
-                                      StringIO(data), **args)[0]
-            
+
+            r = self.client.update_object(self.containers[0], self.obj[0]['name'],
+                                      StringIO(data), **args)
+            status = r[0]
+            etag = r[1]['etag']
             if partial < 0 or (instance_length and l <= last_byte_pos):
             if partial < 0 or (instance_length and l <= last_byte_pos):
-                self.assertEqual(status, 202)    
+                self.assertEqual(status, 202)
             else:
             else:
-                self.assertEqual(status, 204)           
+                self.assertEqual(status, 204)
                 #check modified object
                 content = self.client.retrieve_object(self.containers[0],
                                                   self.obj[0]['name'])
                 self.assertEqual(content[:first_byte_pos], self.obj[0]['data'][:first_byte_pos])
                 self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
                 self.assertEqual(content[last_byte_pos+1:], self.obj[0]['data'][last_byte_pos+1:])
                 #check modified object
                 content = self.client.retrieve_object(self.containers[0],
                                                   self.obj[0]['name'])
                 self.assertEqual(content[:first_byte_pos], self.obj[0]['data'][:first_byte_pos])
                 self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
                 self.assertEqual(content[last_byte_pos+1:], self.obj[0]['data'][last_byte_pos+1:])
-    
+                self.assertEqual(etag, compute_md5_hash(content))
+
     def test_update_object_lt_blocksize(self):
         self.test_update_object(10, 20, content_length=None)
     def test_update_object_lt_blocksize(self):
         self.test_update_object(10, 20, content_length=None)
-    
+
     def test_update_object_gt_blocksize(self):
         o = self.upload_random_data(self.containers[0], o_names[1],
                                 length=4*1024*1024+5)
     def test_update_object_gt_blocksize(self):
         o = self.upload_random_data(self.containers[0], o_names[1],
                                 length=4*1024*1024+5)
@@ -1484,8 +1525,8 @@ class ObjectPost(BaseTestCase):
         content = self.client.retrieve_object(c, o_name)
         self.assertEqual(content[:first_byte_pos], o_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
         content = self.client.retrieve_object(c, o_name)
         self.assertEqual(content[:first_byte_pos], o_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
-        self.assertEqual(content[last_byte_pos+1:], o_data[last_byte_pos+1:])    
-    
+        self.assertEqual(content[last_byte_pos+1:], o_data[last_byte_pos+1:])
+
     def test_update_object_divided_by_blocksize(self):
         o = self.upload_random_data(self.containers[0], o_names[1],
                                 length=4*1024*1024+5)
     def test_update_object_divided_by_blocksize(self):
         o = self.upload_random_data(self.containers[0], o_names[1],
                                 length=4*1024*1024+5)
@@ -1501,78 +1542,78 @@ class ObjectPost(BaseTestCase):
         content = self.client.retrieve_object(c, o_name)
         self.assertEqual(content[:first_byte_pos], o_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
         content = self.client.retrieve_object(c, o_name)
         self.assertEqual(content[:first_byte_pos], o_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], data)
-        self.assertEqual(content[last_byte_pos+1:], o_data[last_byte_pos+1:])    
-    
+        self.assertEqual(content[last_byte_pos+1:], o_data[last_byte_pos+1:])
+
     def test_update_object_no_content_length(self):
         self.test_update_object(content_length = None)
     def test_update_object_no_content_length(self):
         self.test_update_object(content_length = None)
-    
+
     def test_update_object_invalid_content_length(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault(400, self.test_update_object,
                                      content_length = 1000)
     def test_update_object_invalid_content_length(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault(400, self.test_update_object,
                                      content_length = 1000)
-    
+
     def _test_update_object_invalid_range(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault(416, self.test_update_object, 499, 0, True)
     def _test_update_object_invalid_range(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault(416, self.test_update_object, 499, 0, True)
-    
+
     def _test_update_object_invalid_range_and_length(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault([400, 416], self.test_update_object, 499, 0, True,
                                      -1)
     def _test_update_object_invalid_range_and_length(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault([400, 416], self.test_update_object, 499, 0, True,
                                      -1)
-    
+
     def test_update_object_invalid_range_with_no_content_length(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault(416, self.test_update_object, 499, 0, True,
                                      content_length = None)
     def test_update_object_invalid_range_with_no_content_length(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             self.assert_raises_fault(416, self.test_update_object, 499, 0, True,
                                      content_length = None)
-    
-    def test_update_object_out_of_limits(self):    
+
+    def test_update_object_out_of_limits(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             l = len(self.obj[0]['data'])
             self.assert_raises_fault(416, self.test_update_object, 0, l+1, True)
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj[0]['name']):
             l = len(self.obj[0]['data'])
             self.assert_raises_fault(416, self.test_update_object, 0, l+1, True)
-    
+
     def test_append(self):
         data = get_random_data(500)
         headers = {}
         self.client.update_object(self.containers[0], self.obj[0]['name'],
                                   StringIO(data), content_length=500,
                                   content_type='application/octet-stream')
     def test_append(self):
         data = get_random_data(500)
         headers = {}
         self.client.update_object(self.containers[0], self.obj[0]['name'],
                                   StringIO(data), content_length=500,
                                   content_type='application/octet-stream')
-        
+
         content = self.client.retrieve_object(self.containers[0],
                                               self.obj[0]['name'])
         self.assertEqual(len(content), len(self.obj[0]['data']) + 500)
         self.assertEqual(content[:-500], self.obj[0]['data'])
         content = self.client.retrieve_object(self.containers[0],
                                               self.obj[0]['name'])
         self.assertEqual(len(content), len(self.obj[0]['data']) + 500)
         self.assertEqual(content[:-500], self.obj[0]['data'])
-    
+
     def test_update_with_chunked_transfer(self):
         data = get_random_data(500)
         dl = len(data)
         fl = len(self.obj[0]['data'])
     def test_update_with_chunked_transfer(self):
         data = get_random_data(500)
         dl = len(data)
         fl = len(self.obj[0]['data'])
-        
+
         self.client.update_object_using_chunks(self.containers[0],
                                                self.obj[0]['name'],
                                                StringIO(data),
                                                offset=0,
                                                content_type='application/octet-stream')
         self.client.update_object_using_chunks(self.containers[0],
                                                self.obj[0]['name'],
                                                StringIO(data),
                                                offset=0,
                                                content_type='application/octet-stream')
-        
+
         #check modified object
         content = self.client.retrieve_object(self.containers[0],
                                               self.obj[0]['name'])
         self.assertEqual(content[0:dl], data)
         self.assertEqual(content[dl:fl], self.obj[0]['data'][dl:fl])
         #check modified object
         content = self.client.retrieve_object(self.containers[0],
                                               self.obj[0]['name'])
         self.assertEqual(content[0:dl], data)
         self.assertEqual(content[dl:fl], self.obj[0]['data'][dl:fl])
-    
+
     def test_update_from_other_object(self):
         c = self.containers[0]
         src = o_names[0]
         dest = 'object'
     def test_update_from_other_object(self):
         c = self.containers[0]
         src = o_names[0]
         dest = 'object'
-        
+
         source_data = self.client.retrieve_object(c, src)
         source_meta = self.client.retrieve_object_metadata(c, src)
         source_hash = self.client.retrieve_object_hashmap(c, src)["hashes"]
         source_data = self.client.retrieve_object(c, src)
         source_meta = self.client.retrieve_object_metadata(c, src)
         source_hash = self.client.retrieve_object_hashmap(c, src)["hashes"]
-        
+
         #update zero length object
         self.client.create_zero_length_object(c, dest)
         source_object = '/%s/%s' % (c, src)
         #update zero length object
         self.client.create_zero_length_object(c, dest)
         source_object = '/%s/%s' % (c, src)
@@ -1582,20 +1623,20 @@ class ObjectPost(BaseTestCase):
         dest_hash = self.client.retrieve_object_hashmap(c, src)["hashes"]
         self.assertEqual(source_data, dest_data)
         self.assertEqual(source_hash, dest_hash)
         dest_hash = self.client.retrieve_object_hashmap(c, src)["hashes"]
         self.assertEqual(source_data, dest_data)
         self.assertEqual(source_hash, dest_hash)
-        
+
         #test append
         self.client.update_from_other_source(c, dest, source_object)
         content = self.client.retrieve_object(c, dest)
         self.assertEqual(source_data * 2, content)
         #test append
         self.client.update_from_other_source(c, dest, source_object)
         content = self.client.retrieve_object(c, dest)
         self.assertEqual(source_data * 2, content)
-    
+
     def test_update_range_from_other_object(self):
         c = self.containers[0]
         dest = 'object'
     def test_update_range_from_other_object(self):
         c = self.containers[0]
         dest = 'object'
-        
+
         #test update range
         src = self.obj[1]['name']
         src_data = self.client.retrieve_object(c, src)
         #test update range
         src = self.obj[1]['name']
         src_data = self.client.retrieve_object(c, src)
-        
+
         #update zero length object
         prev_data = self.upload_random_data(c, dest, length=4*1024*1024+10)['data']
         source_object = '/%s/%s' % (c, src)
         #update zero length object
         prev_data = self.upload_random_data(c, dest, length=4*1024*1024+10)['data']
         source_object = '/%s/%s' % (c, src)
@@ -1608,14 +1649,14 @@ class ObjectPost(BaseTestCase):
         self.assertEqual(content[:first_byte_pos], prev_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], src_data[:last_byte_pos - first_byte_pos + 1])
         self.assertEqual(content[last_byte_pos+1:], prev_data[last_byte_pos+1:])
         self.assertEqual(content[:first_byte_pos], prev_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], src_data[:last_byte_pos - first_byte_pos + 1])
         self.assertEqual(content[last_byte_pos+1:], prev_data[last_byte_pos+1:])
-    
+
     def test_update_hashes_from_other_object(self):
         c = self.containers[0]
         dest = 'object'
     def test_update_hashes_from_other_object(self):
         c = self.containers[0]
         dest = 'object'
-        
+
         #test update range
         src_data = self.upload_random_data(c, o_names[0], length=1024*1024+10)['data']
         #test update range
         src_data = self.upload_random_data(c, o_names[0], length=1024*1024+10)['data']
-        
+
         #update zero length object
         prev_data = self.upload_random_data(c, dest, length=5*1024*1024+10)['data']
         source_object = '/%s/%s' % (c, o_names[0])
         #update zero length object
         prev_data = self.upload_random_data(c, dest, length=5*1024*1024+10)['data']
         source_object = '/%s/%s' % (c, o_names[0])
@@ -1628,24 +1669,24 @@ class ObjectPost(BaseTestCase):
         self.assertEqual(content[:first_byte_pos], prev_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], src_data[:last_byte_pos - first_byte_pos + 1])
         self.assertEqual(content[last_byte_pos+1:], prev_data[last_byte_pos+1:])
         self.assertEqual(content[:first_byte_pos], prev_data[:first_byte_pos])
         self.assertEqual(content[first_byte_pos:last_byte_pos+1], src_data[:last_byte_pos - first_byte_pos + 1])
         self.assertEqual(content[last_byte_pos+1:], prev_data[last_byte_pos+1:])
-    
-    
+
+
     def test_update_zero_length_object(self):
         c = self.containers[0]
         o = 'object'
         other = 'other'
         zero = self.client.create_zero_length_object(c, o)
     def test_update_zero_length_object(self):
         c = self.containers[0]
         o = 'object'
         other = 'other'
         zero = self.client.create_zero_length_object(c, o)
-        
+
         data = get_random_data()
         self.client.update_object(c, o, StringIO(data))
         self.client.create_object(c, other, StringIO(data))
         data = get_random_data()
         self.client.update_object(c, o, StringIO(data))
         self.client.create_object(c, other, StringIO(data))
-        
+
         self.assertEqual(self.client.retrieve_object(c, o),
                          self.client.retrieve_object(c, other))
         self.assertEqual(self.client.retrieve_object(c, o),
                          self.client.retrieve_object(c, other))
-        
+
         self.assertEqual(self.client.retrieve_object_hashmap(c, o)["hashes"],
                          self.client.retrieve_object_hashmap(c, other)["hashes"])
         self.assertEqual(self.client.retrieve_object_hashmap(c, o)["hashes"],
                          self.client.retrieve_object_hashmap(c, other)["hashes"])
-    
+
 class ObjectDelete(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
 class ObjectDelete(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
@@ -1653,11 +1694,11 @@ class ObjectDelete(BaseTestCase):
         for c in self.containers:
             self.client.create_container(c)
         self.obj = self.upload_random_data(self.containers[0], o_names[0])
         for c in self.containers:
             self.client.create_container(c)
         self.obj = self.upload_random_data(self.containers[0], o_names[0])
-    
+
     def test_delete(self):
         #perform delete object
         self.client.delete_object(self.containers[0], self.obj['name'])[0]
     def test_delete(self):
         #perform delete object
         self.client.delete_object(self.containers[0], self.obj['name'])[0]
-    
+
     def test_delete_invalid(self):
         #assert item not found
         self.assert_raises_fault(404, self.client.delete_object, self.containers[1],
     def test_delete_invalid(self):
         #assert item not found
         self.assert_raises_fault(404, self.client.delete_object, self.containers[1],
@@ -1675,88 +1716,87 @@ class ListSharing(BaseTestCase):
         self.o1_sharing_with = accounts.popitem()
         self.o1_sharing = [self.o1_sharing_with[1]]
         self.client.share_object('c1', 'o1', self.o1_sharing, read=True)
         self.o1_sharing_with = accounts.popitem()
         self.o1_sharing = [self.o1_sharing_with[1]]
         self.client.share_object('c1', 'o1', self.o1_sharing, read=True)
-        
+
         l = []
         for i in range(2):
             l.append(accounts.popitem())
         l = []
         for i in range(2):
             l.append(accounts.popitem())
-    
+
     def test_list_other_shared(self):
     def test_list_other_shared(self):
-        self.other = Pithos_Client(get_server(),
+        self.other = Pithos_Client(get_url(),
                               self.o1_sharing_with[0],
                               self.o1_sharing_with[0],
-                              self.o1_sharing_with[1],
-                              get_api())
+                              self.o1_sharing_with[1])
         self.assertTrue(get_user() in self.other.list_shared_by_others())
         self.assertTrue(get_user() in self.other.list_shared_by_others())
-    
+
     def test_list_my_shared(self):
         my_shared_containers = self.client.list_containers(shared=True)
         self.assertTrue('c1' in my_shared_containers)
         self.assertTrue('c2' not in my_shared_containers)
     def test_list_my_shared(self):
         my_shared_containers = self.client.list_containers(shared=True)
         self.assertTrue('c1' in my_shared_containers)
         self.assertTrue('c2' not in my_shared_containers)
-        
+
         my_shared_objects = self.client.list_objects('c1', shared=True)
         self.assertTrue('o1' in my_shared_objects)
         self.assertTrue('o2' not in my_shared_objects)
         my_shared_objects = self.client.list_objects('c1', shared=True)
         self.assertTrue('o1' in my_shared_objects)
         self.assertTrue('o2' not in my_shared_objects)
-    
+
 class TestGreek(BaseTestCase):
     def test_create_container(self):
         self.client.create_container('φάκελος')
         self.assert_container_exists('φάκελος')
 class TestGreek(BaseTestCase):
     def test_create_container(self):
         self.client.create_container('φάκελος')
         self.assert_container_exists('φάκελος')
-        
+
         self.assertTrue('φάκελος' in self.client.list_containers())
         self.assertTrue('φάκελος' in self.client.list_containers())
-    
+
     def test_create_object(self):
         self.client.create_container('φάκελος')
         self.upload_random_data('φάκελος', 'αντικείμενο')
     def test_create_object(self):
         self.client.create_container('φάκελος')
         self.upload_random_data('φάκελος', 'αντικείμενο')
-        
+
         self.assert_object_exists('φάκελος', 'αντικείμενο')
         self.assertTrue('αντικείμενο' in self.client.list_objects('φάκελος'))
         self.assert_object_exists('φάκελος', 'αντικείμενο')
         self.assertTrue('αντικείμενο' in self.client.list_objects('φάκελος'))
-    
+
     def test_copy_object(self):
         src_container = 'φάκελος'
         src_object = 'αντικείμενο'
         dest_container = 'αντίγραφα'
         dest_object = 'ασφαλές-αντίγραφο'
     def test_copy_object(self):
         src_container = 'φάκελος'
         src_object = 'αντικείμενο'
         dest_container = 'αντίγραφα'
         dest_object = 'ασφαλές-αντίγραφο'
-        
+
         self.client.create_container(src_container)
         self.upload_random_data(src_container, src_object)
         self.client.create_container(src_container)
         self.upload_random_data(src_container, src_object)
-        
+
         self.client.create_container(dest_container)
         self.client.copy_object(src_container, src_object, dest_container,
                                 dest_object)
         self.client.create_container(dest_container)
         self.client.copy_object(src_container, src_object, dest_container,
                                 dest_object)
-        
+
         self.assert_object_exists(src_container, src_object)
         self.assert_object_exists(dest_container, dest_object)
         self.assertTrue(dest_object in self.client.list_objects(dest_container))
         self.assert_object_exists(src_container, src_object)
         self.assert_object_exists(dest_container, dest_object)
         self.assertTrue(dest_object in self.client.list_objects(dest_container))
-    
+
     def test_move_object(self):
         src_container = 'φάκελος'
         src_object = 'αντικείμενο'
         dest_container = 'αντίγραφα'
         dest_object = 'ασφαλές-αντίγραφο'
     def test_move_object(self):
         src_container = 'φάκελος'
         src_object = 'αντικείμενο'
         dest_container = 'αντίγραφα'
         dest_object = 'ασφαλές-αντίγραφο'
-        
+
         self.client.create_container(src_container)
         self.upload_random_data(src_container, src_object)
         self.client.create_container(src_container)
         self.upload_random_data(src_container, src_object)
-        
+
         self.client.create_container(dest_container)
         self.client.move_object(src_container, src_object, dest_container,
                                 dest_object)
         self.client.create_container(dest_container)
         self.client.move_object(src_container, src_object, dest_container,
                                 dest_object)
-        
+
         self.assert_object_not_exists(src_container, src_object)
         self.assert_object_exists(dest_container, dest_object)
         self.assertTrue(dest_object in self.client.list_objects(dest_container))
         self.assert_object_not_exists(src_container, src_object)
         self.assert_object_exists(dest_container, dest_object)
         self.assertTrue(dest_object in self.client.list_objects(dest_container))
-    
+
     def test_delete_object(self):
         self.client.create_container('φάκελος')
         self.upload_random_data('φάκελος', 'αντικείμενο')
         self.assert_object_exists('φάκελος', 'αντικείμενο')
     def test_delete_object(self):
         self.client.create_container('φάκελος')
         self.upload_random_data('φάκελος', 'αντικείμενο')
         self.assert_object_exists('φάκελος', 'αντικείμενο')
-    
+
         self.client.delete_object('φάκελος', 'αντικείμενο')
         self.assert_object_not_exists('φάκελος', 'αντικείμενο')
         self.assertTrue('αντικείμενο' not in self.client.list_objects('φάκελος'))
         self.client.delete_object('φάκελος', 'αντικείμενο')
         self.assert_object_not_exists('φάκελος', 'αντικείμενο')
         self.assertTrue('αντικείμενο' not in self.client.list_objects('φάκελος'))
-    
+
     def test_delete_container(self):
         self.client.create_container('φάκελος')
         self.assert_container_exists('φάκελος')
     def test_delete_container(self):
         self.client.create_container('φάκελος')
         self.assert_container_exists('φάκελος')
-        
+
         self.client.delete_container('φάκελος')
         self.assert_container_not_exists('φάκελος')
         self.assertTrue('φάκελος' not in self.client.list_containers())
         self.client.delete_container('φάκελος')
         self.assert_container_not_exists('φάκελος')
         self.assertTrue('φάκελος' not in self.client.list_containers())
@@ -1767,50 +1807,50 @@ class TestGreek(BaseTestCase):
         meta = self.client.retrieve_account_metadata(restricted=True)
         self.assertTrue('ποιότητα' in meta.keys())
         self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
         meta = self.client.retrieve_account_metadata(restricted=True)
         self.assertTrue('ποιότητα' in meta.keys())
         self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
-    
+
     def test_container_meta(self):
         meta = {'ποιότητα':'ΑΑΑ'}
     def test_container_meta(self):
         meta = {'ποιότητα':'ΑΑΑ'}
-        self.client.create_container('φάκελος', **meta)
-        
+        self.client.create_container('φάκελος', meta=meta)
+
         meta = self.client.retrieve_container_metadata('φάκελος', restricted=True)
         self.assertTrue('ποιότητα' in meta.keys())
         self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
         meta = self.client.retrieve_container_metadata('φάκελος', restricted=True)
         self.assertTrue('ποιότητα' in meta.keys())
         self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
-    
+
     def test_object_meta(self):
         self.client.create_container('φάκελος')
         meta = {'ποιότητα':'ΑΑΑ'}
         self.upload_random_data('φάκελος', 'αντικείμενο', **meta)
     def test_object_meta(self):
         self.client.create_container('φάκελος')
         meta = {'ποιότητα':'ΑΑΑ'}
         self.upload_random_data('φάκελος', 'αντικείμενο', **meta)
-        
+
         meta = self.client.retrieve_object_metadata('φάκελος', 'αντικείμενο',
                                                     restricted=True)
         self.assertTrue('ποιότητα' in meta.keys())
         meta = self.client.retrieve_object_metadata('φάκελος', 'αντικείμενο',
                                                     restricted=True)
         self.assertTrue('ποιότητα' in meta.keys())
-        self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')    
-    
+        self.assertEqual(meta['ποιότητα'], 'ΑΑΑ')
+
     def test_list_meta_filtering(self):
         self.client.create_container('φάκελος')
         meta = {'ποιότητα':'ΑΑΑ'}
         self.upload_random_data('φάκελος', 'ο1', **meta)
         self.upload_random_data('φάκελος', 'ο2')
         self.upload_random_data('φάκελος', 'ο3')
     def test_list_meta_filtering(self):
         self.client.create_container('φάκελος')
         meta = {'ποιότητα':'ΑΑΑ'}
         self.upload_random_data('φάκελος', 'ο1', **meta)
         self.upload_random_data('φάκελος', 'ο2')
         self.upload_random_data('φάκελος', 'ο3')
-        
+
         meta = {'ποσότητα':'μεγάλη'}
         self.client.update_object_metadata('φάκελος', 'ο2', **meta)
         objects = self.client.list_objects('φάκελος', meta='ποιότητα, ποσότητα')
         self.assertEquals(objects, ['ο1', 'ο2'])
         meta = {'ποσότητα':'μεγάλη'}
         self.client.update_object_metadata('φάκελος', 'ο2', **meta)
         objects = self.client.list_objects('φάκελος', meta='ποιότητα, ποσότητα')
         self.assertEquals(objects, ['ο1', 'ο2'])
-        
+
         objects = self.client.list_objects('φάκελος', meta='!ποιότητα')
         self.assertEquals(objects, ['ο2', 'ο3'])
         objects = self.client.list_objects('φάκελος', meta='!ποιότητα')
         self.assertEquals(objects, ['ο2', 'ο3'])
-        
+
         objects = self.client.list_objects('φάκελος', meta='!ποιότητα, !ποσότητα')
         self.assertEquals(objects, ['ο3'])
         objects = self.client.list_objects('φάκελος', meta='!ποιότητα, !ποσότητα')
         self.assertEquals(objects, ['ο3'])
-        
+
         meta = {'ποιότητα':'ΑΒ'}
         self.client.update_object_metadata('φάκελος', 'ο2', **meta)
         objects = self.client.list_objects('φάκελος', meta='ποιότητα=ΑΑΑ')
         self.assertEquals(objects, ['ο1'])
         objects = self.client.list_objects('φάκελος', meta='ποιότητα!=ΑΑΑ')
         self.assertEquals(objects, ['ο2'])
         meta = {'ποιότητα':'ΑΒ'}
         self.client.update_object_metadata('φάκελος', 'ο2', **meta)
         objects = self.client.list_objects('φάκελος', meta='ποιότητα=ΑΑΑ')
         self.assertEquals(objects, ['ο1'])
         objects = self.client.list_objects('φάκελος', meta='ποιότητα!=ΑΑΑ')
         self.assertEquals(objects, ['ο2'])
-        
+
         meta = {'έτος':'2011'}
         self.client.update_object_metadata('φάκελος', 'ο3', **meta)
         meta = {'έτος':'2012'}
         meta = {'έτος':'2011'}
         self.client.update_object_metadata('φάκελος', 'ο3', **meta)
         meta = {'έτος':'2012'}
@@ -1821,7 +1861,7 @@ class TestGreek(BaseTestCase):
         self.assertEquals(objects, ['ο2', 'ο3'])
         objects = self.client.list_objects('φάκελος', meta='έτος<2012,έτος!=2011')
         self.assertEquals(objects, '')
         self.assertEquals(objects, ['ο2', 'ο3'])
         objects = self.client.list_objects('φάκελος', meta='έτος<2012,έτος!=2011')
         self.assertEquals(objects, '')
-    
+
     def test_groups(self):
         #create a group
         groups = {'σεφς':'chazapis,διογένης'}
     def test_groups(self):
         #create a group
         groups = {'σεφς':'chazapis,διογένης'}
@@ -1829,29 +1869,28 @@ class TestGreek(BaseTestCase):
         groups.update(self.initial_groups)
         self.assertEqual(groups['σεφς'],
                          self.client.retrieve_account_groups()['σεφς'])
         groups.update(self.initial_groups)
         self.assertEqual(groups['σεφς'],
                          self.client.retrieve_account_groups()['σεφς'])
-        
+
         #check read access
         self.client.create_container('φάκελος')
         o = self.upload_random_data('φάκελος', 'ο1')
         self.client.share_object('φάκελος', 'ο1', ['%s:σεφς' % get_user()])
         #check read access
         self.client.create_container('φάκελος')
         o = self.upload_random_data('φάκελος', 'ο1')
         self.client.share_object('φάκελος', 'ο1', ['%s:σεφς' % get_user()])
-        chef = Pithos_Client(get_server(),
+        chef = Pithos_Client(get_url(),
                             '0009',
                             '0009',
-                            'διογένης',
-                            get_api())
+                            'διογένης')
         self.assert_not_raises_fault(403, chef.retrieve_object_metadata,
                                      'φάκελος', 'ο1', account=get_user())
         self.assert_not_raises_fault(403, chef.retrieve_object_metadata,
                                      'φάκελος', 'ο1', account=get_user())
-        
+
         #check write access
         self.client.share_object('φάκελος', 'ο1', ['διογένης'], read=False)
         new_data = get_random_data()
         self.assert_not_raises_fault(403, chef.update_object,
                                      'φάκελος', 'ο1', StringIO(new_data),
                                      account=get_user())
         #check write access
         self.client.share_object('φάκελος', 'ο1', ['διογένης'], read=False)
         new_data = get_random_data()
         self.assert_not_raises_fault(403, chef.update_object,
                                      'φάκελος', 'ο1', StringIO(new_data),
                                      account=get_user())
-        
+
         server_data = self.client.retrieve_object('φάκελος', 'ο1')
         self.assertEqual(server_data[:len(o['data'])], o['data'])
         self.assertEqual(server_data[len(o['data']):], new_data)
         server_data = self.client.retrieve_object('φάκελος', 'ο1')
         self.assertEqual(server_data[:len(o['data'])], o['data'])
         self.assertEqual(server_data[len(o['data']):], new_data)
-    
+
     def test_manifestation(self):
         self.client.create_container('κουβάς')
         prefix = 'μέρη/'
     def test_manifestation(self):
         self.client.create_container('κουβάς')
         prefix = 'μέρη/'
@@ -1860,26 +1899,26 @@ class TestGreek(BaseTestCase):
             part = '%s%d' %(prefix, i)
             o = self.upload_random_data('κουβάς', part)
             data += o['data']
             part = '%s%d' %(prefix, i)
             o = self.upload_random_data('κουβάς', part)
             data += o['data']
-        
+
         self.client.create_container('φάκελος')
         manifest = '%s/%s' %('κουβάς', prefix)
         self.client.create_manifestation('φάκελος', 'άπαντα', manifest)
         self.client.create_container('φάκελος')
         manifest = '%s/%s' %('κουβάς', prefix)
         self.client.create_manifestation('φάκελος', 'άπαντα', manifest)
-        
+
         self.assert_object_exists('φάκελος', 'άπαντα')
         self.assertEqual(data, self.client.retrieve_object('φάκελος',
                                                            'άπαντα'))
         self.assert_object_exists('φάκελος', 'άπαντα')
         self.assertEqual(data, self.client.retrieve_object('φάκελος',
                                                            'άπαντα'))
-        
+
         #wrong manifestation
         self.client.create_manifestation('φάκελος', 'άπαντα', 'κουβάς/άκυρο')
         self.assertEqual('', self.client.retrieve_object('φάκελος', 'άπαντα'))
         #wrong manifestation
         self.client.create_manifestation('φάκελος', 'άπαντα', 'κουβάς/άκυρο')
         self.assertEqual('', self.client.retrieve_object('φάκελος', 'άπαντα'))
-    
+
     def test_update_from_another_object(self):
         self.client.create_container('κουβάς')
         src_data = self.upload_random_data('κουβάς', 'πηγή')['data']
         initial_data = self.upload_random_data('κουβάς', 'νέο')['data']
         source_object = '/%s/%s' % ('κουβάς', 'πηγή')
         self.client.update_from_other_source('κουβάς', 'νέο', source_object)
     def test_update_from_another_object(self):
         self.client.create_container('κουβάς')
         src_data = self.upload_random_data('κουβάς', 'πηγή')['data']
         initial_data = self.upload_random_data('κουβάς', 'νέο')['data']
         source_object = '/%s/%s' % ('κουβάς', 'πηγή')
         self.client.update_from_other_source('κουβάς', 'νέο', source_object)
-        
+
         self.assertEqual(
             self.client.retrieve_object('κουβάς', 'νέο'),
             '%s%s' % (initial_data, self.client.retrieve_object('κουβάς', 'πηγή')))
         self.assertEqual(
             self.client.retrieve_object('κουβάς', 'νέο'),
             '%s%s' % (initial_data, self.client.retrieve_object('κουβάς', 'πηγή')))
@@ -1887,45 +1926,66 @@ class TestGreek(BaseTestCase):
 class TestPermissions(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
 class TestPermissions(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
-        
+
         #create a group
         self.authorized = ['chazapis', 'verigak', 'gtsouk']
         groups = {'pithosdev':','.join(self.authorized)}
         self.client.set_account_groups(**groups)
         #create a group
         self.authorized = ['chazapis', 'verigak', 'gtsouk']
         groups = {'pithosdev':','.join(self.authorized)}
         self.client.set_account_groups(**groups)
-    
-    def assert_read(self, authorized=[], any=False):
+
+        self.container = 'c'
+        self.object = 'o'
+        self.client.create_container(self.container)
+        self.upload_random_data(self.container, self.object)
+        self.upload_random_data(self.container, self.object+'/')
+        self.upload_random_data(self.container, self.object+'/a')
+        self.upload_random_data(self.container, self.object+'a')
+        self.upload_random_data(self.container, self.object+'a/')
+        self.dir_content_types = ('application/directory', 'application/folder')
+
+    def assert_read(self, authorized=[], any=False, depth=0):
         for token, account in OTHER_ACCOUNTS.items():
         for token, account in OTHER_ACCOUNTS.items():
-            cl = Pithos_Client(get_server(), token, account, get_api()) 
+            cl = Pithos_Client(get_url(), token, account)
             if account in authorized or any:
                 self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
             if account in authorized or any:
                 self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
-                                             'c', 'o', account=get_user())
+                                             self.container, self.object,
+                                             account=get_user())
             else:
                 self.assert_raises_fault(403, cl.retrieve_object_metadata,
             else:
                 self.assert_raises_fault(403, cl.retrieve_object_metadata,
-                                         'c', 'o', account=get_user())
-        
+                                         self.container, self.object,
+                                         account=get_user())
+
         #check inheritance
         #check inheritance
-        o = self.upload_random_data('c', 'o/also-shared')
-        for token, account in OTHER_ACCOUNTS.items():
-            cl = Pithos_Client(get_server(), token, account, get_api()) 
-            if account in authorized or any:
-                self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
-                                             'c', 'o/also-shared', account=get_user())
-            else:
-                self.assert_raises_fault(403, cl.retrieve_object_metadata,
-                                         'c', 'o/also-shared', account=get_user())
-    
-    def assert_write(self, o_data, authorized=[], any=False):
+        meta = self.client.retrieve_object_metadata(self.container, self.object)
+        type = meta['content-type']
+        derivatives = self.client.list_objects(self.container, prefix=self.object)
+        #exclude the self.object
+        del derivatives[derivatives.index(self.object)]
+        for o in derivatives:
+            for token, account in OTHER_ACCOUNTS.items():
+                cl = Pithos_Client(get_url(), token, account)
+                prefix = self.object if self.object.endswith('/') else self.object+'/'
+                if (account in authorized or any) and \
+                (type in self.dir_content_types) and \
+                o.startswith(prefix):
+                    self.assert_not_raises_fault(403, cl.retrieve_object_metadata,
+                                             self.container, o, account=get_user())
+                else:
+                    self.assert_raises_fault(403, cl.retrieve_object_metadata,
+                                         self.container, o, account=get_user())
+
+    def assert_write(self, authorized=[], any=False):
+        o_data = self.client.retrieve_object(self.container, self.object)
         for token, account in OTHER_ACCOUNTS.items():
         for token, account in OTHER_ACCOUNTS.items():
-            cl = Pithos_Client(get_server(), token, account, get_api()) 
+            cl = Pithos_Client(get_url(), token, account)
             new_data = get_random_data()
             if account in authorized or any:
                 # test write access
                 self.assert_not_raises_fault(403, cl.update_object,
             new_data = get_random_data()
             if account in authorized or any:
                 # test write access
                 self.assert_not_raises_fault(403, cl.update_object,
-                                             'c', 'o', StringIO(new_data),
+                                             self.container, self.object, StringIO(new_data),
                                              account=get_user())
                 try:
                     # test read access
                                              account=get_user())
                 try:
                     # test read access
-                    server_data = cl.retrieve_object('c', 'o', account=get_user())
+                    server_data = cl.retrieve_object(self.container, self.object, account=get_user())
                     self.assertEqual(o_data, server_data[:len(o_data)])
                     self.assertEqual(new_data, server_data[len(o_data):])
                     o_data = server_data
                     self.assertEqual(o_data, server_data[:len(o_data)])
                     self.assertEqual(new_data, server_data[len(o_data):])
                     o_data = server_data
@@ -1933,71 +1993,104 @@ class TestPermissions(BaseTestCase):
                     self.failIf(f.status == 403)
             else:
                 self.assert_raises_fault(403, cl.update_object,
                     self.failIf(f.status == 403)
             else:
                 self.assert_raises_fault(403, cl.update_object,
-                                             'c', 'o', StringIO(new_data),
+                                             self.container, self.object, StringIO(new_data),
                                              account=get_user())
                                              account=get_user())
-        
         #check inheritance
         #check inheritance
-        o = self.upload_random_data('c', 'o/also-shared')
-        o_data = o['data']
-        for token, account in OTHER_ACCOUNTS.items():
-            cl = Pithos_Client(get_server(), token, account, get_api()) 
-            new_data = get_random_data()
-            if account in authorized or any:
-                # test write access
-                self.assert_not_raises_fault(403, cl.update_object,
-                                             'c', o['name'],
-                                             StringIO(new_data),
-                                             account=get_user())
-                try:
-                    server_data = cl.retrieve_object('c', o['name'], account=get_user())
-                    self.assertEqual(o_data, server_data[:len(o_data)])
-                    self.assertEqual(new_data, server_data[len(o_data):])
-                    o_data = server_data
-                except Fault, f:
-                    self.failIf(f.status == 403)
-            else:
-                self.assert_raises_fault(403, cl.update_object,
-                                             'c', o['name'],
-                                             StringIO(new_data),
-                                             account=get_user())
-    
+        meta = self.client.retrieve_object_metadata(self.container, self.object)
+        type = meta['content-type']
+        derivatives = self.client.list_objects(self.container, prefix=self.object)
+        #exclude the object
+        del derivatives[derivatives.index(self.object)]
+        for o in derivatives:
+            for token, account in OTHER_ACCOUNTS.items():
+                prefix = self.object if self.object.endswith('/') else self.object+'/'
+                cl = Pithos_Client(get_url(), token, account)
+                new_data = get_random_data()
+                if (account in authorized or any) and \
+                (type in self.dir_content_types) and \
+                o.startswith(prefix):
+                    # test write access
+                    self.assert_not_raises_fault(403, cl.update_object,
+                                                 self.container, o,
+                                                 StringIO(new_data),
+                                                 account=get_user())
+                    try:
+                        server_data = cl.retrieve_object(self.container, o, account=get_user())
+                        self.assertEqual(new_data, server_data[-len(new_data):])
+                    except Fault, f:
+                        self.failIf(f.status == 403)
+                else:
+                    self.assert_raises_fault(403, cl.update_object,
+                                                 self.container, o,
+                                                 StringIO(new_data),
+                                                 account=get_user())
+
     def test_group_read(self):
     def test_group_read(self):
-        self.client.create_container('c')
-        o = self.upload_random_data('c', 'o')
-        self.client.share_object('c', 'o', ['%s:pithosdev' % get_user()])
+        self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()])
         self.assert_read(authorized=self.authorized)
         self.assert_read(authorized=self.authorized)
-    
+
     def test_read_many(self):
     def test_read_many(self):
-        #test read access
-        self.client.create_container('c')
-        o = self.upload_random_data('c', 'o')
-        self.client.share_object('c', 'o', self.authorized)
+        self.client.share_object(self.container, self.object, self.authorized)
         self.assert_read(authorized=self.authorized)
         self.assert_read(authorized=self.authorized)
-    
+
     def test_read_by_everyone(self):
     def test_read_by_everyone(self):
-        self.client.create_container('c')
-        o = self.upload_random_data('c', 'o')
-        self.client.share_object('c', 'o', ['*'])
+        self.client.share_object(self.container, self.object, ['*'])
         self.assert_read(any=True)
         self.assert_read(any=True)
-    
+
+    def test_read_directory(self):
+        for type in self.dir_content_types:
+            #change content type
+            self.client.move_object(self.container, self.object, self.container, self.object, content_type=type)
+            self.client.share_object(self.container, self.object, ['*'])
+            self.assert_read(any=True)
+            self.client.share_object(self.container, self.object, self.authorized)
+            self.assert_read(authorized=self.authorized)
+            self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()])
+            self.assert_read(authorized=self.authorized)
+
     def test_group_write(self):
     def test_group_write(self):
-        self.client.create_container('c')
-        o = self.upload_random_data('c', 'o')
-        self.client.share_object('c', 'o', ['%s:pithosdev' % get_user()], read=False)
-        self.assert_write(o['data'], authorized=self.authorized)
-    
+        self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()], read=False)
+        self.assert_write(authorized=self.authorized)
+
     def test_write_many(self):
     def test_write_many(self):
-        self.client.create_container('c')
-        o = self.upload_random_data('c', 'o')
-        self.client.share_object('c', 'o', self.authorized, read=False)
-        self.assert_write(o['data'], authorized=self.authorized)
-    
+        self.client.share_object(self.container, self.object, self.authorized, read=False)
+        self.assert_write(authorized=self.authorized)
+
     def test_write_by_everyone(self):
     def test_write_by_everyone(self):
-        self.client.create_container('c')
-        o = self.upload_random_data('c', 'o')
-        self.client.share_object('c', 'o', ['*'], read=False)
-        o_data = o['data']
-        self.assert_write(o['data'], any=True)
+        self.client.share_object(self.container, self.object, ['*'], read=False)
+        self.assert_write(any=True)
+
+    def test_write_directory(self):
+        dir_content_types = ('application/directory', 'application/foler')
+        for type in dir_content_types:
+            #change content type
+            self.client.move_object(self.container, self.object, self.container, self.object, content_type='application/folder')
+            self.client.share_object(self.container, self.object, ['*'], read=False)
+            self.assert_write(any=True)
+            self.client.share_object(self.container, self.object, self.authorized, read=False)
+            self.assert_write(authorized=self.authorized)
+            self.client.share_object(self.container, self.object, ['%s:pithosdev' % get_user()], read=False)
+            self.assert_write(authorized=self.authorized)
+
+    def test_shared_listing(self):
+        self.client.share_object(self.container, self.object, self.authorized)
+
+        my_shared_containers = self.client.list_containers(shared=True)
+        self.assertEqual(['c'], my_shared_containers)
+        my_shared_objects = self.client.list_objects('c', shared=True)
+        self.assertEqual(['o'], my_shared_objects)
+
+        dir_content_types = ('application/directory', 'application/foler')
+        for type in dir_content_types:
+            #change content type
+            self.client.move_object(self.container, self.object, self.container, self.object, content_type='application/folder')
+            my_shared_objects = self.client.list_objects('c', shared=True)
+            self.assertEqual(['o', 'o/', 'o/a'], my_shared_objects)
+
+        for token, account in OTHER_ACCOUNTS.items():
+            if account in self.authorized:
+                self.other = Pithos_Client(get_url(), token, account)
+                self.assertTrue(get_user() in self.other.list_shared_by_others())
 
 class TestPublish(BaseTestCase):
     def test_publish(self):
 
 class TestPublish(BaseTestCase):
     def test_publish(self):
@@ -2007,22 +2100,63 @@ class TestPublish(BaseTestCase):
         meta = self.client.retrieve_object_metadata('c', 'o')
         self.assertTrue('x-object-public' in meta)
         url = meta['x-object-public']
         meta = self.client.retrieve_object_metadata('c', 'o')
         self.assertTrue('x-object-public' in meta)
         url = meta['x-object-public']
-        public_client = Pithos_Client(get_server(), get_auth(), get_user(), api='')
-        data = public_client.get(url)[2]
+
+        p = urlparse(get_url())
+        if p.scheme == 'http':
+            conn = HTTPConnection(p.netloc)
+        elif p.scheme == 'https':
+            conn = HTTPSConnection(p.netloc)
+        else:
+            raise Exception('Unknown URL scheme')
+
+        conn.request('GET', url)
+        resp = conn.getresponse()
+        length = resp.getheader('content-length', None)
+        data = resp.read(length)
         self.assertEqual(o_data, data)
 
         self.assertEqual(o_data, data)
 
+class TestPolicies(BaseTestCase):
+    def test_none_versioning(self):
+        self.client.create_container('c', policies={'versioning':'none'})
+        o = self.upload_random_data('c', 'o')
+        meta = self.client.retrieve_object_metadata('c', 'o')
+        v = meta['x-object-version']
+        more_data = get_random_data()
+        self.client.update_object('c', 'o', StringIO(more_data))
+        vlist = self.client.retrieve_object_versionlist('c', 'o')
+        self.assert_raises_fault(404, self.client.retrieve_object_version,
+                                 'c', 'o', v)
+        data = self.client.retrieve_object('c', 'o')
+        end = len(o['data'])
+        self.assertEqual(data[:end], o['data'])
+        self.assertEqual(data[end:], more_data)
+
+    def test_quota(self):
+        self.client.create_container('c', policies={'quota':'1'})
+        meta = self.client.retrieve_container_metadata('c')
+        self.assertEqual(meta['x-container-policy-quota'], '1')
+        self.assert_raises_fault(413, self.upload_random_data, 'c', 'o',
+                                 length=1024*1024+1)
+
+    def test_quota_none(self):
+        self.client.create_container('c', policies={'quota':'0'})
+        meta = self.client.retrieve_container_metadata('c')
+        self.assertEqual(meta['x-container-policy-quota'], '0')
+        self.assert_not_raises_fault(413, self.upload_random_data, 'c', 'o',
+                                 length=1024*1024+1)
+
 class AssertUUidInvariant(object):
     def __init__(self, callable, *args, **kwargs):
         self.callable = callable
         self.args = args
         self.kwargs = kwargs
 class AssertUUidInvariant(object):
     def __init__(self, callable, *args, **kwargs):
         self.callable = callable
         self.args = args
         self.kwargs = kwargs
-    
+
     def __enter__(self):
         self.map = self.callable(*self.args, **self.kwargs)
         assert('x-object-uuid' in self.map)
         self.uuid = self.map['x-object-uuid']
         return self.map
     def __enter__(self):
         self.map = self.callable(*self.args, **self.kwargs)
         assert('x-object-uuid' in self.map)
         self.uuid = self.map['x-object-uuid']
         return self.map
-    
+
     def __exit__(self, type, value, tb):
         map = self.callable(*self.args, **self.kwargs)
         assert('x-object-uuid' in self.map)
     def __exit__(self, type, value, tb):
         map = self.callable(*self.args, **self.kwargs)
         assert('x-object-uuid' in self.map)
@@ -2034,11 +2168,11 @@ class AssertMappingInvariant(object):
         self.callable = callable
         self.args = args
         self.kwargs = kwargs
         self.callable = callable
         self.args = args
         self.kwargs = kwargs
-    
+
     def __enter__(self):
         self.map = self.callable(*self.args, **self.kwargs)
         return self.map
     def __enter__(self):
         self.map = self.callable(*self.args, **self.kwargs)
         return self.map
-    
+
     def __exit__(self, type, value, tb):
         map = self.callable(*self.args, **self.kwargs)
         for k, v in self.map.items():
     def __exit__(self, type, value, tb):
         map = self.callable(*self.args, **self.kwargs)
         for k, v in self.map.items():
@@ -2047,17 +2181,17 @@ class AssertMappingInvariant(object):
             #print '#', k, v, map[k]
             assert(k in map)
             assert v == map[k]
             #print '#', k, v, map[k]
             assert(k in map)
             assert v == map[k]
-    
+
 class AssertContentInvariant(object):
     def __init__(self, callable, *args, **kwargs):
         self.callable = callable
         self.args = args
         self.kwargs = kwargs
 class AssertContentInvariant(object):
     def __init__(self, callable, *args, **kwargs):
         self.callable = callable
         self.args = args
         self.kwargs = kwargs
-    
+
     def __enter__(self):
         self.content = self.callable(*self.args, **self.kwargs)[2]
         return self.content
     def __enter__(self):
         self.content = self.callable(*self.args, **self.kwargs)[2]
         return self.content
-    
+
     def __exit__(self, type, value, tb):
         content = self.callable(*self.args, **self.kwargs)[2]
         assert self.content == content
     def __exit__(self, type, value, tb):
         content = self.callable(*self.args, **self.kwargs)[2]
         assert self.content == content
@@ -2079,7 +2213,7 @@ def compute_block_hash(data, algorithm):
 
 def get_random_data(length=500):
     char_set = string.ascii_uppercase + string.digits
 
 def get_random_data(length=500):
     char_set = string.ascii_uppercase + string.digits
-    return ''.join(random.choice(char_set) for x in range(length))
+    return ''.join(random.choice(char_set) for x in xrange(length))
 
 def is_date(date):
     MONTHS = 'jan feb mar apr may jun jul aug sep oct nov dec'.split()
 
 def is_date(date):
     MONTHS = 'jan feb mar apr may jun jul aug sep oct nov dec'.split()
@@ -2117,7 +2251,7 @@ o_names = ['kate.jpg',
 
 def main():
     if get_user() == 'test':
 
 def main():
     if get_user() == 'test':
-        unittest.main()
+        unittest.main(module='pithos.tools.test')
     else:
         print 'Will not run tests as any other user except \'test\' (current user: %s).' % get_user()
 
     else:
         print 'Will not run tests as any other user except \'test\' (current user: %s).' % get_user()