summaryrefslogtreecommitdiff
path: root/testing/tests/couch
diff options
context:
space:
mode:
Diffstat (limited to 'testing/tests/couch')
-rw-r--r--testing/tests/couch/common.py16
-rw-r--r--testing/tests/couch/conftest.py31
-rw-r--r--testing/tests/couch/couchdb.ini.template22
-rw-r--r--testing/tests/couch/test_atomicity.py7
-rw-r--r--testing/tests/couch/test_backend.py8
-rw-r--r--testing/tests/couch/test_command.py10
-rw-r--r--testing/tests/couch/test_ddocs.py157
-rw-r--r--testing/tests/couch/test_state.py25
8 files changed, 76 insertions, 200 deletions
diff --git a/testing/tests/couch/common.py b/testing/tests/couch/common.py
index b08e1fa3..84790059 100644
--- a/testing/tests/couch/common.py
+++ b/testing/tests/couch/common.py
@@ -13,20 +13,17 @@ nested_doc = tests.nested_doc
def make_couch_database_for_test(test, replica_uid):
- port = str(test.couch_port)
dbname = ('test-%s' % uuid4().hex)
db = couch.CouchDatabase.open_database(
- urljoin('http://localhost:' + port, dbname),
+ urljoin(test.couch_url, dbname),
create=True,
- replica_uid=replica_uid or 'test',
- ensure_ddocs=True)
+ replica_uid=replica_uid or 'test')
test.addCleanup(test.delete_db, dbname)
return db
def copy_couch_database_for_test(test, db):
- port = str(test.couch_port)
- couch_url = 'http://localhost:' + port
+ couch_url = test.couch_url
new_dbname = db._dbname + '_copy'
new_db = couch.CouchDatabase.open_database(
urljoin(couch_url, new_dbname),
@@ -41,15 +38,10 @@ def copy_couch_database_for_test(test, db):
# bypass u1db_config document
if doc_id == 'u1db_config':
pass
- # copy design docs
- elif doc_id.startswith('_design'):
- del doc['_rev']
- new_couch_db.save(doc)
# copy u1db docs
elif 'u1db_rev' in doc:
new_doc = {
'_id': doc['_id'],
- 'u1db_transactions': doc['u1db_transactions'],
'u1db_rev': doc['u1db_rev']
}
attachments = []
@@ -65,6 +57,8 @@ def copy_couch_database_for_test(test, db):
if (att is not None):
new_couch_db.put_attachment(new_doc, att,
filename=att_name)
+ elif doc_id.startswith('gen-'):
+ new_couch_db.save(doc)
# cleanup connections to prevent file descriptor leaking
return new_db
diff --git a/testing/tests/couch/conftest.py b/testing/tests/couch/conftest.py
new file mode 100644
index 00000000..1074f091
--- /dev/null
+++ b/testing/tests/couch/conftest.py
@@ -0,0 +1,31 @@
+import couchdb
+import pytest
+import random
+import string
+
+
+@pytest.fixture
+def random_name():
+ return 'user-' + ''.join(
+ random.choice(
+ string.ascii_lowercase) for _ in range(10))
+
+
+class RandomDatabase(object):
+
+ def __init__(self, couch_url, name):
+ self.couch_url = couch_url
+ self.name = name
+ self.server = couchdb.client.Server(couch_url)
+ self.database = self.server.create(name)
+
+ def teardown(self):
+ self.server.delete(self.name)
+
+
+@pytest.fixture
+def db(random_name, request):
+ couch_url = request.config.getoption('--couch-url')
+ db = RandomDatabase(couch_url, random_name)
+ request.addfinalizer(db.teardown)
+ return db
diff --git a/testing/tests/couch/couchdb.ini.template b/testing/tests/couch/couchdb.ini.template
deleted file mode 100644
index 174d9d86..00000000
--- a/testing/tests/couch/couchdb.ini.template
+++ /dev/null
@@ -1,22 +0,0 @@
-; etc/couchdb/default.ini.tpl. Generated from default.ini.tpl.in by configure.
-
-; Upgrading CouchDB will overwrite this file.
-
-[couchdb]
-database_dir = %(tempdir)s/lib
-view_index_dir = %(tempdir)s/lib
-max_document_size = 4294967296 ; 4 GB
-os_process_timeout = 120000 ; 120 seconds. for view and external servers.
-max_dbs_open = 100
-delayed_commits = true ; set this to false to ensure an fsync before 201 Created is returned
-uri_file = %(tempdir)s/lib/couch.uri
-file_compression = snappy
-
-[log]
-file = %(tempdir)s/log/couch.log
-level = info
-include_sasl = true
-
-[httpd]
-port = 0
-bind_address = 127.0.0.1
diff --git a/testing/tests/couch/test_atomicity.py b/testing/tests/couch/test_atomicity.py
index aec9c6cf..a3ae0314 100644
--- a/testing/tests/couch/test_atomicity.py
+++ b/testing/tests/couch/test_atomicity.py
@@ -18,7 +18,7 @@
Test atomicity of couch operations.
"""
import os
-import tempfile
+import pytest
import threading
from urlparse import urljoin
@@ -41,6 +41,7 @@ from test_soledad.u1db_tests import TestCaseWithServer
REPEAT_TIMES = 20
+@pytest.mark.usefixtures('method_tmpdir')
class CouchAtomicityTestCase(CouchDBTestCase, TestCaseWithServer):
@staticmethod
@@ -90,9 +91,7 @@ class CouchAtomicityTestCase(CouchDBTestCase, TestCaseWithServer):
self.db = CouchDatabase.open_database(
urljoin(self.couch_url, 'user-' + self.user),
create=True,
- replica_uid='replica',
- ensure_ddocs=True)
- self.tempdir = tempfile.mkdtemp(prefix="leap_tests-")
+ replica_uid='replica')
self.startTwistedServer()
def tearDown(self):
diff --git a/testing/tests/couch/test_backend.py b/testing/tests/couch/test_backend.py
index f178e8a5..4fad11cf 100644
--- a/testing/tests/couch/test_backend.py
+++ b/testing/tests/couch/test_backend.py
@@ -39,12 +39,8 @@ class TestCouchBackendImpl(CouchDBTestCase):
def test__allocate_doc_id(self):
db = couch.CouchDatabase.open_database(
- urljoin(
- 'http://localhost:' + str(self.couch_port),
- ('test-%s' % uuid4().hex)
- ),
- create=True,
- ensure_ddocs=True)
+ urljoin(self.couch_url, 'test-%s' % uuid4().hex),
+ create=True)
doc_id1 = db._allocate_doc_id()
self.assertTrue(doc_id1.startswith('D-'))
self.assertEqual(34, len(doc_id1))
diff --git a/testing/tests/couch/test_command.py b/testing/tests/couch/test_command.py
index f61e118d..68097fb1 100644
--- a/testing/tests/couch/test_command.py
+++ b/testing/tests/couch/test_command.py
@@ -1,6 +1,6 @@
from twisted.trial import unittest
-from leap.soledad.common import couch
+from leap.soledad.common.couch import state as couch_state
from leap.soledad.common.l2db import errors as u1db_errors
from mock import Mock
@@ -9,7 +9,8 @@ from mock import Mock
class CommandBasedDBCreationTest(unittest.TestCase):
def test_ensure_db_using_custom_command(self):
- state = couch.state.CouchServerState("url", create_cmd="echo")
+ state = couch_state.CouchServerState(
+ "url", create_cmd="/bin/echo", check_schema_versions=False)
mock_db = Mock()
mock_db.replica_uid = 'replica_uid'
state.open_database = Mock(return_value=mock_db)
@@ -18,11 +19,12 @@ class CommandBasedDBCreationTest(unittest.TestCase):
self.assertEquals(mock_db.replica_uid, replica_uid)
def test_raises_unauthorized_on_failure(self):
- state = couch.state.CouchServerState("url", create_cmd="inexistent")
+ state = couch_state.CouchServerState(
+ "url", create_cmd="inexistent", check_schema_versions=False)
self.assertRaises(u1db_errors.Unauthorized,
state.ensure_database, "user-1337")
def test_raises_unauthorized_by_default(self):
- state = couch.state.CouchServerState("url")
+ state = couch_state.CouchServerState("url", check_schema_versions=False)
self.assertRaises(u1db_errors.Unauthorized,
state.ensure_database, "user-1337")
diff --git a/testing/tests/couch/test_ddocs.py b/testing/tests/couch/test_ddocs.py
index 9ff32633..3937f2de 100644
--- a/testing/tests/couch/test_ddocs.py
+++ b/testing/tests/couch/test_ddocs.py
@@ -1,6 +1,5 @@
from uuid import uuid4
-from leap.soledad.common.couch import errors
from leap.soledad.common import couch
from test_soledad.util import CouchDBTestCase
@@ -10,174 +9,27 @@ class CouchDesignDocsTests(CouchDBTestCase):
def setUp(self):
CouchDBTestCase.setUp(self)
+ self.create_db()
- def create_db(self, ensure=True, dbname=None):
+ def create_db(self, dbname=None):
if not dbname:
dbname = ('test-%s' % uuid4().hex)
if dbname not in self.couch_server:
self.couch_server.create(dbname)
self.db = couch.CouchDatabase(
- ('http://127.0.0.1:%d' % self.couch_port),
- dbname,
- ensure_ddocs=ensure)
+ (self.couch_url),
+ dbname)
def tearDown(self):
self.db.delete_database()
self.db.close()
CouchDBTestCase.tearDown(self)
- def test_missing_design_doc_raises(self):
- """
- Test that all methods that access design documents will raise if the
- design docs are not present.
- """
- self.create_db(ensure=False)
- # get_generation_info()
- self.assertRaises(
- errors.MissingDesignDocError,
- self.db.get_generation_info)
- # get_trans_id_for_gen()
- self.assertRaises(
- errors.MissingDesignDocError,
- self.db.get_trans_id_for_gen, 1)
- # get_transaction_log()
- self.assertRaises(
- errors.MissingDesignDocError,
- self.db.get_transaction_log)
- # whats_changed()
- self.assertRaises(
- errors.MissingDesignDocError,
- self.db.whats_changed)
-
- def test_missing_design_doc_functions_raises(self):
- """
- Test that all methods that access design documents list functions
- will raise if the functions are not present.
- """
- self.create_db(ensure=True)
- # erase views from _design/transactions
- transactions = self.db._database['_design/transactions']
- transactions['lists'] = {}
- self.db._database.save(transactions)
- # get_generation_info()
- self.assertRaises(
- errors.MissingDesignDocListFunctionError,
- self.db.get_generation_info)
- # get_trans_id_for_gen()
- self.assertRaises(
- errors.MissingDesignDocListFunctionError,
- self.db.get_trans_id_for_gen, 1)
- # whats_changed()
- self.assertRaises(
- errors.MissingDesignDocListFunctionError,
- self.db.whats_changed)
-
- def test_absent_design_doc_functions_raises(self):
- """
- Test that all methods that access design documents list functions
- will raise if the functions are not present.
- """
- self.create_db(ensure=True)
- # erase views from _design/transactions
- transactions = self.db._database['_design/transactions']
- del transactions['lists']
- self.db._database.save(transactions)
- # get_generation_info()
- self.assertRaises(
- errors.MissingDesignDocListFunctionError,
- self.db.get_generation_info)
- # _get_trans_id_for_gen()
- self.assertRaises(
- errors.MissingDesignDocListFunctionError,
- self.db.get_trans_id_for_gen, 1)
- # whats_changed()
- self.assertRaises(
- errors.MissingDesignDocListFunctionError,
- self.db.whats_changed)
-
- def test_missing_design_doc_named_views_raises(self):
- """
- Test that all methods that access design documents' named views will
- raise if the views are not present.
- """
- self.create_db(ensure=True)
- # erase views from _design/docs
- docs = self.db._database['_design/docs']
- del docs['views']
- self.db._database.save(docs)
- # erase views from _design/syncs
- syncs = self.db._database['_design/syncs']
- del syncs['views']
- self.db._database.save(syncs)
- # erase views from _design/transactions
- transactions = self.db._database['_design/transactions']
- del transactions['views']
- self.db._database.save(transactions)
- # get_generation_info()
- self.assertRaises(
- errors.MissingDesignDocNamedViewError,
- self.db.get_generation_info)
- # _get_trans_id_for_gen()
- self.assertRaises(
- errors.MissingDesignDocNamedViewError,
- self.db.get_trans_id_for_gen, 1)
- # _get_transaction_log()
- self.assertRaises(
- errors.MissingDesignDocNamedViewError,
- self.db.get_transaction_log)
- # whats_changed()
- self.assertRaises(
- errors.MissingDesignDocNamedViewError,
- self.db.whats_changed)
-
- def test_deleted_design_doc_raises(self):
- """
- Test that all methods that access design documents will raise if the
- design docs are not present.
- """
- self.create_db(ensure=True)
- # delete _design/docs
- del self.db._database['_design/docs']
- # delete _design/syncs
- del self.db._database['_design/syncs']
- # delete _design/transactions
- del self.db._database['_design/transactions']
- # get_generation_info()
- self.assertRaises(
- errors.MissingDesignDocDeletedError,
- self.db.get_generation_info)
- # get_trans_id_for_gen()
- self.assertRaises(
- errors.MissingDesignDocDeletedError,
- self.db.get_trans_id_for_gen, 1)
- # get_transaction_log()
- self.assertRaises(
- errors.MissingDesignDocDeletedError,
- self.db.get_transaction_log)
- # whats_changed()
- self.assertRaises(
- errors.MissingDesignDocDeletedError,
- self.db.whats_changed)
-
- def test_ensure_ddoc_independently(self):
- """
- Test that a missing ddocs other than _design/docs will be ensured
- even if _design/docs is there.
- """
- self.create_db(ensure=True)
- del self.db._database['_design/transactions']
- self.assertRaises(
- errors.MissingDesignDocDeletedError,
- self.db.get_transaction_log)
- self.create_db(ensure=True, dbname=self.db._dbname)
- self.db.get_transaction_log()
-
def test_ensure_security_doc(self):
"""
Ensure_security creates a _security ddoc to ensure that only soledad
will have the lowest privileged access to an user db.
"""
- self.create_db(ensure=False)
self.assertFalse(self.db._database.resource.get_json('_security')[2])
self.db.ensure_security_ddoc()
security_ddoc = self.db._database.resource.get_json('_security')[2]
@@ -190,7 +42,6 @@ class CouchDesignDocsTests(CouchDBTestCase):
"""
Given a configuration, follow it to create the security document
"""
- self.create_db(ensure=False)
configuration = {'members': ['user1', 'user2'],
'members_roles': ['role1', 'role2'],
'admins': ['admin'],
diff --git a/testing/tests/couch/test_state.py b/testing/tests/couch/test_state.py
new file mode 100644
index 00000000..e293b5b8
--- /dev/null
+++ b/testing/tests/couch/test_state.py
@@ -0,0 +1,25 @@
+import pytest
+
+from leap.soledad.common.couch import CONFIG_DOC_ID
+from leap.soledad.common.couch import SCHEMA_VERSION
+from leap.soledad.common.couch import SCHEMA_VERSION_KEY
+from leap.soledad.common.couch.state import CouchServerState
+
+from leap.soledad.common.errors import WrongCouchSchemaVersionError
+from leap.soledad.common.errors import MissingCouchConfigDocumentError
+
+
+def test_wrong_couch_version_raises(db):
+ wrong_schema_version = SCHEMA_VERSION + 1
+ db.database.create(
+ {'_id': CONFIG_DOC_ID, SCHEMA_VERSION_KEY: wrong_schema_version})
+ with pytest.raises(WrongCouchSchemaVersionError):
+ CouchServerState(db.couch_url, create_cmd='/bin/echo',
+ check_schema_versions=True)
+
+
+def test_missing_config_doc_raises(db):
+ db.database.create({})
+ with pytest.raises(MissingCouchConfigDocumentError):
+ CouchServerState(db.couch_url, create_cmd='/bin/echo',
+ check_schema_versions=True)