コード例 #1
0
    def add_user_to_cohorts_race_condition(self, mock_tracker):
        """
        Makes use of before_after to force a race condition, in order to
        confirm handling of such conditions is done correctly.
        """
        course_user = UserFactory(username="******", email="*****@*****.**")
        course = modulestore().get_course(self.toy_course_key)
        CourseEnrollment.enroll(course_user, self.toy_course_key)
        first_cohort = CohortFactory(course_id=course.id, name="FirstCohort")
        second_cohort = CohortFactory(course_id=course.id, name="SecondCohort")

        # This before_after contextmanager allows for reliable reproduction of a race condition.
        # It will break before the first save() call creates an entry, and then run add_user_to_cohort again.
        # Because this second call will write before control is returned, the first call will be writing stale data.
        # This test confirms that the first add_user_to_cohort call can handle this stale read condition properly.
        # Proper handling is defined as treating calls as sequential, with write time deciding the order.
        with before_after.before_after('django.db.models.Model.save',
                                       after_ftn=cohorts.add_user_to_cohort(
                                           second_cohort,
                                           course_user.username),
                                       autospec=True):
            # This method will read, then break, then try to write stale data.
            # It should fail at that, then retry with refreshed data
            cohorts.add_user_to_cohort(first_cohort, course_user.username)

        mock_tracker.emit.assert_any_call(
            "edx.cohort.user_add_requested", {
                "user_id": course_user.id,
                "cohort_id": first_cohort.id,
                "cohort_name": first_cohort.name,
                "previous_cohort_id": second_cohort.id,
                "previous_cohort_name": second_cohort.name,
            })
        # Note that the following get() will fail with MultipleObjectsReturned if race condition is not handled.
        self.assertEqual(first_cohort.users.get(), course_user)
コード例 #2
0
    def test_before_and_after(self):
        def before_fn(*a):
            test_functions.test_list.append(1)

        def after_fn(*a):
            test_functions.test_list.append(3)

        with before_after('before_after.tests.test_functions.sample_fn',
                          before_fn=before_fn,
                          after_fn=after_fn):
            test_functions.sample_fn(2)

        self.assertEqual(test_functions.test_list, [1, 2, 3])
コード例 #3
0
    def add_user_to_cohorts_race_condition(self, mock_tracker):
        """
        Makes use of before_after to force a race condition, in order to
        confirm handling of such conditions is done correctly.
        """
        course_user = UserFactory(username="******", email="*****@*****.**")
        course = modulestore().get_course(self.toy_course_key)
        CourseEnrollment.enroll(course_user, self.toy_course_key)
        first_cohort = CohortFactory(course_id=course.id, name="FirstCohort")
        second_cohort = CohortFactory(course_id=course.id, name="SecondCohort")

        # This before_after contextmanager allows for reliable reproduction of a race condition.
        # It will break before the first save() call creates an entry, and then run add_user_to_cohort again.
        # Because this second call will write before control is returned, the first call will be writing stale data.
        # This test confirms that the first add_user_to_cohort call can handle this stale read condition properly.
        # Proper handling is defined as treating calls as sequential, with write time deciding the order.
        with before_after.before_after(
            'django.db.models.Model.save',
            after_ftn=cohorts.add_user_to_cohort(second_cohort, course_user.username),
            autospec=True
        ):
            # This method will read, then break, then try to write stale data.
            # It should fail at that, then retry with refreshed data
            cohorts.add_user_to_cohort(first_cohort, course_user.username)

        mock_tracker.emit.assert_any_call(
            "edx.cohort.user_add_requested",
            {
                "user_id": course_user.id,
                "cohort_id": first_cohort.id,
                "cohort_name": first_cohort.name,
                "previous_cohort_id": second_cohort.id,
                "previous_cohort_name": second_cohort.name,
            }
        )
        # Note that the following get() will fail with MultipleObjectsReturned if race condition is not handled.
        self.assertEqual(first_cohort.users.get(), course_user)