Commit d222b2d7 by Calen Pennington

Move bin-task enqueuing into a classmethod (rather than having it on the RecipientResolvers

parent 352fa067
...@@ -8,7 +8,6 @@ from openedx.core.djangoapps.schedules.utils import PrefixedDebugLoggerMixin ...@@ -8,7 +8,6 @@ from openedx.core.djangoapps.schedules.utils import PrefixedDebugLoggerMixin
class SendEmailBaseCommand(PrefixedDebugLoggerMixin, BaseCommand): class SendEmailBaseCommand(PrefixedDebugLoggerMixin, BaseCommand):
resolver_class = None # define in subclass
async_send_task = None # define in subclass async_send_task = None # define in subclass
def add_arguments(self, parser): def add_arguments(self, parser):
...@@ -24,20 +23,27 @@ class SendEmailBaseCommand(PrefixedDebugLoggerMixin, BaseCommand): ...@@ -24,20 +23,27 @@ class SendEmailBaseCommand(PrefixedDebugLoggerMixin, BaseCommand):
parser.add_argument('site_domain_name') parser.add_argument('site_domain_name')
def handle(self, *args, **options): def handle(self, *args, **options):
resolver = self.make_resolver(*args, **options) self.log_debug('Args = %r', options)
self.send_emails(resolver, *args, **options)
def make_resolver(self, *args, **options):
current_date = datetime.datetime( current_date = datetime.datetime(
*[int(x) for x in options['date'].split('-')], *[int(x) for x in options['date'].split('-')],
tzinfo=pytz.UTC tzinfo=pytz.UTC
) )
self.log_debug('Args = %r', options)
self.log_debug('Current date = %s', current_date.isoformat()) self.log_debug('Current date = %s', current_date.isoformat())
site = Site.objects.get(domain__iexact=options['site_domain_name']) site = Site.objects.get(domain__iexact=options['site_domain_name'])
self.log_debug('Running for site %s', site.domain) self.log_debug('Running for site %s', site.domain)
return self.resolver_class(site, current_date, async_send_task=self.async_send_task)
def send_emails(self, resolver, *args, **options): override_recipient_email = options.get('override_recipient_email')
self.send_emails(site, current_date, override_recipient_email)
def enqueue(self, day_offset, site, current_date, override_recipient_email=None):
self.async_send_task.enqueue(
site,
current_date,
day_offset,
override_recipient_email,
)
def send_emails(self, *args, **kwargs):
pass # define in subclass pass # define in subclass
from openedx.core.djangoapps.schedules.management.commands import SendEmailBaseCommand from openedx.core.djangoapps.schedules.management.commands import SendEmailBaseCommand
from openedx.core.djangoapps.schedules.resolvers import CourseUpdateResolver
from openedx.core.djangoapps.schedules.tasks import ScheduleCourseUpdate from openedx.core.djangoapps.schedules.tasks import ScheduleCourseUpdate
class Command(SendEmailBaseCommand): class Command(SendEmailBaseCommand):
resolver_class = CourseUpdateResolver
async_send_task = ScheduleCourseUpdate async_send_task = ScheduleCourseUpdate
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs) super(Command, self).__init__(*args, **kwargs)
self.log_prefix = 'Upgrade Reminder' self.log_prefix = 'Upgrade Reminder'
def send_emails(self, resolver, *args, **options): def send_emails(self, *args, **kwargs):
for day_offset in xrange(-7, -77, -7): for day_offset in xrange(-7, -77, -7):
resolver.send(day_offset, options.get('override_recipient_email')) self.enqueue(day_offset, *args, **kwargs)
from openedx.core.djangoapps.schedules.management.commands import SendEmailBaseCommand from openedx.core.djangoapps.schedules.management.commands import SendEmailBaseCommand
from openedx.core.djangoapps.schedules.resolvers import ScheduleStartResolver
from openedx.core.djangoapps.schedules.tasks import ScheduleRecurringNudge from openedx.core.djangoapps.schedules.tasks import ScheduleRecurringNudge
class Command(SendEmailBaseCommand): class Command(SendEmailBaseCommand):
resolver_class = ScheduleStartResolver
async_send_task = ScheduleRecurringNudge async_send_task = ScheduleRecurringNudge
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs) super(Command, self).__init__(*args, **kwargs)
self.log_prefix = 'Scheduled Nudge' self.log_prefix = 'Scheduled Nudge'
def send_emails(self, resolver, *args, **options): def send_emails(self, *args, **kwargs):
for day_offset in (-3, -10): for day_offset in (-3, -10):
resolver.send(day_offset, options.get('override_recipient_email')) self.enqueue(day_offset, *args, **kwargs)
from openedx.core.djangoapps.schedules.management.commands import SendEmailBaseCommand from openedx.core.djangoapps.schedules.management.commands import SendEmailBaseCommand
from openedx.core.djangoapps.schedules.resolvers import UpgradeReminderResolver
from openedx.core.djangoapps.schedules.tasks import ScheduleUpgradeReminder from openedx.core.djangoapps.schedules.tasks import ScheduleUpgradeReminder
class Command(SendEmailBaseCommand): class Command(SendEmailBaseCommand):
resolver_class = UpgradeReminderResolver
async_send_task = ScheduleUpgradeReminder async_send_task = ScheduleUpgradeReminder
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs) super(Command, self).__init__(*args, **kwargs)
self.log_prefix = 'Upgrade Reminder' self.log_prefix = 'Upgrade Reminder'
def send_emails(self, resolver, *args, **options): def send_emails(self, *args, **kwargs):
resolver.send(2, options.get('override_recipient_email')) self.enqueue(2, *args, **kwargs)
...@@ -18,24 +18,13 @@ from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_un ...@@ -18,24 +18,13 @@ from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_un
class TestSendEmailBaseCommand(CacheIsolationTestCase): class TestSendEmailBaseCommand(CacheIsolationTestCase):
def setUp(self): def setUp(self):
self.command = SendEmailBaseCommand() self.command = SendEmailBaseCommand()
self.site = SiteFactory()
def test_init_resolver_class(self): def test_handle(self):
assert self.command.resolver_class is None with patch.object(self.command, 'send_emails') as send_emails:
self.command.handle(site_domain_name=self.site.domain, date='2017-09-29')
def test_make_resolver(self): send_emails.assert_called_once_with(
with patch.object(self.command, 'resolver_class') as resolver_class: self.site,
example_site = SiteFactory(domain='example.com')
self.command.make_resolver(site_domain_name='example.com', date='2017-09-29')
resolver_class.assert_called_once_with(
example_site,
datetime.datetime(2017, 9, 29, tzinfo=pytz.UTC), datetime.datetime(2017, 9, 29, tzinfo=pytz.UTC),
async_send_task=None, None
) )
def test_handle(self):
with patch.object(self.command, 'make_resolver') as make_resolver:
make_resolver.return_value = 'resolver'
with patch.object(self.command, 'send_emails') as send_emails:
self.command.handle(date='2017-09-29')
make_resolver.assert_called_once_with(date='2017-09-29')
send_emails.assert_called_once_with('resolver', date='2017-09-29')
...@@ -60,35 +60,33 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase): ...@@ -60,35 +60,33 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase):
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True) DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
@patch.object(nudge.Command, 'resolver_class') @patch.object(nudge.Command, 'async_send_task')
def test_handle(self, mock_resolver): def test_handle(self, mock_send):
test_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC) test_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
nudge.Command().handle(date='2017-08-01', site_domain_name=self.site_config.site.domain) nudge.Command().handle(date='2017-08-01', site_domain_name=self.site_config.site.domain)
mock_resolver.assert_called_with(
self.site_config.site,
test_day,
async_send_task=nudge.Command.async_send_task,
)
for day in (-3, -10): for day in (-3, -10):
mock_resolver().send.assert_any_call(day, None) mock_send.enqueue.assert_any_call(
self.site_config.site,
test_day,
day,
None
)
@patch.object(tasks, 'ace') @patch.object(tasks, 'ace')
def test_resolver_send(self, mock_ace): def test_resolver_send(self, mock_ace):
current_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC) current_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
mock_schedule_bin = Mock() with patch.object(tasks.ScheduleRecurringNudge, 'apply_async') as mock_apply_async:
nudge.ScheduleStartResolver(self.site_config.site, current_day, mock_schedule_bin).send(-3) tasks.ScheduleRecurringNudge.enqueue(self.site_config.site, current_day, -3)
test_day = current_day + datetime.timedelta(days=-3) test_day = current_day + datetime.timedelta(days=-3)
self.assertFalse(mock_schedule_bin.called) mock_apply_async.assert_any_call(
mock_schedule_bin.apply_async.assert_any_call( (self.site_config.site.id, serialize(test_day), -3, 0, [], True, None),
(self.site_config.site.id, serialize(test_day), -3, 0, [], True, None), retry=False,
retry=False, )
) mock_apply_async.assert_any_call(
mock_schedule_bin.apply_async.assert_any_call( (self.site_config.site.id, serialize(test_day), -3, resolvers.RECURRING_NUDGE_NUM_BINS - 1, [], True, None),
(self.site_config.site.id, serialize(test_day), -3, resolvers.RECURRING_NUDGE_NUM_BINS - 1, [], True, None), retry=False,
retry=False, )
) self.assertFalse(mock_ace.send.called)
self.assertFalse(mock_ace.send.called)
@ddt.data(1, 10, 100) @ddt.data(1, 10, 100)
@patch.object(tasks, 'ace') @patch.object(tasks, 'ace')
...@@ -180,11 +178,12 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase): ...@@ -180,11 +178,12 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase):
mock_schedule_bin = Mock() mock_schedule_bin = Mock()
current_datetime = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC) current_datetime = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
nudge.ScheduleStartResolver( tasks.ScheduleRecurringNudge.enqueue(
self.site_config.site, self.site_config.site,
current_datetime, current_datetime,
mock_schedule_bin, mock_schedule_bin,
).send(3) 3
)
self.assertFalse(mock_schedule_bin.called) self.assertFalse(mock_schedule_bin.called)
self.assertFalse(mock_schedule_bin.apply_async.called) self.assertFalse(mock_schedule_bin.apply_async.called)
self.assertFalse(mock_ace.send.called) self.assertFalse(mock_ace.send.called)
......
...@@ -63,36 +63,34 @@ class TestUpgradeReminder(FilteredQueryCountMixin, CacheIsolationTestCase): ...@@ -63,36 +63,34 @@ class TestUpgradeReminder(FilteredQueryCountMixin, CacheIsolationTestCase):
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True) DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
@patch.object(reminder.Command, 'resolver_class') @patch.object(reminder.Command, 'async_send_task')
def test_handle(self, mock_resolver): def test_handle(self, mock_send):
test_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC) test_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
reminder.Command().handle(date='2017-08-01', site_domain_name=self.site_config.site.domain) reminder.Command().handle(date='2017-08-01', site_domain_name=self.site_config.site.domain)
mock_resolver.assert_called_with( mock_send.enqueue.assert_called_with(
self.site_config.site, self.site_config.site,
test_day, test_day,
async_send_task=reminder.Command.async_send_task, 2,
None
) )
mock_resolver().send.assert_any_call(2, None)
@patch.object(tasks, 'ace') @patch.object(tasks, 'ace')
def test_resolver_send(self, mock_ace): def test_resolver_send(self, mock_ace):
current_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC) current_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
test_day = current_day + datetime.timedelta(days=2) test_day = current_day + datetime.timedelta(days=2)
ScheduleFactory.create(upgrade_deadline=datetime.datetime(2017, 8, 3, 15, 34, 30, tzinfo=pytz.UTC)) ScheduleFactory.create(upgrade_deadline=datetime.datetime(2017, 8, 3, 15, 34, 30, tzinfo=pytz.UTC))
mock_schedule_bin = Mock()
reminder.UpgradeReminderResolver(self.site_config.site, current_day, mock_schedule_bin).send(2) with patch.object(tasks.ScheduleUpgradeReminder, 'apply_async') as mock_apply_async:
self.assertFalse(mock_schedule_bin.called) tasks.ScheduleUpgradeReminder.enqueue(self.site_config.site, current_day, 2)
mock_schedule_bin.apply_async.assert_any_call( mock_apply_async.assert_any_call(
(self.site_config.site.id, serialize(test_day), 2, 0, [], True, None), (self.site_config.site.id, serialize(test_day), 2, 0, [], True, None),
retry=False, retry=False,
) )
mock_schedule_bin.apply_async.assert_any_call( mock_apply_async.assert_any_call(
(self.site_config.site.id, serialize(test_day), 2, resolvers.UPGRADE_REMINDER_NUM_BINS - 1, [], True, None), (self.site_config.site.id, serialize(test_day), 2, resolvers.UPGRADE_REMINDER_NUM_BINS - 1, [], True, None),
retry=False, retry=False,
) )
self.assertFalse(mock_ace.send.called) self.assertFalse(mock_ace.send.called)
@ddt.data(1, 10, 100) @ddt.data(1, 10, 100)
@patch.object(tasks, 'ace') @patch.object(tasks, 'ace')
...@@ -164,11 +162,11 @@ class TestUpgradeReminder(FilteredQueryCountMixin, CacheIsolationTestCase): ...@@ -164,11 +162,11 @@ class TestUpgradeReminder(FilteredQueryCountMixin, CacheIsolationTestCase):
mock_schedule_bin = Mock() mock_schedule_bin = Mock()
current_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC) current_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
reminder.UpgradeReminderResolver( tasks.ScheduleUpgradeReminder.enqueue(
self.site_config.site, self.site_config.site,
current_day, current_day,
async_send_task=mock_schedule_bin, day_offset=3,
).send(3) )
self.assertFalse(mock_schedule_bin.called) self.assertFalse(mock_schedule_bin.called)
self.assertFalse(mock_schedule_bin.apply_async.called) self.assertFalse(mock_schedule_bin.apply_async.called)
self.assertFalse(mock_ace.send.called) self.assertFalse(mock_ace.send.called)
......
...@@ -13,13 +13,14 @@ from django.utils.formats import dateformat, get_format ...@@ -13,13 +13,14 @@ from django.utils.formats import dateformat, get_format
from edx_ace import ace from edx_ace import ace
from edx_ace.message import Message from edx_ace.message import Message
from edx_ace.recipient import Recipient from edx_ace.recipient import Recipient
from edx_ace.utils.date import deserialize from edx_ace.utils.date import deserialize, serialize
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.monitoring_utils import set_custom_metric from openedx.core.djangoapps.monitoring_utils import set_custom_metric
from openedx.core.djangoapps.schedules.models import Schedule, ScheduleConfig from openedx.core.djangoapps.schedules.models import Schedule, ScheduleConfig
from openedx.core.djangoapps.schedules import resolvers from openedx.core.djangoapps.schedules import resolvers
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
...@@ -68,12 +69,91 @@ def _recurring_nudge_schedule_send(site_id, msg_str): ...@@ -68,12 +69,91 @@ def _recurring_nudge_schedule_send(site_id, msg_str):
class ScheduleMessageBaseTask(Task): class ScheduleMessageBaseTask(Task):
ignore_result = True ignore_result = True
routing_key = ROUTING_KEY routing_key = ROUTING_KEY
num_bins = resolvers.DEFAULT_NUM_BINS
enqueue_config_var = None # define in subclass
log_prefix = None
@classmethod
def log_debug(cls, message, *args, **kwargs):
LOG.debug(cls.log_prefix + ': ' + message, *args, **kwargs)
@classmethod
def enqueue(cls, site, current_date, day_offset, override_recipient_email=None):
current_date = current_date.replace(hour=0, minute=0, second=0)
if not cls.is_enqueue_enabled(site):
cls.log_debug(
'Message queuing disabled for site %s', site.domain)
return
exclude_orgs, org_list = cls.get_course_org_filter(site)
target_date = current_date + datetime.timedelta(days=day_offset)
cls.log_debug('Target date = %s', target_date.isoformat())
for bin in range(cls.num_bins):
task_args = (
site.id,
serialize(target_date),
day_offset,
bin,
org_list,
exclude_orgs,
override_recipient_email,
)
cls.log_debug('Launching task with args = %r', task_args)
cls.apply_async(
task_args,
retry=False,
)
@classmethod
def is_enqueue_enabled(cls, site):
if cls.enqueue_config_var:
return getattr(ScheduleConfig.current(site), cls.enqueue_config_var)
return False
@classmethod
def get_course_org_filter(cls, site):
"""
Given the configuration of sites, get the list of orgs that should be included or excluded from this send.
Returns:
tuple: Returns a tuple (exclude_orgs, org_list). If exclude_orgs is True, then org_list is a list of the
only orgs that should be included in this send. If exclude_orgs is False, then org_list is a list of
orgs that should be excluded from this send. All other orgs should be included.
"""
try:
site_config = SiteConfiguration.objects.get(site_id=site.id)
org_list = site_config.get_value('course_org_filter')
exclude_orgs = False
if not org_list:
not_orgs = set()
for other_site_config in SiteConfiguration.objects.all():
other = other_site_config.get_value('course_org_filter')
if not isinstance(other, list):
if other is not None:
not_orgs.add(other)
else:
not_orgs.update(other)
org_list = list(not_orgs)
exclude_orgs = True
elif not isinstance(org_list, list):
org_list = [org_list]
except SiteConfiguration.DoesNotExist:
org_list = None
exclude_orgs = False
finally:
return exclude_orgs, org_list
class ScheduleRecurringNudge(ScheduleMessageBaseTask): class ScheduleRecurringNudge(ScheduleMessageBaseTask):
num_bins = resolvers.RECURRING_NUDGE_NUM_BINS
enqueue_config_var = 'enqueue_recurring_nudge'
log_prefix = 'Scheduled Nudge'
def run( def run(
self, site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None, self, site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None,
): ):
return resolvers.recurring_nudge_schedule_bin( return resolvers.ScheduleStartResolver().recurring_nudge_schedule_bin(
_recurring_nudge_schedule_send, _recurring_nudge_schedule_send,
site_id, site_id,
target_day_str, target_day_str,
...@@ -86,10 +166,15 @@ class ScheduleRecurringNudge(ScheduleMessageBaseTask): ...@@ -86,10 +166,15 @@ class ScheduleRecurringNudge(ScheduleMessageBaseTask):
class ScheduleUpgradeReminder(ScheduleMessageBaseTask): class ScheduleUpgradeReminder(ScheduleMessageBaseTask):
num_bins = resolvers.UPGRADE_REMINDER_NUM_BINS
enqueue_config_var = 'enqueue_upgrade_reminder'
log_prefix = 'Course Update'
def run( def run(
self, site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None, self, site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None,
): ):
return resolvers.upgrade_reminder_schedule_bin( return resolvers.UpgradeReminderResolver().upgrade_reminder_schedule_bin(
_upgrade_reminder_schedule_send, _upgrade_reminder_schedule_send,
site_id, site_id,
target_day_str, target_day_str,
...@@ -111,10 +196,14 @@ def _upgrade_reminder_schedule_send(site_id, msg_str): ...@@ -111,10 +196,14 @@ def _upgrade_reminder_schedule_send(site_id, msg_str):
class ScheduleCourseUpdate(ScheduleMessageBaseTask): class ScheduleCourseUpdate(ScheduleMessageBaseTask):
num_bins = resolvers.COURSE_UPDATE_NUM_BINS
enqueue_config_var = 'enqueue_course_update'
log_prefix = 'Course Update'
def run( def run(
self, site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None, self, site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None,
): ):
return resolvers.course_update_schedule_bin( return resolvers.CourseUpdateResolver().course_update_schedule_bin(
_course_update_schedule_send, _course_update_schedule_send,
site_id, site_id,
target_day_str, target_day_str,
......
...@@ -3,9 +3,9 @@ from unittest import skipUnless ...@@ -3,9 +3,9 @@ from unittest import skipUnless
import ddt import ddt
from django.conf import settings from django.conf import settings
from mock import patch from mock import patch, DEFAULT, Mock
from openedx.core.djangoapps.schedules.resolvers import BinnedSchedulesBaseResolver from openedx.core.djangoapps.schedules.tasks import ScheduleMessageBaseTask
from openedx.core.djangoapps.schedules.resolvers import DEFAULT_NUM_BINS from openedx.core.djangoapps.schedules.resolvers import DEFAULT_NUM_BINS
from openedx.core.djangoapps.schedules.tests.factories import ScheduleConfigFactory from openedx.core.djangoapps.schedules.tests.factories import ScheduleConfigFactory
from openedx.core.djangoapps.site_configuration.tests.factories import SiteConfigurationFactory, SiteFactory from openedx.core.djangoapps.site_configuration.tests.factories import SiteConfigurationFactory, SiteFactory
...@@ -16,68 +16,61 @@ from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_un ...@@ -16,68 +16,61 @@ from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_un
@skip_unless_lms @skip_unless_lms
@skipUnless('openedx.core.djangoapps.schedules.apps.SchedulesConfig' in settings.INSTALLED_APPS, @skipUnless('openedx.core.djangoapps.schedules.apps.SchedulesConfig' in settings.INSTALLED_APPS,
"Can't test schedules if the app isn't installed") "Can't test schedules if the app isn't installed")
class TestBinnedSchedulesBaseResolver(CacheIsolationTestCase): class TestScheduleMessageBaseTask(CacheIsolationTestCase):
def setUp(self): def setUp(self):
super(TestBinnedSchedulesBaseResolver, self).setUp() super(TestScheduleMessageBaseTask, self).setUp()
self.site = SiteFactory.create() self.site = SiteFactory.create()
self.site_config = SiteConfigurationFactory.create(site=self.site) self.site_config = SiteConfigurationFactory.create(site=self.site)
self.schedule_config = ScheduleConfigFactory.create(site=self.site) self.schedule_config = ScheduleConfigFactory.create(site=self.site)
self.basetask = ScheduleMessageBaseTask
def setup_resolver(self, site=None, current_date=None, async_send_task=None):
if site is None:
site = self.site
if current_date is None:
current_date = datetime.datetime.now()
resolver = BinnedSchedulesBaseResolver(self.site, current_date, async_send_task)
return resolver
def test_init_site(self):
resolver = self.setup_resolver()
assert resolver.site == self.site
def test_init_current_date(self):
current_time = datetime.datetime.now()
resolver = self.setup_resolver(current_date=current_time)
current_date = current_time.replace(hour=0, minute=0, second=0)
assert resolver.current_date == current_date
def test_init_async_send_task(self):
resolver = self.setup_resolver()
assert resolver.async_send_task is None
def test_init_num_bins(self):
resolver = self.setup_resolver()
assert resolver.num_bins == DEFAULT_NUM_BINS
def test_send_enqueue_disabled(self): def test_send_enqueue_disabled(self):
resolver = self.setup_resolver() send = Mock(name='async_send_task')
resolver.is_enqueue_enabled = lambda: False with patch.multiple(
with patch.object(resolver, 'async_send_task') as send: self.basetask,
with patch.object(resolver, 'log_debug') as log_debug: is_enqueue_enabled=Mock(return_value=False),
resolver.send(day_offset=2) log_debug=DEFAULT,
log_debug.assert_called_once_with('Message queuing disabled for site %s', self.site.domain) run=send,
send.apply_async.assert_not_called() ) as patches:
self.basetask.enqueue(
site=self.site,
current_date=datetime.datetime.now(),
day_offset=2
)
patches['log_debug'].assert_called_once_with(
'Message queuing disabled for site %s', self.site.domain)
send.apply_async.assert_not_called()
@ddt.data(0, 2, -3) @ddt.data(0, 2, -3)
def test_send_enqueue_enabled(self, day_offset): def test_send_enqueue_enabled(self, day_offset):
resolver = self.setup_resolver() send = Mock(name='async_send_task')
resolver.is_enqueue_enabled = lambda: True current_date = datetime.datetime.now()
resolver.get_course_org_filter = lambda: (False, None) with patch.multiple(
with patch.object(resolver, 'async_send_task') as send: self.basetask,
with patch.object(resolver, 'log_debug') as log_debug: is_enqueue_enabled=Mock(return_value=True),
resolver.send(day_offset=day_offset) get_course_org_filter=Mock(return_value=(False, None)),
target_date = resolver.current_date + datetime.timedelta(day_offset) log_debug=DEFAULT,
log_debug.assert_any_call('Target date = %s', target_date.isoformat()) run=send,
assert send.apply_async.call_count == DEFAULT_NUM_BINS ) as patches:
self.basetask.enqueue(
site=self.site,
current_date=current_date,
day_offset=day_offset
)
target_date = current_date.replace(hour=0, minute=0, second=0) + \
datetime.timedelta(day_offset)
print(patches['log_debug'].mock_calls)
patches['log_debug'].assert_any_call(
'Target date = %s', target_date.isoformat())
assert send.call_count == DEFAULT_NUM_BINS
@ddt.data(True, False) @ddt.data(True, False)
def test_is_enqueue_enabled(self, enabled): def test_is_enqueue_enabled(self, enabled):
resolver = self.setup_resolver() with patch.object(self.basetask, 'enqueue_config_var', 'enqueue_recurring_nudge'):
resolver.enqueue_config_var = 'enqueue_recurring_nudge' self.schedule_config.enqueue_recurring_nudge = enabled
self.schedule_config.enqueue_recurring_nudge = enabled self.schedule_config.save()
self.schedule_config.save() assert self.basetask.is_enqueue_enabled(self.site) == enabled
assert resolver.is_enqueue_enabled() == enabled
@ddt.unpack @ddt.unpack
@ddt.data( @ddt.data(
...@@ -85,10 +78,9 @@ class TestBinnedSchedulesBaseResolver(CacheIsolationTestCase): ...@@ -85,10 +78,9 @@ class TestBinnedSchedulesBaseResolver(CacheIsolationTestCase):
(['course1', 'course2'], ['course1', 'course2']) (['course1', 'course2'], ['course1', 'course2'])
) )
def test_get_course_org_filter_include(self, course_org_filter, expected_org_list): def test_get_course_org_filter_include(self, course_org_filter, expected_org_list):
resolver = self.setup_resolver()
self.site_config.values['course_org_filter'] = course_org_filter self.site_config.values['course_org_filter'] = course_org_filter
self.site_config.save() self.site_config.save()
exclude_orgs, org_list = resolver.get_course_org_filter() exclude_orgs, org_list = self.basetask.get_course_org_filter(self.site)
assert not exclude_orgs assert not exclude_orgs
assert org_list == expected_org_list assert org_list == expected_org_list
...@@ -99,12 +91,11 @@ class TestBinnedSchedulesBaseResolver(CacheIsolationTestCase): ...@@ -99,12 +91,11 @@ class TestBinnedSchedulesBaseResolver(CacheIsolationTestCase):
(['course1', 'course2'], [u'course1', u'course2']) (['course1', 'course2'], [u'course1', u'course2'])
) )
def test_get_course_org_filter_exclude(self, course_org_filter, expected_org_list): def test_get_course_org_filter_exclude(self, course_org_filter, expected_org_list):
resolver = self.setup_resolver()
self.other_site = SiteFactory.create() self.other_site = SiteFactory.create()
self.other_site_config = SiteConfigurationFactory.create( self.other_site_config = SiteConfigurationFactory.create(
site=self.other_site, site=self.other_site,
values={'course_org_filter': course_org_filter}, values={'course_org_filter': course_org_filter},
) )
exclude_orgs, org_list = resolver.get_course_org_filter() exclude_orgs, org_list = self.basetask.get_course_org_filter(self.site)
assert exclude_orgs assert exclude_orgs
self.assertItemsEqual(org_list, expected_org_list) self.assertItemsEqual(org_list, expected_org_list)
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