From 8dcdeb222fc7adbb35e46825430dc611fa58b9b0 Mon Sep 17 00:00:00 2001
From: drebs <drebs@leap.se>
Date: Sat, 3 Sep 2016 16:18:54 -0300
Subject: [PATCH] [feat] allow bypassing schema verification for tests

---
 common/src/leap/soledad/common/couch/__init__.py |  1 +
 common/src/leap/soledad/common/couch/state.py    |  8 ++++++--
 server/src/leap/soledad/server/__init__.py       |  8 +++++---
 testing/test_soledad/util.py                     |  3 ++-
 testing/tests/client/test_app.py                 |  5 +++++
 testing/tests/couch/test_atomicity.py            |  9 ++++++++-
 testing/tests/couch/test_command.py              | 14 +++++++++++---
 testing/tests/server/test_server.py              | 11 +++++++++--
 testing/tests/sync/test_encdecpool.py            |  5 +++++
 testing/tests/sync/test_sync.py                  |  4 ++++
 testing/tests/sync/test_sync_mutex.py            | 11 ++++++++---
 testing/tests/sync/test_sync_target.py           |  4 ++++
 12 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/common/src/leap/soledad/common/couch/__init__.py b/common/src/leap/soledad/common/couch/__init__.py
index 4d0a80b6..3702fb97 100644
--- a/common/src/leap/soledad/common/couch/__init__.py
+++ b/common/src/leap/soledad/common/couch/__init__.py
@@ -53,6 +53,7 @@ from leap.soledad.common.backend import SoledadBackend
 
 
 COUCH_TIMEOUT = 120  # timeout for transfers between Soledad server and Couch
+VERIFY_SCHEMA_VERSION = True  # allow bypassing verification (for tests)
 
 
 def list_users_dbs(couch_url):
diff --git a/common/src/leap/soledad/common/couch/state.py b/common/src/leap/soledad/common/couch/state.py
index 66dd0ca4..33d54560 100644
--- a/common/src/leap/soledad/common/couch/state.py
+++ b/common/src/leap/soledad/common/couch/state.py
@@ -62,7 +62,7 @@ class CouchServerState(ServerState):
     TOKENS_TYPE_DEF = "Token"
     TOKENS_USER_ID_KEY = "user_id"
 
-    def __init__(self, couch_url, create_cmd=None):
+    def __init__(self, couch_url, create_cmd=None, verify_schema_version=True):
         """
         Initialize the couch server state.
 
@@ -71,7 +71,11 @@ class CouchServerState(ServerState):
         """
         self.couch_url = couch_url
         self.create_cmd = create_cmd
-        current_version = get_couch_schema_version(couch_url)
+        if verify_schema_version:
+            self._verify_schema_version()
+
+    def _verify_schema_version(self):
+        current_version = get_couch_schema_version(self.couch_url)
         if current_version != SCHEMA_VERSION:
             raise WrongCouchSchemaVersionError(
                 expected_version=SCHEMA_VERSION,
diff --git a/server/src/leap/soledad/server/__init__.py b/server/src/leap/soledad/server/__init__.py
index c5dcdc88..70284771 100644
--- a/server/src/leap/soledad/server/__init__.py
+++ b/server/src/leap/soledad/server/__init__.py
@@ -98,6 +98,7 @@ from leap.soledad.server.sync import (
 from leap.soledad.common import SHARED_DB_NAME
 from leap.soledad.common.backend import SoledadBackend
 from leap.soledad.common.couch import WrongCouchSchemaVersionError
+from leap.soledad.common.couch import VERIFY_SCHEMA_VERSION
 from leap.soledad.common.couch.state import CouchServerState
 
 from ._version import get_versions
@@ -315,11 +316,12 @@ def _load_config():
     return conf['soledad-server']
 
 
-def _get_couch_state():
+def _get_couch_state(verify_schema_version=True):
     conf = _load_config()
     try:
         state = CouchServerState(
-            conf['couch_url'], create_cmd=conf['create_cmd'])
+            conf['couch_url'], create_cmd=conf['create_cmd'],
+            verify_schema_version=verify_schema_version)
         SoledadBackend.BATCH_SUPPORT = conf.get('batching', False)
         return state
     except WrongCouchSchemaVersionError as e:
@@ -329,7 +331,7 @@ def _get_couch_state():
         exit(1)
 
 
-_couch_state = _get_couch_state()
+_couch_state = _get_couch_state(verify_schema_version=VERIFY_SCHEMA_VERSION)
 
 # a WSGI application that may be used by `twistd -web`
 application = GzipMiddleware(
diff --git a/testing/test_soledad/util.py b/testing/test_soledad/util.py
index e23d185e..53fcb473 100644
--- a/testing/test_soledad/util.py
+++ b/testing/test_soledad/util.py
@@ -381,7 +381,8 @@ class CouchServerStateForTests(CouchServerState):
 
     def __init__(self, *args, **kwargs):
         self.dbs = []
-        super(CouchServerStateForTests, self).__init__(*args, **kwargs)
+        super(CouchServerStateForTests, self).__init__(
+            *args, verify_schema_version=False, **kwargs)
 
     def _create_database(self, replica_uid=None, dbname=None):
         """
diff --git a/testing/tests/client/test_app.py b/testing/tests/client/test_app.py
index fef2f371..6035dfe3 100644
--- a/testing/tests/client/test_app.py
+++ b/testing/tests/client/test_app.py
@@ -19,6 +19,11 @@ Test ObjectStore and Couch backend bits.
 """
 from testscenarios import TestWithScenarios
 
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
+from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
+
 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
diff --git a/testing/tests/couch/test_atomicity.py b/testing/tests/couch/test_atomicity.py
index 3badfb19..120136e4 100644
--- a/testing/tests/couch/test_atomicity.py
+++ b/testing/tests/couch/test_atomicity.py
@@ -26,6 +26,12 @@ from twisted.internet import defer
 from uuid import uuid4
 
 from leap.soledad.client import Soledad
+
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
+from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
+
 from leap.soledad.common.couch.state import CouchServerState
 from leap.soledad.common.couch import CouchDatabase
 
@@ -80,7 +86,8 @@ class CouchAtomicityTestCase(CouchDBTestCase, TestCaseWithServer):
         return soledad
 
     def make_app(self):
-        self.request_state = CouchServerState(self.couch_url)
+        self.request_state = CouchServerState(
+            self.couch_url, verify_schema_version=False)
         return self.make_app_after_state(self.request_state)
 
     def setUp(self):
diff --git a/testing/tests/couch/test_command.py b/testing/tests/couch/test_command.py
index f61e118d..34cf315c 100644
--- a/testing/tests/couch/test_command.py
+++ b/testing/tests/couch/test_command.py
@@ -1,6 +1,11 @@
 from twisted.trial import unittest
 
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
 from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
+
+from leap.soledad.common.couch.state import CouchServerState
 from leap.soledad.common.l2db import errors as u1db_errors
 
 from mock import Mock
@@ -9,7 +14,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 = CouchServerState(
+            "url", create_cmd="echo", verify_schema_version=False)
         mock_db = Mock()
         mock_db.replica_uid = 'replica_uid'
         state.open_database = Mock(return_value=mock_db)
@@ -18,11 +24,13 @@ 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 = CouchServerState(
+            "url", create_cmd="inexistent", verify_schema_version=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", verify_schema_version=False)
         self.assertRaises(u1db_errors.Unauthorized,
                           state.ensure_database, "user-1337")
diff --git a/testing/tests/server/test_server.py b/testing/tests/server/test_server.py
index 49d25ed0..74e8d1ef 100644
--- a/testing/tests/server/test_server.py
+++ b/testing/tests/server/test_server.py
@@ -30,6 +30,11 @@ from uuid import uuid4
 from twisted.internet import defer
 from twisted.trial import unittest
 
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
+from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
+
 from leap.soledad.common.couch.state import CouchServerState
 from leap.soledad.common.couch import CouchDatabase
 from test_soledad.u1db_tests import TestCaseWithServer
@@ -54,7 +59,8 @@ class ServerAuthenticationMiddlewareTestCase(CouchDBTestCase):
     def setUp(self):
         super(ServerAuthenticationMiddlewareTestCase, self).setUp()
         app = mock.Mock()
-        self._state = CouchServerState(self.couch_url)
+        self._state = CouchServerState(
+            self.couch_url, verify_schema_version=False)
         app.state = self._state
         self.auth_middleware = SoledadTokenAuthMiddleware(app)
         self._authorize('valid-uuid', 'valid-token')
@@ -345,7 +351,8 @@ class EncryptedSyncTestCase(
             shared_db=self.get_default_shared_mock(_put_doc_side_effect))
 
     def make_app(self):
-        self.request_state = CouchServerState(self.couch_url)
+        self.request_state = CouchServerState(
+            self.couch_url, verify_schema_version=False)
         return self.make_app_with_state(self.request_state)
 
     def setUp(self):
diff --git a/testing/tests/sync/test_encdecpool.py b/testing/tests/sync/test_encdecpool.py
index 4a32885e..97e50400 100644
--- a/testing/tests/sync/test_encdecpool.py
+++ b/testing/tests/sync/test_encdecpool.py
@@ -26,6 +26,11 @@ from twisted.internet.defer import inlineCallbacks
 from leap.soledad.client.encdecpool import SyncEncrypterPool
 from leap.soledad.client.encdecpool import SyncDecrypterPool
 
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
+from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
+
 from leap.soledad.common.document import SoledadDocument
 from test_soledad.util import BaseSoledadTest
 from twisted.internet import defer
diff --git a/testing/tests/sync/test_sync.py b/testing/tests/sync/test_sync.py
index 5540b7cb..5092478e 100644
--- a/testing/tests/sync/test_sync.py
+++ b/testing/tests/sync/test_sync.py
@@ -24,7 +24,11 @@ from twisted.internet import defer
 
 from testscenarios import TestWithScenarios
 
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
 from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
+
 from leap.soledad.client import sync
 
 from test_soledad import u1db_tests as tests
diff --git a/testing/tests/sync/test_sync_mutex.py b/testing/tests/sync/test_sync_mutex.py
index 261c6485..154859f6 100644
--- a/testing/tests/sync/test_sync_mutex.py
+++ b/testing/tests/sync/test_sync_mutex.py
@@ -33,8 +33,12 @@ from twisted.internet import defer
 
 from leap.soledad.client.sync import SoledadSynchronizer
 
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
+from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
+
 from leap.soledad.common.couch.state import CouchServerState
-from leap.soledad.common.couch import CouchDatabase
 from test_soledad.u1db_tests import TestCaseWithServer
 
 from test_soledad.util import CouchDBTestCase
@@ -85,7 +89,8 @@ class TestSyncMutex(
     sync_target = soledad_sync_target
 
     def make_app(self):
-        self.request_state = CouchServerState(self.couch_url)
+        self.request_state = CouchServerState(
+            self.couch_url, verify_schema_version=False)
         return self.make_app_with_state(self.request_state)
 
     def setUp(self):
@@ -103,7 +108,7 @@ class TestSyncMutex(
         self.startServer()
 
         # ensure remote db exists before syncing
-        db = CouchDatabase.open_database(
+        db = couch.CouchDatabase.open_database(
             urljoin(self.couch_url, 'user-' + self.user),
             create=True)
 
diff --git a/testing/tests/sync/test_sync_target.py b/testing/tests/sync/test_sync_target.py
index 964468ce..9a1ccd30 100644
--- a/testing/tests/sync/test_sync_target.py
+++ b/testing/tests/sync/test_sync_target.py
@@ -36,6 +36,10 @@ from leap.soledad.client.sqlcipher import SQLCipherOptions
 from leap.soledad.client.sqlcipher import SQLCipherDatabase
 
 from leap.soledad.common import l2db
+# monkeypatch couch backend to avoid verifying the schema version, otherwise
+# tests fail because of lack of soledad config database
+from leap.soledad.common import couch
+couch.VERIFY_SCHEMA_VERSION = False
 
 from leap.soledad.common.document import SoledadDocument
 from test_soledad import u1db_tests as tests
-- 
GitLab