Skip to content

Commit

Permalink
create ot activation cron job
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielRyanSmith committed May 12, 2024
1 parent 18f5096 commit a71f680
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cron.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ cron:
# - description: Check if any origin trials require creation
# url: /cron/create_origin_trials
# schedule: every 5 minutes
# - description: Check if any origin trials require activation
# url: /cron/activate_origin_trials
# schedule: every day 4:00
48 changes: 48 additions & 0 deletions internals/maintenance_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,3 +576,51 @@ def get_template_data(self, **kwargs):
stage.put()

return f'{len(ot_stages)} trial creation request(s) processed.'


class ActivateOriginTrials(FlaskHandler):

def _get_today(self):
return date.today()

def get_template_data(self, **kwargs):
"""Activate any origin trials that are flagged for activation."""
self.require_cron_header()

success_count, fail_count = 0, 0
today = self._get_today()
# Get all OT stages.
ot_stages: list[Stage] = Stage.query(
ndb.OR(
Stage.stage_type == STAGE_BLINK_ORIGIN_TRIAL,
Stage.stage_type == STAGE_FAST_ORIGIN_TRIAL,
Stage.stage_type == STAGE_DEP_DEPRECATION_TRIAL)).fetch()
for stage in ot_stages:
# Only process stages with a delayed activation date set.
if stage.ot_activation_date is None:
continue
# A stage with an activation date but no origin trial ID shouldn't be
# possible.
if stage.origin_trial_id is None:
logging.exception('Stage has a set activation date with no set origin '
f'trial ID. stage={stage.key.integer_id()}')
continue
if today >= stage.ot_activation_date:
logging.info(f'Activating trial {stage.origin_trial_id}')
try:
origin_trials_client.activate_origin_trial(stage.origin_trial_id)
except requests.RequestException:
cloud_tasks_helpers.enqueue_task(
'/tasks/email-ot-activation-failed',
{'stage': converters.stage_to_json_dict(stage)})
fail_count += 1
else:
cloud_tasks_helpers.enqueue_task(
'/tasks/email-ot-activated',
{'stage': converters.stage_to_json_dict(stage)})
stage.ot_activation_date = None
stage.put()
success_count += 1

return (f'{success_count} activation(s) successfully processed and '
f'{fail_count} activation(s) failed to process.')
115 changes: 115 additions & 0 deletions internals/maintenance_scripts_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,118 @@ def test_create_trials__failed_activation(
self.assertEqual('-444555666', self.ot_stage_2.origin_trial_id)
# OT 3 had no action request, so it should not have changed.
self.assertIsNone(self.ot_stage_3.origin_trial_id)


class ActivateOriginTrialsTest(testing_config.CustomTestCase):

def setUp(self):
self.feature_1 = FeatureEntry(
id=1, name='feature one', summary='sum', category=1, feature_type=0)
self.feature_1.put()
self.feature_2 = FeatureEntry(
id=2, name='feature one', summary='sum', category=1, feature_type=1)
self.feature_2.put()
self.ot_stage_1 = Stage(
feature_id=1, stage_type=150, ot_display_name='Example Trial',
origin_trial_id='111222333', ot_activation_date=date(2020, 1, 1),
ot_owner_email='feature_owner@google.com',
ot_chromium_trial_name='ExampleTrial',
milestones=MilestoneSet(desktop_first=100, desktop_last=106),
ot_documentation_url='https://example.com/docs',
ot_feedback_submission_url='https://example.com/feedback',
intent_thread_url='https://example.com/experiment',
ot_description='OT description', ot_has_third_party_support=True,
ot_is_deprecation_trial=False)
self.ot_stage_1.put()
self.ot_stage_1_dict = converters.stage_to_json_dict(self.ot_stage_1)

self.ot_stage_2 = Stage(
feature_id=2, stage_type=250, ot_display_name='Example Trial 2',
origin_trial_id='444555666', ot_activation_date=date(2020, 2, 15),
ot_owner_email='feature_owner2@google.com',
ot_chromium_trial_name='ExampleTrial2',
milestones=MilestoneSet(desktop_first=200, desktop_last=206),
ot_documentation_url='https://example.com/docs2',
ot_feedback_submission_url='https://example.com/feedback2',
intent_thread_url='https://example.com/experiment2',
ot_description='OT description2', ot_has_third_party_support=True,
ot_is_deprecation_trial=False)
self.ot_stage_2.put()
self.ot_stage_2_dict = converters.stage_to_json_dict(self.ot_stage_2)

self.ot_stage_3 = Stage(
feature_id=3, stage_type=450, ot_display_name='Example Trial 3',
origin_trial_id='777888999', ot_activation_date=date(2024, 1, 1),
ot_owner_email='feature_owner2@google.com',
ot_chromium_trial_name='ExampleTrial3',
milestones=MilestoneSet(desktop_first=200, desktop_last=206),
ot_documentation_url='https://example.com/docs3',
ot_feedback_submission_url='https://example.com/feedback3',
intent_thread_url='https://example.com/experiment3',
ot_description='OT description3', ot_has_third_party_support=True,
ot_is_deprecation_trial=True)
self.ot_stage_3
self.handler = maintenance_scripts.ActivateOriginTrials()

def tearDown(self):
for kind in [FeatureEntry, Stage]:
for entity in kind.query():
entity.key.delete()

@mock.patch('framework.cloud_tasks_helpers.enqueue_task')
@mock.patch('internals.maintenance_scripts.ActivateOriginTrials._get_today')
@mock.patch('framework.origin_trials_client.activate_origin_trial')
def test_activate_trials__faled(
self, mock_activate_origin_trial, mock_today, mock_enqueue_task):
"""Origin trials are activated if it is on or after the activation date."""

mock_today.return_value = date(2020, 6, 1) # 2020-06-01

result = self.handler.get_template_data()
self.assertEqual('2 activation(s) successfully processed and 0 '
'activation(s) failed to process.', result)
# Activation requests should have been sent.
mock_activate_origin_trial.assert_has_calls([
mock.call('111222333', ), mock.call('444555666')], any_order=True)
# Check that different email notifications were sent.
mock_enqueue_task.assert_has_calls([
mock.call(
'/tasks/email-ot-activated', {'stage': self.ot_stage_1_dict}),
mock.call(
'/tasks/email-ot-activated', {'stage': self.ot_stage_2_dict})
], any_order=True)
# Activation was handled, so a delayed activation date should not be set.
self.assertIsNone(self.ot_stage_1.ot_activation_date)
self.assertIsNone(self.ot_stage_2.ot_activation_date)
# OT 3 should still have delayed activation date set in the future.
self.assertEqual(date(2024, 1, 1), self.ot_stage_3.ot_activation_date)

@mock.patch('framework.cloud_tasks_helpers.enqueue_task')
@mock.patch('internals.maintenance_scripts.ActivateOriginTrials._get_today')
@mock.patch('framework.origin_trials_client.activate_origin_trial')
def test_activate_trials__failed(
self, mock_activate_origin_trial, mock_today, mock_enqueue_task):

mock_today.return_value = date(2020, 6, 1) # 2020-06-01
# Activate trial request is failing.
mock_activate_origin_trial.side_effect = requests.RequestException(
mock.Mock(status=503), 'Unavailable')

result = self.handler.get_template_data()
self.assertEqual('0 activation(s) successfully processed and 2 '
'activation(s) failed to process.', result)
# Activation requests should have been sent.
mock_activate_origin_trial.assert_has_calls([
mock.call('111222333', ), mock.call('444555666')], any_order=True)
# Failure notications should be sent to the OT support team.
mock_enqueue_task.assert_has_calls([
mock.call(
'/tasks/email-ot-activation-failed',
{'stage': self.ot_stage_1_dict}),
mock.call(
'/tasks/email-ot-activation-failed',
{'stage': self.ot_stage_2_dict})
], any_order=True)
# Activation wasn't handled, so activation dates should still be set.
self.assertIsNotNone(self.ot_stage_1.ot_activation_date)
self.assertIsNotNone(self.ot_stage_2.ot_activation_date)
2 changes: 2 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ class Route:
reminders.SendOTReminderEmailsHandler),
# TODO(DanielRyanSmith): Add this route when OT creation is fully implemented.
# Route('/cron/create_origin_trials', maintenance_scripts.CreateOriginTrials),
# Route('/cron/activate_origin_trials',
# maintenance_scripts.ActivateOriginTrials),

Route('/admin/find_stop_words', search_fulltext.FindStopWords),

Expand Down

0 comments on commit a71f680

Please sign in to comment.