commit eea284923b6d9247ef8d3f5275c72175c86a3f28
Author: Stavros Sachtouris <saxtouri@admin.grnet.gr>
Date:   Mon Jan 20 17:57:12 2014 +0200

    Test everything up to object GET

diff --git a/snf-tools/synnefo_tools/burnin/pithos_tests.py b/snf-tools/synnefo_tools/burnin/pithos_tests.py
index 7aa03c7..6eb8c47 100644
--- a/snf-tools/synnefo_tools/burnin/pithos_tests.py
+++ b/snf-tools/synnefo_tools/burnin/pithos_tests.py
@@ -36,15 +36,25 @@ This is the burnin class that tests the Pithos functionality
 
 """
 
-import os
 import random
-import tempfile
 from datetime import datetime
+from tempfile import NamedTemporaryFile
 
 from synnefo_tools.burnin.common import BurninTests, Proper
 from kamaki.clients import ClientError
 
 
+def sample_block(f, block):
+    block_size = 4 * 1024 * 1024
+    f.seek(block * block_size)
+    ch = [f.read(1)]
+    f.seek(block_size / 2, 1)
+    ch.append(f.read(1))
+    f.seek((block + 1) * block_size - 1)
+    ch.append(f.read(1))
+    return ch
+
+
 # Too many public methods. pylint: disable-msg=R0904
 class PithosTestSuite(BurninTests):
     """Test Pithos functionality"""
@@ -52,6 +62,7 @@ class PithosTestSuite(BurninTests):
     created_container = Proper(value=None)
     now_unformated = Proper(value=datetime.utcnow())
     obj_metakey = Proper(value=None)
+    large_file = Proper(value=None)
 
     def test_005_account_head(self):
         """HEAD on pithos account"""
@@ -216,6 +227,9 @@ class PithosTestSuite(BurninTests):
         self.info('Status code is OK')
 
         fullLen = len(r.json)
+        self.assertGreater(fullLen, 0)
+        self.info('There are enough (%s) containers' % fullLen)
+
         obj1 = 'test%s' % random.randint(1000, 9999)
         pithos.create_object(obj1)
         obj2 = 'test%s' % random.randint(1000, 9999)
@@ -375,9 +389,11 @@ class PithosTestSuite(BurninTests):
         self.info('Set versioning works')
 
         f = self._create_large_file(1024 * 1024 * 100)
+        self.large_file = f
         self.info('Created file %s of 100 MB' % f.name)
 
         pithos.create_directory('dir')
+        self.info('Upload the file ...')
         r = pithos.upload_object('/dir/sample.file', f)
         for term in ('content-length', 'content-type', 'x-object-version'):
             self.assertTrue(term in r)
@@ -398,71 +414,178 @@ class PithosTestSuite(BurninTests):
         self.assertFalse('x-object-meta-%s' % self.obj_metakey not in r)
         self.info('Metadata with update=False works')
 
-    def test_050_stop_test(self):
+    def test_040_container_delete(self):
+        """Test container DELETE"""
+        pithos = self.clients.pithos
+
+        r = pithos.container_delete(success=409)
+        self.assertEqual(r.status_code, 409)
+        self.assertRaises(ClientError, pithos.container_delete)
+        self.info('Successfully failed to delete non-empty container')
+
+        r = pithos.container_delete(until='1000000000')
+        self.assertEqual(r.status_code, 204)
+        self.info('Successfully failed to delete old-timestamped container')
+
+        obj_names = [o['name'] for o in pithos.container_get().json]
+        pithos.del_container(delimiter='/')
+        r = pithos.container_get()
+        self.assertEqual(len(r.json), 0)
+        self.info('Successfully emptied container')
+
+        for obj in obj_names:
+            r = pithos.get_object_versionlist(obj)
+            self.assertTrue(len(r) > 0)
+        self.info('Versions are still there')
+
+        pithos.purge_container()
+        for obj in obj_names:
+            self.assertRaises(ClientError, pithos.get_object_versionlist, obj)
+        self.info('Successfully purged container')
+
+        self.temp_containers.remove(pithos.container)
+        pithos.container = self.temp_containers[-1]
+
+    def test_045_object_head(self):
+        """Test object HEAD"""
+        pithos = self.clients.pithos
+
+        obj = 'dir/sample.file'
+        r = pithos.object_head(obj)
+        self.assertEqual(r.status_code, 200)
+        self.info('Status code is OK')
+        etag = r.headers['etag']
+        real_version = r.headers['x-object-version']
+
+        self.assertRaises(ClientError, pithos.object_head, obj, version=-10)
+        r = pithos.object_head(obj, version=real_version)
+        self.assertEqual(r.headers['x-object-version'], real_version)
+        self.info('Version works')
+
+        r = pithos.object_head(obj, if_etag_match=etag)
+        self.assertEqual(r.status_code, 200)
+        self.info('if-etag-match is OK')
+
+        r = pithos.object_head(
+            obj, if_etag_not_match=etag, success=(200, 412, 304))
+        self.assertNotEqual(r.status_code, 200)
+        self.info('if-etag-not-match works')
+
+        r = pithos.object_head(
+            obj, version=real_version, if_etag_match=etag, success=200)
+        self.assertEqual(r.status_code, 200)
+        self.info('Version with if-etag-match works')
+
+        for format in pithos.DATE_FORMATS:
+            now_formated = self.now_unformated.strftime(format)
+            r1 = pithos.object_head(
+                obj, if_modified_since=now_formated, success=(200, 304, 412))
+            r2 = pithos.object_head(
+                obj, if_unmodified_since=now_formated, success=(200, 304, 412))
+            self.assertNotEqual(r1.status_code, r2.status_code)
+        self.info('if-(un)modified-since works')
+
+    def test_050_object_get(self):
+        """Test object GET"""
+        pithos = self.clients.pithos
+        obj = 'dir/sample.file'
+
+        r = pithos.object_get(obj)
+        self.assertEqual(r.status_code, 200)
+        self.info('Status code is OK')
+
+        osize = int(r.headers['content-length'])
+        etag = r.headers['etag']
+
+        r = pithos.object_get(obj, hashmap=True)
+        self.assertEqual(
+            set(('hashes', 'block_size', 'block_hash', 'bytes')), set(r.json))
+        self.info('Hashmap works')
+        hash0 = r.json['hashes'][0]
+
+        r = pithos.object_get(obj, format='xml', hashmap=True)
+        self.assertTrue(r.text.split('hash>')[1].startswith(hash0))
+        self.info('Hashmap with XML format works')
+
+        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
+        r = pithos.object_get(obj, data_range=rangestr, success=(200, 206))
+        partsize = int(r.headers['content-length'])
+        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
+        self.info('Range x-y works')
+        orig = r.text
+
+        rangestr = 'bytes=%s' % (osize / 3)
+        r = pithos.object_get(
+            obj, data_range=rangestr, if_range=True, success=(200, 206))
+        partsize = int(r.headers['content-length'])
+        self.assertTrue(partsize, 1 + (osize / 3))
+        diff = set(r.text).symmetric_difference(set(orig[:partsize]))
+        self.assertEqual(len(diff), 0)
+        self.info('Range x works')
+
+        rangestr = 'bytes=-%s' % (osize / 3)
+        r = pithos.object_get(
+            obj, data_range=rangestr, if_range=True, success=(200, 206))
+        partsize = int(r.headers['content-length'])
+        self.assertTrue(partsize, osize / 3)
+        diff = set(r.text).symmetric_difference(set(orig[-partsize:]))
+        self.assertEqual(len(diff), 0)
+        self.info('Range -x works')
+
+        r = pithos.object_get(obj, if_etag_match=etag)
+        self.assertEqual(r.status_code, 200)
+        self.info('if-etag-match works')
+
+        r = pithos.object_get(obj, if_etag_not_match=etag + 'LALALA')
+        self.assertEqual(r.status_code, 200)
+        self.info('if-etag-not-match works')
+
+        for format in pithos.DATE_FORMATS:
+            now_formated = self.now_unformated.strftime(format)
+            r1 = pithos.object_get(
+                obj, if_modified_since=now_formated, success=(200, 304, 412))
+            r2 = pithos.object_get(
+                obj, if_unmodified_since=now_formated, success=(200, 304, 412))
+            self.assertNotEqual(r1.status_code, r2.status_code)
+        self.info('if(un)modified-since works')
+
+        obj, dnl_f = 'dir/sample.file', NamedTemporaryFile()
+        self.info('Download %s as %s ...' % (obj, dnl_f.name))
+        pithos.download_object(obj, dnl_f)
+        self.info('Download is completed')
+
+        f_size = len(orig)
+        for pos in (0, f_size / 2, f_size - 128):
+            dnl_f.seek(pos)
+            self.large_file.seek(pos)
+            self.assertEqual(self.large_file.read(64), dnl_f.read(64))
+        self.info('Sampling shows that files match')
+
+        """Upload a boring file"""
+        self.info('Create a boring file of 42 blocks...')
+        bor_f = self._create_boring_file(42)
+        trg_fname = 'dir/uploaded.file'
+        self.info('Now, upload the boring file as %s...' % trg_fname)
+        pithos.upload_object(trg_fname, bor_f)
+        self.info('Boring file %s is uploaded as %s' % (bor_f.name, trg_fname))
+        dnl_f = NamedTemporaryFile()
+        self.info('Download boring file as %s' % dnl_f.name)
+        pithos.download_object(trg_fname, dnl_f)
+        self.info('File is downloaded')
+
+        for i in range(42):
+            self.assertEqual(sample_block(bor_f, i), sample_block(dnl_f, i))
+
+    def test_150_stop_test(self):
         """STOP TESTING ALREADY"""
         self.assertTrue(False)
 
-    def test_051_list_containers(self):
-        """Test container list actually returns containers"""
-        self.containers = self._get_list_of_containers()
-        self.assertGreater(len(self.containers), 0)
-        self.lala = 1
-
-    def test_052_unique_containers(self):
+    def test_152_unique_containers(self):
         """Test if containers have unique names"""
         names = [n['name'] for n in self.containers]
         names = sorted(names)
         self.assertEqual(sorted(list(set(names))), names)
 
-    def test_054_upload_file(self):
-        """Test uploading a txt file to Pithos"""
-        # Create a tmp file
-        with tempfile.TemporaryFile(dir=self.temp_directory) as fout:
-            fout.write("This is a temp file")
-            fout.seek(0, 0)
-            # Upload the file,
-            # The container is the one choosen during the `create_container'
-            self.clients.pithos.upload_object("test.txt", fout)
-            # Verify quotas
-            self._check_quotas(diskspace=+os.fstat(fout.fileno()).st_size)
-
-    def test_055_download_file(self):
-        """Test downloading the file from Pithos"""
-        # Create a tmp directory to save the file
-        with tempfile.TemporaryFile(dir=self.temp_directory) as fout:
-            self.clients.pithos.download_object("test.txt", fout)
-            # Now read the file
-            fout.seek(0, 0)
-            contents = fout.read()
-            # Compare results
-            self.info("Comparing contents with the uploaded file")
-            self.assertEqual(contents, "This is a temp file")
-
-    def test_056_remove(self):
-        """Test removing files and containers from Pithos"""
-        self.info("Removing the file %s from container %s",
-                  "test.txt", self.created_container)
-        # The container is the one choosen during the `create_container'
-        content_length = \
-            self.clients.pithos.get_object_info("test.txt")['content-length']
-        self.clients.pithos.del_object("test.txt")
-
-        # Verify quotas
-        self._check_quotas(diskspace=-int(content_length))
-
-        self.info("Removing the container %s", self.created_container)
-        self.clients.pithos.purge_container()
-
-        # List containers
-        containers = self._get_list_of_containers()
-        self.info("Check that the container %s has been deleted",
-                  self.created_container)
-        names = [n['name'] for n in containers]
-        self.assertNotIn(self.created_container, names)
-        # We successfully deleted our container, no need to do it
-        # in our clean up phase
-        self.created_container = None
-
     @classmethod
     def tearDownClass(cls):  # noqa
         """Clean up"""
