summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/src/leap/soledad/client/sync.py2
-rw-r--r--client/src/leap/soledad/client/target.py34
-rw-r--r--common/src/leap/soledad/common/tests/test_crypto.py62
-rw-r--r--common/src/leap/soledad/common/tests/test_server.py25
-rw-r--r--common/src/leap/soledad/common/tests/test_soledad.py95
-rw-r--r--common/src/leap/soledad/common/tests/test_sqlcipher.py67
-rw-r--r--common/src/leap/soledad/common/tests/test_sync_deferred.py10
-rw-r--r--common/src/leap/soledad/common/tests/test_sync_target.py30
-rw-r--r--common/src/leap/soledad/common/tests/test_target.py19
-rw-r--r--common/src/leap/soledad/common/tests/u1db_tests/test_backends.py1
10 files changed, 180 insertions, 165 deletions
diff --git a/client/src/leap/soledad/client/sync.py b/client/src/leap/soledad/client/sync.py
index 5d545a77..c158f2a7 100644
--- a/client/src/leap/soledad/client/sync.py
+++ b/client/src/leap/soledad/client/sync.py
@@ -29,8 +29,6 @@ Extend u1db Synchronizer with the ability to:
"""
-import json
-
import logging
import traceback
from threading import Lock
diff --git a/client/src/leap/soledad/client/target.py b/client/src/leap/soledad/client/target.py
index 01e1231a..12175f48 100644
--- a/client/src/leap/soledad/client/target.py
+++ b/client/src/leap/soledad/client/target.py
@@ -28,12 +28,10 @@ import logging
import re
import urllib
import threading
-import urlparse
from collections import defaultdict
from time import sleep
from uuid import uuid4
-from contextlib import contextmanager
import simplejson as json
from taskthread import TimerTask
@@ -44,7 +42,6 @@ from u1db.remote.http_client import _encode_query_parameter, HTTPClientBase
from zope.proxy import ProxyBase
from zope.proxy import sameProxiedObjects, setProxiedObject
-from leap.soledad.common import soledad_assert
from leap.soledad.common.document import SoledadDocument
from leap.soledad.client.auth import TokenBasedAuth
from leap.soledad.client.crypto import is_symmetrically_encrypted
@@ -87,7 +84,7 @@ class DocumentSyncerThread(threading.Thread):
"""
def __init__(self, doc_syncer, release_method, failed_method,
- idx, total, last_request_lock=None, last_callback_lock=None):
+ idx, total, last_request_lock=None, last_callback_lock=None):
"""
Initialize a new syncer thread.
@@ -246,7 +243,7 @@ class DocumentSyncerPool(object):
"""
def __init__(self, raw_url, raw_creds, query_string, headers,
- ensure_callback, stop_method):
+ ensure_callback, stop_method):
"""
Initialize the document syncer pool.
@@ -279,7 +276,7 @@ class DocumentSyncerPool(object):
self._threads = []
def new_syncer_thread(self, idx, total, last_request_lock=None,
- last_callback_lock=None):
+ last_callback_lock=None):
"""
Yield a new document syncer thread.
@@ -619,7 +616,7 @@ class HTTPDocumentSyncer(HTTPClientBase, TokenBasedAuth):
self._conn.endheaders()
def _get_doc(self, received, sync_id, last_known_generation,
- last_known_trans_id):
+ last_known_trans_id):
"""
Get a sync document from server by means of a POST request.
@@ -658,7 +655,7 @@ class HTTPDocumentSyncer(HTTPClientBase, TokenBasedAuth):
return self._response()
def _put_doc(self, sync_id, last_known_generation, last_known_trans_id,
- id, rev, content, gen, trans_id, number_of_docs, doc_idx):
+ id, rev, content, gen, trans_id, number_of_docs, doc_idx):
"""
Put a sync document on server by means of a POST request.
@@ -765,7 +762,7 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
#
def __init__(self, url, source_replica_uid=None, creds=None, crypto=None,
- sync_db=None, sync_db_write_lock=None):
+ sync_db=None, sync_db_write_lock=None):
"""
Initialize the SoledadSyncTarget.
@@ -925,7 +922,7 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
"""
new_generation, new_transaction_id, number_of_changes, doc_id, \
rev, content, gen, trans_id = \
- self._parse_received_doc_response(response)
+ self._parse_received_doc_response(response)
if doc_id is not None:
# decrypt incoming document and insert into local database
# -------------------------------------------------------------
@@ -1134,11 +1131,14 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
"""
self._ensure_callback = ensure_callback
- if defer_decryption:
+ if defer_decryption and self._sync_db is not None:
self._sync_exchange_lock.acquire()
self._setup_sync_decr_pool(last_known_generation)
self._setup_sync_watcher()
self._defer_decryption = True
+ else:
+ # fall back
+ defer_decryption = False
self.start()
@@ -1149,7 +1149,7 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
setProxiedObject(self._insert_doc_cb[source_replica_uid],
return_doc_cb)
- if not self.clear_to_sync():
+ if defer_decryption is True and not self.clear_to_sync():
raise PendingReceivedDocsSyncError
self._ensure_connection()
@@ -1171,7 +1171,6 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
self._raw_url, self._raw_creds, url, headers, ensure_callback,
self.stop)
threads = []
- last_request_lock = None
last_callback_lock = None
sent = 0
total = len(docs_by_generations)
@@ -1227,7 +1226,8 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
t.doc_syncer.set_request_method(
'put', sync_id, cur_target_gen, cur_target_trans_id,
id=doc.doc_id, rev=doc.rev, content=doc_json, gen=gen,
- trans_id=trans_id, number_of_docs=number_of_docs, doc_idx=sent + 1)
+ trans_id=trans_id, number_of_docs=number_of_docs,
+ doc_idx=sent + 1)
# set the success calback
def _success_callback(idx, total, response):
@@ -1251,7 +1251,6 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
# save thread and append
t.start()
threads.append((t, doc))
- last_request_lock = t.request_lock
last_callback_lock = t.callback_lock
sent += 1
@@ -1275,7 +1274,7 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
if last_successful_thread is not None:
response_dict = json.loads(last_successful_thread.response[0])[0]
gen_after_send = response_dict['new_generation']
- trans_id_after_send = response_dict['new_transaction_id']
+ trans_id_after_send = response_dict['new_transaction_id']
# get docs from target
if self.stopped is False:
@@ -1356,7 +1355,6 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
# no doc found
return None
-
def delete_encrypted_docs_from_db(self, docs_ids):
"""
Delete several encrypted documents from the database of symmetrically
@@ -1467,7 +1465,7 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):
decrypter = self._sync_decr_pool
decrypter.decrypt_received_docs()
- done = decrypter.process_decrypted()
+ decrypter.process_decrypted()
def _sign_request(self, method, url_query, params):
"""
diff --git a/common/src/leap/soledad/common/tests/test_crypto.py b/common/src/leap/soledad/common/tests/test_crypto.py
index 1071af14..ccff5e46 100644
--- a/common/src/leap/soledad/common/tests/test_crypto.py
+++ b/common/src/leap/soledad/common/tests/test_crypto.py
@@ -57,23 +57,23 @@ class EncryptedSyncTestCase(BaseSoledadTest):
class RecoveryDocumentTestCase(BaseSoledadTest):
def test_export_recovery_document_raw(self):
- rd = self._soledad.export_recovery_document()
- secret_id = rd[self._soledad.STORAGE_SECRETS_KEY].items()[0][0]
- secret = rd[self._soledad.STORAGE_SECRETS_KEY][secret_id]
- self.assertEqual(secret_id, self._soledad._secret_id)
- self.assertEqual(secret, self._soledad._secrets[secret_id])
- self.assertTrue(self._soledad.CIPHER_KEY in secret)
- self.assertTrue(secret[self._soledad.CIPHER_KEY] == 'aes256')
- self.assertTrue(self._soledad.LENGTH_KEY in secret)
- self.assertTrue(self._soledad.SECRET_KEY in secret)
+ rd = self._soledad.secrets._export_recovery_document()
+ secret_id = rd[self._soledad.secrets.STORAGE_SECRETS_KEY].items()[0][0]
+ secret = rd[self._soledad.secrets.STORAGE_SECRETS_KEY][secret_id]
+ self.assertEqual(secret_id, self._soledad.secrets._secret_id)
+ self.assertEqual(secret, self._soledad.secrets._secrets[secret_id])
+ self.assertTrue(self._soledad.secrets.CIPHER_KEY in secret)
+ self.assertTrue(secret[self._soledad.secrets.CIPHER_KEY] == 'aes256')
+ self.assertTrue(self._soledad.secrets.LENGTH_KEY in secret)
+ self.assertTrue(self._soledad.secrets.SECRET_KEY in secret)
def test_import_recovery_document(self):
- rd = self._soledad.export_recovery_document()
+ rd = self._soledad.secrets._export_recovery_document()
s = self._soledad_instance()
- s.import_recovery_document(rd)
- s._set_secret_id(self._soledad._secret_id)
- self.assertEqual(self._soledad._get_storage_secret(),
- s._get_storage_secret(),
+ s.secrets._import_recovery_document(rd)
+ s.set_secret_id(self._soledad.secrets._secret_id)
+ self.assertEqual(self._soledad.storage_secret,
+ s.storage_secret,
'Failed settinng secret for symmetric encryption.')
s.close()
@@ -83,13 +83,13 @@ class SoledadSecretsTestCase(BaseSoledadTest):
def test__gen_secret(self):
# instantiate and save secret_id
sol = self._soledad_instance(user='user@leap.se')
- self.assertTrue(len(sol._secrets) == 1)
+ self.assertTrue(len(sol.secrets._secrets) == 1)
secret_id_1 = sol.secret_id
# assert id is hash of secret
self.assertTrue(
secret_id_1 == hashlib.sha256(sol.storage_secret).hexdigest())
# generate new secret
- secret_id_2 = sol._gen_secret()
+ secret_id_2 = sol.secrets._gen_secret()
self.assertTrue(secret_id_1 != secret_id_2)
sol.close()
# re-instantiate
@@ -97,18 +97,20 @@ class SoledadSecretsTestCase(BaseSoledadTest):
user='user@leap.se',
secret_id=secret_id_1)
# assert ids are valid
- self.assertTrue(len(sol._secrets) == 2)
- self.assertTrue(secret_id_1 in sol._secrets)
- self.assertTrue(secret_id_2 in sol._secrets)
+ self.assertTrue(len(sol.secrets._secrets) == 2)
+ self.assertTrue(secret_id_1 in sol.secrets._secrets)
+ self.assertTrue(secret_id_2 in sol.secrets._secrets)
# assert format of secret 1
self.assertTrue(sol.storage_secret is not None)
self.assertIsInstance(sol.storage_secret, str)
- self.assertTrue(len(sol.storage_secret) == sol.GENERATED_SECRET_LENGTH)
+ secret_length = sol.secrets.LOCAL_STORAGE_SECRET_LENGTH \
+ + sol.secrets.REMOTE_STORAGE_SECRET_LENGTH
+ self.assertTrue(len(sol.storage_secret) == secret_length)
# assert format of secret 2
- sol._set_secret_id(secret_id_2)
+ sol.set_secret_id(secret_id_2)
self.assertTrue(sol.storage_secret is not None)
self.assertIsInstance(sol.storage_secret, str)
- self.assertTrue(len(sol.storage_secret) == sol.GENERATED_SECRET_LENGTH)
+ self.assertTrue(len(sol.storage_secret) == secret_length)
# assert id is hash of new secret
self.assertTrue(
secret_id_2 == hashlib.sha256(sol.storage_secret).hexdigest())
@@ -117,16 +119,18 @@ class SoledadSecretsTestCase(BaseSoledadTest):
def test__has_secret(self):
sol = self._soledad_instance(
user='user@leap.se', prefix=self.rand_prefix)
- self.assertTrue(sol._has_secret(), "Should have a secret at "
- "this point")
+ self.assertTrue(
+ sol.secrets._has_secret(),
+ "Should have a secret at this point")
# setting secret id to None should not interfere in the fact we have a
# secret.
- sol._set_secret_id(None)
- self.assertTrue(sol._has_secret(), "Should have a secret at "
- "this point")
+ sol.set_secret_id(None)
+ self.assertTrue(
+ sol.secrets._has_secret(),
+ "Should have a secret at this point")
# but not being able to decrypt correctly should
- sol._secrets[sol.secret_id][sol.SECRET_KEY] = None
- self.assertFalse(sol._has_secret())
+ sol.secrets._secrets[sol.secret_id][sol.secrets.SECRET_KEY] = None
+ self.assertFalse(sol.secrets._has_secret())
sol.close()
diff --git a/common/src/leap/soledad/common/tests/test_server.py b/common/src/leap/soledad/common/tests/test_server.py
index cb5348b4..acd0a54c 100644
--- a/common/src/leap/soledad/common/tests/test_server.py
+++ b/common/src/leap/soledad/common/tests/test_server.py
@@ -302,6 +302,7 @@ class EncryptedSyncTestCase(
put_doc = mock.Mock(side_effect=_put_doc_side_effect)
lock = mock.Mock(return_value=('atoken', 300))
unlock = mock.Mock()
+ close = mock.Mock()
def __call__(self):
return self
@@ -373,9 +374,9 @@ class EncryptedSyncTestCase(
sol2 = self._soledad_instance(prefix='x', auth_token='auth-token')
_, doclist = sol2.get_all_docs()
self.assertEqual([], doclist)
- sol2._secrets_path = sol1.secrets_path
- sol2._load_secrets()
- sol2._set_secret_id(sol1._secret_id)
+ sol2.secrets_path = sol1.secrets_path
+ sol2.secrets._load_secrets()
+ sol2.set_secret_id(sol1.secret_id)
# sync the new instance
sol2._server_url = self.getURL()
sol2.sync()
@@ -435,9 +436,9 @@ class EncryptedSyncTestCase(
)
_, doclist = sol2.get_all_docs()
self.assertEqual([], doclist)
- sol2._secrets_path = sol1.secrets_path
- sol2._load_secrets()
- sol2._set_secret_id(sol1._secret_id)
+ sol2.secrets_path = sol1.secrets_path
+ sol2.secrets._load_secrets()
+ sol2.set_secret_id(sol1.secret_id)
# sync the new instance
sol2._server_url = self.getURL()
sol2.sync()
@@ -479,9 +480,9 @@ class EncryptedSyncTestCase(
sol2 = self._soledad_instance(prefix='x', auth_token='auth-token')
_, doclist = sol2.get_all_docs()
self.assertEqual([], doclist)
- sol2._secrets_path = sol1.secrets_path
- sol2._load_secrets()
- sol2._set_secret_id(sol1._secret_id)
+ sol2.secrets_path = sol1.secrets_path
+ sol2.secrets._load_secrets()
+ sol2.set_secret_id(sol1.secret_id)
# sync the new instance
sol2._server_url = self.getURL()
sol2.sync()
@@ -524,9 +525,9 @@ class EncryptedSyncTestCase(
sol2 = self._soledad_instance(prefix='x', auth_token='auth-token')
_, doclist = sol2.get_all_docs()
self.assertEqual([], doclist)
- sol2._secrets_path = sol1.secrets_path
- sol2._load_secrets()
- sol2._set_secret_id(sol1._secret_id)
+ sol2.secrets_path = sol1.secrets_path
+ sol2.secrets._load_secrets()
+ sol2.set_secret_id(sol1.secret_id)
# sync the new instance
sol2._server_url = self.getURL()
sol2.sync()
diff --git a/common/src/leap/soledad/common/tests/test_soledad.py b/common/src/leap/soledad/common/tests/test_soledad.py
index 11e43423..12bfbc3e 100644
--- a/common/src/leap/soledad/common/tests/test_soledad.py
+++ b/common/src/leap/soledad/common/tests/test_soledad.py
@@ -29,8 +29,9 @@ from leap.soledad.common.tests import (
from leap import soledad
from leap.soledad.common.document import SoledadDocument
from leap.soledad.common.crypto import WrongMac
-from leap.soledad.client import Soledad, PassphraseTooShort
-from leap.soledad.client.crypto import SoledadCrypto
+from leap.soledad.client import Soledad
+from leap.soledad.client.sqlcipher import SQLCipherDatabase
+from leap.soledad.client.secrets import PassphraseTooShort
from leap.soledad.client.shared_db import SoledadSharedDatabase
from leap.soledad.client.target import SoledadSyncTarget
@@ -39,7 +40,6 @@ class AuxMethodsTestCase(BaseSoledadTest):
def test__init_dirs(self):
sol = self._soledad_instance(prefix='_init_dirs')
- sol._init_dirs()
local_db_dir = os.path.dirname(sol.local_db_path)
secrets_path = os.path.dirname(sol.secrets_path)
self.assertTrue(os.path.isdir(local_db_dir))
@@ -47,16 +47,9 @@ class AuxMethodsTestCase(BaseSoledadTest):
sol.close()
def test__init_db(self):
- sol = self._soledad_instance()
- sol._init_dirs()
- sol._crypto = SoledadCrypto(sol)
- #self._soledad._gpg.import_keys(PUBLIC_KEY)
- if not sol._has_secret():
- sol._gen_secret()
- sol._load_secrets()
- sol._init_db()
- from leap.soledad.client.sqlcipher import SQLCipherDatabase
+ sol = self._soledad_instance(prefix='_init_db')
self.assertIsInstance(sol._db, SQLCipherDatabase)
+ self.assertTrue(os.path.isfile(sol.local_db_path))
sol.close()
def test__init_config_defaults(self):
@@ -71,16 +64,21 @@ class AuxMethodsTestCase(BaseSoledadTest):
# instantiate without initializing so we just test _init_config()
sol = SoledadMock()
- Soledad._init_config(sol, None, None, '')
+ sol._passphrase = u''
+ sol._secrets_path = None
+ sol._local_db_path = None
+ sol._server_url = ''
+ sol._init_config()
# assert value of secrets_path
self.assertEquals(
os.path.join(
sol.DEFAULT_PREFIX, Soledad.STORAGE_SECRETS_FILE_NAME),
- sol.secrets_path)
+ sol._secrets_path)
# assert value of local_db_path
self.assertEquals(
os.path.join(sol.DEFAULT_PREFIX, 'soledad.u1db'),
sol.local_db_path)
+ sol.close()
def test__init_config_from_params(self):
"""
@@ -174,8 +172,8 @@ class SoledadSharedDBTestCase(BaseSoledadTest):
"""
Ensure the shared db is queried with the correct doc_id.
"""
- doc_id = self._soledad._shared_db_doc_id()
- self._soledad._get_secrets_from_shared_db()
+ doc_id = self._soledad.secrets._shared_db_doc_id()
+ self._soledad.secrets._get_secrets_from_shared_db()
self.assertTrue(
self._soledad._shared_db().get_doc.assert_called_with(
doc_id) is None,
@@ -185,8 +183,8 @@ class SoledadSharedDBTestCase(BaseSoledadTest):
"""
Ensure recovery document is put into shared recover db.
"""
- doc_id = self._soledad._shared_db_doc_id()
- self._soledad._put_secrets_in_shared_db()
+ doc_id = self._soledad.secrets._shared_db_doc_id()
+ self._soledad.secrets._put_secrets_in_shared_db()
self.assertTrue(
self._soledad._shared_db().get_doc.assert_called_with(
doc_id) is None,
@@ -210,6 +208,7 @@ class SoledadSignalingTestCase(BaseSoledadTest):
def setUp(self):
# mock signaling
soledad.client.signal = Mock()
+ soledad.client.secrets.signal = Mock()
# run parent's setUp
BaseSoledadTest.setUp(self)
@@ -231,57 +230,57 @@ class SoledadSignalingTestCase(BaseSoledadTest):
- downloading keys / done downloading keys.
- uploading keys / done uploading keys.
"""
- soledad.client.signal.reset_mock()
+ soledad.client.secrets.signal.reset_mock()
# get a fresh instance so it emits all bootstrap signals
sol = self._soledad_instance(
secrets_path='alternative_stage3.json',
local_db_path='alternative_stage3.u1db')
# reverse call order so we can verify in the order the signals were
# expected
- soledad.client.signal.mock_calls.reverse()
- soledad.client.signal.call_args = \
- soledad.client.signal.call_args_list[0]
- soledad.client.signal.call_args_list.reverse()
+ soledad.client.secrets.signal.mock_calls.reverse()
+ soledad.client.secrets.signal.call_args = \
+ soledad.client.secrets.signal.call_args_list[0]
+ soledad.client.secrets.signal.call_args_list.reverse()
# downloading keys signals
- soledad.client.signal.assert_called_with(
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DOWNLOADING_KEYS,
ADDRESS,
)
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DONE_DOWNLOADING_KEYS,
ADDRESS,
)
# creating keys signals
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_CREATING_KEYS,
ADDRESS,
)
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DONE_CREATING_KEYS,
ADDRESS,
)
# downloading once more (inside _put_keys_in_shared_db)
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DOWNLOADING_KEYS,
ADDRESS,
)
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DONE_DOWNLOADING_KEYS,
ADDRESS,
)
# uploading keys signals
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_UPLOADING_KEYS,
ADDRESS,
)
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DONE_UPLOADING_KEYS,
ADDRESS,
)
@@ -298,8 +297,8 @@ class SoledadSignalingTestCase(BaseSoledadTest):
# get existing instance so we have access to keys
sol = self._soledad_instance()
# create a document with secrets
- doc = SoledadDocument(doc_id=sol._shared_db_doc_id())
- doc.content = sol.export_recovery_document()
+ doc = SoledadDocument(doc_id=sol.secrets._shared_db_doc_id())
+ doc.content = sol.secrets._export_recovery_document()
class Stage2MockSharedDB(object):
@@ -313,7 +312,7 @@ class SoledadSignalingTestCase(BaseSoledadTest):
sol.close()
# reset mock
- soledad.client.signal.reset_mock()
+ soledad.client.secrets.signal.reset_mock()
# get a fresh instance so it emits all bootstrap signals
sol = self._soledad_instance(
secrets_path='alternative_stage2.json',
@@ -321,17 +320,17 @@ class SoledadSignalingTestCase(BaseSoledadTest):
shared_db_class=Stage2MockSharedDB)
# reverse call order so we can verify in the order the signals were
# expected
- soledad.client.signal.mock_calls.reverse()
- soledad.client.signal.call_args = \
- soledad.client.signal.call_args_list[0]
- soledad.client.signal.call_args_list.reverse()
+ soledad.client.secrets.signal.mock_calls.reverse()
+ soledad.client.secrets.signal.call_args = \
+ soledad.client.secrets.signal.call_args_list[0]
+ soledad.client.secrets.signal.call_args_list.reverse()
# assert download keys signals
- soledad.client.signal.assert_called_with(
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DOWNLOADING_KEYS,
ADDRESS,
)
- self._pop_mock_call(soledad.client.signal)
- soledad.client.signal.assert_called_with(
+ self._pop_mock_call(soledad.client.secrets.signal)
+ soledad.client.secrets.signal.assert_called_with(
proto.SOLEDAD_DONE_DOWNLOADING_KEYS,
ADDRESS,
)
diff --git a/common/src/leap/soledad/common/tests/test_sqlcipher.py b/common/src/leap/soledad/common/tests/test_sqlcipher.py
index 595966ec..273ac06e 100644
--- a/common/src/leap/soledad/common/tests/test_sqlcipher.py
+++ b/common/src/leap/soledad/common/tests/test_sqlcipher.py
@@ -24,8 +24,6 @@ import threading
from pysqlcipher import dbapi2
-from StringIO import StringIO
-from urlparse import urljoin
# u1db stuff.
@@ -79,6 +77,7 @@ class TestSQLCipherBackendImpl(tests.TestCase):
self.assertEqual(34, len(doc_id1))
int(doc_id1[len('D-'):], 16)
self.assertNotEqual(doc_id1, db._allocate_doc_id())
+ db.close()
#-----------------------------------------------------------------------------
@@ -123,9 +122,6 @@ class SQLCipherIndexTests(test_backends.DatabaseIndexTests):
scenarios = SQLCIPHER_SCENARIOS
-load_tests = tests.load_with_scenarios
-
-
#-----------------------------------------------------------------------------
# The following tests come from `u1db.tests.test_sqlite_backend`.
#-----------------------------------------------------------------------------
@@ -174,6 +170,8 @@ class TestSQLCipherDatabase(test_sqlite_backend.TestSQLiteDatabase):
self.assertIsInstance(outcome2[0], SQLCipherDatabaseTesting)
db2 = outcome2[0]
self.assertTrue(db2._is_initialized(db1._get_sqlite_handle().cursor()))
+ db1.close()
+ db2.close()
class TestAlternativeDocument(SoledadDocument):
@@ -190,22 +188,22 @@ class TestSQLCipherPartialExpandDatabase(
def setUp(self):
test_sqlite_backend.TestSQLitePartialExpandDatabase.setUp(self)
self.db = SQLCipherDatabase(':memory:', PASSWORD)
- self.db._set_replica_uid('test')
+
+ def tearDown(self):
+ self.db.close()
+ test_sqlite_backend.TestSQLitePartialExpandDatabase.tearDown(self)
def test_default_replica_uid(self):
- self.db = SQLCipherDatabase(':memory:', PASSWORD)
self.assertIsNot(None, self.db._replica_uid)
self.assertEqual(32, len(self.db._replica_uid))
int(self.db._replica_uid, 16)
def test__parse_index(self):
- self.db = SQLCipherDatabase(':memory:', PASSWORD)
g = self.db._parse_index_definition('fieldname')
self.assertIsInstance(g, query_parser.ExtractField)
self.assertEqual(['fieldname'], g.field)
def test__update_indexes(self):
- self.db = SQLCipherDatabase(':memory:', PASSWORD)
g = self.db._parse_index_definition('fieldname')
c = self.db._get_sqlite_handle().cursor()
self.db._update_indexes('doc-id', {'fieldname': 'val'},
@@ -216,7 +214,6 @@ class TestSQLCipherPartialExpandDatabase(
def test__set_replica_uid(self):
# Start from scratch, so that replica_uid isn't set.
- self.db = SQLCipherDatabase(':memory:', PASSWORD)
self.assertIsNot(None, self.db._real_replica_uid)
self.assertIsNot(None, self.db._replica_uid)
self.db._set_replica_uid('foo')
@@ -231,19 +228,23 @@ class TestSQLCipherPartialExpandDatabase(
def test__open_database(self):
temp_dir = self.createTempDir(prefix='u1db-test-')
path = temp_dir + '/test.sqlite'
- SQLCipherDatabase(path, PASSWORD)
+ db1 = SQLCipherDatabase(path, PASSWORD)
db2 = SQLCipherDatabase._open_database(path, PASSWORD)
self.assertIsInstance(db2, SQLCipherDatabase)
+ db1.close()
+ db2.close()
def test__open_database_with_factory(self):
temp_dir = self.createTempDir(prefix='u1db-test-')
path = temp_dir + '/test.sqlite'
- SQLCipherDatabase(path, PASSWORD)
+ db1 = SQLCipherDatabase(path, PASSWORD)
db2 = SQLCipherDatabase._open_database(
path, PASSWORD,
document_factory=TestAlternativeDocument)
doc = db2.create_doc({})
self.assertTrue(isinstance(doc, SoledadDocument))
+ db1.close()
+ db2.close()
def test__open_database_non_existent(self):
temp_dir = self.createTempDir(prefix='u1db-test-')
@@ -258,7 +259,9 @@ class TestSQLCipherPartialExpandDatabase(
db = SQLCipherDatabase.__new__(
SQLCipherDatabase)
db._db_handle = dbapi2.connect(path) # db is there but not yet init-ed
+ db._sync_db = None
db._syncers = {}
+ db.sync_queue = None
c = db._db_handle.cursor()
c.execute('PRAGMA key="%s"' % PASSWORD)
self.addCleanup(db.close)
@@ -281,6 +284,8 @@ class TestSQLCipherPartialExpandDatabase(
[None,
SQLCipherDatabase._index_storage_value],
observed)
+ db.close()
+ db2.close()
def test__open_database_invalid(self):
class SQLiteDatabaseTesting(SQLCipherDatabase):
@@ -301,26 +306,32 @@ class TestSQLCipherPartialExpandDatabase(
def test_open_database_existing(self):
temp_dir = self.createTempDir(prefix='u1db-test-')
path = temp_dir + '/existing.sqlite'
- SQLCipherDatabase(path, PASSWORD)
+ db1 = SQLCipherDatabase(path, PASSWORD)
db2 = SQLCipherDatabase.open_database(path, PASSWORD, create=False)
self.assertIsInstance(db2, SQLCipherDatabase)
+ db1.close()
+ db2.close()
def test_open_database_with_factory(self):
temp_dir = self.createTempDir(prefix='u1db-test-')
path = temp_dir + '/existing.sqlite'
- SQLCipherDatabase(path, PASSWORD)
+ db1 = SQLCipherDatabase(path, PASSWORD)
db2 = SQLCipherDatabase.open_database(
path, PASSWORD, create=False,
document_factory=TestAlternativeDocument)
doc = db2.create_doc({})
self.assertTrue(isinstance(doc, SoledadDocument))
+ db1.close()
+ db2.close()
def test_open_database_create(self):
temp_dir = self.createTempDir(prefix='u1db-test-')
path = temp_dir + '/new.sqlite'
- SQLCipherDatabase.open_database(path, PASSWORD, create=True)
+ db1 = SQLCipherDatabase.open_database(path, PASSWORD, create=True)
db2 = SQLCipherDatabase.open_database(path, PASSWORD, create=False)
self.assertIsInstance(db2, SQLCipherDatabase)
+ db1.close()
+ db2.close()
def test_create_database_initializes_schema(self):
# This test had to be cloned because our implementation of SQLCipher
@@ -331,7 +342,8 @@ class TestSQLCipherPartialExpandDatabase(
c = raw_db.cursor()
c.execute("SELECT * FROM u1db_config")
config = dict([(r[0], r[1]) for r in c.fetchall()])
- self.assertEqual({'sql_schema': '0', 'replica_uid': 'test',
+ replica_uid = self.db._replica_uid
+ self.assertEqual({'sql_schema': '0', 'replica_uid': replica_uid,
'index_storage': 'expand referenced encrypted'},
config)
@@ -444,6 +456,22 @@ class SQLCipherDatabaseSyncTests(
def tearDown(self):
test_sync.DatabaseSyncTests.tearDown(self)
+ if hasattr(self, 'db1') and isinstance(self.db1, SQLCipherDatabase):
+ self.db1.close()
+ if hasattr(self, 'db1_copy') \
+ and isinstance(self.db1_copy, SQLCipherDatabase):
+ self.db1_copy.close()
+ if hasattr(self, 'db2') \
+ and isinstance(self.db2, SQLCipherDatabase):
+ self.db2.close()
+ if hasattr(self, 'db2_copy') \
+ and isinstance(self.db2_copy, SQLCipherDatabase):
+ self.db2_copy.close()
+ if hasattr(self, 'db3') \
+ and isinstance(self.db3, SQLCipherDatabase):
+ self.db3.close()
+
+
def test_sync_autoresolves(self):
"""
@@ -612,6 +640,9 @@ class SQLCipherDatabaseSyncTests(
doc3.doc_id, doc3.rev, key, secret))
self.assertEqual(doc4.get_json(), doc3.get_json())
self.assertFalse(doc3.has_conflicts)
+ self.db1.close()
+ self.db2.close()
+ db3.close()
def test_sync_puts_changes(self):
"""
@@ -778,6 +809,7 @@ class SQLCipherEncryptionTest(BaseLeapTest):
doc = db.get_doc(doc.doc_id)
self.assertEqual(tests.simple_doc, doc.get_json(),
'decrypted content mismatch')
+ db.close()
def test_try_to_open_raw_db_with_sqlcipher_backend(self):
"""
@@ -790,7 +822,8 @@ class SQLCipherEncryptionTest(BaseLeapTest):
try:
# trying to open the a non-encrypted database with sqlcipher
# backend should raise a DatabaseIsNotEncrypted exception.
- SQLCipherDatabase(self.DB_FILE, PASSWORD)
+ db = SQLCipherDatabase(self.DB_FILE, PASSWORD)
+ db.close()
raise dbapi2.DatabaseError(
"SQLCipher backend should not be able to open non-encrypted "
"dbs.")
diff --git a/common/src/leap/soledad/common/tests/test_sync_deferred.py b/common/src/leap/soledad/common/tests/test_sync_deferred.py
index 48e3150f..7643b27c 100644
--- a/common/src/leap/soledad/common/tests/test_sync_deferred.py
+++ b/common/src/leap/soledad/common/tests/test_sync_deferred.py
@@ -37,9 +37,6 @@ DEFER_DECRYPTION = True
WAIT_STEP = 1
MAX_WAIT = 10
-from leap.soledad.common.tests import test_sqlcipher as ts
-from leap.soledad.server import SoledadApp
-
from leap.soledad.client.sqlcipher import open as open_sqlcipher
from leap.soledad.common.tests.util import SoledadWithCouchServerMixin
@@ -89,11 +86,8 @@ class BaseSoledadDeferredEncTest(SoledadWithCouchServerMixin):
self._soledad.close()
# XXX should not access "private" attrs
- for f in [self._soledad._local_db_path,
- self._soledad._secrets_path,
- self.db1._sync_db_path]:
- if os.path.isfile(f):
- os.unlink(f)
+ import shutil
+ shutil.rmtree(os.path.dirname(self._soledad._local_db_path))
#SQLCIPHER_SCENARIOS = [
diff --git a/common/src/leap/soledad/common/tests/test_sync_target.py b/common/src/leap/soledad/common/tests/test_sync_target.py
index edc4589b..45009f4e 100644
--- a/common/src/leap/soledad/common/tests/test_sync_target.py
+++ b/common/src/leap/soledad/common/tests/test_sync_target.py
@@ -23,29 +23,15 @@ import os
import simplejson as json
import u1db
-from uuid import uuid4
-
from u1db.remote import http_database
-from u1db import SyncTarget
-from u1db.sync import Synchronizer
-from u1db.remote import (
- http_client,
- http_database,
- http_target,
-)
-
-from leap.soledad import client
from leap.soledad.client import (
target,
auth,
crypto,
- VerifiedHTTPSConnection,
sync,
)
from leap.soledad.common.document import SoledadDocument
-from leap.soledad.server.auth import SoledadTokenAuthMiddleware
-
from leap.soledad.common.tests import u1db_tests as tests
from leap.soledad.common.tests import BaseSoledadTest
@@ -58,13 +44,6 @@ from leap.soledad.common.tests.util import (
from leap.soledad.common.tests.u1db_tests import test_backends
from leap.soledad.common.tests.u1db_tests import test_remote_sync_target
from leap.soledad.common.tests.u1db_tests import test_sync
-from leap.soledad.common.tests.test_couch import (
- CouchDBTestCase,
- CouchDBWrapper,
-)
-
-from leap.soledad.server import SoledadApp
-from leap.soledad.server.auth import SoledadTokenAuthMiddleware
#-----------------------------------------------------------------------------
@@ -279,8 +258,9 @@ class TestSoledadSyncTarget(
def tearDown(self):
SoledadWithCouchServerMixin.tearDown(self)
tests.TestCaseWithServer.tearDown(self)
- db, _ = self.request_state.ensure_database('test2')
- db.delete_database()
+ db2, _ = self.request_state.ensure_database('test2')
+ db2.delete_database()
+ self.db1.close()
def test_sync_exchange_send(self):
"""
@@ -540,6 +520,10 @@ class TestSoledadDbSync(
self.main_test_class = test_sync.TestDbSync
SoledadWithCouchServerMixin.setUp(self)
+ def tearDown(self):
+ SoledadWithCouchServerMixin.tearDown(self)
+ self.db.close()
+
def do_sync(self, target_name):
"""
Perform sync using SoledadSynchronizer, SoledadSyncTarget
diff --git a/common/src/leap/soledad/common/tests/test_target.py b/common/src/leap/soledad/common/tests/test_target.py
index 6242099d..eb5e2874 100644
--- a/common/src/leap/soledad/common/tests/test_target.py
+++ b/common/src/leap/soledad/common/tests/test_target.py
@@ -22,17 +22,14 @@ Test Leap backend bits.
import u1db
import os
-import ssl
import simplejson as json
import cStringIO
-from u1db import SyncTarget
from u1db.sync import Synchronizer
from u1db.remote import (
http_client,
http_database,
- http_target,
)
from leap.soledad import client
@@ -40,7 +37,6 @@ from leap.soledad.client import (
target,
auth,
VerifiedHTTPSConnection,
- sync,
)
from leap.soledad.common.document import SoledadDocument
from leap.soledad.server.auth import SoledadTokenAuthMiddleware
@@ -61,10 +57,6 @@ from leap.soledad.common.tests.u1db_tests import test_document
from leap.soledad.common.tests.u1db_tests import test_remote_sync_target
from leap.soledad.common.tests.u1db_tests import test_https
from leap.soledad.common.tests.u1db_tests import test_sync
-from leap.soledad.common.tests.test_couch import (
- CouchDBTestCase,
- CouchDBWrapper,
-)
#-----------------------------------------------------------------------------
@@ -391,6 +383,10 @@ class TestSoledadSyncTarget(
tests.TestCaseWithServer.tearDown(self)
db, _ = self.request_state.ensure_database('test2')
db.delete_database()
+ for i in ['db1', 'db2']:
+ if hasattr(self, i):
+ db = getattr(self, i)
+ db.close()
def test_sync_exchange_send(self):
"""
@@ -413,6 +409,7 @@ class TestSoledadSyncTarget(
self.assertEqual(1, new_gen)
self.assertGetEncryptedDoc(
db, 'doc-here', 'replica:1', '{"value": "here"}', False)
+ db.close()
def test_sync_exchange_send_failure_and_retry_scenario(self):
"""
@@ -486,6 +483,7 @@ class TestSoledadSyncTarget(
self.assertEqual(
('doc-here', 'replica:1', '{"value": "here"}', 1),
other_changes[0][:-1])
+ db.close()
def test_sync_exchange_send_ensure_callback(self):
"""
@@ -515,6 +513,7 @@ class TestSoledadSyncTarget(
self.assertEqual(db._replica_uid, replica_uid_box[0])
self.assertGetEncryptedDoc(
db, 'doc-here', 'replica:1', '{"value": "here"}', False)
+ db.close()
def test_sync_exchange_in_stream_error(self):
# we bypass this test because our sync_exchange process does not
@@ -747,6 +746,10 @@ class TestSoledadDbSync(
self.main_test_class = test_sync.TestDbSync
SoledadWithCouchServerMixin.setUp(self)
+ def tearDown(self):
+ SoledadWithCouchServerMixin.tearDown(self)
+ self.db.close()
+
def do_sync(self, target_name):
"""
Perform sync using SoledadSyncTarget and Token auth.
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_backends.py b/common/src/leap/soledad/common/tests/u1db_tests/test_backends.py
index 86e76fad..54adcde1 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/test_backends.py
+++ b/common/src/leap/soledad/common/tests/u1db_tests/test_backends.py
@@ -363,6 +363,7 @@ class LocalDatabaseTests(tests.DatabaseBaseTests):
db2 = self.create_database('other-uid')
doc2 = db2.create_doc_from_json(simple_doc)
self.assertNotEqual(doc1.doc_id, doc2.doc_id)
+ db2.close()
def test_put_doc_refuses_slashes_picky(self):
doc = self.make_document('/a', None, simple_doc)