From 8fe99a6be2e65ba4850233ed27bef57c5c0cd431 Mon Sep 17 00:00:00 2001
From: Don Mitchell <dmitchell@edx.org>
Date: Thu, 10 Oct 2013 13:43:18 -0400
Subject: [PATCH] Revert "Revert "Merge pull request #1240 from
 edx/dhm/config_separation""

This reverts commit a517dc208588509df3337fc7ce35e513f5d65b5a.
---
 .../contentstore/tests/test_contentstore.py   |  6 +--
 .../contentstore/tests/test_import_export.py  |  4 +-
 .../tests/test_import_nostatic.py             |  4 +-
 cms/envs/acceptance.py                        |  9 ++--
 cms/envs/dev.py                               |  9 ++--
 cms/envs/test.py                              | 10 ++--
 common/djangoapps/contentserver/tests/test.py |  4 +-
 common/djangoapps/terrain/browser.py          |  2 +-
 .../xmodule/xmodule/contentstore/django.py    |  2 +-
 .../xmodule/xmodule/modulestore/__init__.py   |  7 ++-
 .../lib/xmodule/xmodule/modulestore/django.py | 10 ++--
 .../lib/xmodule/xmodule/modulestore/mixed.py  |  8 +++-
 .../xmodule/xmodule/modulestore/mongo/base.py | 39 +++++++++------
 .../xmodule/modulestore/split_mongo/split.py  | 47 ++++++++++++-------
 .../xmodule/modulestore/store_utilities.py    |  1 -
 .../xmodule/modulestore/tests/django_utils.py | 26 ++++++----
 .../tests/test_mixed_modulestore.py           |  6 ++-
 .../xmodule/modulestore/tests/test_mongo.py   | 14 ++++--
 .../xmodule/modulestore/tests/test_publish.py | 10 ++--
 .../modulestore/tests/test_split_migrator.py  | 12 +++--
 .../tests/test_split_modulestore.py           | 20 +++++---
 lms/envs/acceptance.py                        |  7 +--
 lms/envs/cms/dev.py                           |  7 +--
 lms/envs/cms/mixed_dev.py                     |  6 ++-
 lms/envs/cms/preview_dev.py                   |  1 +
 lms/envs/dev_mongo.py                         |  6 ++-
 lms/envs/test.py                              |  8 ++--
 27 files changed, 182 insertions(+), 103 deletions(-)

diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py
index 7f09e4dd60f..6559df4ef9f 100644
--- a/cms/djangoapps/contentstore/tests/test_contentstore.py
+++ b/cms/djangoapps/contentstore/tests/test_contentstore.py
@@ -58,7 +58,7 @@ from student.models import CourseEnrollment
 from contentstore.utils import delete_course_and_groups
 
 TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
-TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
+TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
 
 
 class MongoCollectionFindWrapper(object):
@@ -101,7 +101,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
         self.client.login(username=uname, password=password)
 
     def tearDown(self):
-        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
+        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
         _CONTENTSTORE.clear()
 
     def check_components_on_page(self, component_types, expected_types):
@@ -1354,7 +1354,7 @@ class ContentStoreTest(ModuleStoreTestCase):
 
     def tearDown(self):
         mongo = MongoClient()
-        mongo.drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
+        mongo.drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
         _CONTENTSTORE.clear()
 
     def test_create_course(self):
diff --git a/cms/djangoapps/contentstore/tests/test_import_export.py b/cms/djangoapps/contentstore/tests/test_import_export.py
index 005cfbc1e04..9f60680d17d 100644
--- a/cms/djangoapps/contentstore/tests/test_import_export.py
+++ b/cms/djangoapps/contentstore/tests/test_import_export.py
@@ -20,7 +20,7 @@ from django.conf import settings
 from xmodule.contentstore.django import _CONTENTSTORE
 
 TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
-TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
+TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
 
 log = logging.getLogger(__name__)
 
@@ -70,7 +70,7 @@ class ImportTestCase(CourseTestCase):
 
     def tearDown(self):
         shutil.rmtree(self.content_dir)
-        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
+        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
         _CONTENTSTORE.clear()
 
 
diff --git a/cms/djangoapps/contentstore/tests/test_import_nostatic.py b/cms/djangoapps/contentstore/tests/test_import_nostatic.py
index 275f9b6b1f9..510f0ca6f7e 100644
--- a/cms/djangoapps/contentstore/tests/test_import_nostatic.py
+++ b/cms/djangoapps/contentstore/tests/test_import_nostatic.py
@@ -28,7 +28,7 @@ from uuid import uuid4
 from pymongo import MongoClient
 
 TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
-TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
+TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
 
 
 @override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE, MODULESTORE=TEST_MODULESTORE)
@@ -61,7 +61,7 @@ class ContentStoreImportNoStaticTest(ModuleStoreTestCase):
         self.client.login(username=uname, password=password)
 
     def tearDown(self):
-        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
+        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
         _CONTENTSTORE.clear()
 
     def load_test_import_course(self):
diff --git a/cms/envs/acceptance.py b/cms/envs/acceptance.py
index 51e3183a526..fc7b23518fa 100644
--- a/cms/envs/acceptance.py
+++ b/cms/envs/acceptance.py
@@ -31,30 +31,33 @@ DOC_STORE_CONFIG = {
     'collection': 'acceptance_modulestore_%s' % seed(),
 }
 
-MODULESTORE_OPTIONS = dict({
+MODULESTORE_OPTIONS = {
     'default_class': 'xmodule.raw_module.RawDescriptor',
     'fs_root': TEST_ROOT / "data",
     'render_template': 'mitxmako.shortcuts.render_to_string',
-}, **DOC_STORE_CONFIG)
+}
 
 MODULESTORE = {
     'default': {
         'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': MODULESTORE_OPTIONS
     },
     'direct': {
         'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': MODULESTORE_OPTIONS
     },
     'draft': {
         'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': MODULESTORE_OPTIONS
     }
 }
 
 CONTENTSTORE = {
     'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
-    'OPTIONS': {
+    'DOC_STORE_CONFIG': {
         'host': 'localhost',
         'db': 'acceptance_xcontent_%s' % seed(),
     },
diff --git a/cms/envs/dev.py b/cms/envs/dev.py
index cb51ef37b1f..f96506665ab 100644
--- a/cms/envs/dev.py
+++ b/cms/envs/dev.py
@@ -23,23 +23,26 @@ DOC_STORE_CONFIG = {
     'collection': 'modulestore',
 }
 
-modulestore_options = dict({
+modulestore_options = {
     'default_class': 'xmodule.raw_module.RawDescriptor',
     'fs_root': GITHUB_REPO_ROOT,
     'render_template': 'mitxmako.shortcuts.render_to_string',
-}, **DOC_STORE_CONFIG)
+}
 
 MODULESTORE = {
     'default': {
         'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': modulestore_options
     },
     'direct': {
         'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': modulestore_options
     },
     'split': {
         'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': modulestore_options
     }
 }
@@ -49,7 +52,7 @@ MODULESTORE = {
 # This is for static content for courseware, not system static content (e.g. javascript, css, edX branding, etc)
 CONTENTSTORE = {
     'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
-    'OPTIONS': {
+    'DOC_STORE_CONFIG': {
         'host': 'localhost',
         'db': 'xcontent',
     },
diff --git a/cms/envs/test.py b/cms/envs/test.py
index 77c05d9fa49..b391bcbe181 100644
--- a/cms/envs/test.py
+++ b/cms/envs/test.py
@@ -57,34 +57,38 @@ DOC_STORE_CONFIG = {
     'collection': 'test_modulestore',
 }
 
-MODULESTORE_OPTIONS = dict({
+MODULESTORE_OPTIONS = {
     'default_class': 'xmodule.raw_module.RawDescriptor',
     'fs_root': TEST_ROOT / "data",
     'render_template': 'mitxmako.shortcuts.render_to_string',
-}, **DOC_STORE_CONFIG)
+}
 
 MODULESTORE = {
     'default': {
         'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': MODULESTORE_OPTIONS
     },
     'direct': {
         'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': MODULESTORE_OPTIONS
     },
     'draft': {
         'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': MODULESTORE_OPTIONS
     },
     'split': {
         'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': MODULESTORE_OPTIONS
     }
 }
 
 CONTENTSTORE = {
     'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
-    'OPTIONS': {
+    'DOC_STORE_CONFIG': {
         'host': 'localhost',
         'db': 'test_xcontent',
     },
diff --git a/common/djangoapps/contentserver/tests/test.py b/common/djangoapps/contentserver/tests/test.py
index 94a614c85ab..ce934c1ded7 100644
--- a/common/djangoapps/contentserver/tests/test.py
+++ b/common/djangoapps/contentserver/tests/test.py
@@ -25,7 +25,7 @@ from xmodule.modulestore.xml_importer import import_from_xml
 log = logging.getLogger(__name__)
 
 TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
-TEST_DATA_CONTENTSTORE['OPTIONS']['db'] = 'test_xcontent_%s' % uuid4().hex
+TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
 
 TEST_MODULESTORE = studio_store_config(settings.TEST_ROOT / "data")
 
@@ -80,7 +80,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase):
 
     def tearDown(self):
 
-        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['OPTIONS']['db'])
+        MongoClient().drop_database(TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'])
         _CONTENTSTORE.clear()
 
     def test_unlocked_asset(self):
diff --git a/common/djangoapps/terrain/browser.py b/common/djangoapps/terrain/browser.py
index c02ad7a2f99..8c18c40a79c 100644
--- a/common/djangoapps/terrain/browser.py
+++ b/common/djangoapps/terrain/browser.py
@@ -175,7 +175,7 @@ def reset_databases(scenario):
     If no data is created during the test, these lines equivilently do nothing.
     '''
     mongo = MongoClient()
-    mongo.drop_database(settings.CONTENTSTORE['OPTIONS']['db'])
+    mongo.drop_database(settings.CONTENTSTORE['DOC_STORE_CONFIG']['db'])
     _CONTENTSTORE.clear()
 
     modulestore = xmodule.modulestore.django.editable_modulestore()
diff --git a/common/lib/xmodule/xmodule/contentstore/django.py b/common/lib/xmodule/xmodule/contentstore/django.py
index 25a5d7912f5..84ba75797b7 100644
--- a/common/lib/xmodule/xmodule/contentstore/django.py
+++ b/common/lib/xmodule/xmodule/contentstore/django.py
@@ -21,7 +21,7 @@ def contentstore(name='default'):
     if name not in _CONTENTSTORE:
         class_ = load_function(settings.CONTENTSTORE['ENGINE'])
         options = {}
-        options.update(settings.CONTENTSTORE['OPTIONS'])
+        options.update(settings.CONTENTSTORE['DOC_STORE_CONFIG'])
         if 'ADDITIONAL_OPTIONS' in settings.CONTENTSTORE:
             if name in settings.CONTENTSTORE['ADDITIONAL_OPTIONS']:
                 options.update(settings.CONTENTSTORE['ADDITIONAL_OPTIONS'][name])
diff --git a/common/lib/xmodule/xmodule/modulestore/__init__.py b/common/lib/xmodule/xmodule/modulestore/__init__.py
index 43f88de137c..a29021cdc9e 100644
--- a/common/lib/xmodule/xmodule/modulestore/__init__.py
+++ b/common/lib/xmodule/xmodule/modulestore/__init__.py
@@ -397,7 +397,12 @@ class ModuleStoreBase(ModuleStore):
     '''
     Implement interface functionality that can be shared.
     '''
-    def __init__(self, metadata_inheritance_cache_subsystem=None, request_cache=None, modulestore_update_signal=None, xblock_mixins=()):
+    def __init__(
+        self,
+        doc_store_config=None,  # ignore if passed up
+        metadata_inheritance_cache_subsystem=None, request_cache=None,
+        modulestore_update_signal=None, xblock_mixins=()
+    ):
         '''
         Set up the error-tracking logic.
         '''
diff --git a/common/lib/xmodule/xmodule/modulestore/django.py b/common/lib/xmodule/xmodule/modulestore/django.py
index 34a26ff7cca..42372ab64f7 100644
--- a/common/lib/xmodule/xmodule/modulestore/django.py
+++ b/common/lib/xmodule/xmodule/modulestore/django.py
@@ -38,7 +38,7 @@ def load_function(path):
     return getattr(import_module(module_path), name)
 
 
-def create_modulestore_instance(engine, options):
+def create_modulestore_instance(engine, doc_store_config, options):
     """
     This will return a new instance of a modulestore given an engine and options
     """
@@ -66,6 +66,7 @@ def create_modulestore_instance(engine, options):
         request_cache=request_cache,
         modulestore_update_signal=Signal(providing_args=['modulestore', 'course_id', 'location']),
         xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
+        doc_store_config=doc_store_config,
         **_options
     )
 
@@ -106,8 +107,11 @@ def modulestore(name=None):
         name = get_default_store_name_for_current_request()
 
     if name not in _MODULESTORES:
-        _MODULESTORES[name] = create_modulestore_instance(settings.MODULESTORE[name]['ENGINE'],
-                                                          settings.MODULESTORE[name]['OPTIONS'])
+        _MODULESTORES[name] = create_modulestore_instance(
+            settings.MODULESTORE[name]['ENGINE'],
+            settings.MODULESTORE[name].get('DOC_STORE_CONFIG', {}),
+            settings.MODULESTORE[name].get('OPTIONS', {})
+        )
         # inject loc_mapper into newly created modulestore if it needs it
         if name == 'split' and _loc_singleton is not None:
             _MODULESTORES['split'].loc_mapper = _loc_singleton
diff --git a/common/lib/xmodule/xmodule/modulestore/mixed.py b/common/lib/xmodule/xmodule/modulestore/mixed.py
index 6a1c3b37c9f..2883c104d97 100644
--- a/common/lib/xmodule/xmodule/modulestore/mixed.py
+++ b/common/lib/xmodule/xmodule/modulestore/mixed.py
@@ -30,8 +30,12 @@ class MixedModuleStore(ModuleStoreBase):
             raise Exception('Missing a default modulestore in the MixedModuleStore __init__ method.')
 
         for key, store in stores.items():
-            self.modulestores[key] = create_modulestore_instance(store['ENGINE'],
-                                                                 store['OPTIONS'])
+            self.modulestores[key] = create_modulestore_instance(
+                store['ENGINE'],
+                # XMLModuleStore's don't have doc store configs
+                store.get('DOC_STORE_CONFIG', {}),
+                store['OPTIONS']
+            )
 
     def _get_modulestore_for_courseid(self, course_id):
         """
diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py
index c49b413638c..352ebce61a9 100644
--- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py
+++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py
@@ -256,25 +256,35 @@ class MongoModuleStore(ModuleStoreBase):
     """
 
     # TODO (cpennington): Enable non-filesystem filestores
-    def __init__(self, host, db, collection, fs_root, render_template,
-                 port=27017, default_class=None,
+    # pylint: disable=C0103
+    # pylint: disable=W0201
+    def __init__(self, doc_store_config, fs_root, render_template,
+                 default_class=None,
                  error_tracker=null_error_tracker,
-                 user=None, password=None, mongo_options=None, **kwargs):
+                 **kwargs):
+        """
+        :param doc_store_config: must have a host, db, and collection entries. Other common entries: port, tz_aware.
+        """
 
         super(MongoModuleStore, self).__init__(**kwargs)
 
-        if mongo_options is None:
-            mongo_options = {}
+        def do_connection(
+            db, collection, host, port=27017, tz_aware=True, user=None, password=None, **kwargs
+        ):
+            """
+            Create & open the connection, authenticate, and provide pointers to the collection
+            """
+            self.collection = pymongo.connection.Connection(
+                host=host,
+                port=port,
+                tz_aware=tz_aware,
+                **kwargs
+            )[db][collection]
 
-        self.collection = pymongo.connection.Connection(
-            host=host,
-            port=port,
-            tz_aware=True,
-            **mongo_options
-        )[db][collection]
+            if user is not None and password is not None:
+                self.collection.database.authenticate(user, password)
 
-        if user is not None and password is not None:
-            self.collection.database.authenticate(user, password)
+        do_connection(**doc_store_config)
 
         # Force mongo to report errors, at the expense of performance
         self.collection.safe = True
@@ -282,7 +292,8 @@ class MongoModuleStore(ModuleStoreBase):
         # Force mongo to maintain an index over _id.* that is in the same order
         # that is used when querying by a location
         self.collection.ensure_index(
-            zip(('_id.' + field for field in Location._fields), repeat(1)))
+            zip(('_id.' + field for field in Location._fields), repeat(1))
+        )
 
         if default_class is not None:
             module_path, _, class_name = default_class.rpartition('.')
diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
index a6b7d6932fb..a77035d2222 100644
--- a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
@@ -49,37 +49,48 @@ class SplitMongoModuleStore(ModuleStoreBase):
     A Mongodb backed ModuleStore supporting versions, inheritance,
     and sharing.
     """
-    # pylint: disable=C0103
-    def __init__(self, host, db, collection, fs_root, render_template,
-                 port=27017, default_class=None,
+    # pylint: disable=W0201
+    def __init__(self, doc_store_config, fs_root, render_template,
+                 default_class=None,
                  error_tracker=null_error_tracker,
-                 user=None, password=None,
-                 mongo_options=None,
                  loc_mapper=None,
                  **kwargs):
+        """
+        :param doc_store_config: must have a host, db, and collection entries. Other common entries: port, tz_aware.
+        """
 
         super(SplitMongoModuleStore, self).__init__(**kwargs)
         self.loc_mapper = loc_mapper
-        if mongo_options is None:
-            mongo_options = {}
 
-        self.db = pymongo.database.Database(pymongo.MongoClient(
-            host=host,
-            port=port,
-            tz_aware=True,
-            **mongo_options
-        ), db)
+        def do_connection(
+            db, collection, host, port=27017, tz_aware=True, user=None, password=None, **kwargs
+        ):
+            """
+            Create & open the connection, authenticate, and provide pointers to the collections
+            """
+            self.db = pymongo.database.Database(
+                pymongo.MongoClient(
+                    host=host,
+                    port=port,
+                    tz_aware=tz_aware,
+                    **kwargs
+                ),
+                db
+            )
+
+            if user is not None and password is not None:
+                self.db.authenticate(user, password)
+
+            self.course_index = self.db[collection + '.active_versions']
+            self.structures = self.db[collection + '.structures']
+            self.definitions = self.db[collection + '.definitions']
 
-        self.course_index = self.db[collection + '.active_versions']
-        self.structures = self.db[collection + '.structures']
-        self.definitions = self.db[collection + '.definitions']
+        do_connection(**doc_store_config)
 
         # Code review question: How should I expire entries?
         # _add_cache could use a lru mechanism to control the cache size?
         self.thread_cache = threading.local()
 
-        if user is not None and password is not None:
-            self.db.authenticate(user, password)
 
         # every app has write access to the db (v having a flag to indicate r/o v write)
         # Force mongo to report errors, at the expense of performance
diff --git a/common/lib/xmodule/xmodule/modulestore/store_utilities.py b/common/lib/xmodule/xmodule/modulestore/store_utilities.py
index a69ea327610..8ff5b6797dd 100644
--- a/common/lib/xmodule/xmodule/modulestore/store_utilities.py
+++ b/common/lib/xmodule/xmodule/modulestore/store_utilities.py
@@ -1,7 +1,6 @@
 import re
 from xmodule.contentstore.content import StaticContent
 from xmodule.modulestore import Location
-from xmodule.modulestore.mongo import MongoModuleStore
 from xmodule.modulestore.inheritance import own_metadata
 
 import logging
diff --git a/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py b/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
index 47418823e57..776543ec4eb 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
@@ -52,11 +52,13 @@ def mongo_store_config(data_dir):
     store = {
         'default': {
             'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
-            'OPTIONS': {
-                'default_class': 'xmodule.raw_module.RawDescriptor',
+            'DOC_STORE_CONFIG': {
                 'host': 'localhost',
                 'db': 'test_xmodule',
                 'collection': 'modulestore_%s' % uuid4().hex,
+            },
+            'OPTIONS': {
+                'default_class': 'xmodule.raw_module.RawDescriptor',
                 'fs_root': data_dir,
                 'render_template': 'mitxmako.shortcuts.render_to_string'
             }
@@ -74,9 +76,6 @@ def draft_mongo_store_config(data_dir):
 
     modulestore_options = {
         'default_class': 'xmodule.raw_module.RawDescriptor',
-        'host': 'localhost',
-        'db': 'test_xmodule',
-        'collection': 'modulestore_%s' % uuid4().hex,
         'fs_root': data_dir,
         'render_template': 'mitxmako.shortcuts.render_to_string'
     }
@@ -84,6 +83,11 @@ def draft_mongo_store_config(data_dir):
     store = {
         'default': {
             'ENGINE': 'xmodule.modulestore.mongo.draft.DraftModuleStore',
+            'DOC_STORE_CONFIG': {
+                'host': 'localhost',
+                'db': 'test_xmodule',
+                'collection': 'modulestore_%s' % uuid4().hex,
+            },
             'OPTIONS': modulestore_options
         }
     }
@@ -114,11 +118,13 @@ def studio_store_config(data_dir):
     """
     Defines modulestore structure used by Studio tests.
     """
-    options = {
-        'default_class': 'xmodule.raw_module.RawDescriptor',
+    store_config = {
         'host': 'localhost',
         'db': 'test_xmodule',
         'collection': 'modulestore_%s' % uuid4().hex,
+    }
+    options = {
+        'default_class': 'xmodule.raw_module.RawDescriptor',
         'fs_root': data_dir,
         'render_template': 'mitxmako.shortcuts.render_to_string',
     }
@@ -126,18 +132,22 @@ def studio_store_config(data_dir):
     store = {
         'default': {
             'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+            'DOC_STORE_CONFIG': store_config,
             'OPTIONS': options
         },
         'direct': {
             'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+            'DOC_STORE_CONFIG': store_config,
             'OPTIONS': options
         },
         'draft': {
             'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+            'DOC_STORE_CONFIG': store_config,
             'OPTIONS': options
         },
         'split': {
             'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
+            'DOC_STORE_CONFIG': store_config,
             'OPTIONS': options
         }
     }
@@ -206,7 +216,7 @@ class ModuleStoreTestCase(TestCase):
         If using a Mongo-backed modulestore, drop the collection.
         """
 
-        # This will return the mongo-backed modulestore 
+        # This will return the mongo-backed modulestore
         # even if we're using a mixed modulestore
         store = editable_modulestore()
 
diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
index d4557b3dc09..821a41f137e 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
@@ -47,11 +47,13 @@ OPTIONS = {
         },
         'default': {
             'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
-            'OPTIONS': {
-                'default_class': DEFAULT_CLASS,
+            'DOC_STORE_CONFIG': {
                 'host': HOST,
                 'db': DB,
                 'collection': COLLECTION,
+            },
+            'OPTIONS': {
+                'default_class': DEFAULT_CLASS,
                 'fs_root': DATA_DIR,
                 'render_template': RENDER_TEMPLATE,
             }
diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
index c2e6be27935..eb7efa04315 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
@@ -56,14 +56,19 @@ class TestMongoModuleStore(object):
     @staticmethod
     def initdb():
         # connect to the db
-        store = MongoModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
+        doc_store_config = {
+            'host': HOST,
+            'db': DB,
+            'collection': COLLECTION,
+        }
+        store = MongoModuleStore(doc_store_config, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
         # since MongoModuleStore and MongoContentStore are basically assumed to be together, create this class
         # as well
         content_store = MongoContentStore(HOST, DB)
         #
         # Also test draft store imports
         #
-        draft_store = DraftModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
+        draft_store = DraftModuleStore(doc_store_config, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
         # Explicitly list the courses to load (don't want the big one)
         courses = ['toy', 'simple', 'simple_with_draft', 'test_unicode']
         import_from_xml(store, DATA_DIR, courses, draft_store=draft_store, static_content_store=content_store)
@@ -113,7 +118,10 @@ class TestMongoModuleStore(object):
         pprint([Location(i['_id']).url() for i in ids])
 
     def test_mongo_modulestore_type(self):
-        store = MongoModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS)
+        store = MongoModuleStore(
+            {'host': HOST, 'db': DB, 'collection': COLLECTION},
+            FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS
+        )
         assert_equals(store.get_modulestore_type('foo/bar/baz'), 'mongo')
 
     def test_get_courses(self):
diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_publish.py b/common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
index 99d0e8dbd3f..f36b98e24a1 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/test_publish.py
@@ -26,18 +26,18 @@ class TestPublish(unittest.TestCase):
         'db': 'test_xmodule',
     }
 
-    modulestore_options = dict({
+    modulestore_options = {
         'default_class': 'xmodule.raw_module.RawDescriptor',
         'fs_root': '',
         'render_template': mock.Mock(return_value=""),
         'xblock_mixins': (InheritanceMixin,)
-    }, **db_config)
+    }
 
     def setUp(self):
-        self.modulestore_options['collection'] = 'modulestore{0}'.format(uuid.uuid4().hex)
+        self.db_config['collection'] = 'modulestore{0}'.format(uuid.uuid4().hex)
 
-        self.old_mongo = MongoModuleStore(**self.modulestore_options)
-        self.draft_mongo = DraftMongoModuleStore(**self.modulestore_options)
+        self.old_mongo = MongoModuleStore(self.db_config, **self.modulestore_options)
+        self.draft_mongo = DraftMongoModuleStore(self.db_config, **self.modulestore_options)
         self.addCleanup(self.tear_down_mongo)
         self.course_location = None
 
diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_migrator.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_migrator.py
index 92b1304d733..049fbd2ef80 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_migrator.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_migrator.py
@@ -34,20 +34,22 @@ class TestMigration(unittest.TestCase):
         'collection': 'modulestore{0}'.format(uuid.uuid4().hex),
     }
 
-    modulestore_options = dict({
+    modulestore_options = {
         'default_class': 'xmodule.raw_module.RawDescriptor',
         'fs_root': '',
         'render_template': mock.Mock(return_value=""),
         'xblock_mixins': (InheritanceMixin,)
-    }, **db_config)
+    }
 
     def setUp(self):
         super(TestMigration, self).setUp()
         self.loc_mapper = LocMapperStore(**self.db_config)
-        self.old_mongo = MongoModuleStore(**self.modulestore_options)
-        self.draft_mongo = DraftModuleStore(**self.modulestore_options)
+        self.old_mongo = MongoModuleStore(self.db_config, **self.modulestore_options)
+        self.draft_mongo = DraftModuleStore(self.db_config, **self.modulestore_options)
         self.split_mongo = SplitMongoModuleStore(
-            loc_mapper=self.loc_mapper, **self.modulestore_options
+            doc_store_config=self.db_config,
+            loc_mapper=self.loc_mapper,
+            **self.modulestore_options
         )
         self.migrator = SplitMigrator(self.split_mongo, self.old_mongo, self.draft_mongo, self.loc_mapper)
         self.course_location = None
diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
index 78affa9aca5..aa095d8e4c4 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
@@ -28,18 +28,21 @@ class SplitModuleTest(unittest.TestCase):
     versions. It creates unique collection names and removes them after all
     tests finish.
     '''
-    # Snippet of what would be in the django settings envs file
-    modulestore_options = {
-        'default_class': 'xmodule.raw_module.RawDescriptor',
+    # Snippets of what would be in the django settings envs file
+    DOC_STORE_CONFIG = {
         'host': 'localhost',
         'db': 'test_xmodule',
         'collection': 'modulestore{0}'.format(uuid.uuid4().hex),
+    }
+    modulestore_options = {
+        'default_class': 'xmodule.raw_module.RawDescriptor',
         'fs_root': '',
         'xblock_mixins': (InheritanceMixin, XModuleMixin)
     }
 
     MODULESTORE = {
         'ENGINE': 'xmodule.modulestore.split_mongo.SplitMongoModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': modulestore_options
     }
 
@@ -66,8 +69,8 @@ class SplitModuleTest(unittest.TestCase):
         Loads the initial data into the db ensuring the collection name is
         unique.
         '''
-        collection_prefix = SplitModuleTest.MODULESTORE['OPTIONS']['collection'] + '.'
-        dbname = SplitModuleTest.MODULESTORE['OPTIONS']['db']
+        collection_prefix = SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG']['collection'] + '.'
+        dbname = SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG']['db']
         processes = [
             subprocess.Popen([
                 'mongoimport', '-d', dbname, '-c',
@@ -89,7 +92,7 @@ class SplitModuleTest(unittest.TestCase):
 
     @classmethod
     def tearDownClass(cls):
-        collection_prefix = SplitModuleTest.MODULESTORE['OPTIONS']['collection'] + '.'
+        collection_prefix = SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG']['collection'] + '.'
         if SplitModuleTest.modulestore:
             for collection in ('active_versions', 'structures', 'definitions'):
                 modulestore().db.drop_collection(collection_prefix + collection)
@@ -1115,7 +1118,10 @@ def modulestore():
         options['render_template'] = render_to_template_mock
 
         # pylint: disable=W0142
-        SplitModuleTest.modulestore = class_(**options)
+        SplitModuleTest.modulestore = class_(
+            SplitModuleTest.MODULESTORE['DOC_STORE_CONFIG'],
+            **options
+        )
 
     return SplitModuleTest.modulestore
 
diff --git a/lms/envs/acceptance.py b/lms/envs/acceptance.py
index 07d646d3083..e1976f32e70 100644
--- a/lms/envs/acceptance.py
+++ b/lms/envs/acceptance.py
@@ -33,11 +33,11 @@ DOC_STORE_CONFIG = {
     'collection': 'acceptance_modulestore_%s' % seed(),
 }
 
-modulestore_options = dict({
+modulestore_options = {
     'default_class': 'xmodule.raw_module.RawDescriptor',
     'fs_root': TEST_ROOT / "data",
     'render_template': 'mitxmako.shortcuts.render_to_string',
-}, **DOC_STORE_CONFIG)
+}
 
 MODULESTORE = {
     'default': {
@@ -47,6 +47,7 @@ MODULESTORE = {
             'stores': {
                 'default': {
                     'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+                    'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
                     'OPTIONS': modulestore_options
                 }
             }
@@ -58,7 +59,7 @@ MODULESTORE['direct'] = MODULESTORE['default']
 
 CONTENTSTORE = {
     'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
-    'OPTIONS': {
+    'DOC_STORE_CONFIG': {
         'host': 'localhost',
         'db': 'acceptance_xcontent_%s' % seed(),
     }
diff --git a/lms/envs/cms/dev.py b/lms/envs/cms/dev.py
index 6444ed569d9..38d70ddab7c 100644
--- a/lms/envs/cms/dev.py
+++ b/lms/envs/cms/dev.py
@@ -28,15 +28,16 @@ DOC_STORE_CONFIG = {
     'collection': 'modulestore',
 }
 
-modulestore_options = dict({
+modulestore_options = {
     'default_class': 'xmodule.raw_module.RawDescriptor',
     'fs_root': DATA_DIR,
     'render_template': 'mitxmako.shortcuts.render_to_string',
-}, **DOC_STORE_CONFIG)
+}
 
 MODULESTORE = {
     'default': {
         'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': modulestore_options
     },
     'draft': {
@@ -47,7 +48,7 @@ MODULESTORE = {
 
 CONTENTSTORE = {
     'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
-    'OPTIONS': {
+    'DOC_STORE_CONFIG': {
         'host': 'localhost',
         'db': 'xcontent',
     }
diff --git a/lms/envs/cms/mixed_dev.py b/lms/envs/cms/mixed_dev.py
index b0ffb5dee77..ba45d7e747c 100644
--- a/lms/envs/cms/mixed_dev.py
+++ b/lms/envs/cms/mixed_dev.py
@@ -25,11 +25,13 @@ MODULESTORE = {
                 },
                 'default': {
                     'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
-                    'OPTIONS': {
-                        'default_class': 'xmodule.raw_module.RawDescriptor',
+                    'DOC_STORE_CONFIG': {
                         'host': 'localhost',
                         'db': 'xmodule',
                         'collection': 'modulestore',
+                    },
+                    'OPTIONS': {
+                        'default_class': 'xmodule.raw_module.RawDescriptor',
                         'fs_root': DATA_DIR,
                         'render_template': 'mitxmako.shortcuts.render_to_string',
                     }
diff --git a/lms/envs/cms/preview_dev.py b/lms/envs/cms/preview_dev.py
index bfa7fec8260..4a65b50e59d 100644
--- a/lms/envs/cms/preview_dev.py
+++ b/lms/envs/cms/preview_dev.py
@@ -11,6 +11,7 @@ from .dev import *
 MODULESTORE = {
     'default': {
         'ENGINE': 'xmodule.modulestore.draft.DraftModuleStore',
+        'DOC_STORE_CONFIG': DOC_STORE_CONFIG,
         'OPTIONS': modulestore_options
     },
 }
diff --git a/lms/envs/dev_mongo.py b/lms/envs/dev_mongo.py
index dfbf473b45f..bd7a8b20aa9 100644
--- a/lms/envs/dev_mongo.py
+++ b/lms/envs/dev_mongo.py
@@ -13,11 +13,13 @@ GITHUB_REPO_ROOT = ENV_ROOT / "data"
 MODULESTORE = {
     'default': {
         'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
-        'OPTIONS': {
-            'default_class': 'xmodule.raw_module.RawDescriptor',
+        'DOC_STORE_CONFIG': {
             'host': 'localhost',
             'db': 'xmodule',
             'collection': 'modulestore',
+        },
+        'OPTIONS': {
+            'default_class': 'xmodule.raw_module.RawDescriptor',
             'fs_root': GITHUB_REPO_ROOT,
             'render_template': 'mitxmako.shortcuts.render_to_string',
         }
diff --git a/lms/envs/test.py b/lms/envs/test.py
index 63ff830c923..42a4d844365 100644
--- a/lms/envs/test.py
+++ b/lms/envs/test.py
@@ -40,7 +40,7 @@ MITX_FEATURES['ENABLE_SHOPPING_CART'] = True
 WIKI_ENABLED = True
 
 # Makes the tests run much faster...
-SOUTH_TESTS_MIGRATE = False   # To disable migrations and use syncdb instead
+SOUTH_TESTS_MIGRATE = False  # To disable migrations and use syncdb instead
 
 # Nose Test Runner
 TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
@@ -78,7 +78,7 @@ XQUEUE_INTERFACE = {
     },
     "basic_auth": ('anant', 'agarwal'),
 }
-XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5   # seconds
+XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5  # seconds
 
 
 # Don't rely on a real staff grading backend
@@ -115,7 +115,7 @@ INIT_MODULESTORE_ON_STARTUP = False
 
 CONTENTSTORE = {
     'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
-    'OPTIONS': {
+    'DOC_STORE_CONFIG': {
         'host': 'localhost',
         'db': 'xcontent',
     }
@@ -247,4 +247,4 @@ PASSWORD_HASHERS = (
 #   Generated checkid_setup request to http://testserver/openid/provider/login/ with assocication {HMAC-SHA1}{51d49995}{s/kRmA==}
 
 import openid.oidutil
-openid.oidutil.log = lambda message, level=0: None
+openid.oidutil.log = lambda message, level = 0: None
-- 
GitLab