Merge pull request #5031 from edx/andya/merge-hotfix-2014-08-29
Merge hotfix-2014-08-29 to master
This commit is contained in:
@@ -24,6 +24,7 @@ from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xblock.runtime import Mixologist
|
||||
from xblock.core import XBlock
|
||||
import functools
|
||||
|
||||
log = logging.getLogger('edx.modulestore')
|
||||
|
||||
@@ -577,6 +578,36 @@ class ModuleStoreReadBase(ModuleStoreRead):
|
||||
"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def memoize_request_cache(func):
|
||||
"""
|
||||
Memoize a function call results on the request_cache if there's one. Creates the cache key by
|
||||
joining the unicode of all the args with &; so, if your arg may use the default &, it may
|
||||
have false hits
|
||||
"""
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self.request_cache:
|
||||
cache_key = '&'.join([hashvalue(arg) for arg in args])
|
||||
if cache_key in self.request_cache.data.setdefault(func.__name__, {}):
|
||||
return self.request_cache.data[func.__name__][cache_key]
|
||||
|
||||
result = func(self, *args, **kwargs)
|
||||
|
||||
self.request_cache.data[func.__name__][cache_key] = result
|
||||
return result
|
||||
else:
|
||||
return func(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
def hashvalue(arg):
|
||||
"""
|
||||
If arg is an xblock, use its location. otherwise just turn it into a string
|
||||
"""
|
||||
if isinstance(arg, XBlock):
|
||||
return unicode(arg.location)
|
||||
else:
|
||||
return unicode(arg)
|
||||
|
||||
class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
|
||||
'''
|
||||
|
||||
@@ -589,6 +589,7 @@ class DraftModuleStore(MongoModuleStore):
|
||||
_internal([root_usage.to_deprecated_son() for root_usage in root_usages])
|
||||
self.collection.remove({'_id': {'$in': to_be_deleted}}, safe=self.collection.safe)
|
||||
|
||||
@MongoModuleStore.memoize_request_cache
|
||||
def has_changes(self, xblock):
|
||||
"""
|
||||
Check if the subtree rooted at xblock has any drafts and thus may possibly have changes
|
||||
|
||||
@@ -10,6 +10,7 @@ from xmodule.modulestore.django import modulestore, clear_existing_modulestores
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
import datetime
|
||||
import pytz
|
||||
from request_cache.middleware import RequestCache
|
||||
from xmodule.tabs import CoursewareTab, CourseInfoTab, StaticTab, DiscussionTab, ProgressTab, WikiTab
|
||||
from xmodule.modulestore.tests.sample_courses import default_block_info_tree, TOY_BLOCK_INFO_TREE
|
||||
from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST
|
||||
@@ -275,6 +276,8 @@ class ModuleStoreTestCase(TestCase):
|
||||
# the next time they are accessed.
|
||||
# We do this at *both* setup and teardown just to be safe.
|
||||
clear_existing_modulestores()
|
||||
# clear RequestCache to emulate its clearance after each http request.
|
||||
RequestCache().clear_request_cache()
|
||||
|
||||
# Call superclass implementation
|
||||
super(ModuleStoreTestCase, self)._post_teardown()
|
||||
|
||||
@@ -354,8 +354,9 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
)
|
||||
|
||||
# draft: 2 to look in draft and then published and then 5 for updating ancestors.
|
||||
# split: 1 for the course index, 1 for the course structure before the change, 1 for the structure after the change
|
||||
# 2 sends: insert structure, update index_entry
|
||||
# split: 3 to get the course structure & the course definition (show_calculator is scope content)
|
||||
# before the change. 1 during change to refetch the definition. 3 afterward (b/c it calls get_item to return the "new" object).
|
||||
# 2 sends to update index & structure (calculator is a setting field)
|
||||
@ddt.data(('draft', 11, 5), ('split', 3, 2))
|
||||
@ddt.unpack
|
||||
def test_update_item(self, default_ms, max_find, max_send):
|
||||
@@ -438,7 +439,6 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
self.assertFalse(self.store.has_changes(component))
|
||||
|
||||
# TODO: LMS-11220: Document why split find count is 4
|
||||
# TODO: LMS-11220: Document why draft find count is 8
|
||||
# TODO: LMS-11220: Document why split send count is 3
|
||||
@ddt.data(('draft', 8, 2), ('split', 4, 3))
|
||||
@ddt.unpack
|
||||
@@ -459,7 +459,7 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
with self.assertRaises(ItemNotFoundError):
|
||||
self.store.get_item(self.writable_chapter_location)
|
||||
|
||||
# TODO: LMS-11220: Document why draft find count is 9
|
||||
# TODO: LMS-11220: Document why split find count is 4
|
||||
# TODO: LMS-11220: Document why split send count is 3
|
||||
@ddt.data(('draft', 9, 2), ('split', 4, 3))
|
||||
@ddt.unpack
|
||||
@@ -506,8 +506,7 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
self.assertFalse(self.store.has_item(leaf_loc))
|
||||
self.assertNotIn(vert_loc, course.children)
|
||||
|
||||
# TODO: LMS-11220: Document why split send count is 2
|
||||
# TODO: LMS-11220: Document why draft find count is 5
|
||||
# TODO: LMS-11220: Document why split find count is 2
|
||||
@ddt.data(('draft', 5, 1), ('split', 2, 2))
|
||||
@ddt.unpack
|
||||
def test_delete_draft_vertical(self, default_ms, max_find, max_send):
|
||||
@@ -712,9 +711,9 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
# - load vertical
|
||||
# - load inheritance data
|
||||
|
||||
# TODO: LMS-11220: Document why draft send count is 6
|
||||
# TODO: LMS-11220: Document why draft find count is 18
|
||||
# TODO: LMS-11220: Document why split find count is 16
|
||||
# TODO: LMS-11220: Document why draft send count is 5
|
||||
# TODO: LMS-11220: Document why draft find count is [19, 6]
|
||||
# TODO: LMS-11220: Document why split find count is [2, 2]
|
||||
@ddt.data(('draft', [19, 6], 0), ('split', [2, 2], 0))
|
||||
@ddt.unpack
|
||||
def test_path_to_location(self, default_ms, num_finds, num_sends):
|
||||
@@ -1045,6 +1044,7 @@ class TestMixedModuleStore(unittest.TestCase):
|
||||
# Sends:
|
||||
# - insert structure
|
||||
# - write index entry
|
||||
# TODO: LMS-11220: Document why split find count is 3
|
||||
@ddt.data(('draft', 3, 6), ('split', 3, 2))
|
||||
@ddt.unpack
|
||||
def test_unpublish(self, default_ms, max_find, max_send):
|
||||
|
||||
Reference in New Issue
Block a user