diff options
| -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} | 
