diff --git a/src/sentry/grouping/ingest/config.py b/src/sentry/grouping/ingest/config.py index ad2a0da9906310..e6b0fe4e67014f 100644 --- a/src/sentry/grouping/ingest/config.py +++ b/src/sentry/grouping/ingest/config.py @@ -17,6 +17,9 @@ Job = MutableMapping[str, Any] +# We are moving all projects off these configuration without waiting for events +CONFIGS_TO_DEPRECATE: list[str] = [] + def update_grouping_config_if_needed(project: Project) -> None: if _project_should_update_grouping(project): @@ -27,7 +30,9 @@ def _project_should_update_grouping(project: Project) -> bool: should_update_org = ( project.organization_id % 1000 < float(settings.SENTRY_GROUPING_AUTO_UPDATE_ENABLED) * 1000 ) - return bool(project.get_option("sentry:grouping_auto_update")) and should_update_org + is_deprecated_config = project.get_option("sentry:grouping_config") in CONFIGS_TO_DEPRECATE + auto_update = bool(project.get_option("sentry:grouping_auto_update")) + return is_deprecated_config or (auto_update and should_update_org) def _config_update_happened_recently(project: Project, tolerance: int) -> bool: @@ -79,6 +84,12 @@ def _auto_update_grouping(project: Project) -> None: "sentry:secondary_grouping_expiry": expiry, "sentry:grouping_config": new_config, } + # Any project on deprecated configs may be there only because auto updates are + # disabled (not because they want to use that specific config). This will reduce the + # chance of that happening unintentionally. + if current_config in CONFIGS_TO_DEPRECATE: + changes["sentry:grouping_auto_update"] = True + for key, value in changes.items(): project.update_option(key, value) diff --git a/tests/sentry/event_manager/test_event_manager_grouping.py b/tests/sentry/event_manager/test_event_manager_grouping.py index ccad39cc2470b3..4ddd1e8bc3c840 100644 --- a/tests/sentry/event_manager/test_event_manager_grouping.py +++ b/tests/sentry/event_manager/test_event_manager_grouping.py @@ -12,6 +12,7 @@ from sentry.conf.server import SENTRY_GROUPING_UPDATE_MIGRATION_PHASE from sentry.event_manager import _get_updated_group_title from sentry.eventtypes.base import DefaultEvent +from sentry.grouping.ingest.config import update_grouping_config_if_needed from sentry.grouping.result import CalculatedHashes from sentry.models.auditlogentry import AuditLogEntry from sentry.models.group import Group @@ -171,6 +172,37 @@ def test_auto_updates_grouping_config(self): ) assert actual_expiry == expected_expiry or actual_expiry == expected_expiry - 1 + def test_disabled_auto_update_does_not_update(self): + self.project.update_option("sentry:grouping_config", LEGACY_CONFIG) + + with override_settings(SENTRY_GROUPING_AUTO_UPDATE_ENABLED=True): + self.project.update_option("sentry:grouping_auto_update", False) + save_new_event({"message": "foo"}, self.project) + # It does not update the config because it is False + assert self.project.get_option("sentry:grouping_config") == LEGACY_CONFIG + + def test_deprecated_configs_upgrade_automatically(self): + # This is not yet a deprecated config but we will simulate it + self.project.update_option("sentry:grouping_config", "mobile:2021-02-12") + self.project.update_option("sentry:grouping_auto_update", False) + + with override_settings(SENTRY_GROUPING_AUTO_UPDATE_ENABLED=True): + update_grouping_config_if_needed(self.project) + # Nothing changes + assert self.project.get_option("sentry:grouping_config") == "mobile:2021-02-12" + assert self.project.get_option("sentry:grouping_auto_update") is False + + # XXX: In the future, once the mobile grouping is added to the list, we will remove this line + with mock.patch( + "sentry.grouping.ingest.config.CONFIGS_TO_DEPRECATE", + new=["mobile:2021-02-12"], + ): + update_grouping_config_if_needed(self.project) + # Even though auto update is disabled we have upgraded the project + assert self.project.get_option("sentry:grouping_config") == DEFAULT_GROUPING_CONFIG + # We have also updated the auto_update option + assert self.project.get_option("sentry:grouping_auto_update") is True + class PlaceholderTitleTest(TestCase): """