From 6328511e86429bcd23f6ca179ef10114aa69a4e9 Mon Sep 17 00:00:00 2001 From: drebs Date: Wed, 6 Feb 2013 16:52:53 -0200 Subject: Remove OpenStack backend from soledad. --- src/leap/soledad/README | 14 +++-- src/leap/soledad/backends/openstack.py | 98 ---------------------------------- 2 files changed, 6 insertions(+), 106 deletions(-) delete mode 100644 src/leap/soledad/backends/openstack.py (limited to 'src') diff --git a/src/leap/soledad/README b/src/leap/soledad/README index 3bf62494..b14d5932 100644 --- a/src/leap/soledad/README +++ b/src/leap/soledad/README @@ -9,16 +9,14 @@ Dependencies Soledad depends on the following python libraries: * u1db 0.1.4 [1] - * python-swiftclient 1.2.0 [2] - * python-gnupg 0.3.1 [3] - * CouchDB 0.8 [4] - * hmac 20101005 [5] + * python-gnupg 0.3.1 [2] + * CouchDB 0.8 [3] + * hmac 20101005 [4] [1] http://pypi.python.org/pypi/u1db/0.1.4 -[2] http://pypi.python.org/pypi/python-swiftclient/1.2.0 -[3] http://pypi.python.org/pypi/python-gnupg/0.3.1 -[4] http://pypi.python.org/pypi/CouchDB/0.8 -[5] http://pypi.python.org/pypi/hmac/20101005 +[2] http://pypi.python.org/pypi/python-gnupg/0.3.1 +[3] http://pypi.python.org/pypi/CouchDB/0.8 +[4] http://pypi.python.org/pypi/hmac/20101005 Tests diff --git a/src/leap/soledad/backends/openstack.py b/src/leap/soledad/backends/openstack.py deleted file mode 100644 index a9615736..00000000 --- a/src/leap/soledad/backends/openstack.py +++ /dev/null @@ -1,98 +0,0 @@ -# TODO: this backend is not tested yet. -from u1db.remote.http_target import HTTPSyncTarget -import swiftclient -from soledad.backends.objectstore import ObjectStore - - -class OpenStackDatabase(ObjectStore): - """A U1DB implementation that uses OpenStack as its persistence layer.""" - - def __init__(self, auth_url, user, auth_key, container): - """Create a new OpenStack data container.""" - self._auth_url = auth_url - self._user = user - self._auth_key = auth_key - self._container = container - self._connection = swiftclient.Connection(self._auth_url, self._user, - self._auth_key) - self._get_auth() - # this will ensure transaction and sync logs exist and are up-to-date. - super(OpenStackDatabase, self).__init__() - - #------------------------------------------------------------------------- - # implemented methods from Database - #------------------------------------------------------------------------- - - def _get_doc(self, doc_id, check_for_conflicts=False): - """Get just the document content, without fancy handling. - - Conflicts do not happen on server side, so there's no need to check - for them. - """ - try: - response, contents = self._connection.get_object(self._container, - doc_id) - # TODO: change revision to be a dictionary element? - rev = response['x-object-meta-rev'] - return self._factory(doc_id, rev, contents) - except swiftclient.ClientException: - return None - - def get_all_docs(self, include_deleted=False): - """Get all documents from the database.""" - generation = self._get_generation() - results = [] - _, doc_ids = self._connection.get_container(self._container, - full_listing=True) - for doc_id in doc_ids: - doc = self._get_doc(doc_id) - if doc.content is None and not include_deleted: - continue - results.append(doc) - return (generation, results) - - def _put_doc(self, doc, new_rev): - new_rev = self._allocate_doc_rev(doc.rev) - # TODO: change revision to be a dictionary element? - headers = {'X-Object-Meta-Rev': new_rev} - self._connection.put_object(self._container, doc_id, doc.get_json(), - headers=headers) - - def get_sync_target(self): - return OpenStackSyncTarget(self) - - def close(self): - raise NotImplementedError(self.close) - - def sync(self, url, creds=None, autocreate=True): - from u1db.sync import Synchronizer - from u1db.remote.http_target import OpenStackSyncTarget - return Synchronizer(self, OpenStackSyncTarget(url, creds=creds)).sync( - autocreate=autocreate) - - #------------------------------------------------------------------------- - # OpenStack specific methods - #------------------------------------------------------------------------- - - def _get_auth(self): - self._url, self._auth_token = self._connection.get_auth() - return self._url, self.auth_token - - -class OpenStackSyncTarget(HTTPSyncTarget): - - def get_sync_info(self, source_replica_uid): - source_gen, source_trans_id = self._db._get_replica_gen_and_trans_id( - source_replica_uid) - my_gen, my_trans_id = self._db._get_generation_info() - return ( - self._db._replica_uid, my_gen, my_trans_id, source_gen, - source_trans_id) - - def record_sync_info(self, source_replica_uid, source_replica_generation, - source_replica_transaction_id): - if self._trace_hook: - self._trace_hook('record_sync_info') - self._db._set_replica_gen_and_trans_id( - source_replica_uid, source_replica_generation, - source_replica_transaction_id) -- cgit v1.2.3 From 4a0ecb6832f28453976757fe4a7c4a5f1f811105 Mon Sep 17 00:00:00 2001 From: drebs Date: Wed, 6 Feb 2013 18:01:58 -0200 Subject: SQLCipher syncs using LeapSyncTarget. --- src/leap/soledad/backends/sqlcipher.py | 7 +++++-- src/leap/soledad/tests/test_couch.py | 2 ++ src/leap/soledad/tests/test_sqlcipher.py | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/leap/soledad/backends/sqlcipher.py b/src/leap/soledad/backends/sqlcipher.py index 6cebcf7d..354fcd31 100644 --- a/src/leap/soledad/backends/sqlcipher.py +++ b/src/leap/soledad/backends/sqlcipher.py @@ -131,8 +131,11 @@ class SQLCipherDatabase(SQLitePartialExpandDatabase): """ from u1db.sync import Synchronizer from leap.soledad.backends.leap_backend import LeapSyncTarget - return Synchronizer(self, LeapSyncTarget(url, creds=creds), - soledad=self._soledad).sync(autocreate=autocreate) + return Synchronizer( + self, + LeapSyncTarget(url, + creds=creds, + soledad=self._soledad)).sync(autocreate=autocreate) def _extra_schema_init(self, c): c.execute( diff --git a/src/leap/soledad/tests/test_couch.py b/src/leap/soledad/tests/test_couch.py index b5d6378c..a9b2f39e 100644 --- a/src/leap/soledad/tests/test_couch.py +++ b/src/leap/soledad/tests/test_couch.py @@ -27,6 +27,8 @@ import time import unittest +# from: https://github.com/smcq/paisley/blob/master/paisley/test/util.py +# TODO: include license of above project. class CouchDBWrapper(object): """ Wrapper for external CouchDB instance which is started and stopped for diff --git a/src/leap/soledad/tests/test_sqlcipher.py b/src/leap/soledad/tests/test_sqlcipher.py index 0d5d00ee..b964f51e 100644 --- a/src/leap/soledad/tests/test_sqlcipher.py +++ b/src/leap/soledad/tests/test_sqlcipher.py @@ -27,6 +27,7 @@ from leap.soledad.tests import u1db_tests as tests from leap.soledad.tests.u1db_tests import test_sqlite_backend from leap.soledad.tests.u1db_tests import test_backends from leap.soledad.tests.u1db_tests import test_open +from leap.soledad.tests.u1db_tests import test_sync PASSWORD = '123456' @@ -321,6 +322,23 @@ class SQLCipherOpen(test_open.TestU1DBOpen): self.assertIsInstance(db2, SQLCipherDatabase) +#----------------------------------------------------------------------------- +# The following tests come from `u1db.tests.test_sync`. +#----------------------------------------------------------------------------- + +sync_scenarios = [] +for name, scenario in SQLCIPHER_SCENARIOS: + scenario = dict(scenario) + scenario['do_sync'] = test_sync.sync_via_synchronizer + sync_scenarios.append((name, scenario)) + scenario = dict(scenario) + + +class SQLCipherDatabaseSyncTests(test_sync.DatabaseSyncTests): + + scenarios = sync_scenarios + + #----------------------------------------------------------------------------- # Tests for actual encryption of the database #----------------------------------------------------------------------------- @@ -373,4 +391,5 @@ class SQLCipherEncryptionTest(unittest.TestCase): except DatabaseIsNotEncrypted: pass + load_tests = tests.load_with_scenarios -- cgit v1.2.3 From c1289d25f25814e1b34bb1ccf3e55b809d0c5f96 Mon Sep 17 00:00:00 2001 From: drebs Date: Wed, 6 Feb 2013 19:14:50 -0200 Subject: Add test scenario for SQLCipher backend using LeapSyncTarget. --- src/leap/soledad/backends/couch.py | 1 + src/leap/soledad/backends/leap_backend.py | 1 - src/leap/soledad/tests/test_sqlcipher.py | 22 ++++++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/leap/soledad/backends/couch.py b/src/leap/soledad/backends/couch.py index 11122aa8..8757f5af 100644 --- a/src/leap/soledad/backends/couch.py +++ b/src/leap/soledad/backends/couch.py @@ -243,6 +243,7 @@ class CouchSyncTarget(LocalSyncTarget): source_replica_uid, source_replica_generation, source_replica_transaction_id) + class CouchServerState(ServerState): """ Inteface of the WSGI server with the CouchDB backend. diff --git a/src/leap/soledad/backends/leap_backend.py b/src/leap/soledad/backends/leap_backend.py index f9d37e19..41027e50 100644 --- a/src/leap/soledad/backends/leap_backend.py +++ b/src/leap/soledad/backends/leap_backend.py @@ -200,4 +200,3 @@ class LeapSyncTarget(HTTPSyncTarget): res = self._parse_sync_stream(data, return_doc_cb, ensure_callback) data = None return res['new_generation'], res['new_transaction_id'] - diff --git a/src/leap/soledad/tests/test_sqlcipher.py b/src/leap/soledad/tests/test_sqlcipher.py index b964f51e..85b9e486 100644 --- a/src/leap/soledad/tests/test_sqlcipher.py +++ b/src/leap/soledad/tests/test_sqlcipher.py @@ -11,6 +11,7 @@ import threading from u1db import ( errors, query_parser, + sync, ) from u1db.backends.sqlite_backend import SQLitePartialExpandDatabase @@ -28,6 +29,7 @@ from leap.soledad.tests.u1db_tests import test_sqlite_backend from leap.soledad.tests.u1db_tests import test_backends from leap.soledad.tests.u1db_tests import test_open from leap.soledad.tests.u1db_tests import test_sync +from leap.soledad.backends.leap_backend import LeapSyncTarget PASSWORD = '123456' @@ -334,6 +336,26 @@ for name, scenario in SQLCIPHER_SCENARIOS: scenario = dict(scenario) +def sync_via_synchronizer_and_leap(test, db_source, db_target, + trace_hook=None, trace_hook_shallow=None): + if trace_hook: + test.skipTest("full trace hook unsupported over http") + path = test._http_at[db_target] + target = LeapSyncTarget.connect(test.getURL(path)) + if trace_hook_shallow: + target._set_trace_hook_shallow(trace_hook_shallow) + return sync.Synchronizer(db_source, target).sync() + + +sync_scenarios.append(('pyleap', { + 'make_database_for_test': test_sync.make_database_for_http_test, + 'copy_database_for_test': test_sync.copy_database_for_http_test, + 'make_document_for_test': tests.make_document_for_test, + 'make_app_with_state': tests.test_remote_sync_target.make_http_app, + 'do_sync': sync_via_synchronizer_and_leap, +})) + + class SQLCipherDatabaseSyncTests(test_sync.DatabaseSyncTests): scenarios = sync_scenarios -- cgit v1.2.3 From 634f82d95984b4bb78cbfdd52e6e75116c8df53d Mon Sep 17 00:00:00 2001 From: drebs Date: Wed, 6 Feb 2013 20:01:31 -0200 Subject: Add DatabaseSyncTargetTests to SQLCipher tests. --- src/leap/soledad/tests/test_sqlcipher.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/leap/soledad/tests/test_sqlcipher.py b/src/leap/soledad/tests/test_sqlcipher.py index 85b9e486..042ee4ff 100644 --- a/src/leap/soledad/tests/test_sqlcipher.py +++ b/src/leap/soledad/tests/test_sqlcipher.py @@ -361,6 +361,26 @@ class SQLCipherDatabaseSyncTests(test_sync.DatabaseSyncTests): scenarios = sync_scenarios +def _make_local_db_and_leap_target(test, path='test'): + test.startServer() + db = test.request_state._create_database(os.path.basename(path)) + st = LeapSyncTarget.connect(test.getURL(path)) + return db, st + + +target_scenarios = [ + ('leap', { + 'create_db_and_target': _make_local_db_and_leap_target, + 'make_app_with_state': tests.test_remote_sync_target.make_http_app}), +] + + +class SQLCipherSyncTargetTests(test_sync.DatabaseSyncTargetTests): + + scenarios = (tests.multiply_scenarios(SQLCIPHER_SCENARIOS, + target_scenarios)) + + #----------------------------------------------------------------------------- # Tests for actual encryption of the database #----------------------------------------------------------------------------- -- cgit v1.2.3