Enforce the use of XModuleFactory only in contexts where something will clean up after it

This commit is contained in:
Calen Pennington
2015-01-23 16:04:01 -05:00
parent b353ed2ea2
commit 199a8b783f
3 changed files with 49 additions and 0 deletions

View File

@@ -8,6 +8,9 @@ import xmodule.modulestore.tests.factories as xf
import course_modes.tests.factories as cmf
from lettuce import world
# Unlock XBlock factories, because we're randomizing the collection
# name above to prevent collisions
xf.XMODULE_FACTORY_LOCK.enable()
world.absorb(sf.UserFactory)
world.absorb(sf.UserProfileFactory)

View File

@@ -20,6 +20,7 @@ from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore, clear_existing_modulestores
from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST
from xmodule.modulestore.tests.sample_courses import default_block_info_tree, TOY_BLOCK_INFO_TREE
from xmodule.modulestore.tests.factories import XMODULE_FACTORY_LOCK
from xmodule.tabs import CoursewareTab, CourseInfoTab, StaticTab, DiscussionTab, ProgressTab, WikiTab
@@ -242,6 +243,10 @@ class ModuleStoreTestCase(TestCase):
self.addCleanup(RequestCache().clear_request_cache)
# Enable XModuleFactories for the space of this test (and its setUp).
self.addCleanup(XMODULE_FACTORY_LOCK.disable)
XMODULE_FACTORY_LOCK.enable()
super(ModuleStoreTestCase, self).setUp()
self.store = modulestore()

View File

@@ -22,6 +22,44 @@ class Dummy(object):
pass
class XModuleFactoryLock(threading.local):
"""
This class exists to store whether XModuleFactory can be accessed in a safe
way (meaning, in a context where the data it creates will be cleaned up).
Users of XModuleFactory (or its subclasses) should only call XModuleFactoryLock.enable
after ensuring that a) the modulestore will be cleaned up, and b) that XModuleFactoryLock.disable
will be called.
"""
def __init__(self):
super(XModuleFactoryLock, self).__init__()
self._enabled = False
def enable(self):
"""
Enable XModuleFactories. This should only be turned in a context
where the modulestore will be reset at the end of the test (such
as inside ModuleStoreTestCase).
"""
self._enabled = True
def disable(self):
"""
Disable XModuleFactories. This should be called once the data
from the factory has been cleaned up.
"""
self._enabled = False
def is_enabled(self):
"""
Return whether XModuleFactories are enabled.
"""
return self._enabled
XMODULE_FACTORY_LOCK = XModuleFactoryLock()
class XModuleFactory(Factory):
"""
Factory for XModules
@@ -34,6 +72,9 @@ class XModuleFactory(Factory):
@lazy_attribute
def modulestore(self):
msg = "XMODULE_FACTORY_LOCK not enabled. Please use ModuleStoreTestCase as your test baseclass."
assert XMODULE_FACTORY_LOCK.is_enabled(), msg
from xmodule.modulestore.django import modulestore
return modulestore()