Browse Source

fix: Fix requires autoassignment types error on codeowners deletion (#48285)

Clear autoassigned_owner_cache when autoassignment is turned off.
Only clear the autoassigned_owner_cache in process_resource_change if
autoassignment is on.

Fixes SENTRY-Z88
Jodi Jang 1 year ago
parent
commit
f3b15b2f8b

+ 5 - 0
src/sentry/api/endpoints/project_ownership.py

@@ -8,6 +8,7 @@ from sentry.api.base import region_silo_endpoint
 from sentry.api.bases.project import ProjectEndpoint, ProjectOwnershipPermission
 from sentry.api.serializers import serialize
 from sentry.models import ProjectOwnership
+from sentry.models.groupowner import GroupOwner
 from sentry.models.project import Project
 from sentry.ownership.grammar import CODEOWNERS, create_schema_from_issue_owners
 from sentry.signals import ownership_rule_created
@@ -133,6 +134,10 @@ class ProjectOwnershipSerializer(serializers.Serializer):
             new_values["auto_assignment"] = True
             new_values["suspect_committer_auto_assignment"] = False
         if auto_assignment == "Turn off Auto-Assignment":
+            autoassignment_types = ProjectOwnership._get_autoassignment_types(ownership)
+            GroupOwner.invalidate_autoassigned_owner_cache(
+                ownership.project_id, autoassignment_types
+            )
             new_values["auto_assignment"] = False
             new_values["suspect_committer_auto_assignment"] = False
 

+ 2 - 1
src/sentry/models/projectcodeowners.py

@@ -145,7 +145,8 @@ def process_resource_change(instance, change, **kwargs):
         ownership = ProjectOwnership(project_id=instance.project_id)
 
     autoassignment_types = ProjectOwnership._get_autoassignment_types(ownership)
-    GroupOwner.invalidate_autoassigned_owner_cache(instance.project_id, autoassignment_types)
+    if ownership.auto_assignment:
+        GroupOwner.invalidate_autoassigned_owner_cache(instance.project_id, autoassignment_types)
     GroupOwner.invalidate_debounce_issue_owners_evaluation_cache(instance.project_id)
 
 

+ 43 - 0
tests/sentry/api/endpoints/test_project_ownership.py

@@ -1,13 +1,18 @@
+from datetime import timedelta
 from unittest import mock
 
 from django.urls import reverse
+from django.utils import timezone
 from rest_framework.exceptions import ErrorDetail
 
 from sentry import audit_log
 from sentry.models import AuditLogEntry, ProjectOwnership
+from sentry.models.group import Group
+from sentry.models.groupowner import ISSUE_OWNERS_DEBOUNCE_DURATION, GroupOwner, GroupOwnerType
 from sentry.testutils import APITestCase
 from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.silo import region_silo_test
+from sentry.utils.cache import cache
 
 
 @region_silo_test
@@ -356,3 +361,41 @@ class ProjectOwnershipEndpointTestCase(APITestCase):
         assert resp.data["dateCreated"] is not None
         assert resp.data["lastUpdated"] is not None
         assert resp.data["codeownersAutoSync"] is True
+
+    def test_turn_off_auto_assignment_clears_autoassignment_cache(self):
+        ProjectOwnership.objects.create(
+            project=self.project, raw="*.js member@localhost #tiger-team"
+        )
+        # Turn auto assignment on
+        self.client.put(self.path, {"autoAssignment": "Auto Assign to Issue Owner"})
+        auto_assignment_ownership = ProjectOwnership.objects.get(project=self.project)
+        auto_assignment_types = ProjectOwnership._get_autoassignment_types(
+            auto_assignment_ownership
+        )
+        # Get the cache keys
+        groups = Group.objects.filter(
+            project_id=self.project.id,
+            last_seen__gte=timezone.now() - timedelta(seconds=ISSUE_OWNERS_DEBOUNCE_DURATION),
+        ).values_list("id", flat=True)
+        auto_assignment_cache_keys = [
+            GroupOwner.get_autoassigned_cache_key(group.id, self.project.id, auto_assignment_types)
+            for group in groups
+        ]
+        assert auto_assignment_types == [
+            GroupOwnerType.OWNERSHIP_RULE.value,
+            GroupOwnerType.CODEOWNERS.value,
+        ]
+        # Assert the cache is set
+        for cache_key in auto_assignment_cache_keys:
+            assert cache.get(cache_key) is None
+
+        # Turn auto assignment off
+        self.client.put(self.path, {"autoAssignment": "Turn off Auto-Assignment"})
+        no_auto_assignment_ownership = ProjectOwnership.objects.get(project=self.project)
+        no_auto_assignment_types = ProjectOwnership._get_autoassignment_types(
+            no_auto_assignment_ownership
+        )
+        assert no_auto_assignment_types == []
+        # Assert that the autoassignment cache was cleared
+        for cache_key in auto_assignment_cache_keys:
+            assert cache.get(cache_key) is None