Browse Source

chore(similarity): Turn on ML grouping for new EA projects (#75026)

Add project option to turn on ML similarity grouping for newly created
projects that belong to an EA org
Jodi Jang 7 months ago
parent
commit
6fb96c49e8

+ 12 - 0
src/sentry/api/endpoints/team_projects.py

@@ -1,3 +1,5 @@
+import time
+
 from django.db import IntegrityError, router, transaction
 from drf_spectacular.utils import OpenApiResponse, extend_schema
 from rest_framework import serializers, status
@@ -21,6 +23,7 @@ from sentry.apidocs.parameters import CursorQueryParam, GlobalParams
 from sentry.apidocs.utils import inline_sentry_response_serializer
 from sentry.constants import RESERVED_PROJECT_SLUGS, ObjectStatus
 from sentry.models.project import Project
+from sentry.seer.similarity.utils import SEER_ELIGIBLE_PLATFORMS
 from sentry.signals import project_created
 from sentry.utils.snowflake import MaxSnowflakeRetryError
 
@@ -214,4 +217,13 @@ class TeamProjectsEndpoint(TeamEndpoint, EnvironmentMixin):
                 sender=self,
             )
 
+            # Create project option to turn on ML similarity feature for new EA projects
+            is_seer_eligible_platform = project.platform in SEER_ELIGIBLE_PLATFORMS
+            if (
+                project.organization.flags
+                and project.organization.flags.early_adopter
+                and is_seer_eligible_platform
+            ):
+                project.update_option("sentry:similarity_backfill_completed", int(time.time()))
+
         return Response(serialize(project, request.user), status=201)

+ 67 - 0
tests/sentry/api/endpoints/test_team_projects.py

@@ -3,6 +3,7 @@ from unittest.mock import Mock
 from sentry.api.endpoints.organization_projects_experiment import DISABLED_FEATURE_ERROR_STRING
 from sentry.constants import RESERVED_PROJECT_SLUGS
 from sentry.ingest import inbound_filters
+from sentry.models.options.project_option import ProjectOption
 from sentry.models.project import Project
 from sentry.models.rule import Rule
 from sentry.notifications.types import FallthroughChoiceType
@@ -65,6 +66,14 @@ class TeamProjectsCreateTest(APITestCase):
         assert project.platform == "python"
         assert project.teams.first() == self.team
 
+        # Assert project option is not set for non-EA organizations
+        assert (
+            ProjectOption.objects.get_value(
+                project=project, key="sentry:similarity_backfill_completed"
+            )
+            is None
+        )
+
     def test_invalid_numeric_slug(self):
         response = self.get_error_response(
             self.organization.slug,
@@ -228,3 +237,61 @@ class TeamProjectsCreateTest(APITestCase):
         }
         assert javascript_filter_states["web-crawlers"]
         assert javascript_filter_states["filtered-transaction"]
+
+    def test_similarity_project_option_valid(self):
+        """
+        Test that project option for similarity grouping is created for EA organizations
+        where the project platform is Seer-eligible.
+        """
+
+        self.organization.flags.early_adopter = True
+        self.organization.save()
+        response = self.get_success_response(
+            self.organization.slug,
+            self.team.slug,
+            **self.data,
+            status_code=201,
+        )
+
+        project = Project.objects.get(id=response.data["id"])
+        assert project.name == "foo"
+        assert project.slug == "bar"
+        assert project.platform == "python"
+        assert project.teams.first() == self.team
+
+        assert (
+            ProjectOption.objects.get_value(
+                project=project, key="sentry:similarity_backfill_completed"
+            )
+            is not None
+        )
+
+    def test_similarity_project_option_invalid(self):
+        """
+        Test that project option for similarity grouping is not created for EA organizations
+        where the project platform is not seer eligible.
+        """
+
+        self.organization.flags.early_adopter = True
+        self.organization.save()
+        response = self.get_success_response(
+            self.organization.slug,
+            self.team.slug,
+            name="foo",
+            slug="bar",
+            platform="php",
+            status_code=201,
+        )
+
+        project = Project.objects.get(id=response.data["id"])
+        assert project.name == "foo"
+        assert project.slug == "bar"
+        assert project.platform == "php"
+        assert project.teams.first() == self.team
+
+        assert (
+            ProjectOption.objects.get_value(
+                project=project, key="sentry:similarity_backfill_completed"
+            )
+            is None
+        )