refactor: deprecates ModuleSystem properties for code sandboxing and cache

* Deprecates ModuleSystem can_execute_unsafe_code, get_python_lib_zip and cache properties
* Adds a new CacheService and SandboxService to provide the deprecated property
* Adds tests for the added CacheService and SandboxService
* Updates the ModuleSystemShim tests in Lms and Studio
This commit is contained in:
Jillian Vogel
2021-12-06 12:03:55 +10:30
parent 3eea5d9337
commit 2173a98ef8
11 changed files with 374 additions and 119 deletions

View File

@@ -10,6 +10,7 @@ from completion.waffle import ENABLE_COMPLETION_TRACKING_SWITCH
from completion.models import BlockCompletion
from completion.services import CompletionService
from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from functools import lru_cache # lint-amnesty, pylint: disable=wrong-import-order
from eventtracking import tracker
@@ -19,6 +20,10 @@ from xblock.field_data import SplitFieldData
from xblock.fields import Scope
from xblock.runtime import KvsFieldData, MemoryIdManager, Runtime
from xmodule.errortracker import make_error_tracker
from xmodule.contentstore.django import contentstore
from xmodule.modulestore.django import ModuleI18nService
from xmodule.util.sandboxing import SandboxService
from common.djangoapps.edxmako.services import MakoService
from common.djangoapps.track import contexts as track_contexts
from common.djangoapps.track import views as track_views
@@ -30,10 +35,9 @@ from openedx.core.djangoapps.xblock.runtime.blockstore_field_data import Blockst
from openedx.core.djangoapps.xblock.runtime.ephemeral_field_data import EphemeralKeyValueStore
from openedx.core.djangoapps.xblock.runtime.mixin import LmsBlockMixin
from openedx.core.djangoapps.xblock.utils import get_xblock_id_for_anonymous_user
from openedx.core.lib.cache_utils import CacheService
from openedx.core.lib.xblock_utils import wrap_fragment, xblock_local_resource_url
from common.djangoapps.static_replace import process_static_urls
from xmodule.errortracker import make_error_tracker # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.django import ModuleI18nService # lint-amnesty, pylint: disable=wrong-import-order
from .id_managers import OpaqueKeyReader
from .shims import RuntimeShim, XBlockShim
@@ -240,6 +244,12 @@ class XBlockRuntime(RuntimeShim, Runtime):
return MakoService()
elif service_name == "i18n":
return ModuleI18nService(block=block)
elif service_name == 'sandbox':
context_key = block.scope_ids.usage_id.context_key
return SandboxService(contentstore=contentstore, course_id=context_key)
elif service_name == 'cache':
return CacheService(cache)
# Check if the XBlockRuntimeSystem wants to handle this:
service = self.system.get_service(block, service_name)
# Otherwise, fall back to the base implementation which loads services

View File

@@ -223,3 +223,27 @@ def get_cache(name):
"""
assert name is not None
return RequestCache(name).data
class CacheService:
"""
An XBlock service which provides a cache.
Args:
cache(object): provides get/set functions for retrieving/storing key/value pairs.
"""
def __init__(self, cache, **kwargs):
super().__init__(**kwargs)
self._cache = cache
def get(self, key, *args, **kwargs):
"""
Returns the value cached against the given key, or None.
"""
return self._cache.get(key, *args, **kwargs)
def set(self, key, value, *args, **kwargs):
"""
Caches the value against the given key.
"""
return self._cache.set(key, value, *args, **kwargs)

View File

@@ -1,14 +1,16 @@
"""
Tests for cache_utils.py
"""
from time import sleep
from unittest import TestCase
from unittest.mock import Mock
import ddt
from edx_django_utils.cache import RequestCache
from django.core.cache import cache
from django.test.utils import override_settings
from openedx.core.lib.cache_utils import request_cached
from openedx.core.lib.cache_utils import CacheService, request_cached
@ddt.ddt
@@ -295,3 +297,26 @@ class TestRequestCachedDecorator(TestCase):
result = wrapped(3)
assert result == 2
assert to_be_wrapped.call_count == 2
class CacheServiceTest(TestCase):
"""
Test CacheService methods.
"""
@override_settings(CACHES={
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
})
def test_cache(self):
'''
Ensure the default cache works as expected.
'''
cache_service = CacheService(cache)
key = 'my_key'
value = 'some random value'
timeout = 1
cache_service.set(key, value, timeout=timeout)
assert cache_service.get(key) == value
sleep(timeout)
assert cache_service.get(key) is None