Move waffle_utils/testutils.py to edx-toggles

This commit is contained in:
Régis Behmo
2020-10-13 12:13:01 +02:00
parent 58043727d5
commit db5feec4cf
2 changed files with 9 additions and 126 deletions

View File

@@ -1,68 +0,0 @@
"""
Tests for waffle utils test utilities.
"""
import crum
from django.test import TestCase
from django.test.client import RequestFactory
from edx_django_utils.cache import RequestCache
from opaque_keys.edx.keys import CourseKey
from .. import CourseWaffleFlag, WaffleFlagNamespace
from ..testutils import override_waffle_flag
class OverrideWaffleFlagTests(TestCase):
"""
Tests for the override_waffle_flag decorator/context manager.
"""
NAMESPACE_NAME = "test_namespace"
FLAG_NAME = "test_flag"
NAMESPACED_FLAG_NAME = NAMESPACE_NAME + "." + FLAG_NAME
TEST_COURSE_KEY = CourseKey.from_string("edX/DemoX/Demo_Course")
TEST_NAMESPACE = WaffleFlagNamespace(NAMESPACE_NAME)
TEST_COURSE_FLAG = CourseWaffleFlag(TEST_NAMESPACE, FLAG_NAME, __name__)
def setUp(self):
super(OverrideWaffleFlagTests, self).setUp()
request = RequestFactory().request()
self.addCleanup(crum.set_current_request, None)
crum.set_current_request(request)
RequestCache.clear_all_namespaces()
@override_waffle_flag(TEST_COURSE_FLAG, True)
def assert_decorator_activates_flag(self):
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
def test_override_waffle_flag_pre_cached(self):
# checks and caches the is_enabled value
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
flag_cache = self.TEST_COURSE_FLAG.waffle_namespace._cached_flags
assert self.NAMESPACED_FLAG_NAME in flag_cache
self.assert_decorator_activates_flag()
# test cached flag is restored
assert self.NAMESPACED_FLAG_NAME in flag_cache
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
def test_override_waffle_flag_not_pre_cached(self):
# check that the flag is not yet cached
flag_cache = self.TEST_COURSE_FLAG.waffle_namespace._cached_flags
assert self.NAMESPACED_FLAG_NAME not in flag_cache
self.assert_decorator_activates_flag()
# test cache is removed when no longer using decorator/context manager
assert self.NAMESPACED_FLAG_NAME not in flag_cache
def test_override_waffle_flag_as_context_manager(self):
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
with override_waffle_flag(self.TEST_COURSE_FLAG, True):
assert self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)
assert not self.TEST_COURSE_FLAG.is_enabled(self.TEST_COURSE_KEY)

View File

@@ -2,66 +2,17 @@
Test utilities for waffle utilities.
"""
from waffle.testutils import override_flag
# Import from edx-toggles to preserve import paths
# pylint: disable=unused-import
from edx_toggles.toggles.testutils import override_waffle_flag
# Can be used with FilteredQueryCountMixin.assertNumQueries() to blacklist
# waffle tables. For example:
# QUERY_COUNT_TABLE_BLACKLIST = WAFFLE_TABLES
# with self.assertNumQueries(6, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
WAFFLE_TABLES = ['waffle_utils_waffleflagcourseoverridemodel', 'waffle_flag', 'waffle_switch', 'waffle_sample']
class override_waffle_flag(override_flag):
"""
override_waffle_flag is a contextmanager for easier testing of flags.
It accepts two parameters, the flag itself and its intended state. Example
usage::
with override_waffle_flag(SOME_COURSE_FLAG, active=True):
...
If the flag already exists, its value will be changed inside the context
block, then restored to the original value. If the flag does not exist
before entering the context, it is created, then removed at the end of the
block.
It can also act as a decorator::
@override_waffle_flag(SOME_COURSE_FLAG, active=True)
def test_happy_mode_enabled():
...
"""
_cached_value = None
def __init__(self, flag, active):
"""
Args:
flag (WaffleFlag): The namespaced cached waffle flag.
active (Boolean): The value to which the flag will be set.
"""
self.flag = flag
waffle_namespace = flag.waffle_namespace
name = waffle_namespace._namespaced_name(flag.flag_name) # pylint: disable=protected-access
super(override_waffle_flag, self).__init__(name, active)
def __enter__(self):
super(override_waffle_flag, self).__enter__()
# pylint: disable=protected-access
# Store values that have been cached on the flag
self._cached_value = self.flag.waffle_namespace._cached_flags.get(self.name)
self.flag.waffle_namespace._cached_flags[self.name] = self.active
def __exit__(self, exc_type, exc_val, exc_tb):
super(override_waffle_flag, self).__exit__(exc_type, exc_val, exc_tb)
# pylint: disable=protected-access
# Restore the cached values
waffle_namespace = self.flag.waffle_namespace
waffle_namespace._cached_flags.pop(self.name, None)
if self._cached_value is not None:
waffle_namespace._cached_flags[self.name] = self._cached_value
WAFFLE_TABLES = [
"waffle_utils_waffleflagcourseoverridemodel",
"waffle_flag",
"waffle_switch",
"waffle_sample",
]