def test_get_autoassign_owners_only_codeowners_exists(self):
        # This case will never exist bc we create a ProjectOwnership record if none exists when creating a ProjectCodeOwner record.
        # We have this testcase for potential corrupt data.
        self.team = self.create_team(organization=self.organization,
                                     slug="tiger-team",
                                     members=[self.user])
        self.code_mapping = self.create_code_mapping(project=self.project)

        rule_a = Rule(Matcher("path", "*.js"), [Owner("team", self.team.slug)])

        self.create_codeowners(
            self.project,
            self.code_mapping,
            raw="*.js @tiger-team",
            schema=dump_schema([rule_a]),
        )
        # No data matches
        assert ProjectOwnership.get_autoassign_owners(self.project.id,
                                                      {}) == (False, [], False)

        # No autoassignment on match
        assert ProjectOwnership.get_autoassign_owners(
            self.project.id,
            {"stacktrace": {
                "frames": [{
                    "filename": "foo.js"
                }]
            }}) == (False, [self.team], True)
    def test_get_autoassign_owners_only_issueowners_exists(self):
        rule_a = Rule(Matcher("path", "*.py"), [Owner("team", self.team.slug)])
        rule_b = Rule(Matcher("path", "src/*"),
                      [Owner("user", self.user.email)])

        ProjectOwnership.objects.create(
            project_id=self.project.id,
            schema=dump_schema([rule_a, rule_b]),
        )

        # No data matches
        assert ProjectOwnership.get_autoassign_owners(self.project.id,
                                                      {}) == (False, [], False)

        # No autoassignment on match
        assert ProjectOwnership.get_autoassign_owners(
            self.project.id,
            {"stacktrace": {
                "frames": [{
                    "filename": "foo.py"
                }]
            }}) == (False, [self.team], False)

        # autoassignment is True
        owner = ProjectOwnership.objects.get(project_id=self.project.id)
        owner.auto_assignment = True
        owner.save()

        assert ProjectOwnership.get_autoassign_owners(
            self.project.id,
            {"stacktrace": {
                "frames": [{
                    "filename": "foo.py"
                }]
            }}) == (True, [self.team], False)
    def test_get_autoassign_owners_when_codeowners_and_issueowners_exists(
            self):
        self.team = self.create_team(organization=self.organization,
                                     slug="tiger-team",
                                     members=[self.user])
        self.team2 = self.create_team(organization=self.organization,
                                      slug="dolphin-team",
                                      members=[self.user])
        self.project = self.create_project(organization=self.organization,
                                           teams=[self.team, self.team2])
        self.code_mapping = self.create_code_mapping(project=self.project)

        rule_a = Rule(Matcher("path", "*.py"), [Owner("team", self.team.slug)])
        rule_b = Rule(Matcher("path", "src/*"),
                      [Owner("user", self.user.email)])
        rule_c = Rule(Matcher("path", "*.py"),
                      [Owner("team", self.team2.slug)])

        ProjectOwnership.objects.create(project_id=self.project.id,
                                        schema=dump_schema([rule_a, rule_b]),
                                        fallthrough=True)

        self.create_codeowners(self.project,
                               self.code_mapping,
                               raw="*.py @tiger-team",
                               schema=dump_schema([rule_c]))

        # No autoassignment on match
        assert ProjectOwnership.get_autoassign_owners(
            self.project.id,
            {"stacktrace": {
                "frames": [{
                    "filename": "api/foo.py"
                }]
            }}) == (False, [self.team, self.team2], False)
        # autoassignment is True
        owner = ProjectOwnership.objects.get(project_id=self.project.id)
        owner.auto_assignment = True
        owner.save()

        assert ProjectOwnership.get_autoassign_owners(
            self.project.id,
            {"stacktrace": {
                "frames": [{
                    "filename": "api/foo.py"
                }]
            }}) == (True, [self.team, self.team2], False)

        # # more than 2 matches
        assert ProjectOwnership.get_autoassign_owners(
            self.project.id,
            {"stacktrace": {
                "frames": [{
                    "filename": "src/foo.py"
                }]
            }}) == (True, [self.user, self.team], False)
Beispiel #4
0
def handle_owner_assignment(project, group, event):
    from sentry.models import GroupAssignee, ProjectOwnership

    with metrics.timer("post_process.handle_owner_assignment"):
        # Is the issue already assigned to a team or user?
        key = "assignee_exists:1:%s" % group.id
        owners_exists = cache.get(key)
        if owners_exists is None:
            owners_exists = group.assignee_set.exists() or group.groupowner_set.exists()
            # Cache for an hour if it's assigned. We don't need to move that fast.
            cache.set(key, owners_exists, 3600 if owners_exists else 60)
        if owners_exists:
            return

        auto_assignment, owners, assigned_by_codeowners = ProjectOwnership.get_autoassign_owners(
            group.project_id, event.data
        )
        if auto_assignment and owners:
            GroupAssignee.objects.assign(group, owners[0])
            if assigned_by_codeowners:
                analytics.record(
                    "codeowners.assignment",
                    organization_id=project.organization_id,
                    project_id=project.id,
                    group_id=group.id,
                )

        if owners:
            try:
                handle_group_owners(project, group, owners)
            except Exception:
                logger.exception("Failed to store group owners")
Beispiel #5
0
def handle_owner_assignment(project, group, event):
    from sentry.models import GroupAssignee, ProjectOwnership

    with metrics.timer("post_process.handle_owner_assignment"):
        owners_ingestion = features.has("projects:workflow-owners-ingestion",
                                        event.project)

        # Is the issue already assigned to a team or user?
        key = "assignee_exists:1:%s" % group.id
        owners_exists = cache.get(key)
        if owners_exists is None:
            owners_exists = group.assignee_set.exists() and (
                not owners_ingestion or group.groupowner_set.exists())
            # Cache for an hour if it's assigned. We don't need to move that fast.
            cache.set(key, owners_exists, 3600 if owners_exists else 60)
        if owners_exists:
            return

        auto_assignment, owners = ProjectOwnership.get_autoassign_owners(
            group.project_id, event.data)
        if auto_assignment and owners:
            GroupAssignee.objects.assign(group, owners[0])

        if owners and owners_ingestion:
            try:
                handle_group_owners(project, group, owners)
            except Exception:
                logger.exception("Failed to store group owners")
 def test_get_autoassign_owners_no_codeowners_or_issueowners(self):
     assert ProjectOwnership.get_autoassign_owners(self.project.id,
                                                   {}) == (False, [], False)
Beispiel #7
0
def handle_owner_assignment(project, group, event):
    from sentry.models import GroupAssignee, ProjectOwnership

    with metrics.timer("post_process.handle_owner_assignment"):
        with sentry_sdk.start_span(
                op="post_process.handle_owner_assignment.cache_set_owner"):
            owner_key = "owner_exists:1:%s" % group.id
            owners_exists = cache.get(owner_key)
            if owners_exists is None:
                owners_exists = group.groupowner_set.exists()
                # Cache for an hour if it's assigned. We don't need to move that fast.
                cache.set(owner_key, owners_exists,
                          3600 if owners_exists else 60)

        with sentry_sdk.start_span(
                op="post_process.handle_owner_assignment.cache_set_assignee"):
            # Is the issue already assigned to a team or user?
            assignee_key = "assignee_exists:1:%s" % group.id
            assignees_exists = cache.get(assignee_key)
            if assignees_exists is None:
                assignees_exists = group.assignee_set.exists()
                # Cache for an hour if it's assigned. We don't need to move that fast.
                cache.set(assignee_key, assignees_exists,
                          3600 if assignees_exists else 60)

        if owners_exists and assignees_exists:
            return

        with sentry_sdk.start_span(
                op="post_process.handle_owner_assignment.get_autoassign_owners"
        ):
            if killswitch_matches_context(
                    "post_process.get-autoassign-owners",
                {
                    "project_id": project.id,
                },
            ):
                # see ProjectOwnership.get_autoassign_owners
                auto_assignment = False
                owners = []
                assigned_by_codeowners = False
            else:
                (
                    auto_assignment,
                    owners,
                    assigned_by_codeowners,
                ) = ProjectOwnership.get_autoassign_owners(
                    group.project_id, event.data)

        with sentry_sdk.start_span(
                op="post_process.handle_owner_assignment.analytics_record"):
            if auto_assignment and owners and not assignees_exists:
                assignment = GroupAssignee.objects.assign(group,
                                                          owners[0],
                                                          create_only=True)
                if assignment["new_assignment"] or assignment[
                        "updated_assignment"]:
                    analytics.record(
                        "codeowners.assignment" if assigned_by_codeowners else
                        "issueowners.assignment",
                        organization_id=project.organization_id,
                        project_id=project.id,
                        group_id=group.id,
                    )

        with sentry_sdk.start_span(
                op="post_process.handle_owner_assignment.handle_group_owners"):
            if owners and not owners_exists:
                try:
                    handle_group_owners(project, group, owners)
                except Exception:
                    logger.exception("Failed to store group owners")