diff --git a/gso/schedules/validate_subscriptions.py b/gso/schedules/validate_subscriptions.py index db3573802cd6d9fb29438068fa3737a57f0b4bf9..fb728a1a967d1b24156bd2d48f6cf17201e36a5c 100644 --- a/gso/schedules/validate_subscriptions.py +++ b/gso/schedules/validate_subscriptions.py @@ -7,6 +7,8 @@ From this list, each workflow is selected that meets the following: * The name of the workflow follows the pattern `validate_*`. """ +import re + import structlog from celery import shared_task from orchestrator.services.processes import get_execution_context @@ -37,6 +39,17 @@ def validate_subscriptions() -> None: return for subscription in subscriptions: + if re.search(r"SKIP VALIDATION: .+", subscription.note or ""): + # The subscription is marked to skip validation altogether. We continue to the next subscription. + logger.warning( + "Manually skipped validation workflows for a subscription.", + product=subscription.product.name, + subscription_id=subscription.subscription_id, + subscription_description=subscription.description, + skip_reason=subscription.note, + ) + continue + found_a_validation_workflow = False for workflow in subscription.product.workflows: if workflow.target == Target.SYSTEM and workflow.name.startswith("validate_"): diff --git a/test/schedules/test_scheduling.py b/test/schedules/test_scheduling.py index a1eb56b48a4d0023c527635701ba85dbfa5a4bab..8f6feafcc1b62b7522e4f85786e8a4e288217bb8 100644 --- a/test/schedules/test_scheduling.py +++ b/test/schedules/test_scheduling.py @@ -93,7 +93,10 @@ def test_subscriptions_without_system_target_workflow( mock_logger, validate_subscriptions, ): - mock_get_active_subscriptions.return_value = [MagicMock(product=MagicMock(workflows=[]))] + subscription_mock = MagicMock() + subscription_mock.product.workflows = [] + subscription_mock.note = None + mock_get_active_subscriptions.return_value = [subscription_mock] validate_subscriptions() mock_logger.warning.assert_called_once() @@ -106,6 +109,7 @@ def test_subscription_status_not_usable( subscription_mock = MagicMock() subscription_mock.product.workflows = [MagicMock(target=Target.SYSTEM, name="workflow_name")] subscription_mock.status = "Not Usable Status" + subscription_mock.note = None mock_get_active_subscriptions.return_value = [subscription_mock] validate_subscriptions() @@ -123,6 +127,7 @@ def test_valid_subscriptions_for_validation( mocked_workflow = MagicMock(target=Target.SYSTEM, name="workflow_name") subscription_mock.product.workflows = [mocked_workflow] subscription_mock.status = "active" + subscription_mock.note = None mock_get_active_subscriptions.return_value = [subscription_mock] validate_subscriptions() validate_func = mock_get_execution_context()["validate"] @@ -130,3 +135,18 @@ def test_valid_subscriptions_for_validation( mocked_workflow.name, json=[{"subscription_id": str(subscription_mock.subscription_id)}], ) + + +def test_subscription_skipped_with_note( + mock_get_active_subscriptions, + mock_get_execution_context, + validate_subscriptions, +): + subscription_mock = MagicMock() + subscription_mock.product.workflows = [MagicMock(target=Target.SYSTEM, name="workflow_name")] + subscription_mock.note = "SKIP VALIDATION: Because we don't want to." + mock_get_active_subscriptions.return_value = [subscription_mock] + validate_subscriptions() + + validate_func = mock_get_execution_context()["validate"] + validate_func.assert_not_called()