summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/src/leap/soledad/common/tests/server_state.py81
-rw-r--r--common/src/leap/soledad/common/tests/u1db_tests/test_https.py114
-rw-r--r--testing/setup.py9
-rw-r--r--testing/test_soledad/__init__.py5
-rw-r--r--testing/test_soledad/fixture_soledad.conf (renamed from common/src/leap/soledad/common/tests/fixture_soledad.conf)0
-rw-r--r--testing/test_soledad/u1db_tests/README (renamed from common/src/leap/soledad/common/tests/u1db_tests/README)2
-rw-r--r--testing/test_soledad/u1db_tests/__init__.py (renamed from common/src/leap/soledad/common/tests/u1db_tests/__init__.py)46
-rw-r--r--testing/test_soledad/u1db_tests/test_backends.py (renamed from common/src/leap/soledad/common/tests/u1db_tests/test_backends.py)31
-rw-r--r--testing/test_soledad/u1db_tests/test_document.py (renamed from common/src/leap/soledad/common/tests/u1db_tests/test_document.py)2
-rw-r--r--testing/test_soledad/u1db_tests/test_http_client.py (renamed from common/src/leap/soledad/common/tests/u1db_tests/test_http_client.py)58
-rw-r--r--testing/test_soledad/u1db_tests/test_http_database.py (renamed from common/src/leap/soledad/common/tests/u1db_tests/test_http_database.py)24
-rw-r--r--testing/test_soledad/u1db_tests/test_https.py105
-rw-r--r--testing/test_soledad/u1db_tests/test_open.py (renamed from common/src/leap/soledad/common/tests/u1db_tests/test_open.py)4
-rw-r--r--testing/test_soledad/u1db_tests/testing-certs/Makefile (renamed from common/src/leap/soledad/common/tests/u1db_tests/testing-certs/Makefile)0
-rw-r--r--testing/test_soledad/u1db_tests/testing-certs/cacert.pem (renamed from common/src/leap/soledad/common/tests/u1db_tests/testing-certs/cacert.pem)0
-rw-r--r--testing/test_soledad/u1db_tests/testing-certs/testing.cert (renamed from common/src/leap/soledad/common/tests/u1db_tests/testing-certs/testing.cert)0
-rw-r--r--testing/test_soledad/u1db_tests/testing-certs/testing.key (renamed from common/src/leap/soledad/common/tests/u1db_tests/testing-certs/testing.key)0
-rw-r--r--testing/test_soledad/util.py (renamed from common/src/leap/soledad/common/tests/util.py)13
-rw-r--r--testing/tests/client/__init__.py0
-rw-r--r--testing/tests/client/hacker_crackdown.txt (renamed from common/src/leap/soledad/common/tests/hacker_crackdown.txt)0
-rw-r--r--testing/tests/client/test_app.py (renamed from common/src/leap/soledad/common/tests/test_soledad_app.py)24
-rw-r--r--testing/tests/client/test_async.py (renamed from common/src/leap/soledad/common/tests/test_async.py)2
-rw-r--r--testing/tests/client/test_aux_methods.py147
-rw-r--r--testing/tests/client/test_crypto.py (renamed from common/src/leap/soledad/common/tests/test_crypto.py)2
-rw-r--r--testing/tests/client/test_doc.py46
-rw-r--r--testing/tests/client/test_http.py (renamed from common/src/leap/soledad/common/tests/test_http.py)6
-rw-r--r--testing/tests/client/test_http_client.py (renamed from common/src/leap/soledad/common/tests/test_http_client.py)35
-rw-r--r--testing/tests/client/test_https.py (renamed from common/src/leap/soledad/common/tests/test_https.py)14
-rw-r--r--testing/tests/client/test_shared_db.py50
-rw-r--r--testing/tests/client/test_signals.py (renamed from common/src/leap/soledad/common/tests/test_soledad.py)197
-rw-r--r--testing/tests/client/test_soledad_doc.py (renamed from common/src/leap/soledad/common/tests/test_soledad_doc.py)6
-rw-r--r--testing/tests/client/test_sqlcipher.py (renamed from common/src/leap/soledad/common/tests/test_sqlcipher.py)34
-rw-r--r--testing/tests/client/test_sqlcipher_sync.py (renamed from common/src/leap/soledad/common/tests/test_sqlcipher_sync.py)23
-rw-r--r--testing/tests/couch/__init__.py0
-rw-r--r--testing/tests/couch/couchdb.ini.template (renamed from common/src/leap/soledad/common/tests/couchdb.ini.template)0
-rw-r--r--testing/tests/couch/test_couch.py (renamed from common/src/leap/soledad/common/tests/test_couch.py)12
-rw-r--r--testing/tests/couch/test_couch_operations_atomicity.py (renamed from common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py)6
-rw-r--r--testing/tests/server/__init__.py0
-rw-r--r--testing/tests/server/test_server.py (renamed from common/src/leap/soledad/common/tests/test_server.py)11
-rw-r--r--testing/tests/sync/__init__.py0
-rw-r--r--testing/tests/sync/test_encdecpool.py (renamed from common/src/leap/soledad/common/tests/test_encdecpool.py)2
-rw-r--r--testing/tests/sync/test_sync.py (renamed from common/src/leap/soledad/common/tests/test_sync.py)18
-rw-r--r--testing/tests/sync/test_sync_deferred.py (renamed from common/src/leap/soledad/common/tests/test_sync_deferred.py)10
-rw-r--r--testing/tests/sync/test_sync_mutex.py (renamed from common/src/leap/soledad/common/tests/test_sync_mutex.py)12
-rw-r--r--testing/tests/sync/test_sync_target.py (renamed from common/src/leap/soledad/common/tests/test_sync_target.py)28
-rw-r--r--testing/tox.ini21
46 files changed, 510 insertions, 690 deletions
diff --git a/common/src/leap/soledad/common/tests/server_state.py b/common/src/leap/soledad/common/tests/server_state.py
deleted file mode 100644
index 26838f89..00000000
--- a/common/src/leap/soledad/common/tests/server_state.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# -*- coding: utf-8 -*-
-# server_state.py
-# Copyright (C) 2013 LEAP
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-"""
-State for servers to be used in tests.
-"""
-
-
-import os
-import errno
-import tempfile
-
-
-from leap.soledad.common.l2db.remote.server_state import ServerState
-from leap.soledad.common.tests.util import (
- copy_sqlcipher_database_for_test,
-)
-
-
-class ServerStateForTests(ServerState):
-
- """Passed to a Request when it is instantiated.
-
- This is used to track server-side state, such as working-directory, open
- databases, etc.
- """
-
- def __init__(self):
- self._workingdir = tempfile.mkdtemp()
-
- def _relpath(self, relpath):
- return os.path.join(self._workingdir, relpath)
-
- def open_database(self, path):
- """Open a database at the given location."""
- from leap.soledad.client.sqlcipher import SQLCipherDatabase
- return SQLCipherDatabase.open_database(path, '123', False)
-
- def create_database(self, path):
- """Create a database at the given location."""
- from leap.soledad.client.sqlcipher import SQLCipherDatabase
- return SQLCipherDatabase.open_database(path, '123', True)
-
- def check_database(self, path):
- """Check if the database at the given location exists.
-
- Simply returns if it does or raises DatabaseDoesNotExist.
- """
- db = self.open_database(path)
- db.close()
-
- def ensure_database(self, path):
- """Ensure database at the given location."""
- from leap.soledad.client.sqlcipher import SQLCipherDatabase
- full_path = self._relpath(path)
- db = SQLCipherDatabase.open_database(full_path, '123', False)
- return db, db._replica_uid
-
- def delete_database(self, path):
- """Delete database at the given location."""
- from leap.u1db.backends import sqlite_backend
- full_path = self._relpath(path)
- sqlite_backend.SQLiteDatabase.delete_database(full_path)
-
- def _copy_database(self, db):
- return copy_sqlcipher_database_for_test(None, db)
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_https.py b/common/src/leap/soledad/common/tests/u1db_tests/test_https.py
deleted file mode 100644
index 8a5743e7..00000000
--- a/common/src/leap/soledad/common/tests/u1db_tests/test_https.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""Test support for client-side https support."""
-
-import os
-import ssl
-import sys
-
-#from paste import httpserver
-from unittest import skip
-
-from leap.soledad.common.l2db.remote import http_client
-#from leap.soledad.common.l2db.remote import http_target
-
-from leap import soledad
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.u1db_tests import make_oauth_http_app
-
-
-#def https_server_def():
- #def make_server(host_port, application):
- #from OpenSSL import SSL
- #cert_file = os.path.join(os.path.dirname(__file__), 'testing-certs',
- #'testing.cert')
- #key_file = os.path.join(os.path.dirname(__file__), 'testing-certs',
- #'testing.key')
- #ssl_context = SSL.Context(SSL.SSLv23_METHOD)
- #ssl_context.use_privatekey_file(key_file)
- #ssl_context.use_certificate_chain_file(cert_file)
- #srv = httpserver.WSGIServerBase(application, host_port,
- #httpserver.WSGIHandler,
- #ssl_context=ssl_context
- #)
-#
- #def shutdown_request(req):
- #req.shutdown()
- #srv.close_request(req)
-#
- #srv.shutdown_request = shutdown_request
- #application.base_url = "https://localhost:%s" % srv.server_address[1]
- #return srv
- #return make_server, "shutdown", "https"
-
-
-#@skip("Skiping tests imported from U1DB.")
-#class TestHttpSyncTargetHttpsSupport(tests.TestCaseWithServer):
-#
- #scenarios = [
- #('oauth_https', {'server_def': https_server_def,
- #'make_app_with_state': make_oauth_http_app,
- #'make_document_for_test':
- #tests.make_document_for_test,
- #'sync_target': oauth_https_sync_target
- #}),
- #]
-#
- #def setUp(self):
- #try:
- #import OpenSSL # noqa
- #except ImportError:
- #self.skipTest("Requires pyOpenSSL")
- #self.cacert_pem = os.path.join(os.path.dirname(__file__),
- #'testing-certs', 'cacert.pem')
- # The default u1db http_client class for doing HTTPS only does HTTPS
- # if the platform is linux. Because of this, soledad replaces that
- # class with one that will do HTTPS independent of the platform. In
- # order to maintain the compatibility with u1db default tests, we undo
- # that replacement here.
- #http_client._VerifiedHTTPSConnection = \
- #soledad.client.api.old__VerifiedHTTPSConnection
- #super(TestHttpSyncTargetHttpsSupport, self).setUp()
-#
- #def getSyncTarget(self, host, path=None, cert_file=None):
- #if self.server is None:
- #self.startServer()
- #return self.sync_target(self, host, path, cert_file=cert_file)
-#
- #def test_working(self):
- #self.startServer()
- #db = self.request_state._create_database('test')
- #self.patch(http_client, 'CA_CERTS', self.cacert_pem)
- #remote_target = self.getSyncTarget('localhost', 'test')
- #remote_target.record_sync_info('other-id', 2, 'T-id')
- #self.assertEqual(
- #(2, 'T-id'), db._get_replica_gen_and_trans_id('other-id'))
-#
- #def test_cannot_verify_cert(self):
- #if not sys.platform.startswith('linux'):
- #self.skipTest(
- #"XXX certificate verification happens on linux only for now")
- #self.startServer()
- # don't print expected traceback server-side
- #self.server.handle_error = lambda req, cli_addr: None
- #self.request_state._create_database('test')
- #remote_target = self.getSyncTarget('localhost', 'test')
- #try:
- #remote_target.record_sync_info('other-id', 2, 'T-id')
- #except ssl.SSLError, e:
- #self.assertIn("certificate verify failed", str(e))
- #else:
- #self.fail("certificate verification should have failed.")
-#
- #def test_host_mismatch(self):
- #if not sys.platform.startswith('linux'):
- #self.skipTest(
- #"XXX certificate verification happens on linux only for now")
- #self.startServer()
- #self.request_state._create_database('test')
- #self.patch(http_client, 'CA_CERTS', self.cacert_pem)
- #remote_target = self.getSyncTarget('127.0.0.1', 'test')
- #self.assertRaises(
- #http_client.CertificateError, remote_target.record_sync_info,
- #'other-id', 2, 'T-id')
-#
-#
-#load_tests = tests.load_with_scenarios
diff --git a/testing/setup.py b/testing/setup.py
new file mode 100644
index 00000000..059b2489
--- /dev/null
+++ b/testing/setup.py
@@ -0,0 +1,9 @@
+from setuptools import setup
+from setuptools import find_packages
+
+
+setup(
+ name='test_soledad',
+ packages=find_packages('.'),
+ package_data={'': ['*.conf']}
+)
diff --git a/testing/test_soledad/__init__.py b/testing/test_soledad/__init__.py
new file mode 100644
index 00000000..c07c8b0e
--- /dev/null
+++ b/testing/test_soledad/__init__.py
@@ -0,0 +1,5 @@
+from test_soledad import util
+
+__all__ = [
+ 'util',
+]
diff --git a/common/src/leap/soledad/common/tests/fixture_soledad.conf b/testing/test_soledad/fixture_soledad.conf
index 8d8161c3..8d8161c3 100644
--- a/common/src/leap/soledad/common/tests/fixture_soledad.conf
+++ b/testing/test_soledad/fixture_soledad.conf
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/README b/testing/test_soledad/u1db_tests/README
index 0525cfdb..546dfdc9 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/README
+++ b/testing/test_soledad/u1db_tests/README
@@ -17,9 +17,7 @@ u1db tests depend on the following python packages:
hgtools
testtools
discover
- oauth
testscenarios
- dirspec
paste
routes
cython
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/__init__.py b/testing/test_soledad/u1db_tests/__init__.py
index 7f334b4a..ba776864 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/__init__.py
+++ b/testing/test_soledad/u1db_tests/__init__.py
@@ -26,7 +26,6 @@ import json
from wsgiref import simple_server
-from oauth import oauth
from pysqlcipher import dbapi2
from StringIO import StringIO
@@ -394,44 +393,6 @@ def socket_pair():
return server_sock, client_sock
-# OAuth related testing
-
-consumer1 = oauth.OAuthConsumer('K1', 'S1')
-token1 = oauth.OAuthToken('kkkk1', 'XYZ')
-consumer2 = oauth.OAuthConsumer('K2', 'S2')
-token2 = oauth.OAuthToken('kkkk2', 'ZYX')
-token3 = oauth.OAuthToken('kkkk3', 'ZYX')
-
-
-class TestingOAuthDataStore(oauth.OAuthDataStore):
-
- """In memory predefined OAuthDataStore for testing."""
-
- consumers = {
- consumer1.key: consumer1,
- consumer2.key: consumer2,
- }
-
- tokens = {
- token1.key: token1,
- token2.key: token2
- }
-
- def lookup_consumer(self, key):
- return self.consumers.get(key)
-
- def lookup_token(self, token_type, token_token):
- return self.tokens.get(token_token)
-
- def lookup_nonce(self, oauth_consumer, oauth_token, nonce):
- return None
-
-testingOAuthStore = TestingOAuthDataStore()
-
-sign_meth_HMAC_SHA1 = oauth.OAuthSignatureMethod_HMAC_SHA1()
-sign_meth_PLAINTEXT = oauth.OAuthSignatureMethod_PLAINTEXT()
-
-
def load_with_scenarios(loader, standard_tests, pattern):
"""Load the tests in a given module.
@@ -452,10 +413,3 @@ def make_http_app(state):
def http_sync_target(test, path):
return http_target.HTTPSyncTarget(test.getURL(path))
-
-
-def make_oauth_http_app(state):
- app = http_app.HTTPApp(state)
- application = oauth_middleware.OAuthMiddleware(app, None, prefix='/~/')
- application.get_oauth_data_store = lambda: tests.testingOAuthStore
- return application
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_backends.py b/testing/test_soledad/u1db_tests/test_backends.py
index c0c6ea6b..10dcdff9 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/test_backends.py
+++ b/testing/test_soledad/u1db_tests/test_backends.py
@@ -26,9 +26,7 @@ from leap.soledad.common.l2db import errors
from leap.soledad.common.l2db import vectorclock
from leap.soledad.common.l2db.remote import http_database
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.u1db_tests import make_http_app
-from leap.soledad.common.tests.u1db_tests import make_oauth_http_app
+from test_soledad import u1db_tests as tests
from unittest import skip
@@ -51,25 +49,6 @@ def copy_http_database_for_test(test, db):
return test.request_state._copy_database(db)
-def make_oauth_http_database_for_test(test, replica_uid):
- http_db = make_http_database_for_test(test, replica_uid, '~/test')
- http_db.set_oauth_credentials(tests.consumer1.key, tests.consumer1.secret,
- tests.token1.key, tests.token1.secret)
- return http_db
-
-
-def copy_oauth_http_database_for_test(test, db):
- # DO NOT COPY OR REUSE THIS CODE OUTSIDE TESTS: COPYING U1DB DATABASES IS
- # THE WRONG THING TO DO, THE ONLY REASON WE DO SO HERE IS TO TEST THAT WE
- # CORRECTLY DETECT IT HAPPENING SO THAT WE CAN RAISE ERRORS RATHER THAN
- # CORRUPT USER DATA. USE SYNC INSTEAD, OR WE WILL SEND NINJA TO YOUR
- # HOUSE.
- http_db = test.request_state._copy_database(db)
- http_db.set_oauth_credentials(tests.consumer1.key, tests.consumer1.secret,
- tests.token1.key, tests.token1.secret)
- return http_db
-
-
class TestAlternativeDocument(DocumentBase):
"""A (not very) alternative implementation of Document."""
@@ -82,13 +61,7 @@ class AllDatabaseTests(tests.DatabaseBaseTests, tests.TestCaseWithServer):
('http', {'make_database_for_test': make_http_database_for_test,
'copy_database_for_test': copy_http_database_for_test,
'make_document_for_test': tests.make_document_for_test,
- 'make_app_with_state': make_http_app}),
- ('oauth_http', {'make_database_for_test':
- make_oauth_http_database_for_test,
- 'copy_database_for_test':
- copy_oauth_http_database_for_test,
- 'make_document_for_test': tests.make_document_for_test,
- 'make_app_with_state': make_oauth_http_app})
+ 'make_app_with_state': tests.make_http_app}),
]
def test_close(self):
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_document.py b/testing/test_soledad/u1db_tests/test_document.py
index 4e8bcaf9..a7ead2d1 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/test_document.py
+++ b/testing/test_soledad/u1db_tests/test_document.py
@@ -18,7 +18,7 @@ from unittest import skip
from leap.soledad.common.l2db import errors
-from leap.soledad.common.tests import u1db_tests as tests
+from test_soledad import u1db_tests as tests
@skip("Skiping tests imported from U1DB.")
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_http_client.py b/testing/test_soledad/u1db_tests/test_http_client.py
index 344dcb29..e9516236 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/test_http_client.py
+++ b/testing/test_soledad/u1db_tests/test_http_client.py
@@ -25,7 +25,7 @@ from unittest import skip
from leap.soledad.common.l2db import errors
from leap.soledad.common.l2db.remote import http_client
-from leap.soledad.common.tests import u1db_tests as tests
+from test_soledad import u1db_tests as tests
@skip("Skiping tests imported from U1DB.")
@@ -106,26 +106,6 @@ class TestHTTPClientBase(tests.TestCaseWithServer):
else:
start_response(status, [('Content-Type', 'application/json')])
return [json.dumps(response)]
- elif '/oauth' in environ['PATH_INFO']:
- base_url = self.getURL('').rstrip('/')
- oauth_req = oauth.OAuthRequest.from_request(
- http_method=environ['REQUEST_METHOD'],
- http_url=base_url + environ['PATH_INFO'],
- headers={'Authorization': environ['HTTP_AUTHORIZATION']},
- query_string=environ['QUERY_STRING']
- )
- oauth_server = oauth.OAuthServer(tests.testingOAuthStore)
- oauth_server.add_signature_method(tests.sign_meth_HMAC_SHA1)
- try:
- consumer, token, params = oauth_server.verify_request(
- oauth_req)
- except oauth.OAuthError, e:
- start_response("401 Unauthorized",
- [('Content-Type', 'application/json')])
- return [json.dumps({"error": "unauthorized",
- "message": e.message})]
- start_response("200 OK", [('Content-Type', 'application/json')])
- return [json.dumps([environ['PATH_INFO'], token.key, params])]
def make_app(self):
return self.app
@@ -317,44 +297,8 @@ class TestHTTPClientBase(tests.TestCaseWithServer):
self.assertEqual("<Bad Request>", e.message)
self.assertTrue("content-type" in e.headers)
- def test_oauth(self):
- cli = self.getClient()
- cli.set_oauth_credentials(tests.consumer1.key, tests.consumer1.secret,
- tests.token1.key, tests.token1.secret)
- params = {'x': u'\xf0', 'y': "foo"}
- res, headers = cli._request('GET', ['doc', 'oauth'], params)
- self.assertEqual(
- ['/dbase/doc/oauth', tests.token1.key, params], json.loads(res))
-
- # oauth does its own internal quoting
- params = {'x': u'\xf0', 'y': "foo"}
- res, headers = cli._request('GET', ['doc', 'oauth', 'foo bar'], params)
- self.assertEqual(
- ['/dbase/doc/oauth/foo bar', tests.token1.key, params],
- json.loads(res))
-
- def test_oauth_ctr_creds(self):
- cli = self.getClient(creds={'oauth': {
- 'consumer_key': tests.consumer1.key,
- 'consumer_secret': tests.consumer1.secret,
- 'token_key': tests.token1.key,
- 'token_secret': tests.token1.secret,
- }})
- params = {'x': u'\xf0', 'y': "foo"}
- res, headers = cli._request('GET', ['doc', 'oauth'], params)
- self.assertEqual(
- ['/dbase/doc/oauth', tests.token1.key, params], json.loads(res))
-
def test_unknown_creds(self):
self.assertRaises(errors.UnknownAuthMethod,
self.getClient, creds={'foo': {}})
self.assertRaises(errors.UnknownAuthMethod,
self.getClient, creds={})
-
- def test_oauth_Unauthorized(self):
- cli = self.getClient()
- cli.set_oauth_credentials(tests.consumer1.key, tests.consumer1.secret,
- tests.token1.key, "WRONG")
- params = {'y': 'foo'}
- self.assertRaises(errors.Unauthorized, cli._request, 'GET',
- ['doc', 'oauth'], params)
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_http_database.py b/testing/test_soledad/u1db_tests/test_http_database.py
index 001aebd4..a3ed9361 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/test_http_database.py
+++ b/testing/test_soledad/u1db_tests/test_http_database.py
@@ -25,8 +25,8 @@ from leap.soledad.common.l2db import errors
from leap.soledad.common.l2db import Document
from leap.soledad.common.l2db.remote import http_database
from leap.soledad.common.l2db.remote import http_target
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.u1db_tests import make_http_app
+from test_soledad import u1db_tests as tests
+from test_soledad.u1db_tests import make_http_app
@skip("Skiping tests imported from U1DB.")
@@ -174,26 +174,6 @@ class TestHTTPDatabaseSimpleOperations(tests.TestCase):
self.assertIsInstance(st, http_target.HTTPSyncTarget)
self.assertEqual(st._url, self.db._url)
- def test_get_sync_target_inherits_oauth_credentials(self):
- self.db.set_oauth_credentials(tests.consumer1.key,
- tests.consumer1.secret,
- tests.token1.key, tests.token1.secret)
- st = self.db.get_sync_target()
- self.assertEqual(self.db._creds, st._creds)
-
-
-@skip("Skiping tests imported from U1DB.")
-class TestHTTPDatabaseCtrWithCreds(tests.TestCase):
-
- def test_ctr_with_creds(self):
- db1 = http_database.HTTPDatabase('http://dbs/db', creds={'oauth': {
- 'consumer_key': tests.consumer1.key,
- 'consumer_secret': tests.consumer1.secret,
- 'token_key': tests.token1.key,
- 'token_secret': tests.token1.secret
- }})
- self.assertIn('oauth', db1._creds)
-
@skip("Skiping tests imported from U1DB.")
class TestHTTPDatabaseIntegration(tests.TestCaseWithServer):
diff --git a/testing/test_soledad/u1db_tests/test_https.py b/testing/test_soledad/u1db_tests/test_https.py
new file mode 100644
index 00000000..baffa723
--- /dev/null
+++ b/testing/test_soledad/u1db_tests/test_https.py
@@ -0,0 +1,105 @@
+"""Test support for client-side https support."""
+
+import os
+import ssl
+import sys
+
+from paste import httpserver
+from unittest import skip
+
+from leap.soledad.common.l2db.remote import http_client
+
+from leap import soledad
+from test_soledad import u1db_tests as tests
+
+
+def https_server_def():
+ def make_server(host_port, application):
+ from OpenSSL import SSL
+ cert_file = os.path.join(os.path.dirname(__file__), 'testing-certs',
+ 'testing.cert')
+ key_file = os.path.join(os.path.dirname(__file__), 'testing-certs',
+ 'testing.key')
+ ssl_context = SSL.Context(SSL.SSLv23_METHOD)
+ ssl_context.use_privatekey_file(key_file)
+ ssl_context.use_certificate_chain_file(cert_file)
+ srv = httpserver.WSGIServerBase(application, host_port,
+ httpserver.WSGIHandler,
+ ssl_context=ssl_context
+ )
+
+ def shutdown_request(req):
+ req.shutdown()
+ srv.close_request(req)
+
+ srv.shutdown_request = shutdown_request
+ application.base_url = "https://localhost:%s" % srv.server_address[1]
+ return srv
+ return make_server, "shutdown", "https"
+
+
+@skip("Skiping tests imported from U1DB.")
+class TestHttpSyncTargetHttpsSupport(tests.TestCaseWithServer):
+
+ scenarios = []
+
+ def setUp(self):
+ try:
+ import OpenSSL # noqa
+ except ImportError:
+ self.skipTest("Requires pyOpenSSL")
+ self.cacert_pem = os.path.join(os.path.dirname(__file__),
+ 'testing-certs', 'cacert.pem')
+ # The default u1db http_client class for doing HTTPS only does HTTPS
+ # if the platform is linux. Because of this, soledad replaces that
+ # class with one that will do HTTPS independent of the platform. In
+ # order to maintain the compatibility with u1db default tests, we undo
+ # that replacement here.
+ http_client._VerifiedHTTPSConnection = \
+ soledad.client.api.old__VerifiedHTTPSConnection
+ super(TestHttpSyncTargetHttpsSupport, self).setUp()
+
+ def getSyncTarget(self, host, path=None, cert_file=None):
+ if self.server is None:
+ self.startServer()
+ return self.sync_target(self, host, path, cert_file=cert_file)
+
+ def test_working(self):
+ self.startServer()
+ db = self.request_state._create_database('test')
+ self.patch(http_client, 'CA_CERTS', self.cacert_pem)
+ remote_target = self.getSyncTarget('localhost', 'test')
+ remote_target.record_sync_info('other-id', 2, 'T-id')
+ self.assertEqual(
+ (2, 'T-id'), db._get_replica_gen_and_trans_id('other-id'))
+
+ def test_cannot_verify_cert(self):
+ if not sys.platform.startswith('linux'):
+ self.skipTest(
+ "XXX certificate verification happens on linux only for now")
+ self.startServer()
+ # don't print expected traceback server-side
+ self.server.handle_error = lambda req, cli_addr: None
+ self.request_state._create_database('test')
+ remote_target = self.getSyncTarget('localhost', 'test')
+ try:
+ remote_target.record_sync_info('other-id', 2, 'T-id')
+ except ssl.SSLError, e:
+ self.assertIn("certificate verify failed", str(e))
+ else:
+ self.fail("certificate verification should have failed.")
+
+ def test_host_mismatch(self):
+ if not sys.platform.startswith('linux'):
+ self.skipTest(
+ "XXX certificate verification happens on linux only for now")
+ self.startServer()
+ self.request_state._create_database('test')
+ self.patch(http_client, 'CA_CERTS', self.cacert_pem)
+ remote_target = self.getSyncTarget('127.0.0.1', 'test')
+ self.assertRaises(
+ http_client.CertificateError, remote_target.record_sync_info,
+ 'other-id', 2, 'T-id')
+
+
+load_tests = tests.load_with_scenarios
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/test_open.py b/testing/test_soledad/u1db_tests/test_open.py
index 2fc04e38..30d4de00 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/test_open.py
+++ b/testing/test_soledad/u1db_tests/test_open.py
@@ -23,9 +23,9 @@ from unittest import skip
from leap.soledad.common.l2db import (
errors, open as u1db_open,
)
-from leap.soledad.common.tests import u1db_tests as tests
+from test_soledad import u1db_tests as tests
from leap.soledad.common.l2db.backends import sqlite_backend
-from leap.soledad.common.tests.u1db_tests.test_backends \
+from test_soledad.u1db_tests.test_backends \
import TestAlternativeDocument
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/Makefile b/testing/test_soledad/u1db_tests/testing-certs/Makefile
index 2385e75b..2385e75b 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/Makefile
+++ b/testing/test_soledad/u1db_tests/testing-certs/Makefile
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/cacert.pem b/testing/test_soledad/u1db_tests/testing-certs/cacert.pem
index c019a730..c019a730 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/cacert.pem
+++ b/testing/test_soledad/u1db_tests/testing-certs/cacert.pem
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/testing.cert b/testing/test_soledad/u1db_tests/testing-certs/testing.cert
index 985684fb..985684fb 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/testing.cert
+++ b/testing/test_soledad/u1db_tests/testing-certs/testing.cert
diff --git a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/testing.key b/testing/test_soledad/u1db_tests/testing-certs/testing.key
index d83d4920..d83d4920 100644
--- a/common/src/leap/soledad/common/tests/u1db_tests/testing-certs/testing.key
+++ b/testing/test_soledad/u1db_tests/testing-certs/testing.key
diff --git a/common/src/leap/soledad/common/tests/util.py b/testing/test_soledad/util.py
index abe531ce..f81001b9 100644
--- a/common/src/leap/soledad/common/tests/util.py
+++ b/testing/test_soledad/util.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- CODING: UTF-8 -*-
# util.py
# Copyright (C) 2013 LEAP
#
@@ -70,6 +70,10 @@ def make_local_db_and_target(test):
return db, st
+def make_document_for_test(test, doc_id, rev, content, has_conflicts=False):
+ return SoledadDocument(doc_id, rev, content, has_conflicts=has_conflicts)
+
+
def make_sqlcipher_database_for_test(test, replica_uid):
db = SQLCipherDatabase(
SQLCipherOptions(':memory:', PASSWORD))
@@ -97,6 +101,13 @@ def copy_sqlcipher_database_for_test(test, db):
return new_db
+SQLCIPHER_SCENARIOS = [
+ ('sqlcipher', {'make_database_for_test': make_sqlcipher_database_for_test,
+ 'copy_database_for_test': copy_sqlcipher_database_for_test,
+ 'make_document_for_test': make_document_for_test, }),
+]
+
+
def make_soledad_app(state):
return SoledadApp(state)
diff --git a/testing/tests/client/__init__.py b/testing/tests/client/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/testing/tests/client/__init__.py
diff --git a/common/src/leap/soledad/common/tests/hacker_crackdown.txt b/testing/tests/client/hacker_crackdown.txt
index a01eb509..a01eb509 100644
--- a/common/src/leap/soledad/common/tests/hacker_crackdown.txt
+++ b/testing/tests/client/hacker_crackdown.txt
diff --git a/common/src/leap/soledad/common/tests/test_soledad_app.py b/testing/tests/client/test_app.py
index 7f9a58d3..fef2f371 100644
--- a/common/src/leap/soledad/common/tests/test_soledad_app.py
+++ b/testing/tests/client/test_app.py
@@ -19,32 +19,22 @@ Test ObjectStore and Couch backend bits.
"""
from testscenarios import TestWithScenarios
-from leap.soledad.common.tests.util import BaseSoledadTest
-from leap.soledad.common.tests.util import make_soledad_document_for_test
-from leap.soledad.common.tests.util import make_soledad_app
-from leap.soledad.common.tests.util import make_token_soledad_app
-from leap.soledad.common.tests.util import make_token_http_database_for_test
-from leap.soledad.common.tests.util import copy_token_http_database_for_test
-from leap.soledad.common.tests.u1db_tests import test_backends
+from test_soledad.util import BaseSoledadTest
+from test_soledad.util import make_soledad_document_for_test
+from test_soledad.util import make_token_soledad_app
+from test_soledad.util import make_token_http_database_for_test
+from test_soledad.util import copy_token_http_database_for_test
+from test_soledad.u1db_tests import test_backends
# -----------------------------------------------------------------------------
# The following tests come from `u1db.tests.test_backends`.
# -----------------------------------------------------------------------------
-LEAP_SCENARIOS = [
- ('http', {
- 'make_database_for_test': test_backends.make_http_database_for_test,
- 'copy_database_for_test': test_backends.copy_http_database_for_test,
- 'make_document_for_test': make_soledad_document_for_test,
- 'make_app_with_state': make_soledad_app}),
-]
-
-
class SoledadTests(
TestWithScenarios, test_backends.AllDatabaseTests, BaseSoledadTest):
- scenarios = LEAP_SCENARIOS + [
+ scenarios = [
('token_http', {
'make_database_for_test': make_token_http_database_for_test,
'copy_database_for_test': copy_token_http_database_for_test,
diff --git a/common/src/leap/soledad/common/tests/test_async.py b/testing/tests/client/test_async.py
index 52be4ff3..2ff70864 100644
--- a/common/src/leap/soledad/common/tests/test_async.py
+++ b/testing/tests/client/test_async.py
@@ -19,7 +19,7 @@ import hashlib
from twisted.internet import defer
-from leap.soledad.common.tests.util import BaseSoledadTest
+from test_soledad.util import BaseSoledadTest
from leap.soledad.client import adbapi
from leap.soledad.client.sqlcipher import SQLCipherOptions
diff --git a/testing/tests/client/test_aux_methods.py b/testing/tests/client/test_aux_methods.py
new file mode 100644
index 00000000..c25ff8ca
--- /dev/null
+++ b/testing/tests/client/test_aux_methods.py
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+# test_soledad.py
+# Copyright (C) 2013 LEAP
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+Tests for general Soledad functionality.
+"""
+import os
+
+from twisted.internet import defer
+
+from leap.soledad.common.errors import DatabaseAccessError
+from leap.soledad.client import Soledad
+from leap.soledad.client.adbapi import U1DBConnectionPool
+from leap.soledad.client.secrets import PassphraseTooShort
+
+from test_soledad.util import BaseSoledadTest
+
+
+class AuxMethodsTestCase(BaseSoledadTest):
+
+ def test__init_dirs(self):
+ sol = self._soledad_instance(prefix='_init_dirs')
+ local_db_dir = os.path.dirname(sol.local_db_path)
+ secrets_path = os.path.dirname(sol.secrets.secrets_path)
+ self.assertTrue(os.path.isdir(local_db_dir))
+ self.assertTrue(os.path.isdir(secrets_path))
+
+ def _close_soledad(results):
+ sol.close()
+
+ d = sol.create_doc({})
+ d.addCallback(_close_soledad)
+ return d
+
+ def test__init_u1db_sqlcipher_backend(self):
+ sol = self._soledad_instance(prefix='_init_db')
+ self.assertIsInstance(sol._dbpool, U1DBConnectionPool)
+ self.assertTrue(os.path.isfile(sol.local_db_path))
+ sol.close()
+
+ def test__init_config_with_defaults(self):
+ """
+ Test if configuration defaults point to the correct place.
+ """
+
+ class SoledadMock(Soledad):
+
+ def __init__(self):
+ pass
+
+ # instantiate without initializing so we just test
+ # _init_config_with_defaults()
+ sol = SoledadMock()
+ sol._passphrase = u''
+ sol._server_url = ''
+ sol._init_config_with_defaults()
+ # assert value of local_db_path
+ self.assertEquals(
+ os.path.join(sol.default_prefix, 'soledad.u1db'),
+ sol.local_db_path)
+
+ def test__init_config_from_params(self):
+ """
+ Test if configuration is correctly read from file.
+ """
+ sol = self._soledad_instance(
+ 'leap@leap.se',
+ passphrase=u'123',
+ secrets_path='value_3',
+ local_db_path='value_2',
+ server_url='value_1',
+ cert_file=None)
+ self.assertEqual(
+ os.path.join(self.tempdir, 'value_3'),
+ sol.secrets.secrets_path)
+ self.assertEqual(
+ os.path.join(self.tempdir, 'value_2'),
+ sol.local_db_path)
+ self.assertEqual('value_1', sol._server_url)
+ sol.close()
+
+ @defer.inlineCallbacks
+ def test_change_passphrase(self):
+ """
+ Test if passphrase can be changed.
+ """
+ prefix = '_change_passphrase'
+ sol = self._soledad_instance(
+ 'leap@leap.se',
+ passphrase=u'123',
+ prefix=prefix,
+ )
+
+ doc1 = yield sol.create_doc({'simple': 'doc'})
+ sol.change_passphrase(u'654321')
+ sol.close()
+
+ with self.assertRaises(DatabaseAccessError):
+ self._soledad_instance(
+ 'leap@leap.se',
+ passphrase=u'123',
+ prefix=prefix)
+
+ sol2 = self._soledad_instance(
+ 'leap@leap.se',
+ passphrase=u'654321',
+ prefix=prefix)
+ doc2 = yield sol2.get_doc(doc1.doc_id)
+
+ self.assertEqual(doc1, doc2)
+
+ sol2.close()
+
+ def test_change_passphrase_with_short_passphrase_raises(self):
+ """
+ Test if attempt to change passphrase passing a short passphrase
+ raises.
+ """
+ sol = self._soledad_instance(
+ 'leap@leap.se',
+ passphrase=u'123')
+ # check that soledad complains about new passphrase length
+ self.assertRaises(
+ PassphraseTooShort,
+ sol.change_passphrase, u'54321')
+ sol.close()
+
+ def test_get_passphrase(self):
+ """
+ Assert passphrase getter works fine.
+ """
+ sol = self._soledad_instance()
+ self.assertEqual('123', sol._passphrase)
+ sol.close()
diff --git a/common/src/leap/soledad/common/tests/test_crypto.py b/testing/tests/client/test_crypto.py
index 5ced024b..77252b46 100644
--- a/common/src/leap/soledad/common/tests/test_crypto.py
+++ b/testing/tests/client/test_crypto.py
@@ -23,7 +23,7 @@ import binascii
from leap.soledad.client import crypto
from leap.soledad.common.document import SoledadDocument
-from leap.soledad.common.tests.util import BaseSoledadTest
+from test_soledad.util import BaseSoledadTest
from leap.soledad.common.crypto import WrongMacError
from leap.soledad.common.crypto import UnknownMacMethodError
from leap.soledad.common.crypto import ENC_JSON_KEY
diff --git a/testing/tests/client/test_doc.py b/testing/tests/client/test_doc.py
new file mode 100644
index 00000000..e158d768
--- /dev/null
+++ b/testing/tests/client/test_doc.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# test_soledad_doc.py
+# Copyright (C) 2013, 2014 LEAP
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+Test Leap backend bits: soledad docs
+"""
+from testscenarios import TestWithScenarios
+
+from test_soledad.u1db_tests import test_document
+from test_soledad.util import BaseSoledadTest
+from test_soledad.util import make_soledad_document_for_test
+
+
+# -----------------------------------------------------------------------------
+# The following tests come from `u1db.tests.test_document`.
+# -----------------------------------------------------------------------------
+
+class TestSoledadDocument(
+ TestWithScenarios,
+ test_document.TestDocument, BaseSoledadTest):
+
+ scenarios = ([(
+ 'leap', {
+ 'make_document_for_test': make_soledad_document_for_test})])
+
+
+class TestSoledadPyDocument(
+ TestWithScenarios,
+ test_document.TestPyDocument, BaseSoledadTest):
+
+ scenarios = ([(
+ 'leap', {
+ 'make_document_for_test': make_soledad_document_for_test})])
diff --git a/common/src/leap/soledad/common/tests/test_http.py b/testing/tests/client/test_http.py
index 2351748d..47df4b4a 100644
--- a/common/src/leap/soledad/common/tests/test_http.py
+++ b/testing/tests/client/test_http.py
@@ -18,8 +18,9 @@
Test Leap backend bits: test http database
"""
+from twisted.trial import unittest
+
from leap.soledad.client import auth
-from leap.soledad.common.tests.u1db_tests import test_http_database
from leap.soledad.common.l2db.remote import http_database
@@ -41,8 +42,7 @@ class _HTTPDatabase(http_database.HTTPDatabase, auth.TokenBasedAuth):
self, method, url_query, params)
-class TestHTTPDatabaseWithCreds(
- test_http_database.TestHTTPDatabaseCtrWithCreds):
+class TestHTTPDatabaseWithCreds(unittest.TestCase):
def test_get_sync_target_inherits_token_credentials(self):
# this test was from TestDatabaseSimpleOperations but we put it here
diff --git a/common/src/leap/soledad/common/tests/test_http_client.py b/testing/tests/client/test_http_client.py
index d932b2b0..a107930a 100644
--- a/common/src/leap/soledad/common/tests/test_http_client.py
+++ b/testing/tests/client/test_http_client.py
@@ -23,7 +23,7 @@ from testscenarios import TestWithScenarios
from leap.soledad.client import auth
from leap.soledad.common.l2db.remote import http_client
-from leap.soledad.common.tests.u1db_tests import test_http_client
+from test_soledad.u1db_tests import test_http_client
from leap.soledad.server.auth import SoledadTokenAuthMiddleware
@@ -39,6 +39,12 @@ class TestSoledadClientBase(
This class should be used to test Token auth.
"""
+ def getClient(self, **kwds):
+ cli = self.getClientWithToken(**kwds)
+ if 'creds' not in kwds:
+ cli.set_token_credentials('user-uuid', 'auth-token')
+ return cli
+
def getClientWithToken(self, **kwds):
self.startServer()
@@ -54,24 +60,6 @@ class TestSoledadClientBase(
return _HTTPClientWithToken(self.getURL('dbase'), **kwds)
- def test_oauth(self):
- """
- Suppress oauth test (we test for token auth here).
- """
- pass
-
- def test_oauth_ctr_creds(self):
- """
- Suppress oauth test (we test for token auth here).
- """
- pass
-
- def test_oauth_Unauthorized(self):
- """
- Suppress oauth test (we test for token auth here).
- """
- pass
-
def app(self, environ, start_response):
res = test_http_client.TestHTTPClientBase.app(
self, environ, start_response)
@@ -83,14 +71,17 @@ class TestSoledadClientBase(
if not auth:
start_response("401 Unauthorized",
[('Content-Type', 'application/json')])
- return [json.dumps({"error": "unauthorized",
- "message": e.message})]
+ return [
+ json.dumps(
+ {"error": "unauthorized",
+ "message": "no token found in environment"})
+ ]
scheme, encoded = auth.split(None, 1)
if scheme.lower() != 'token':
start_response("401 Unauthorized",
[('Content-Type', 'application/json')])
return [json.dumps({"error": "unauthorized",
- "message": e.message})]
+ "message": "unknown scheme: %s" % scheme})]
uuid, token = encoded.decode('base64').split(':', 1)
if uuid != 'user-uuid' and token != 'auth-token':
return Exception("Incorrect address or token.")
diff --git a/common/src/leap/soledad/common/tests/test_https.py b/testing/tests/client/test_https.py
index 8d9b8d92..caac16da 100644
--- a/common/src/leap/soledad/common/tests/test_https.py
+++ b/testing/tests/client/test_https.py
@@ -24,9 +24,9 @@ from testscenarios import TestWithScenarios
from leap.soledad import client
from leap.soledad.common.l2db.remote import http_client
-from leap.soledad.common.tests.u1db_tests import test_backends
-from leap.soledad.common.tests.u1db_tests import test_https
-from leap.soledad.common.tests.util import (
+from test_soledad.u1db_tests import test_backends
+from test_soledad.u1db_tests import test_https
+from test_soledad.util import (
BaseSoledadTest,
make_soledad_document_for_test,
make_soledad_app,
@@ -71,10 +71,10 @@ class TestSoledadHTTPSyncTargetHttpsSupport(
scenarios = [
('token_soledad_https',
{
- #'server_def': test_https.https_server_def,
- 'make_app_with_state': make_token_soledad_app,
- 'make_document_for_test': make_soledad_document_for_test,
- 'sync_target': token_leap_https_sync_target}),
+ # 'server_def': test_https.https_server_def,
+ 'make_app_with_state': make_token_soledad_app,
+ 'make_document_for_test': make_soledad_document_for_test,
+ 'sync_target': token_leap_https_sync_target}),
]
def setUp(self):
diff --git a/testing/tests/client/test_shared_db.py b/testing/tests/client/test_shared_db.py
new file mode 100644
index 00000000..aac766c2
--- /dev/null
+++ b/testing/tests/client/test_shared_db.py
@@ -0,0 +1,50 @@
+from leap.soledad.common.document import SoledadDocument
+from leap.soledad.client.shared_db import SoledadSharedDatabase
+
+from test_soledad.util import BaseSoledadTest
+from test_soledad.util import ADDRESS
+
+
+class SoledadSharedDBTestCase(BaseSoledadTest):
+
+ """
+ These tests ensure the functionalities of the shared recovery database.
+ """
+
+ def setUp(self):
+ BaseSoledadTest.setUp(self)
+ self._shared_db = SoledadSharedDatabase(
+ 'https://provider/', ADDRESS, document_factory=SoledadDocument,
+ creds=None)
+
+ def tearDown(self):
+ BaseSoledadTest.tearDown(self)
+
+ def test__get_secrets_from_shared_db(self):
+ """
+ Ensure the shared db is queried with the correct doc_id.
+ """
+ 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,
+ 'Wrong doc_id when fetching recovery document.')
+
+ def test__put_secrets_in_shared_db(self):
+ """
+ Ensure recovery document is put into shared recover 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,
+ 'Wrong doc_id when fetching recovery document.')
+ self.assertTrue(
+ self._soledad.shared_db.put_doc.assert_called_with(
+ self._doc_put) is None,
+ 'Wrong document when putting recovery document.')
+ self.assertTrue(
+ self._doc_put.doc_id == doc_id,
+ 'Wrong doc_id when putting recovery document.')
diff --git a/common/src/leap/soledad/common/tests/test_soledad.py b/testing/tests/client/test_signals.py
index aa52a733..4e9ebfd0 100644
--- a/common/src/leap/soledad/common/tests/test_soledad.py
+++ b/testing/tests/client/test_signals.py
@@ -1,203 +1,12 @@
-# -*- coding: utf-8 -*-
-# test_soledad.py
-# Copyright (C) 2013 LEAP
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""
-Tests for general Soledad functionality.
-"""
-import os
-
from mock import Mock
-
from twisted.internet import defer
-from leap.common.events import catalog
-from leap.soledad.common.tests.util import (
- BaseSoledadTest,
- ADDRESS,
-)
from leap import soledad
+from leap.common.events import catalog
from leap.soledad.common.document import SoledadDocument
-from leap.soledad.common.errors import DatabaseAccessError
-from leap.soledad.client import Soledad
-from leap.soledad.client.adbapi import U1DBConnectionPool
-from leap.soledad.client.secrets import PassphraseTooShort
-from leap.soledad.client.shared_db import SoledadSharedDatabase
-
-
-class AuxMethodsTestCase(BaseSoledadTest):
-
- def test__init_dirs(self):
- sol = self._soledad_instance(prefix='_init_dirs')
- local_db_dir = os.path.dirname(sol.local_db_path)
- secrets_path = os.path.dirname(sol.secrets.secrets_path)
- self.assertTrue(os.path.isdir(local_db_dir))
- self.assertTrue(os.path.isdir(secrets_path))
-
- def _close_soledad(results):
- sol.close()
-
- d = sol.create_doc({})
- d.addCallback(_close_soledad)
- return d
-
- def test__init_u1db_sqlcipher_backend(self):
- sol = self._soledad_instance(prefix='_init_db')
- self.assertIsInstance(sol._dbpool, U1DBConnectionPool)
- self.assertTrue(os.path.isfile(sol.local_db_path))
- sol.close()
-
- def test__init_config_with_defaults(self):
- """
- Test if configuration defaults point to the correct place.
- """
-
- class SoledadMock(Soledad):
-
- def __init__(self):
- pass
-
- # instantiate without initializing so we just test
- # _init_config_with_defaults()
- sol = SoledadMock()
- sol._passphrase = u''
- sol._server_url = ''
- sol._init_config_with_defaults()
- # assert value of local_db_path
- self.assertEquals(
- os.path.join(sol.default_prefix, 'soledad.u1db'),
- sol.local_db_path)
-
- def test__init_config_from_params(self):
- """
- Test if configuration is correctly read from file.
- """
- sol = self._soledad_instance(
- 'leap@leap.se',
- passphrase=u'123',
- secrets_path='value_3',
- local_db_path='value_2',
- server_url='value_1',
- cert_file=None)
- self.assertEqual(
- os.path.join(self.tempdir, 'value_3'),
- sol.secrets.secrets_path)
- self.assertEqual(
- os.path.join(self.tempdir, 'value_2'),
- sol.local_db_path)
- self.assertEqual('value_1', sol._server_url)
- sol.close()
-
- @defer.inlineCallbacks
- def test_change_passphrase(self):
- """
- Test if passphrase can be changed.
- """
- prefix = '_change_passphrase'
- sol = self._soledad_instance(
- 'leap@leap.se',
- passphrase=u'123',
- prefix=prefix,
- )
-
- doc1 = yield sol.create_doc({'simple': 'doc'})
- sol.change_passphrase(u'654321')
- sol.close()
- with self.assertRaises(DatabaseAccessError):
- self._soledad_instance(
- 'leap@leap.se',
- passphrase=u'123',
- prefix=prefix)
-
- sol2 = self._soledad_instance(
- 'leap@leap.se',
- passphrase=u'654321',
- prefix=prefix)
- doc2 = yield sol2.get_doc(doc1.doc_id)
-
- self.assertEqual(doc1, doc2)
-
- sol2.close()
-
- def test_change_passphrase_with_short_passphrase_raises(self):
- """
- Test if attempt to change passphrase passing a short passphrase
- raises.
- """
- sol = self._soledad_instance(
- 'leap@leap.se',
- passphrase=u'123')
- # check that soledad complains about new passphrase length
- self.assertRaises(
- PassphraseTooShort,
- sol.change_passphrase, u'54321')
- sol.close()
-
- def test_get_passphrase(self):
- """
- Assert passphrase getter works fine.
- """
- sol = self._soledad_instance()
- self.assertEqual('123', sol._passphrase)
- sol.close()
-
-
-class SoledadSharedDBTestCase(BaseSoledadTest):
-
- """
- These tests ensure the functionalities of the shared recovery database.
- """
-
- def setUp(self):
- BaseSoledadTest.setUp(self)
- self._shared_db = SoledadSharedDatabase(
- 'https://provider/', ADDRESS, document_factory=SoledadDocument,
- creds=None)
-
- def tearDown(self):
- BaseSoledadTest.tearDown(self)
-
- def test__get_secrets_from_shared_db(self):
- """
- Ensure the shared db is queried with the correct doc_id.
- """
- 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,
- 'Wrong doc_id when fetching recovery document.')
-
- def test__put_secrets_in_shared_db(self):
- """
- Ensure recovery document is put into shared recover 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,
- 'Wrong doc_id when fetching recovery document.')
- self.assertTrue(
- self._soledad.shared_db.put_doc.assert_called_with(
- self._doc_put) is None,
- 'Wrong document when putting recovery document.')
- self.assertTrue(
- self._doc_put.doc_id == doc_id,
- 'Wrong doc_id when putting recovery document.')
+from test_soledad.util import ADDRESS
+from test_soledad.util import BaseSoledadTest
class SoledadSignalingTestCase(BaseSoledadTest):
diff --git a/common/src/leap/soledad/common/tests/test_soledad_doc.py b/testing/tests/client/test_soledad_doc.py
index df9fd09e..e158d768 100644
--- a/common/src/leap/soledad/common/tests/test_soledad_doc.py
+++ b/testing/tests/client/test_soledad_doc.py
@@ -19,9 +19,9 @@ Test Leap backend bits: soledad docs
"""
from testscenarios import TestWithScenarios
-from leap.soledad.common.tests.u1db_tests import test_document
-from leap.soledad.common.tests.util import BaseSoledadTest
-from leap.soledad.common.tests.util import make_soledad_document_for_test
+from test_soledad.u1db_tests import test_document
+from test_soledad.util import BaseSoledadTest
+from test_soledad.util import make_soledad_document_for_test
# -----------------------------------------------------------------------------
diff --git a/common/src/leap/soledad/common/tests/test_sqlcipher.py b/testing/tests/client/test_sqlcipher.py
index 2bcdf0fb..11472d46 100644
--- a/common/src/leap/soledad/common/tests/test_sqlcipher.py
+++ b/testing/tests/client/test_sqlcipher.py
@@ -29,7 +29,8 @@ from testscenarios import TestWithScenarios
# l2db stuff.
from leap.soledad.common.l2db import errors
from leap.soledad.common.l2db import query_parser
-from leap.soledad.common.l2db.backends.sqlite_backend import SQLitePartialExpandDatabase
+from leap.soledad.common.l2db.backends.sqlite_backend \
+ import SQLitePartialExpandDatabase
# soledad stuff.
from leap.soledad.common import soledad_assert
@@ -39,13 +40,12 @@ from leap.soledad.client.sqlcipher import SQLCipherOptions
from leap.soledad.client.sqlcipher import DatabaseIsNotEncrypted
# u1db tests stuff.
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.u1db_tests import test_backends
-from leap.soledad.common.tests.u1db_tests import test_open
-from leap.soledad.common.tests.util import make_sqlcipher_database_for_test
-from leap.soledad.common.tests.util import copy_sqlcipher_database_for_test
-from leap.soledad.common.tests.util import PASSWORD
-from leap.soledad.common.tests.util import BaseSoledadTest
+from test_soledad import u1db_tests as tests
+from test_soledad.u1db_tests import test_backends
+from test_soledad.u1db_tests import test_open
+from test_soledad.util import SQLCIPHER_SCENARIOS
+from test_soledad.util import PASSWORD
+from test_soledad.util import BaseSoledadTest
def sqlcipher_open(path, passphrase, create=True, document_factory=None):
@@ -73,17 +73,6 @@ class TestSQLCipherBackendImpl(tests.TestCase):
# The following tests come from `u1db.tests.test_backends`.
# -----------------------------------------------------------------------------
-def make_document_for_test(test, doc_id, rev, content, has_conflicts=False):
- return SoledadDocument(doc_id, rev, content, has_conflicts=has_conflicts)
-
-
-SQLCIPHER_SCENARIOS = [
- ('sqlcipher', {'make_database_for_test': make_sqlcipher_database_for_test,
- 'copy_database_for_test': copy_sqlcipher_database_for_test,
- 'make_document_for_test': make_document_for_test, }),
-]
-
-
class SQLCipherTests(TestWithScenarios, test_backends.AllDatabaseTests):
scenarios = SQLCIPHER_SCENARIOS
@@ -175,11 +164,6 @@ class TestSQLCipherDatabase(tests.TestCase):
db1.close()
-class TestAlternativeDocument(SoledadDocument):
-
- """A (not very) alternative implementation of Document."""
-
-
class TestSQLCipherPartialExpandDatabase(tests.TestCase):
"""
Tests from u1db.tests.test_sqlite_backend.TestSQLitePartialExpandDatabase.
@@ -607,7 +591,7 @@ class SQLCipherOpen(test_open.TestU1DBOpen):
def test_open_with_factory(self):
db = sqlcipher_open(self.db_path, PASSWORD, create=True,
- document_factory=TestAlternativeDocument)
+ document_factory=SoledadDocument)
self.addCleanup(db.close)
doc = db.create_doc({})
self.assertTrue(isinstance(doc, SoledadDocument))
diff --git a/common/src/leap/soledad/common/tests/test_sqlcipher_sync.py b/testing/tests/client/test_sqlcipher_sync.py
index 42cfa6b7..3cbefc8b 100644
--- a/common/src/leap/soledad/common/tests/test_sqlcipher_sync.py
+++ b/testing/tests/client/test_sqlcipher_sync.py
@@ -31,13 +31,11 @@ from leap.soledad.common.crypto import ENC_SCHEME_KEY
from leap.soledad.client.crypto import decrypt_doc_dict
from leap.soledad.client.http_target import SoledadHTTPSyncTarget
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.test_sqlcipher import SQLCIPHER_SCENARIOS
-from leap.soledad.common.tests.util import make_soledad_app
-from leap.soledad.common.tests.test_sync_target import \
- SoledadDatabaseSyncTargetTests
-from leap.soledad.common.tests.util import soledad_sync_target
-from leap.soledad.common.tests.util import BaseSoledadTest
+from test_soledad import u1db_tests as tests
+from test_soledad.util import SQLCIPHER_SCENARIOS
+from test_soledad.util import make_soledad_app
+from test_soledad.util import soledad_sync_target
+from test_soledad.util import BaseSoledadTest
# -----------------------------------------------------------------------------
@@ -730,14 +728,3 @@ target_scenarios = [
'make_app_with_state': make_soledad_app,
'do_sync': sync_via_synchronizer_and_soledad}),
]
-
-
-class SQLCipherSyncTargetTests(SoledadDatabaseSyncTargetTests):
-
- # TODO: implement _set_trace_hook(_shallow) in SoledadHTTPSyncTarget so
- # skipped tests can be succesfully executed.
-
- scenarios = (tests.multiply_scenarios(SQLCIPHER_SCENARIOS,
- target_scenarios))
-
- whitebox = False
diff --git a/testing/tests/couch/__init__.py b/testing/tests/couch/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/testing/tests/couch/__init__.py
diff --git a/common/src/leap/soledad/common/tests/couchdb.ini.template b/testing/tests/couch/couchdb.ini.template
index 174d9d86..174d9d86 100644
--- a/common/src/leap/soledad/common/tests/couchdb.ini.template
+++ b/testing/tests/couch/couchdb.ini.template
diff --git a/common/src/leap/soledad/common/tests/test_couch.py b/testing/tests/couch/test_couch.py
index eefefc5d..94c6ca92 100644
--- a/common/src/leap/soledad/common/tests/test_couch.py
+++ b/testing/tests/couch/test_couch.py
@@ -36,13 +36,13 @@ from leap.soledad.common import couch
from leap.soledad.common.document import ServerDocument
from leap.soledad.common.couch import errors
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.util import CouchDBTestCase
-from leap.soledad.common.tests.util import make_local_db_and_target
-from leap.soledad.common.tests.util import sync_via_synchronizer
+from test_soledad import u1db_tests as tests
+from test_soledad.util import CouchDBTestCase
+from test_soledad.util import make_local_db_and_target
+from test_soledad.util import sync_via_synchronizer
-from leap.soledad.common.tests.u1db_tests import test_backends
-from leap.soledad.common.tests.u1db_tests import DatabaseBaseTests
+from test_soledad.u1db_tests import test_backends
+from test_soledad.u1db_tests import DatabaseBaseTests
# -----------------------------------------------------------------------------
diff --git a/common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py b/testing/tests/couch/test_couch_operations_atomicity.py
index 8cd3ae08..aec9c6cf 100644
--- a/common/src/leap/soledad/common/tests/test_couch_operations_atomicity.py
+++ b/testing/tests/couch/test_couch_operations_atomicity.py
@@ -29,13 +29,13 @@ from leap.soledad.client import Soledad
from leap.soledad.common.couch.state import CouchServerState
from leap.soledad.common.couch import CouchDatabase
-from leap.soledad.common.tests.util import (
+from test_soledad.util import (
make_token_soledad_app,
make_soledad_document_for_test,
soledad_sync_target,
)
-from leap.soledad.common.tests.test_couch import CouchDBTestCase
-from leap.soledad.common.tests.u1db_tests import TestCaseWithServer
+from test_soledad.util import CouchDBTestCase
+from test_soledad.u1db_tests import TestCaseWithServer
REPEAT_TIMES = 20
diff --git a/testing/tests/server/__init__.py b/testing/tests/server/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/testing/tests/server/__init__.py
diff --git a/common/src/leap/soledad/common/tests/test_server.py b/testing/tests/server/test_server.py
index 357027e9..b99d1939 100644
--- a/common/src/leap/soledad/common/tests/test_server.py
+++ b/testing/tests/server/test_server.py
@@ -21,7 +21,6 @@ import binascii
import mock
import os
import tempfile
-import time
from hashlib import sha512
from pkg_resources import resource_filename
@@ -33,9 +32,9 @@ from twisted.trial import unittest
from leap.soledad.common.couch.state import CouchServerState
from leap.soledad.common.couch import CouchDatabase
-from leap.soledad.common.tests.u1db_tests import TestCaseWithServer
-from leap.soledad.common.tests.test_couch import CouchDBTestCase
-from leap.soledad.common.tests.util import (
+from test_soledad.u1db_tests import TestCaseWithServer
+from test_soledad.util import CouchDBTestCase
+from test_soledad.util import (
make_token_soledad_app,
make_soledad_document_for_test,
soledad_sync_target,
@@ -507,7 +506,7 @@ class ConfigurationParsingTest(unittest.TestCase):
def test_security_values_configuration(self):
# given
- config_path = resource_filename('leap.soledad.common.tests',
+ config_path = resource_filename('test_soledad',
'fixture_soledad.conf')
# when
config = load_configuration(config_path)
@@ -521,7 +520,7 @@ class ConfigurationParsingTest(unittest.TestCase):
def test_server_values_configuration(self):
# given
- config_path = resource_filename('leap.soledad.common.tests',
+ config_path = resource_filename('test_soledad',
'fixture_soledad.conf')
# when
config = load_configuration(config_path)
diff --git a/testing/tests/sync/__init__.py b/testing/tests/sync/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/testing/tests/sync/__init__.py
diff --git a/common/src/leap/soledad/common/tests/test_encdecpool.py b/testing/tests/sync/test_encdecpool.py
index c626561d..82e99a47 100644
--- a/common/src/leap/soledad/common/tests/test_encdecpool.py
+++ b/testing/tests/sync/test_encdecpool.py
@@ -27,7 +27,7 @@ from leap.soledad.client.encdecpool import SyncEncrypterPool
from leap.soledad.client.encdecpool import SyncDecrypterPool
from leap.soledad.common.document import SoledadDocument
-from leap.soledad.common.tests.util import BaseSoledadTest
+from test_soledad.util import BaseSoledadTest
from twisted.internet import defer
from twisted.test.proto_helpers import MemoryReactorClock
diff --git a/common/src/leap/soledad/common/tests/test_sync.py b/testing/tests/sync/test_sync.py
index cc18d387..095884ce 100644
--- a/common/src/leap/soledad/common/tests/test_sync.py
+++ b/testing/tests/sync/test_sync.py
@@ -27,15 +27,15 @@ from testscenarios import TestWithScenarios
from leap.soledad.common import couch
from leap.soledad.client import sync
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.u1db_tests import TestCaseWithServer
-from leap.soledad.common.tests.u1db_tests import simple_doc
-from leap.soledad.common.tests.util import make_token_soledad_app
-from leap.soledad.common.tests.util import make_soledad_document_for_test
-from leap.soledad.common.tests.util import soledad_sync_target
-from leap.soledad.common.tests.util import BaseSoledadTest
-from leap.soledad.common.tests.util import SoledadWithCouchServerMixin
-from leap.soledad.common.tests.test_couch import CouchDBTestCase
+from test_soledad import u1db_tests as tests
+from test_soledad.u1db_tests import TestCaseWithServer
+from test_soledad.u1db_tests import simple_doc
+from test_soledad.util import make_token_soledad_app
+from test_soledad.util import make_soledad_document_for_test
+from test_soledad.util import soledad_sync_target
+from test_soledad.util import BaseSoledadTest
+from test_soledad.util import SoledadWithCouchServerMixin
+from test_soledad.util import CouchDBTestCase
class InterruptableSyncTestCase(
diff --git a/common/src/leap/soledad/common/tests/test_sync_deferred.py b/testing/tests/sync/test_sync_deferred.py
index c62bd156..4948aaf8 100644
--- a/common/src/leap/soledad/common/tests/test_sync_deferred.py
+++ b/testing/tests/sync/test_sync_deferred.py
@@ -34,11 +34,11 @@ from leap.soledad.client.sqlcipher import SQLCipherDatabase
from testscenarios import TestWithScenarios
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.util import ADDRESS
-from leap.soledad.common.tests.util import SoledadWithCouchServerMixin
-from leap.soledad.common.tests.util import make_soledad_app
-from leap.soledad.common.tests.util import soledad_sync_target
+from test_soledad import u1db_tests as tests
+from test_soledad.util import ADDRESS
+from test_soledad.util import SoledadWithCouchServerMixin
+from test_soledad.util import make_soledad_app
+from test_soledad.util import soledad_sync_target
# Just to make clear how this test is different... :)
diff --git a/common/src/leap/soledad/common/tests/test_sync_mutex.py b/testing/tests/sync/test_sync_mutex.py
index 973a8587..787cfee8 100644
--- a/common/src/leap/soledad/common/tests/test_sync_mutex.py
+++ b/testing/tests/sync/test_sync_mutex.py
@@ -35,13 +35,13 @@ from leap.soledad.client.sync import SoledadSynchronizer
from leap.soledad.common.couch.state import CouchServerState
from leap.soledad.common.couch import CouchDatabase
-from leap.soledad.common.tests.u1db_tests import TestCaseWithServer
-from leap.soledad.common.tests.test_couch import CouchDBTestCase
+from test_soledad.u1db_tests import TestCaseWithServer
-from leap.soledad.common.tests.util import BaseSoledadTest
-from leap.soledad.common.tests.util import make_token_soledad_app
-from leap.soledad.common.tests.util import make_soledad_document_for_test
-from leap.soledad.common.tests.util import soledad_sync_target
+from test_soledad.util import CouchDBTestCase
+from test_soledad.util import BaseSoledadTest
+from test_soledad.util import make_token_soledad_app
+from test_soledad.util import make_soledad_document_for_test
+from test_soledad.util import soledad_sync_target
# monkey-patch the soledad synchronizer so it stores start and finish times
diff --git a/common/src/leap/soledad/common/tests/test_sync_target.py b/testing/tests/sync/test_sync_target.py
index c9b705a3..964468ce 100644
--- a/common/src/leap/soledad/common/tests/test_sync_target.py
+++ b/testing/tests/sync/test_sync_target.py
@@ -38,14 +38,15 @@ from leap.soledad.client.sqlcipher import SQLCipherDatabase
from leap.soledad.common import l2db
from leap.soledad.common.document import SoledadDocument
-from leap.soledad.common.tests import u1db_tests as tests
-from leap.soledad.common.tests.util import make_sqlcipher_database_for_test
-from leap.soledad.common.tests.util import make_soledad_app
-from leap.soledad.common.tests.util import make_token_soledad_app
-from leap.soledad.common.tests.util import make_soledad_document_for_test
-from leap.soledad.common.tests.util import soledad_sync_target
-from leap.soledad.common.tests.util import SoledadWithCouchServerMixin
-from leap.soledad.common.tests.util import ADDRESS
+from test_soledad import u1db_tests as tests
+from test_soledad.util import make_sqlcipher_database_for_test
+from test_soledad.util import make_soledad_app
+from test_soledad.util import make_token_soledad_app
+from test_soledad.util import make_soledad_document_for_test
+from test_soledad.util import soledad_sync_target
+from test_soledad.util import SoledadWithCouchServerMixin
+from test_soledad.util import ADDRESS
+from test_soledad.util import SQLCIPHER_SCENARIOS
# -----------------------------------------------------------------------------
@@ -954,3 +955,14 @@ class TestSoledadDbSync(
d.addCallback(_assert_successful_sync)
return d
+
+
+class SQLCipherSyncTargetTests(SoledadDatabaseSyncTargetTests):
+
+ # TODO: implement _set_trace_hook(_shallow) in SoledadHTTPSyncTarget so
+ # skipped tests can be succesfully executed.
+
+ scenarios = (tests.multiply_scenarios(SQLCIPHER_SCENARIOS,
+ target_scenarios))
+
+ whitebox = False
diff --git a/testing/tox.ini b/testing/tox.ini
new file mode 100644
index 00000000..0a8dda9d
--- /dev/null
+++ b/testing/tox.ini
@@ -0,0 +1,21 @@
+[tox]
+envlist = py27
+
+[testenv]
+commands = py.test {posargs}
+changedir = tests
+deps =
+ pytest
+ mock
+ testscenarios
+ setuptools-trial
+ pep8
+ pdbpp
+ couchdb
+# install soledad local packages
+ -e../common
+ -e../client
+ -e../server
+setenv =
+ HOME=/tmp
+install_command = pip install {opts} {packages}