extend api tests + bug fixing client lib
authorSofia Papagiannaki <papagian@gmail.com>
Tue, 19 Jul 2011 15:22:42 +0000 (18:22 +0300)
committerSofia Papagiannaki <papagian@gmail.com>
Tue, 19 Jul 2011 15:22:42 +0000 (18:22 +0300)
pithos/api/tests.py
pithos/lib/client.py
tools/store

index b966e21..187d9ea 100644 (file)
@@ -169,7 +169,6 @@ class BaseTestCase(unittest.TestCase):
             self._assert_json(data, type, size)
     
     def _assert_json(self, data, type, size):
-        print '#', data
         convert = lambda s: s.lower()
         info = [convert(elem) for elem in self.extended[type]]
         self.assertTrue(len(data) <= size)
@@ -191,7 +190,6 @@ class BaseTestCase(unittest.TestCase):
         self.assertTrue(len(entities) <= size)
         for e in entities:
             for item in info:
-                print '#', item
                 self.assertTrue(e.hasAttribute(item))
     
     def assert_raises_fault(self, status, callableObj, *args, **kwargs):
@@ -424,19 +422,105 @@ class AccountPost(BaseTestCase):
         self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears']
         for item in self.containers:
             self.client.create_container(item)
-    
-    def test_update_meta(self):
-        meta = {'test':'test', 'tost':'tost'}
+        
+        #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)
+        
+        meta = {'foo':'bar'}
         self.client.update_account_metadata(**meta)
-        self.assertEqual(meta, self.client.retrieve_account_metadata(restricted=True))
+        self.updated_meta = self.initial_meta.update(meta)
     
+    def tearDown(self):
+        #delete additionally created meta
+        l = []
+        for m in self.client.retrieve_account_metadata(restricted=True):
+            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():
+            if g not in self.initial_groups:
+                l.append(g)
+        self.client.unset_account_groups(l)
+        
+        #print '#', self.client.retrieve_account_groups()
+        #print '#', self.client.retrieve_account_metadata(restricted=True)
+        BaseTestCase.tearDown(self)
+    
+    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))
+        
     def test_invalid_account_update_meta(self):
-        meta = {'HTTP_X_ACCOUNT_META_TEST':'test',
-               'HTTP_X_ACCOUNT_META_TOST':'tost'}
+        meta = {'test':'test', 'tost':'tost'}
         self.assert_raises_fault(401,
                                  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)
+            
+            meta = {'test':'test33'}
+            self.client.reset_account_metadata(**meta)
+            
+            self.assertEqual(meta, self.client.retrieve_account_metadata(restricted=True))
+    
+    #def test_delete_meta(self):
+    #    with AssertMappingInvariant(self.client.reset_account_groups):
+    #        meta = {'test':'test', 'tost':'tost'}
+    #        self.client.update_account_metadata(**meta)
+    #        
+    #        self.client.delete_account_metadata(**meta)
+    
+    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(groups, self.client.retrieve_account_groups())
+            
+            more_groups = {'clientsdev':'pkanavos,mvasilak'}
+            self.client.set_account_groups(**more_groups)
+            
+            groups.update(more_groups)
+            self.assertEqual(groups, self.client.retrieve_account_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(groups, self.client.retrieve_account_groups())
+            
+            groups = {'pithosdev':'verigak,gtsouk,chazapis, papagian'}
+            self.client.reset_account_groups(**groups)
+            
+            self.assertTrue(groups, self.client.retrieve_account_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.assertEqual({}, self.client.retrieve_account_groups())
+    
 class ContainerHead(BaseTestCase):
     def setUp(self):
         BaseTestCase.setUp(self)
@@ -1198,6 +1282,7 @@ class ObjectPost(BaseTestCase):
                 'content_range':'%s' %range}
         if content_length:
             args['content_length'] = content_length
+        
         status = self.client.update_object(self.containers[0], self.obj['name'],
                                   StringIO(data), **args)[0]
         
@@ -1223,17 +1308,19 @@ class ObjectPost(BaseTestCase):
     def test_update_object_invalid_range(self):
         with AssertContentInvariant(self.client.retrieve_object,
                                     self.containers[0], self.obj['name']):
-            self.test_update_object(499, 0, True)
+            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['name']):
-            self.test_update_object(499, 0, True, -1)
+            self.assert_raises_fault(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['name']):
-            self.test_update_object(499, 0, True, content_length = None)
+            self.assert_raises_fault(416, self.test_update_object, 499, 0, True,
+                                     content_length = None)
     
     def test_update_object_out_of_limits(self):    
         with AssertContentInvariant(self.client.retrieve_object,
@@ -1300,7 +1387,7 @@ class AssertMappingInvariant(object):
     def __exit__(self, type, value, tb):
         map = self.callable(*self.args, **self.kwargs)
         for k in self.map.keys():
-            if is_date(map[k]):
+            if is_date(self.map[k]):
                 continue
             assert map[k] == self.map[k]
 
index 0e55d1e..b2ecf98 100644 (file)
@@ -94,8 +94,9 @@ class Client(object):
         kwargs['headers']['X-Auth-Token'] = self.token
         if body:
             kwargs['body'] = body
+            kwargs['headers'].setdefault('content-type',
+                                         'application/octet-stream')
         kwargs['headers'].setdefault('content-length', len(body) if body else 0)
-        kwargs['headers'].setdefault('content-type', 'application/octet-stream')
         try:
             #print '*', method, full_path, kwargs
             conn.request(method, full_path, **kwargs)
@@ -118,9 +119,10 @@ class Client(object):
             print
         
         if int(resp.status) in ERROR_CODES.keys():
+            #print '**', resp.status
             raise Fault(data, int(resp.status))
         
-        #print '*',  resp.status, headers, data
+        #print '**',  resp.status, headers, data
         return resp.status, headers, data
     
     def delete(self, path, format='text', params={}):
@@ -146,7 +148,6 @@ class Client(object):
         if format == 'json':
             data = json.loads(data) if data else ''
         elif format == 'xml':
-            print '#', data
             data = minidom.parseString(data)
         else:
             data = data.strip().split('\n') if data else ''
@@ -190,7 +191,7 @@ class OOS_Client(Client):
         for k,v in ex_meta.items():
             k = '%s%s' % (prefix, k)
             headers[k] = v
-        return self.post(path, headers=headers, params=params)
+        return self.post(path, headers=headers)
     
     def _reset_metadata(self, path, entity, **meta):
         """
@@ -309,10 +310,14 @@ class OOS_Client(Client):
         h = {'Content-Type':'application/directory'}
         return self.create_zero_length_object(container, object, **h)
     
+    def create_directory_marker(self, container, object):
+        """creates a dierectory marker"""
+        return self.create_object(container, object, f=None)
+    
     def create_object(self, container, object, f=stdin, format='text', meta={},
                       etag=None, content_type=None, content_encoding=None,
                       content_disposition=None, **headers):
-        """creates an object"""
+        """creates a zero-length object"""
         path = '/%s/%s' % (container, object)
         for k, v  in headers.items():
             if not v:
@@ -328,6 +333,15 @@ class OOS_Client(Client):
         data = f.read() if f else None
         return self.put(path, data, format, headers=headers)
     
+    def create_zero_length_object(self, container, object, meta={}, etag=None,
+                                  content_type=None, content_encoding=None,
+                                  content_disposition=None, **headers):
+        args = locals()
+        for elem in ['self', 'container', 'headers']:
+            args.pop(elem)
+        args.update(headers)
+        return self.create_object(container, f=None, **args)
+    
     def update_object(self, container, object, f=stdin, offset=None, meta={},
                       content_length=None, content_type=None,
                       content_encoding=None, content_disposition=None,
@@ -537,6 +551,15 @@ class Pithos_Client(OOS_Client):
         params = {'update':None}
         return self.post('', headers=headers, params=params)
     
+    def reset_account_groups(self, **groups):
+        """overrides account groups"""
+        headers = {}
+        for key, val in groups.items():
+            headers['x-account-group-%s' % key] = val
+        meta = self.retrieve_account_metadata()
+        headers.update(meta)
+        return self.post('', headers=headers)
+    
     # Storage Container Services
     
     def list_objects(self, container, format='text', limit=10000, marker=None,
@@ -614,6 +637,17 @@ class Pithos_Client(OOS_Client):
         return self.retrieve_object_version(container, object, version='list',
                                             detail=True, **args)
     
+    def create_zero_length_object(self, container, object, meta={},
+                      etag=None, content_type=None, content_encoding=None,
+                      content_disposition=None, x_object_manifest=None,
+                      x_object_sharing=None, x_object_public=None):
+        """createas a zero length object"""
+        args = locals()
+        for elem in ['self', 'container', 'object']:
+            args.pop(elem)
+        return OOS_Client.create_zero_length_object(self, container, object,
+                                                    **args)
+    
     def create_object(self, container, object, f=stdin, meta={},
                       etag=None, content_type=None, content_encoding=None,
                       content_disposition=None, x_object_manifest=None,
index 1d555a3..582cc50 100755 (executable)
@@ -406,8 +406,10 @@ class PutObject(Command):
                                  meta=meta, **args)
         elif self.x_object_manifest:
             self.client.create_manifestation(container, object, self.x_object_manifest)
+        elif not f:
+            self.client.create_zero_length_object(container, object, meta=meta, **args)
         else:
-            data = f.read() if f else None
+            data = f.read()
             self.client.create_object(container, object, data, meta=meta, **args)
         if f:
             f.close()