Add setting for automated OT creation flag (#4122)
* Add setting for automated OT creation toggle * Update cron.yaml * add/change tests
This commit is contained in:
Родитель
ec9a9c1c51
Коммит
85faf4a48f
|
@ -25,6 +25,7 @@ from api import stages_api
|
|||
from internals.user_models import AppUser
|
||||
from internals.core_models import FeatureEntry, MilestoneSet, Stage
|
||||
from internals.review_models import Gate
|
||||
import settings
|
||||
|
||||
test_app = flask.Flask(__name__)
|
||||
|
||||
|
@ -178,7 +179,7 @@ class StagesAPITest(testing_config.CustomTestCase):
|
|||
with test_app.test_request_context(f'{self.request_path}1/stages/3001'):
|
||||
with self.assertRaises(werkzeug.exceptions.BadRequest):
|
||||
self.handler.do_get(feature_id=1, stage_id=3001)
|
||||
mock_abort.assert_called_once_with(404, description=f'Stage 3001 not found')
|
||||
mock_abort.assert_called_once_with(404, description='Stage 3001 not found')
|
||||
|
||||
@mock.patch('flask.abort')
|
||||
def test_get__no_id(self, mock_abort):
|
||||
|
@ -531,11 +532,11 @@ class StagesAPITest(testing_config.CustomTestCase):
|
|||
# Existing fields not specified should not be changed.
|
||||
self.assertEqual(stage.experiment_goals, 'To be the very best.')
|
||||
|
||||
@mock.patch('internals.notifier_helpers.send_ot_notification')
|
||||
def test_patch__ot_creation(self, mock_send_ot_notification):
|
||||
@mock.patch('internals.notifier_helpers.send_ot_creation_notification')
|
||||
def test_patch__ot_creation(self, mock_send_ot_creation_notification):
|
||||
"""A valid PATCH request should update an existing stage."""
|
||||
testing_config.sign_in('feature_owner@example.com', 123)
|
||||
mock_send_ot_notification.return_value = None
|
||||
mock_send_ot_creation_notification.return_value = None
|
||||
json = {
|
||||
'ot_action_requested': {
|
||||
'form_field_name': 'ot_action_requested',
|
||||
|
@ -558,16 +559,16 @@ class StagesAPITest(testing_config.CustomTestCase):
|
|||
# Existing fields not specified should not be changed.
|
||||
self.assertEqual(stage.experiment_goals, 'To be the very best.')
|
||||
# OT creation request notification should be sent.
|
||||
mock_send_ot_notification.assert_called_once()
|
||||
mock_send_ot_creation_notification.assert_called_once()
|
||||
|
||||
@mock.patch('internals.notifier_helpers.send_ot_notification')
|
||||
def test_patch__ot_extension(self, mock_send_ot_notification):
|
||||
@mock.patch('internals.notifier_helpers.send_ot_creation_notification')
|
||||
def test_patch__ot_extension(self, mock_send_ot_creation_notification):
|
||||
"""A valid PATCH request should update an existing stage."""
|
||||
testing_config.sign_in('feature_owner@example.com', 123)
|
||||
# extension stage type.
|
||||
self.stage_1.stage_type = 151
|
||||
self.stage_1.put()
|
||||
mock_send_ot_notification.return_value = None
|
||||
mock_send_ot_creation_notification.return_value = None
|
||||
json = {
|
||||
'ot_action_requested': {
|
||||
'form_field_name': 'ot_action_requested',
|
||||
|
@ -590,7 +591,7 @@ class StagesAPITest(testing_config.CustomTestCase):
|
|||
# Existing fields not specified should not be changed.
|
||||
self.assertEqual(stage.experiment_goals, 'To be the very best.')
|
||||
# OT extension request should NOT send a notification.
|
||||
mock_send_ot_notification.assert_not_called()
|
||||
mock_send_ot_creation_notification.assert_not_called()
|
||||
|
||||
def test_patch__ot_request_googler(self):
|
||||
"""A valid OT creation request from a googler should update stage."""
|
||||
|
|
14
cron.yaml
14
cron.yaml
|
@ -38,11 +38,9 @@ cron:
|
|||
- description: Send origin trial process reminder emails.
|
||||
url: /cron/send-ot-process-reminders
|
||||
schedule: every monday 4:00
|
||||
|
||||
# TODO(DanielRyanSmith): Add this job when OT creation is fully implemented.
|
||||
# - 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
|
||||
- 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 9:00
|
||||
|
|
|
@ -378,9 +378,11 @@ class EntitiesAPIHandler(APIHandler):
|
|||
stage.put()
|
||||
|
||||
# Notify of OT creation request if one was sent.
|
||||
# This notification is for non-automated OT creation only.
|
||||
if (ot_action_requested and
|
||||
stage.stage_type in ALL_ORIGIN_TRIAL_STAGE_TYPES):
|
||||
notifier_helpers.send_ot_notification(stage)
|
||||
stage.stage_type in ALL_ORIGIN_TRIAL_STAGE_TYPES and
|
||||
not settings.AUTOMATED_OT_CREATION):
|
||||
notifier_helpers.send_ot_creation_notification(stage)
|
||||
|
||||
return stage_was_updated
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ from internals.data_types import StageDict
|
|||
from internals.review_models import Gate, Vote, Activity
|
||||
from internals.core_enums import *
|
||||
from internals.feature_links import batch_index_feature_entries
|
||||
import settings
|
||||
|
||||
class EvaluateGateStatus(FlaskHandler):
|
||||
|
||||
|
@ -571,6 +572,8 @@ class CreateOriginTrials(FlaskHandler):
|
|||
def get_template_data(self, **kwargs):
|
||||
"""Create any origin trials that are flagged for creation."""
|
||||
self.require_cron_header()
|
||||
if not settings.AUTOMATED_OT_CREATION:
|
||||
return 'Automated OT creation process is not active.'
|
||||
|
||||
# OT stages that are flagged to process a trial creation.
|
||||
ot_stages: list[Stage] = Stage.query(
|
||||
|
@ -597,6 +600,8 @@ class ActivateOriginTrials(FlaskHandler):
|
|||
them.
|
||||
"""
|
||||
self.require_cron_header()
|
||||
if not settings.AUTOMATED_OT_CREATION:
|
||||
return 'Automated OT creation process is not active.'
|
||||
|
||||
success_count, fail_count = 0, 0
|
||||
today = self._get_today()
|
||||
|
|
|
@ -23,6 +23,7 @@ from internals import maintenance_scripts
|
|||
from internals import core_enums
|
||||
from internals.core_models import FeatureEntry, Stage, MilestoneSet
|
||||
from internals.review_models import Gate, Vote
|
||||
import settings
|
||||
|
||||
class AssociateOTsTest(testing_config.CustomTestCase):
|
||||
|
||||
|
@ -278,10 +279,14 @@ class CreateOriginTrialsTest(testing_config.CustomTestCase):
|
|||
self.ot_stage_3
|
||||
self.handler = maintenance_scripts.CreateOriginTrials()
|
||||
|
||||
# Needs to be set in order to test any functionality here.
|
||||
settings.AUTOMATED_OT_CREATION = True
|
||||
|
||||
def tearDown(self):
|
||||
for kind in [FeatureEntry, Stage]:
|
||||
for entity in kind.query():
|
||||
entity.key.delete()
|
||||
settings.AUTOMATED_OT_CREATION = False
|
||||
|
||||
@mock.patch('framework.cloud_tasks_helpers.enqueue_task')
|
||||
@mock.patch('internals.maintenance_scripts.CreateOriginTrials._get_today')
|
||||
|
@ -432,6 +437,12 @@ class CreateOriginTrialsTest(testing_config.CustomTestCase):
|
|||
# OT 3 had no action request, so it should not have changed.
|
||||
self.assertIsNone(self.ot_stage_3.origin_trial_id)
|
||||
|
||||
def test_create_trials__automation_not_active(self):
|
||||
"""Cron job doesn't run when automated creation is not turned on."""
|
||||
settings.AUTOMATED_OT_CREATION = False
|
||||
|
||||
result = self.handler.get_template_data()
|
||||
self.assertEqual('Automated OT creation process is not active.', result)
|
||||
|
||||
class ActivateOriginTrialsTest(testing_config.CustomTestCase):
|
||||
|
||||
|
@ -487,10 +498,14 @@ class ActivateOriginTrialsTest(testing_config.CustomTestCase):
|
|||
self.ot_stage_3
|
||||
self.handler = maintenance_scripts.ActivateOriginTrials()
|
||||
|
||||
# Needs to be set in order to test any functionality here.
|
||||
settings.AUTOMATED_OT_CREATION = True
|
||||
|
||||
def tearDown(self):
|
||||
for kind in [FeatureEntry, Stage]:
|
||||
for entity in kind.query():
|
||||
entity.key.delete()
|
||||
settings.AUTOMATED_OT_CREATION = False
|
||||
|
||||
@mock.patch('framework.cloud_tasks_helpers.enqueue_task')
|
||||
@mock.patch('internals.maintenance_scripts.ActivateOriginTrials._get_today')
|
||||
|
@ -551,6 +566,13 @@ class ActivateOriginTrialsTest(testing_config.CustomTestCase):
|
|||
self.assertIsNotNone(self.ot_stage_1.ot_activation_date)
|
||||
self.assertIsNotNone(self.ot_stage_2.ot_activation_date)
|
||||
|
||||
def test_activate_trials__automation_not_active(self):
|
||||
"""Cron job doesn't run when automated creation is not turned on."""
|
||||
settings.AUTOMATED_OT_CREATION = False
|
||||
|
||||
result = self.handler.get_template_data()
|
||||
self.assertEqual('Automated OT creation process is not active.', result)
|
||||
|
||||
|
||||
class DeleteEmptyExtensionStagesTest(testing_config.CustomTestCase):
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ def notify_subscribers_of_new_comments(fe: 'FeatureEntry', gate: Gate,
|
|||
cloud_tasks_helpers.enqueue_task('/tasks/email-comments', params)
|
||||
|
||||
|
||||
def send_ot_notification(stage: Stage):
|
||||
def send_ot_creation_notification(stage: Stage):
|
||||
"""Notify about new trial creation request."""
|
||||
stage_dict = converters.stage_to_json_dict(stage)
|
||||
# Add the OT request note, which is usually not publicly visible.
|
||||
|
|
|
@ -38,6 +38,9 @@ DEFAULT_COMPONENT = 'Blink'
|
|||
# The default component for enterprise features.
|
||||
DEFAULT_ENTERPRISE_COMPONENT = 'Enterprise'
|
||||
|
||||
# Enable to activate the automated OT creation process
|
||||
AUTOMATED_OT_CREATION = False
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче