diff options
-rw-r--r-- | src/leap/soledad/client/_db/blobs.py | 20 | ||||
-rw-r--r-- | tests/blobs/test_blob_manager.py | 21 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/leap/soledad/client/_db/blobs.py b/src/leap/soledad/client/_db/blobs.py index 4b90f8f2..e23b1cf9 100644 --- a/src/leap/soledad/client/_db/blobs.py +++ b/src/leap/soledad/client/_db/blobs.py @@ -275,6 +275,15 @@ class BlobManager(object): return self.local.list(namespace, sync_status) @defer.inlineCallbacks + def refresh_sync_status_from_server(self): + d1 = self.remote_list() + d2 = self.local_list() + remote_list, local_list = yield defer.gatherResults([d1, d2]) + pending_download_ids = tuple(set(remote_list) - set(local_list)) + yield self.local.update_batch_sync_status( + pending_download_ids, sync_status=SyncStatus.PENDING_DOWNLOAD) + + @defer.inlineCallbacks def send_missing(self, namespace=''): """ Compare local and remote blobs and send what's missing in server. @@ -590,6 +599,17 @@ class SQLiteBlobBackend(object): values = (sync_status, blob_id,) return self.dbpool.runQuery(query, values) + def update_batch_sync_status(self, blob_id_list, sync_status, + namespace=''): + insert = 'INSERT INTO blobs (blob_id, namespace, payload, sync_status)' + first_blob_id, blob_id_list = blob_id_list[0], blob_id_list[1:] + insert += ' VALUES (?, ?, zeroblob(0), ?)' + values = (first_blob_id, namespace, sync_status) + for blob_id in blob_id_list: + insert += ', (?, ?, zeroblob(0), ?)' + values += (blob_id, namespace, sync_status) + return self.dbpool.runQuery(insert, values) + def increment_retries(self, blob_id): query = 'update blobs set retries = retries + 1 where blob_id = ?' return self.dbpool.runQuery(query, (blob_id,)) diff --git a/tests/blobs/test_blob_manager.py b/tests/blobs/test_blob_manager.py index 0fcfff72..1fe47864 100644 --- a/tests/blobs/test_blob_manager.py +++ b/tests/blobs/test_blob_manager.py @@ -193,3 +193,24 @@ class BlobManagerTestCase(unittest.TestCase): message = 'Unavailable blob showing up on listing!' for blob_id in unavailable_ids: self.assertNotIn(blob_id, local_list, 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)] + local_ids = [uuid4().hex for _ in range(10)] + self.manager.remote_list = Mock(return_value=defer.succeed(remote_ids)) + content, pending = self.cleartext, SyncStatus.PENDING_UPLOAD + length, deferreds = len(content.getvalue()), [] + for blob_id in local_ids: + d = local.put(blob_id, content, length, status=pending) + deferreds.append(d) + yield defer.gatherResults(deferreds) + yield self.manager.refresh_sync_status_from_server() + d = self.manager.local_list(sync_status=SyncStatus.PENDING_UPLOAD) + pending_upload_list = yield d + d = self.manager.local_list(sync_status=SyncStatus.PENDING_DOWNLOAD) + pending_download_list = yield d + self.assertEquals(set(pending_upload_list), set(local_ids)) + self.assertEquals(set(pending_download_list), set(remote_ids)) |