diff options
-rw-r--r-- | glance_store/_drivers/swift/store.py | 22 | ||||
-rw-r--r-- | glance_store/exceptions.py | 4 | ||||
-rw-r--r-- | glance_store/tests/unit/test_swift_store.py | 38 |
3 files changed, 45 insertions, 19 deletions
diff --git a/glance_store/_drivers/swift/store.py b/glance_store/_drivers/swift/store.py index 2467f16..952e397 100644 --- a/glance_store/_drivers/swift/store.py +++ b/glance_store/_drivers/swift/store.py @@ -540,14 +540,14 @@ class BaseStore(driver.Store): chunk_name = "%s-%05d" % (location.obj, chunk_id) reader = ChunkReader(image_file, checksum, chunk_size) + if reader.is_zero_size is True: + LOG.debug('Not writing zero-length chunk.') + break try: chunk_etag = connection.put_object( location.container, chunk_name, reader, content_length=content_length) written_chunks.append(chunk_name) - except exceptions.ZeroSizeChunk: - LOG.debug('Not writing zero-length chunk') - break except Exception: # Delete orphaned segments from swift backend with excutils.save_and_reraise_exception(): @@ -943,15 +943,23 @@ class ChunkReader(object): self.checksum = checksum self.total = total self.bytes_read = 0 + self.is_zero_size = False + self.byteone = fd.read(1) + if len(self.byteone) == 0: + self.is_zero_size = True + + def do_read(self, i): + if self.bytes_read == 0 and i > 0 and self.byteone is not None: + return self.byteone + self.fd.read(i - 1) + else: + return self.fd.read(i) def read(self, i): left = self.total - self.bytes_read if i > left: i = left - result = self.fd.read(i) - if len(result) == 0 and self.bytes_read == 0: - # fd was empty - raise exceptions.ZeroSizeChunk() + + result = self.do_read(i) self.bytes_read += len(result) self.checksum.update(result) return result diff --git a/glance_store/exceptions.py b/glance_store/exceptions.py index d4d31bb..ef4a363 100644 --- a/glance_store/exceptions.py +++ b/glance_store/exceptions.py @@ -81,10 +81,6 @@ class NotFound(GlanceStoreException): message = _("Image %(image)s not found") -class ZeroSizeChunk(GlanceStoreException): - message = _("Zero size chunk") - - class UnknownScheme(GlanceStoreException): message = _("Unknown scheme '%(scheme)s' found in URI") diff --git a/glance_store/tests/unit/test_swift_store.py b/glance_store/tests/unit/test_swift_store.py index d938b47..3963e4d 100644 --- a/glance_store/tests/unit/test_swift_store.py +++ b/glance_store/tests/unit/test_swift_store.py @@ -734,11 +734,8 @@ class SwiftTests(object): self.assertEqual(expected_location, loc) self.assertEqual(expected_swift_size, size) self.assertEqual(expected_checksum, checksum) - # Expecting 7 calls to put_object -- 5 chunks, a zero chunk which is - # then deleted, and the manifest. Note the difference with above - # where the image_size is specified in advance (there's no zero chunk - # in that case). - self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 7) + # Expecting 6 calls to put_object -- 5 chunks, and the manifest. + self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 6) loc = location.get_location_from_uri(expected_location, conf=self.conf) (new_image_swift, new_image_size) = self.store.get(loc) @@ -1502,12 +1499,37 @@ class TestChunkReader(base.StoreBaseTest): bytes_read = 0 while True: cr = swift.ChunkReader(infile, checksum, CHUNKSIZE) - try: - chunk = cr.read(CHUNKSIZE) - except exceptions.ZeroSizeChunk: + chunk = cr.read(CHUNKSIZE) + if len(chunk) == 0: + self.assertEqual(True, cr.is_zero_size) break bytes_read += len(chunk) self.assertEqual(units.Ki, bytes_read) + self.assertEqual('fb10c6486390bec8414be90a93dfff3b', + cr.checksum.hexdigest()) + data_file.close() + infile.close() + + def test_read_zero_size_data(self): + """ + Replicate what goes on in the Swift driver with the + repeated creation of the ChunkReader object + """ + CHUNKSIZE = 100 + checksum = hashlib.md5() + data_file = tempfile.NamedTemporaryFile() + infile = open(data_file.name, 'rb') + bytes_read = 0 + while True: + cr = swift.ChunkReader(infile, checksum, CHUNKSIZE) + chunk = cr.read(CHUNKSIZE) + if len(chunk) == 0: + break + bytes_read += len(chunk) + self.assertEqual(True, cr.is_zero_size) + self.assertEqual(0, bytes_read) + self.assertEqual('d41d8cd98f00b204e9800998ecf8427e', + cr.checksum.hexdigest()) data_file.close() infile.close() |