(Almost) complete pithos client unittesting
authorStavros Sachtouris <saxtouri@admin.grnet.gr>
Mon, 30 Jul 2012 15:49:47 +0000 (18:49 +0300)
committerStavros Sachtouris <saxtouri@admin.grnet.gr>
Mon, 30 Jul 2012 15:49:47 +0000 (18:49 +0300)
transfer_encoding still unchecked

kamaki/cli.py
kamaki/clients/pithos.py
kamaki/clients/tests.py

index fedb6b5..ceef3b7 100755 (executable)
@@ -1032,10 +1032,21 @@ class store_setversioning(_store_account_command):
 @command(api='storage')
 class store_test(_store_account_command):
     """Perform a developer-level custom test"""
+
     def main(self):
         super(store_test, self).main()
-        self.client.container = 'testCo'
-        r2 = self.client.container_post(transfer_encoding='chunked', data='lala')
+        self.client.container = 'testCo0'
+        obj = 'test'
+        
+        r = self.client.object_put(obj, content_encoding='application/octet-stream', trasnfer_encoding='chunked')
+        while True:
+            try:
+                s = raw_input('(ctrl^D to exit):')
+                print('You gave me [%s] and I will append it at %s'%(s, obj))
+            except EOFError:
+                print('\nThanks!')
+                break
+
 
 @command(api='storage')
 class store_group(_store_account_command):
index 80cdf46..34b5867 100644 (file)
@@ -384,7 +384,7 @@ class PithosClient(StorageClient):
     def object_copy(self, object, destination, format='json', ignore_content_type=False,
         if_etag_match=None, if_etag_not_match=None, destination_account=None,
         content_type=None, content_encoding=None, content_disposition=None, source_version=None,
-        manifest=None, permitions={}, public=False, metadata={}, *args, **kwargs):
+        permitions={}, public=False, metadata={}, *args, **kwargs):
         """ Full Pithos+ COPY at object level
         --- request parameters ---
         @param format (string): json (default) or xml
@@ -400,7 +400,6 @@ class PithosClient(StorageClient):
         @param content_encoding (string): The encoding of the object
         @param content_disposition (string): The presentation style of the object
         @param source_version (string): The source version to copy from
-        @param manifest (string): Object parts prefix in /<container>/<object> form
         @param permitions (dict): Object permissions in the form (all fields are optional)
                 {'read':[user1, group1, user2, ...], 'write':['user3, group2, group3, ...]}
                 permitions override source permitions, removing any old permitions
@@ -423,7 +422,6 @@ class PithosClient(StorageClient):
         self.set_header('Content-Encoding', content_encoding)
         self.set_header('Content-Disposition', content_disposition)
         self.set_header('X-Source-Version', source_version)
-        self.set_header('X-Object-Manifest', manifest)
         perms = None
         for permition_type, permition_list in permitions.items():
             if perms is None:
@@ -441,8 +439,8 @@ class PithosClient(StorageClient):
 
     def object_move(self, object, format='json', ignore_content_type=False,
         if_etag_match=None, if_etag_not_match=None, destination=None, destination_account=None,
-        content_type=None, content_encoding=None, content_disposition=None, manifest=None,
-        permitions={}, public=False, metadata={}, *args, **kwargs):
+        content_type=None, content_encoding=None, content_disposition=None, permitions={},
+        public=False, metadata={}, *args, **kwargs):
         """ Full Pithos+ COPY at object level
         --- request parameters ---
         @param format (string): json (default) or xml
@@ -458,7 +456,6 @@ class PithosClient(StorageClient):
         @param content_encoding (string): The encoding of the object
         @param content_disposition (string): The presentation style of the object
         @param source_version (string): The source version to copy from
-        @param manifest (string): Object parts prefix in /<container>/<object> form
         @param permitions (dict): Object permissions in the form (all fields are optional)
                 {'read':[user1, group1, user2, ...], 'write':['user3, group2, group3, ...]}
         @param public (bool): If true, Object is publicly accessible, if false, not
@@ -477,7 +474,6 @@ class PithosClient(StorageClient):
         self.set_header('Content-Type', content_type)
         self.set_header('Content-Encoding', content_encoding)
         self.set_header('Content-Disposition', content_disposition)
-        self.set_header('X-Object-Manifest', manifest)
         perms = None
         for permition_type, permition_list in permitions.items():
             if perms is None:
index fbb0b99..e73e5ee 100644 (file)
@@ -82,7 +82,6 @@ class testPithos(unittest.TestCase):
             name = obj['name']
             self.client.reset_headers()
             self.client.object_delete(name)
-            #print('Just deleted '+name+' in '+container)
         self.client.reset_headers()
         self.client.container_delete()
         self.client.reset_headers()
@@ -90,7 +89,6 @@ class testPithos(unittest.TestCase):
 
     def tearDown(self):
         """Destroy test cases"""
-        print('destroy test ...')
         if self.fname is not None:
             try:
                 os.remove(self.fname)
@@ -105,7 +103,7 @@ class testPithos(unittest.TestCase):
             pass
         self.client.container=''
 
-    def atest_account_head(self):
+    def test_account_head(self):
         """Test account_HEAD"""
         r = self.client.account_head()
         self.assertEqual(r.status_code, 204)
@@ -124,7 +122,7 @@ class testPithos(unittest.TestCase):
             self.client.reset_headers()
             self.assertNotEqual(r1.status_code, r2.status_code)
 
-    def atest_account_get(self):
+    def test_account_get(self):
         """Test account_GET"""
         r = self.client.account_get()
         self.assertEqual(r.status_code, 200)
@@ -157,7 +155,7 @@ class testPithos(unittest.TestCase):
             self.client.reset_headers()
             self.assertNotEqual(r1.status_code, r2.status_code)
 
-    def atest_account_post(self):
+    def test_account_post(self):
         """Test account_POST"""
         r = self.client.account_post()
         self.assertEqual(r.status_code, 202)
@@ -194,7 +192,7 @@ class testPithos(unittest.TestCase):
         you don't have permitions to modify those at account level
         """
 
-    def atest_container_head(self):
+    def test_container_head(self):
         """Test container_HEAD"""
         self.client.container = self.c1
 
@@ -215,7 +213,7 @@ class testPithos(unittest.TestCase):
             self.client.reset_headers()
             self.assertNotEqual(r1.status_code, r2.status_code)
 
-    def atest_container_get(self):
+    def test_container_get(self):
         """Test container_GET"""
         self.client.container = self.c1
 
@@ -278,7 +276,7 @@ class testPithos(unittest.TestCase):
             self.assertNotEqual(r1.status_code, r2.status_code)
             self.client.reset_headers()
        
-    def atest_container_put(self):
+    def test_container_put(self):
         """Test container_PUT"""
         self.client.container = self.c2
 
@@ -330,7 +328,7 @@ class testPithos(unittest.TestCase):
        
         self.client.del_container_meta(self.client.container)
 
-    def atest_container_post(self):
+    def test_container_post(self):
         """Test container_POST"""
         self.client.container = self.c2
 
@@ -415,7 +413,7 @@ class testPithos(unittest.TestCase):
         r = self.client.del_container_meta('m2')
         self.client.reset_headers()
 
-    def atest_container_delete(self):
+    def test_container_delete(self):
         """Test container_DELETE"""
 
         """Fail to delete a non-empty container"""
@@ -435,7 +433,8 @@ class testPithos(unittest.TestCase):
         self.assertEqual(r.status_code, 204)
         self.client.reset_headers()
 
-    def atest_object_head(self):
+    def test_object_head(self):
+        """Test object_HEAD"""
         self.client.container = self.c2
         obj = 'test'
 
@@ -468,7 +467,8 @@ class testPithos(unittest.TestCase):
             self.assertNotEqual(r1.status_code, r2.status_code)
             self.client.reset_headers()
 
-    def atest_object_get(self):
+    def test_object_get(self):
+        """Test object_GET"""
         self.client.container = self.c1
         obj = 'test'
 
@@ -519,7 +519,7 @@ class testPithos(unittest.TestCase):
             self.assertNotEqual(r1.status_code, r2.status_code)
             self.client.reset_headers()
 
-    def atest_object_put(self):
+    def test_object_put(self):
         """test object_PUT"""
 
         self.client.container = self.c2
@@ -734,94 +734,97 @@ class testPithos(unittest.TestCase):
         self.assertTrue(r.has_key('x-object-public'))
         self.client.reset_headers()
 
-        """Still untested: manifest"""
-
-    def atest_object_move(self):
-        self.client.container='testCo0'
-        obj = 'obj'+unicode(self.now)
+    def test_object_move(self):
+        """Test object_MOVE"""
+        self.client.container= self.c2
+        obj = 'test2'
 
         data= '{"key1":"val1", "key2":"val2"}'
         r = self.client.object_put(obj+'orig', content_type='application/octet-stream',
             data= data, metadata={'mkey1':'mval1', 'mkey2':'mval2'},
             permitions={'read':['accX:groupA', 'u1', 'u2'], 'write':['u2', 'u3']})
         self.client.reset_headers()
-        r = self.client.object_move(obj+'orig', destination = '/'+self.client.container+'/'+obj, ignore_content_type=False, content_type='application/json', 
+        r = self.client.object_move(obj+'orig', destination = '/'+self.client.container+'/'+obj,
+            ignore_content_type=False, content_type='application/json', 
             metadata={'mkey2':'mval2a', 'mkey3':'mval3'},
             permitions={'write':['u5', 'accX:groupB']})
         self.assertEqual(r.status_code, 201)
         self.client.reset_headers()
 
         """Check Metadata"""
-        r = self.client.object_get(obj)
-        self.assertTrue(r.headers.has_key('x-object-meta-mkey1'))
-        self.assertEqual(r.headers['x-object-meta-mkey1'], 'mval1')
-        self.assertTrue(r.headers.has_key('x-object-meta-mkey2'))
-        self.assertEqual(r.headers['x-object-meta-mkey2'], 'mval2a')
-        self.assertTrue(r.headers.has_key('x-object-meta-mkey3'))
-        self.assertEqual(r.headers['x-object-meta-mkey3'], 'mval3')
+        r = self.client.get_object_meta(obj)
+        self.assertEqual(r['mkey1'], 'mval1')
+        self.assertEqual(r['mkey2'], 'mval2a')
+        self.assertEqual(r['mkey3'], 'mval3')
+        self.client.reset_headers()
+
         """Check permitions"""
-        self.assertFalse('read' in r.headers['x-object-sharing'])
-        self.assertFalse('u2' in r.headers['x-object-sharing'])
-        self.assertTrue('write' in r.headers['x-object-sharing'])
-        self.assertTrue('accx:groupb' in r.headers['x-object-sharing'])
+        r = self.client.get_object_sharing(obj)
+        self.assertFalse(r.has_key('read'))
+        self.assertTrue('u5' in r['write'])
+        self.assertTrue('accx:groupb' in r['write'])
         self.client.reset_headers()
 
         """Check destination account"""
-        r = self.client.object_move(obj, destination='/testCo/'+obj, content_encoding='utf8',
+        r = self.client.object_move(obj, destination='/%s/%s'%(self.c1,obj), content_encoding='utf8',
             content_type='application/json', destination_account='nonExistendAddress@NeverLand.com',
             success=(201, 403))
         self.assertEqual(r.status_code, 403)
         self.client.reset_headers()
 
-        """Check destination being another container and also content_type and content encoding"""
-        r = self.client.object_move(obj, destination='/testCo/'+obj,
-            content_encoding='utf8', content_type='application/json')
+        """Check destination being another container and also
+        content_type, content_disposition and content encoding"""
+        r = self.client.object_move(obj, destination='/%s/%s'%(self.c1,obj),
+            content_encoding='utf8', content_type='application/json',
+            content_disposition='attachment; filename="fname.ext"')
         self.assertEqual(r.status_code, 201)
         self.assertEqual(r.headers['content-type'], 'application/json; charset=UTF-8')
         self.client.reset_headers()
+        r = self.client.container=self.c1
+        r = self.client.get_object_info(obj)
+        self.assertTrue(r.has_key('content-disposition') and 'fname.ext' in r['content-disposition'])
+        etag = r['etag']
+        ctype = r['content-type']
+        self.assertEqual(ctype, 'application/json')
         self.client.reset_headers()
 
         """Check ignore_content_type and content_type"""
-        r = self.client.container='testCo'
-        r = self.client.object_get(obj)
-        etag = r.headers['etag']
-        ctype = r.headers['content-type']
-        self.assertEqual(ctype, 'application/json')
-        self.client.reset_headers()
-        r = self.client.object_move(obj, destination = '/testCo0/'+obj,
+        r = self.client.object_move(obj, destination = '/%s/%s'%(self.c2,obj),
             ignore_content_type=True, content_type='application/json')
         self.assertEqual(r.status_code, 201)
         self.assertNotEqual(r.headers['content-type'], 'application/json')
-        r = self.client.container='testCo0'
         self.client.reset_headers()
 
         """Check if_etag_(not_)match"""
-        r = self.client.object_move(obj, destination='/'+self.client.container+'/'+obj+'0', if_etag_match=etag)
+        r = self.client.container=self.c2
+        r = self.client.object_move(obj, destination='/'+self.client.container+'/'+obj+'0',
+            if_etag_match=etag)
         self.assertEqual(r.status_code, 201)
         self.client.reset_headers()
-        r = self.client.object_move(obj+'0', destination='/'+self.client.container+'/'+obj+'1', if_etag_not_match='lalala')
+        r = self.client.object_move(obj+'0', destination='/'+self.client.container+'/'+obj+'1',
+            if_etag_not_match='lalala')
         self.assertEqual(r.status_code, 201)
         self.client.reset_headers()
 
         """Check public and format """
-        r = self.client.object_move(obj+'1', destination='/'+self.client.container+'/'+obj+'2', format='xml', public=True)
+        r = self.client.object_move(obj+'1', destination='/'+self.client.container+'/'+obj+'2',
+            format='xml', public=True)
         self.assertEqual(r.status_code, 201)
         self.assertTrue(r.headers['content-type'].index('xml') > 0)
         self.client.reset_headers()
-        r = self.client.object_get(obj+'2')
-        self.assertTrue(r.headers.has_key('x-object-public'))
+        r = self.client.get_object_info(obj+'2')
+        self.assertTrue(r.has_key('x-object-public'))
         self.client.reset_headers()
 
-        """Still untested: content_disposition, manifest"""
-        self.client.delete_object(obj+'2')
-        self.client.container=''
-
-    def atest_object_post(self):
-        self.client.container='testCo0'
-        obj = 'obj'+unicode(self.now)
+    def test_object_post(self):
+        """Test object_POST"""
+        self.client.container=self.c2
+        obj = 'test2'
         """create a filesystem file"""
-        newf = open(obj, 'w')
+        self.fname = obj
+        newf = open(self.fname, 'w')
         newf.writelines(['ello!\n','This is a test line\n','inside a test file\n'])
+        newf.close()
         """create a file on container"""
         r = self.client.object_put(obj, content_type='application/octet-stream',
             data= 'H', metadata={'mkey1':'mval1', 'mkey2':'mval2'},
@@ -857,27 +860,25 @@ class testPithos(unittest.TestCase):
         self.client.set_object_meta(obj, {'mkey2':'mval2a', 'mkey3':'mval3'})
         self.client.reset_headers()
         r = self.client.get_object_meta(obj)
-        self.assertTrue(r.has_key('x-object-meta-mkey1'))
-        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
-        self.assertTrue(r.has_key('x-object-meta-mkey2'))
-        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
-        self.assertTrue(r.has_key('x-object-meta-mkey3'))
-        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
+        self.assertEqual(r['mkey1'], 'mval1')
+        self.assertEqual(r['mkey2'], 'mval2a')
+        self.assertEqual(r['mkey3'], 'mval3')
         self.client.reset_headers()
         self.client.del_object_meta('mkey1', obj)
         self.client.reset_headers()
         r = self.client.get_object_meta(obj)
-        self.assertFalse(r.has_key('x-object-meta-mkey1'))
+        self.assertFalse(r.has_key('mkey1'))
         self.client.reset_headers()
 
         """Check permitions"""
-        self.client.set_object_sharing(obj, read_permition=['u4', 'u5'], write_permition=['u4'])
+        self.client.set_object_sharing(obj,
+            read_permition=['u4', 'u5'], write_permition=['u4'])
         self.client.reset_headers()
         r = self.client.get_object_sharing(obj)
         self.assertTrue(r.has_key('read'))
-        self.assertTrue(r['read'].index('u5') >= 0)
+        self.assertTrue('u5' in r['read'])
         self.assertTrue(r.has_key('write'))
-        self.assertTrue(r['write'].index('u4') >= 0)
+        self.assertTrue('u4' in r['write'])
         self.client.reset_headers()
         self.client.del_object_sharing(obj)
         r = self.client.get_object_sharing(obj)
@@ -911,30 +912,47 @@ class testPithos(unittest.TestCase):
         self.assertEqual(r['content-encoding'], 'application/json')
         self.client.reset_headers()
 
-        """Check source_version and source_account"""
+        """Check source_version and source_account and content_disposition"""
         r = self.client.object_post(obj, update=True, content_type='application/octet-srteam',
-            content_length=5, content_range='bytes 1-5/*', source_object='/testCo0/'+obj,
-            source_account='thisAccountWillNeverExist@adminland.com', source_version=helloVersion, data='12345',
-            success=(403, 202, 204))
+            content_length=5, content_range='bytes 1-5/*', source_object='/%s/%s'%(self.c2,obj),
+            source_account='thisAccountWillNeverExist@adminland.com',
+            source_version=helloVersion, data='12345', success=(403, 202, 204))
         self.assertEqual(r.status_code, 403)
         self.client.reset_headers()
         r = self.client.object_post(obj, update=True, content_type='application/octet-srteam',
-            content_length=5, content_range='bytes 1-5/*', source_object='/testCo0/'+obj,
-            source_account='thisAccountWillNeverExist@adminland.com', source_version=helloVersion, data='12345')
+            content_length=5, content_range='bytes 1-5/*', source_object='/%s/%s'%(self.c2,obj),
+            source_account=self.client.account, source_version=helloVersion, data='12345',
+            content_disposition='attachment; filename="fname.ext"')
         self.client.reset_headers()
         r = self.client.object_get(obj)
         self.assertEqual(r.text, 'eello!')
+        self.assertTrue(r.headers.has_key('content-disposition')
+            and 'fname.ext' in r.headers['content-disposition'])
         self.client.reset_headers()
 
-        """We need to check transfer_encoding, content_disposition, manifest """
+        """Check manifest"""
+        mobj = 'manifest.test'
+        txt = ''
+        for i in range(10):
+            txt += '%s'%i
+            r = self.client.object_put('%s/%s'%(mobj, i), data='%s'%i,
+                content_encoding='application/octet-stream',
+                content_length=1, success=201)
+            self.client.reset_headers()
+        self.client.object_put(mobj, content_length=0)
+        self.client.reset_headers()
+        r = self.client.object_post(mobj, manifest='%s/%s'%(self.client.container, mobj))
+        self.client.reset_headers()
+        r = self.client.object_get(mobj)
+        self.assertEqual(r.text, txt)
+        self.client.reset_headers()
 
-        self.client.object_delete(obj)
-        os.remove(obj)
-        self.client.container=''
+        """We need to check transfer_encoding """
 
-    def atest_object_delete(self):
-        self.client.container='testCo0'
-        obj = 'obj'+unicode(self.now)
+    def test_object_delete(self):
+        """Test object_DELETE"""
+        self.client.container=self.c2
+        obj = 'test2'
         """create a file on container"""
         r = self.client.object_put(obj, content_type='application/octet-stream',
             data= 'H', metadata={'mkey1':'mval1', 'mkey2':'mval2'},
@@ -954,8 +972,6 @@ class testPithos(unittest.TestCase):
         r = self.client.object_get(obj, success=(200, 404))
         self.assertEqual(r.status_code, 404)
 
-        self.client.container = ''
-
 class testCyclades(unittest.TestCase):
     def setUp(self):
         pass
@@ -973,7 +989,6 @@ if __name__ == '__main__':
     suiteFew = unittest.TestSuite()
 
     #kamaki/pithos.py
-    """
     suiteFew.addTest(testPithos('test_account_head'))
     suiteFew.addTest(testPithos('test_account_get'))
     suiteFew.addTest(testPithos('test_account_post'))
@@ -985,13 +1000,10 @@ if __name__ == '__main__':
     suiteFew.addTest(testPithos('test_object_head'))
     suiteFew.addTest(testPithos('test_object_get'))
     suiteFew.addTest(testPithos('test_object_put'))
-    """
     suiteFew.addTest(testPithos('test_object_copy'))
-    """
     suiteFew.addTest(testPithos('test_object_move'))
     suiteFew.addTest(testPithos('test_object_post'))
     suiteFew.addTest(testPithos('test_object_delete'))
-    """
 
     #kamaki/cyclades.py
     #suiteFew.addTest(testCyclades('test_list_servers'))