summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/soledad/client/_db/blobs.py12
-rw-r--r--tests/blobs/test_blob_manager.py19
2 files changed, 30 insertions, 1 deletions
diff --git a/src/leap/soledad/client/_db/blobs.py b/src/leap/soledad/client/_db/blobs.py
index e23b1cf9..75f196c7 100644
--- a/src/leap/soledad/client/_db/blobs.py
+++ b/src/leap/soledad/client/_db/blobs.py
@@ -552,6 +552,11 @@ class SQLiteBlobBackend(object):
@defer.inlineCallbacks
def put(self, blob_id, blob_fd, size=None,
namespace='', status=SyncStatus.PENDING_UPLOAD):
+ previous_state = yield self.get_sync_status(blob_id)
+ unavailable = SyncStatus.UNAVAILABLE_STATUSES
+ if previous_state and previous_state[0] in unavailable:
+ yield self.delete(blob_id, namespace)
+ status = SyncStatus.SYNCED
logger.info("Saving blob in local database...")
insert = 'INSERT INTO blobs (blob_id, namespace, payload, sync_status)'
insert += ' VALUES (?, ?, zeroblob(?), ?)'
@@ -565,7 +570,12 @@ class SQLiteBlobBackend(object):
# TODO we can also stream the blob value using sqlite
# incremental interface for blobs - and just return the raw fd instead
select = 'SELECT payload FROM blobs WHERE blob_id = ? AND namespace= ?'
- result = yield self.dbpool.runQuery(select, (blob_id, namespace,))
+ values = (blob_id, namespace,)
+ avoid_values = SyncStatus.UNAVAILABLE_STATUSES
+ select += ' AND sync_status NOT IN (%s)'
+ select %= ','.join(['?' for _ in avoid_values])
+ values += avoid_values
+ result = yield self.dbpool.runQuery(select, values)
if result:
defer.returnValue(BytesIO(str(result[0][0])))
diff --git a/tests/blobs/test_blob_manager.py b/tests/blobs/test_blob_manager.py
index 1fe47864..81379c73 100644
--- a/tests/blobs/test_blob_manager.py
+++ b/tests/blobs/test_blob_manager.py
@@ -196,6 +196,25 @@ class BlobManagerTestCase(unittest.TestCase):
@defer.inlineCallbacks
@pytest.mark.usefixtures("method_tmpdir")
+ def test_get_doesnt_include_unavailable_blobs(self):
+ local = self.manager.local
+ unavailable_ids, deferreds = [], []
+ for unavailable_status in SyncStatus.UNAVAILABLE_STATUSES:
+ current_blob_id = uuid4().hex
+ deferreds.append(local.put(current_blob_id, BytesIO(''), 0,
+ status=unavailable_status))
+ unavailable_ids.append(current_blob_id)
+ available_blob_id = uuid4().hex
+ content, length = self.cleartext, len(self.cleartext.getvalue())
+ deferreds.append(local.put(available_blob_id, content, length))
+ yield defer.gatherResults(deferreds)
+ message = 'Unavailable blob showing up on GET!'
+ for blob_id in unavailable_ids:
+ blob = yield local.get(blob_id)
+ self.assertFalse(blob, message)
+
+ @defer.inlineCallbacks
+ @pytest.mark.usefixtures("method_tmpdir")
def test_persist_sync_statuses_listing_from_server(self):
local = self.manager.local
remote_ids = [uuid4().hex for _ in range(10)]