summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--glance_store/_drivers/swift/store.py22
-rw-r--r--glance_store/exceptions.py4
-rw-r--r--glance_store/tests/unit/test_swift_store.py38
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()