Commit 4dc03642 by Zia Fazal

disconnect signals to improve tests time

add feature to disable course_published signal

fixed broken tests

fix for test failures in test_crud

disabled course indexing for test crud

fixed quality violations
parent 82265160
import unittest
"""
Module contains tests for finding and using the templates (boilerplates) for xblocks
"""
from django.conf import settings
from django.test.utils import override_settings
from opaque_keys.edx.locator import LocalId
from xmodule import templates
......@@ -7,14 +10,23 @@ from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests import persistent_factories
from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore, clear_existing_modulestores
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.seq_module import SequenceDescriptor
from xmodule.capa_module import CapaDescriptor
from xmodule.contentstore.django import _CONTENTSTORE
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError
from xmodule.html_module import HtmlDescriptor
from openedx.core.djangoapps.util.testing import SignalDisconnectTestMixin
# some tests are failed if course indexing is switced on
# so we need to turn it off
FEATURES_WITHOUT_COURSE_INDEXING = settings.FEATURES.copy()
FEATURES_WITHOUT_COURSE_INDEXING['ENABLE_COURSEWARE_INDEX'] = False
class TemplateTests(unittest.TestCase):
@override_settings(FEATURES=FEATURES_WITHOUT_COURSE_INDEXING)
class TemplateTests(SignalDisconnectTestMixin, ModuleStoreTestCase):
"""
Test finding and using the templates (boilerplates) for xblocks.
"""
......
......@@ -20,9 +20,11 @@ from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey
from capa.tests.response_xml_factory import OptionResponseXMLFactory
from courseware.model_data import StudentModule
from courseware.tests.tests import LoginEnrollmentTestCase
from openedx.core.djangoapps.content.course_structures.signals import listen_for_course_publish
from openedx.core.djangoapps.util.testing import SignalDisconnectTestMixin
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.django import modulestore, SignalHandler
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
......@@ -108,6 +110,11 @@ class InstructorTaskCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase)
course = None
current_user = None
def setUp(self):
super(InstructorTaskCourseTestCase, self).setUp()
SignalHandler.course_published.connect(listen_for_course_publish)
self.addCleanup(SignalDisconnectTestMixin.disconnect_course_published_signals)
def initialize_course(self, course_factory_kwargs=None):
"""
Create a course in the store, with a chapter and section.
......
......@@ -554,6 +554,12 @@ FEATURES['ORGANIZATIONS_APP'] = True
if FEATURES.get('ORGANIZATIONS_APP') and "organizations" not in INSTALLED_APPS:
INSTALLED_APPS += ('organizations',)
# Disable course_published signals
# If we don't disconnect then tests take too much time to run since
# this signal is sent every time course or a course block is created
# via CourseFactory or ItemFactory
FEATURES['DISABLE_COURSE_PUBLISHED_SIGNAL'] = True
# Test mode. Used to let code that might otherwise affect global state know that it shouldn't
# (such as management commands.)
TEST_MODE = True
......@@ -3,6 +3,7 @@ Module for code that should run during LMS startup
"""
# pylint: disable=unused-argument
# pylint: disable=invalid-name
from django.conf import settings
......@@ -54,6 +55,9 @@ def run():
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
analytics.init(settings.SEGMENT_IO_LMS_KEY, flush_at=50)
if settings.FEATURES.get('DISABLE_COURSE_PUBLISHED_SIGNAL', False):
disable_course_published_signals()
def add_mimetypes():
"""
......@@ -155,6 +159,14 @@ def enable_third_party_auth():
auth_settings.apply_settings(settings)
def disable_course_published_signals():
"""
Disables course_published signal receivers in openedx.core.djangoapps
"""
from openedx.core.djangoapps.util.testing import SignalDisconnectTestMixin
SignalDisconnectTestMixin.disconnect_course_published_signals()
def startup_notification_subsystem():
"""
Initialize the Notification subsystem
......
"""
Setup the signals on startup.
"""
import openedx.core.djangoapps.content.course_structures.signals
import openedx.core.djangoapps.content.course_metadata.signals
"""
Setup the signals on startup.
"""
import openedx.core.djangoapps.content.course_metadata.signals # pylint: disable=unused-import
......@@ -7,7 +7,7 @@ from xmodule.modulestore.django import SignalHandler
from openedx.core.djangoapps.content.course_metadata.tasks import update_course_aggregate_metadata
@receiver(SignalHandler.course_published)
@receiver(SignalHandler.course_published, dispatch_uid='openedx.core.djangoapps.content.course_metadata')
def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument
"""
Receives signal and kicks off celery task to update course aggregate metadata
......
......@@ -9,12 +9,14 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from openedx.core.djangoapps.content.course_metadata.signals import listen_for_course_publish
from openedx.core.djangoapps.content.course_metadata.models import CourseAggregatedMetaData
from openedx.core.djangoapps.util.testing import SignalDisconnectTestMixin
class CoursesMetaDataTests(ModuleStoreTestCase):
""" Test suite for Course Meta Data """
def setUp(self):
SignalHandler.course_published.connect(listen_for_course_publish)
super(CoursesMetaDataTests, self).setUp()
self.course = CourseFactory.create()
......@@ -44,6 +46,8 @@ class CoursesMetaDataTests(ModuleStoreTestCase):
display_name="Html component"
)
self.addCleanup(SignalDisconnectTestMixin.disconnect_course_published_signals)
def test_course_aggregate_metadata_update_on_course_published(self):
"""
Test course aggregate metadata update receiver is called on course_published signal
......
......@@ -8,8 +8,8 @@ from xmodule.modulestore.django import SignalHandler
from .models import CourseOverview
@receiver(SignalHandler.course_published)
def _listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument
@receiver(SignalHandler.course_published, dispatch_uid='openedx.core.djangoapps.content.course_overviews')
def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument
"""
Catches the signal that a course has been published in Studio and
invalidates the corresponding CourseOverview cache entry if one exists.
......
......@@ -13,9 +13,11 @@ from lms.djangoapps.certificates.api import get_active_web_certificate
from lms.djangoapps.courseware.courses import course_image_url
from xmodule.course_metadata_utils import DEFAULT_START_DATE
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import SignalHandler
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls, check_mongo_calls_range
from openedx.core.djangoapps.util.testing import SignalDisconnectTestMixin
from openedx.core.djangoapps.content.course_overviews.signals import listen_for_course_publish
from .models import CourseOverview
......@@ -31,6 +33,11 @@ class CourseOverviewTestCase(ModuleStoreTestCase):
NEXT_WEEK = TODAY + datetime.timedelta(days=7)
NEXT_MONTH = TODAY + datetime.timedelta(days=30)
def setUp(self):
super(CourseOverviewTestCase, self).setUp()
SignalHandler.course_published.connect(listen_for_course_publish)
self.addCleanup(SignalDisconnectTestMixin.disconnect_course_published_signals)
def check_course_overview_against_course(self, course):
"""
Compares a CourseOverview object against its corresponding
......
"""
Setup the signals on startup.
"""
import openedx.core.djangoapps.content.course_structures.signals # pylint: disable=unused-import
"""
Course Structure api.py tests
"""
import mock
from django.core import cache
from .api import course_structure
from openedx.core.djangoapps.content.course_structures.signals import listen_for_course_publish
from xmodule.modulestore.django import SignalHandler
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
import mock
from django.core import cache
from openedx.core.djangoapps.content.course_structures.signals import listen_for_course_publish
from openedx.core.djangoapps.util.testing import SignalDisconnectTestMixin
class CourseStructureApiTests(ModuleStoreTestCase):
......@@ -42,14 +45,7 @@ class CourseStructureApiTests(ModuleStoreTestCase):
parent_location=self.vertical.location, category="html", display_name="My HTML"
)
self.addCleanup(self._disconnect_course_published_event)
def _disconnect_course_published_event(self):
"""
Disconnect course_published event.
"""
# If we don't disconnect then tests are getting failed in test_crud.py
SignalHandler.course_published.disconnect(listen_for_course_publish)
self.addCleanup(SignalDisconnectTestMixin.disconnect_course_published_signals)
def _expected_blocks(self, block_types=None, get_parent=False):
"""
......
......@@ -3,7 +3,7 @@ from django.dispatch.dispatcher import receiver
from xmodule.modulestore.django import SignalHandler
@receiver(SignalHandler.course_published)
@receiver(SignalHandler.course_published, dispatch_uid='openedx.core.djangoapps.content.course_structures')
def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument
# Import tasks here to avoid a circular import.
from .tasks import update_course_structure
......
......@@ -11,9 +11,14 @@ from student.tests.factories import CourseEnrollmentFactory, UserFactory
from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup
from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory
from openedx.core.djangoapps.content.course_structures.signals import listen_for_course_publish
from openedx.core.djangoapps.content.course_structures.signals import (
listen_for_course_publish as listener_in_course_structures
)
from openedx.core.djangoapps.content.course_metadata.signals import (
listen_for_course_publish as course_publish_listener
listen_for_course_publish as listener_in_course_metadata
)
from openedx.core.djangoapps.content.course_overviews.signals import (
listen_for_course_publish as listener_in_course_overviews
)
from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory
......@@ -217,10 +222,24 @@ class TestConditionalContent(ModuleStoreTestCase):
class SignalDisconnectTestMixin(object):
"""
Mixin for tests to disable calls to signals.listen_for_course_publish when the course_published signal is fired.
Mixin for tests to disable calls to signals.
"""
def setUp(self):
super(SignalDisconnectTestMixin, self).setUp()
SignalHandler.course_published.disconnect(listen_for_course_publish)
SignalHandler.course_published.disconnect(course_publish_listener)
SignalDisconnectTestMixin.disconnect_course_published_signals()
@staticmethod
def disconnect_course_published_signals():
"""
Disconnects receivers from course_published signals
"""
SignalHandler.course_published.disconnect(
listener_in_course_structures, dispatch_uid='openedx.core.djangoapps.content.course_structures'
)
SignalHandler.course_published.disconnect(
listener_in_course_metadata, dispatch_uid='openedx.core.djangoapps.content.course_metadata'
)
SignalHandler.course_published.disconnect(
listener_in_course_overviews, dispatch_uid='openedx.core.djangoapps.content.course_overviews'
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment