diff options
author | drebs <drebs@leap.se> | 2016-07-07 11:44:01 +0200 |
---|---|---|
committer | Kali Kaneko <kali@leap.se> | 2016-07-12 03:09:27 +0200 |
commit | 26f87181f8a8fc7fef58ddd1e52cb5f0edd641bb (patch) | |
tree | 899c0a7ec979f60073f87af3732edc2eac811044 | |
parent | b3fb215860a8e50e4a6c551fef78628acdbf25c7 (diff) |
[test] toxify tests
- move tests to root directory
- split tests in different subdirectories
- setup a small package with common test dependencies in /testing/test_soledad
- add tox.ini that will:
- install the test_soledad package and other test dependencies
- install soledad common, client, server from the repository
- run tests contianed in /testing/tests directory using pytest
This commit also removes all oauth code from tests, as we have removed the
u1db dependency (by importing it into the repo and naming it l2db) and don't
neet oauth at all right now.
-rw-r--r-- | common/src/leap/soledad/common/tests/server_state.py | 81 | ||||
-rw-r--r-- | common/src/leap/soledad/common/tests/u1db_tests/test_https.py | 114 | ||||
-rw-r--r-- | testing/setup.py | 9 | ||||
-rw-r--r-- | testing/test_soledad/__init__.py | 5 | ||||
-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.py | 105 | ||||
-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__.py | 0 | ||||
-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.py | 147 | ||||
-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.py | 46 | ||||
-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.py | 50 | ||||
-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__.py | 0 | ||||
-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__.py | 0 | ||||
-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__.py | 0 | ||||
-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.ini | 21 |
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} |