summaryrefslogtreecommitdiff
path: root/common/src/leap/soledad/common/tests/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/leap/soledad/common/tests/util.py')
-rw-r--r--common/src/leap/soledad/common/tests/util.py177
1 files changed, 177 insertions, 0 deletions
diff --git a/common/src/leap/soledad/common/tests/util.py b/common/src/leap/soledad/common/tests/util.py
new file mode 100644
index 00000000..249cbdaa
--- /dev/null
+++ b/common/src/leap/soledad/common/tests/util.py
@@ -0,0 +1,177 @@
+# -*- coding: utf-8 -*-
+# util.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/>.
+
+
+"""
+Utilities used by multiple test suites.
+"""
+
+
+import tempfile
+import shutil
+from urlparse import urljoin
+
+from StringIO import StringIO
+from pysqlcipher import dbapi2
+from u1db.errors import DatabaseDoesNotExist
+
+
+from leap.soledad.common import soledad_assert
+from leap.soledad.common.couch import CouchDatabase, CouchServerState
+from leap.soledad.server import SoledadApp
+from leap.soledad.server.auth import SoledadTokenAuthMiddleware
+
+
+from leap.soledad.common.tests import u1db_tests as tests, BaseSoledadTest
+from leap.soledad.common.tests.test_couch import CouchDBWrapper, CouchDBTestCase
+
+
+from leap.soledad.client.sqlcipher import SQLCipherDatabase
+
+
+PASSWORD = '123456'
+
+
+def make_sqlcipher_database_for_test(test, replica_uid):
+ db = SQLCipherDatabase(':memory:', PASSWORD)
+ db._set_replica_uid(replica_uid)
+ return db
+
+
+def copy_sqlcipher_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.
+ new_db = SQLCipherDatabase(':memory:', PASSWORD)
+ tmpfile = StringIO()
+ for line in db._db_handle.iterdump():
+ if not 'sqlite_sequence' in line: # work around bug in iterdump
+ tmpfile.write('%s\n' % line)
+ tmpfile.seek(0)
+ new_db._db_handle = dbapi2.connect(':memory:')
+ new_db._db_handle.cursor().executescript(tmpfile.read())
+ new_db._db_handle.commit()
+ new_db._set_replica_uid(db._replica_uid)
+ new_db._factory = db._factory
+ return new_db
+
+
+def make_soledad_app(state):
+ return SoledadApp(state)
+
+
+def make_token_soledad_app(state):
+ app = SoledadApp(state)
+
+ def _verify_authentication_data(uuid, auth_data):
+ if uuid == 'user-uuid' and auth_data == 'auth-token':
+ return True
+ return False
+
+ # we test for action authorization in leap.soledad.common.tests.test_server
+ def _verify_authorization(uuid, environ):
+ return True
+
+ application = SoledadTokenAuthMiddleware(app)
+ application._verify_authentication_data = _verify_authentication_data
+ application._verify_authorization = _verify_authorization
+ return application
+
+
+class CouchServerStateForTests(CouchServerState):
+ """
+ This is a slightly modified CouchDB server state that allows for creating
+ a database.
+
+ Ordinarily, the CouchDB server state does not allow some operations,
+ because for security purposes the Soledad Server should not even have
+ enough permissions to perform them. For tests, we allow database creation,
+ otherwise we'd have to create those databases in setUp/tearDown methods,
+ which is less pleasant than allowing the db to be automatically created.
+ """
+
+ def _create_database(self, dbname):
+ return CouchDatabase.open_database(
+ urljoin(self._couch_url, dbname),
+ True,
+ replica_uid=dbname,
+ ensure_ddocs=True)
+
+ def ensure_database(self, dbname):
+ db = self._create_database(dbname)
+ return db, db.replica_uid
+
+
+class SoledadWithCouchServerMixin(
+ BaseSoledadTest,
+ CouchDBTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ """
+ Make sure we have a CouchDB instance for a test.
+ """
+ # from BaseLeapTest
+ cls.tempdir = tempfile.mkdtemp(prefix="leap_tests-")
+ # from CouchDBTestCase
+ cls.wrapper = CouchDBWrapper()
+ cls.wrapper.start()
+ #self.db = self.wrapper.db
+
+ @classmethod
+ def tearDownClass(cls):
+ """
+ Stop CouchDB instance for test.
+ """
+ # from BaseLeapTest
+ soledad_assert(
+ cls.tempdir.startswith('/tmp/leap_tests-'),
+ "beware! tried to remove a dir which does not "
+ "live in temporal folder!")
+ shutil.rmtree(cls.tempdir)
+ # from CouchDBTestCase
+ cls.wrapper.stop()
+
+ def setUp(self):
+ BaseSoledadTest.setUp(self)
+ CouchDBTestCase.setUp(self)
+ main_test_class = getattr(self, 'main_test_class', None)
+ if main_test_class is not None:
+ main_test_class.setUp(self)
+ self._couch_url = 'http://localhost:%d' % self.wrapper.port
+
+ def tearDown(self):
+ BaseSoledadTest.tearDown(self)
+ CouchDBTestCase.tearDown(self)
+ main_test_class = getattr(self, 'main_test_class', None)
+ if main_test_class is not None:
+ main_test_class.tearDown(self)
+ # delete the test database
+ try:
+ db = CouchDatabase(self._couch_url, 'test')
+ db.delete_database()
+ except DatabaseDoesNotExist:
+ pass
+
+ def make_app(self):
+ couch_url = urljoin(
+ 'http://localhost:' + str(self.wrapper.port), 'tests')
+ self.request_state = CouchServerStateForTests(
+ couch_url, 'shared', 'tokens')
+ return self.make_app_with_state(self.request_state)