示例#1
0
    def test_get_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])
        )

        self.assert_ownership_equals(
            ProjectOwnership.get_owners(
                self.project.id, {"stacktrace": {"frames": [{"filename": "api/foo.py"}]}}
            ),
            (
                [ActorTuple(self.team.id, Team), ActorTuple(self.team2.id, Team)],
                [rule_a, rule_c],
            ),
        )
示例#2
0
    def setUp(self):
        self.user = self.create_user(email="*****@*****.**", is_active=True)
        self.user2 = self.create_user(email="*****@*****.**", is_active=True)
        self.organization = self.create_organization(owner=self.user)
        self.team = self.create_team(organization=self.organization)

        self.project = self.create_project(name="Test", teams=[self.team])
        OrganizationMemberTeam.objects.create(
            organizationmember=OrganizationMember.objects.get(
                user=self.user, organization=self.organization
            ),
            team=self.team,
        )
        self.create_member(user=self.user2, organization=self.organization, teams=[self.team])
        ProjectOwnership.objects.create(
            project_id=self.project.id,
            schema=dump_schema(
                [
                    Rule(Matcher("path", "*.py"), [Owner("team", self.team.slug)]),
                    Rule(Matcher("path", "*.jx"), [Owner("user", self.user2.email)]),
                    Rule(
                        Matcher("path", "*.cbl"),
                        [Owner("user", self.user.email), Owner("user", self.user2.email)],
                    ),
                ]
            ),
            fallthrough=True,
        )
示例#3
0
    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)
示例#4
0
    def test_multiple_owners_order_matters(self):
        users = [self.user, self.user2, self.user3]
        rules = [
            Rule(Matcher("path", "*.py"), [Owner("user", users[0].email)]),
            Rule(Matcher("path", "*foo*"), [Owner("user", users[1].email)]),
            Rule(Matcher("path", "*"), [Owner("user", users[2].email)]),
        ]
        rules.reverse()

        ProjectOwnership.objects.create(
            project_id=self.project.id, schema=dump_schema(rules), fallthrough=True
        )

        event1 = self.store_event(
            data={"stacktrace": {"frames": [{"filename": "foo.py"}]}}, project_id=self.project.id
        )

        self.path = reverse(
            "sentry-api-0-event-owners",
            kwargs={
                "organization_slug": self.organization.slug,
                "project_slug": self.project.slug,
                "event_id": event1.event_id,
            },
        )

        resp = self.client.get(self.path)
        assert resp.status_code == 200
        assert len(resp.data["owners"]) == 3
        assert [o["id"] for o in resp.data["owners"]] == [str(u.id) for u in reversed(users)]
        assert resp.data["rule"] == Matcher("path", "*")
        assert len(resp.data["rules"]) == 3
示例#5
0
def test_parse_rules():
    assert parse_rules(fixture_data) == [
        Rule(Matcher("path", "*.js"), [Owner("team", "frontend"), Owner("user", "*****@*****.**")]),
        Rule(Matcher("url", "http://google.com/*"), [Owner("team", "backend")]),
        Rule(Matcher("path", "src/sentry/*"), [Owner("user", "*****@*****.**")]),
        Rule(Matcher("tags.foo", "bar"), [Owner("user", "*****@*****.**")]),
        Rule(Matcher("tags.foo", "bar baz"), [Owner("user", "*****@*****.**")]),
    ]
示例#6
0
    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)
示例#7
0
def test_parse_rules():
    assert parse_rules(fixture_data) == [
        Rule(Matcher('path', '*.js'),
             [Owner('team', 'frontend'),
              Owner('user', '*****@*****.**')]),
        Rule(Matcher('url', 'http://google.com/*'),
             [Owner('team', 'backend')]),
        Rule(Matcher('path', 'src/sentry/*'),
             [Owner('user', '*****@*****.**')]),
    ]
示例#8
0
    def test_get_owners_basic(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]), fallthrough=True
        )

        # No data matches
        assert ProjectOwnership.get_owners(self.project.id, {}) == (ProjectOwnership.Everyone, None)

        # Match only rule_a
        self.assert_ownership_equals(
            ProjectOwnership.get_owners(
                self.project.id, {"stacktrace": {"frames": [{"filename": "foo.py"}]}}
            ),
            ([Actor(self.team.id, Team)], [rule_a]),
        )

        # Match only rule_b
        self.assert_ownership_equals(
            ProjectOwnership.get_owners(
                self.project.id, {"stacktrace": {"frames": [{"filename": "src/thing.txt"}]}}
            ),
            ([Actor(self.user.id, User)], [rule_b]),
        )

        # Matches both rule_a and rule_b
        self.assert_ownership_equals(
            ProjectOwnership.get_owners(
                self.project.id, {"stacktrace": {"frames": [{"filename": "src/foo.py"}]}}
            ),
            ([Actor(self.team.id, Team), Actor(self.user.id, User)], [rule_a, rule_b]),
        )

        assert ProjectOwnership.get_owners(
            self.project.id, {"stacktrace": {"frames": [{"filename": "xxxx"}]}}
        ) == (ProjectOwnership.Everyone, None)

        # When fallthrough = False, we don't implicitly assign to Everyone
        owner = ProjectOwnership.objects.get(project_id=self.project.id)
        owner.fallthrough = False
        owner.save()

        assert ProjectOwnership.get_owners(
            self.project.id, {"stacktrace": {"frames": [{"filename": "xxxx"}]}}
        ) == ([], None)

        self.assert_ownership_equals(
            ProjectOwnership.get_owners(
                self.project.id, {"stacktrace": {"frames": [{"filename": "src/foo.py"}]}}
            ),
            ([Actor(self.team.id, Team), Actor(self.user.id, User)], [rule_a, rule_b]),
        )
示例#9
0
    def make_ownership(self):
        rule_a = Rule(Matcher("path", "src/*"), [Owner("user", self.user.email)])
        rule_b = Rule(Matcher("path", "tests/*"), [Owner("team", self.team.name)])
        rule_c = Rule(Matcher("path", "src/app/*"), [Owner("team", self.team.name)])

        ProjectOwnership.objects.create(
            project_id=self.project.id,
            schema=dump_schema([rule_a, rule_b, rule_c]),
            fallthrough=True,
            auto_assignment=True,
        )
示例#10
0
文件: tests.py 项目: snilwx/sentry
    def make_ownership(self, extra_rules=None):
        rules = [
            Rule(Matcher("path", "src/*"), [Owner("user", self.user.email)]),
            Rule(Matcher("path", "tests/*"), [Owner("team", self.team.name)]),
            Rule(Matcher("path", "src/app/*"), [Owner("team", self.team.name)]),
        ]
        if extra_rules:
            rules.extend(extra_rules)

        ProjectOwnership.objects.create(
            project_id=self.project.id,
            schema=dump_schema(rules),
            fallthrough=True,
            auto_assignment=True,
        )
示例#11
0
    def test_matching_non_existing_owner(self):
        rule_a = Rule(Matcher("path", "*"),
                      [Owner("user", "*****@*****.**")])

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

        event1 = self.store_event(
            data={"stacktrace": {
                "frames": [{
                    "filename": "foo.py"
                }]
            }},
            project_id=self.project.id)

        self.path = reverse(
            "sentry-api-0-event-owners",
            kwargs={
                "organization_slug": self.organization.slug,
                "project_slug": self.project.slug,
                "event_id": event1.event_id,
            },
        )

        resp = self.client.get(self.path)
        assert resp.status_code == 200
        assert len(resp.data["owners"]) == 0
        assert resp.data["rule"] == Matcher(type="path", pattern="*")
        assert len(resp.data["rules"]) == 1
示例#12
0
文件: tests.py 项目: snilwx/sentry
    def test_owner_assignment_extra_groups(self):
        extra_user = self.create_user()
        self.create_team_membership(self.team, user=extra_user)
        self.make_ownership(
            [Rule(Matcher("path", "src/app/things/in/*"), [Owner("user", extra_user.email)])],
        )
        event = self.store_event(
            data={
                "message": "oh no",
                "platform": "python",
                "stacktrace": {"frames": [{"filename": "src/app/things/in/a/path/example2.py"}]},
            },
            project_id=self.project.id,
        )
        cache_key = write_event_to_cache(event)
        post_process_group(
            is_new=False,
            is_regression=False,
            is_new_group_environment=False,
            cache_key=cache_key,
            group_id=event.group_id,
        )
        assignee = event.group.assignee_set.first()
        assert assignee.user == extra_user
        assert assignee.team is None

        owners = list(GroupOwner.objects.filter(group=event.group))
        assert len(owners) == 2
        assert set([(extra_user.id, None), (None, self.team.id)]) == {
            (o.user_id, o.team_id) for o in owners
        }
示例#13
0
    def test_one_owner(self):
        rule_a = Rule(Matcher("path", "*.py"),
                      [Owner("user", self.user.email)])

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

        event1 = self.store_event(
            data={"stacktrace": {
                "frames": [{
                    "filename": "foo.py"
                }]
            }},
            project_id=self.project.id)

        self.path = reverse(
            "sentry-api-0-event-owners",
            kwargs={
                "organization_slug": self.organization.slug,
                "project_slug": self.project.slug,
                "event_id": event1.event_id,
            },
        )

        resp = self.client.get(self.path)
        assert resp.status_code == 200
        assert len(resp.data["owners"]) == 1
        assert resp.data["owners"][0]["id"] == six.text_type(self.user.id)
        assert resp.data["rule"] == Matcher("path", "*.py")
        assert len(resp.data["rules"]) == 1
示例#14
0
    def test_get_owners_when_codeowners_exists_and_no_issueowners(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]),
        )
        self.assert_ownership_equals(
            ProjectOwnership.get_owners(
                self.project.id,
                {"stacktrace": {
                    "frames": [{
                        "filename": "src/foo.js"
                    }]
                }}),
            (
                [ActorTuple(self.team.id, Team)],
                [rule_a],
            ),
        )
示例#15
0
    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)
示例#16
0
    def make_ownership(self):
        rule_a = Rule(Matcher('path', 'src/*'), [
            Owner('user', self.user.email),
        ])
        rule_b = Rule(Matcher('path', 'tests/*'), [
            Owner('team', self.team.name),
        ])
        rule_c = Rule(Matcher('path', 'src/app/*'), [
            Owner('team', self.team.name),
        ])

        ProjectOwnership.objects.create(
            project_id=self.project.id,
            schema=dump_schema([rule_a, rule_b, rule_c]),
            fallthrough=True,
            auto_assignment=True,
        )
示例#17
0
    def test_owner_assignment_when_owners_have_been_unassigned(self):
        """
        Test that ensures that if certain assignees get unassigned, and project rules are changed
        then the new group assignees should be re-calculated and re-assigned
        """
        # Create rules and check assignees
        self.make_ownership()
        event = self.store_event(
            data={
                "message": "oh no",
                "platform": "python",
                "stacktrace": {
                    "frames": [{
                        "filename": "src/app/example.py"
                    }]
                },
            },
            project_id=self.project.id,
        )
        cache_key = write_event_to_cache(event)
        post_process_group(
            is_new=False,
            is_regression=False,
            is_new_group_environment=False,
            cache_key=cache_key,
            group_id=event.group_id,
        )
        assignee = event.group.assignee_set.first()
        assert assignee.user == self.user

        user_3 = self.create_user()
        self.create_team_membership(self.team, user=user_3)

        # De-assign group assignees
        GroupAssignee.objects.deassign(event.group, self.user)
        assert event.group.assignee_set.first() is None

        # Change ProjectOwnership rules
        rules = [
            Rule(Matcher("path", "src/*"), [Owner("user", user_3.email)]),
        ]
        self.prj_ownership.schema = dump_schema(rules)
        self.prj_ownership.save()

        cache_key = write_event_to_cache(event)
        post_process_group(
            is_new=False,
            is_regression=False,
            is_new_group_environment=False,
            cache_key=cache_key,
            group_id=event.group_id,
        )

        # Group should be re-assigned to the new group owner
        assignee = event.group.assignee_set.first()
        assert assignee.user == user_3
示例#18
0
def test_dump_schema():
    assert dump_schema([Rule(Matcher("path", "*.js"), [Owner("team", "frontend")])]) == {
        "$version": 1,
        "rules": [
            {
                "matcher": {"type": "path", "pattern": "*.js"},
                "owners": [{"type": "team", "identifier": "frontend"}],
            }
        ],
    }
示例#19
0
 def setUp(self):
     self.user_1 = self.create_user(email="*****@*****.**")
     self.user_2 = self.create_user(email="*****@*****.**")
     self.user_3 = self.create_user(email="*****@*****.**")
     self.organization = self.create_organization(name="Padishah Emperor")
     self.team_1 = self.create_team(
         organization=self.organization,
         name="House Atreides",
         members=[self.user_1, self.user_2],
     )
     self.team_2 = self.create_team(
         organization=self.organization, name="Bene Gesserit", members=[self.user_1, self.user_3]
     )
     self.project = self.create_project(
         name="Settle Arrakis", organization=self.organization, teams=[self.team_1, self.team_2]
     )
     self.rule_1 = Rule(Matcher("path", "*.js"), [Owner("team", self.team_1.slug)])
     self.rule_2 = Rule(Matcher("path", "*.js"), [Owner("team", self.team_2.slug)])
     self.rule_3 = Rule(Matcher("path", "*.js"), [Owner("user", self.user_1.email)])
示例#20
0
    def test_owners_of_different_types_ordered_correctly(self):
        owners = [self.user, self.team3, self.user2, self.team2, self.user3, self.team]
        rules = [
            Rule(Matcher("path", "*.py"), [Owner("user", owners[0].email)]),
            Rule(Matcher("path", "*py"), [Owner("team", owners[1].slug)]),
            Rule(Matcher("path", "*foo*"), [Owner("user", owners[2].email)]),
            Rule(Matcher("path", "*y"), [Owner("team", owners[3].slug)]),
            Rule(Matcher("path", "*"), [Owner("user", owners[4].email)]),
            Rule(Matcher("path", "*o.py"), [Owner("team", owners[5].slug)]),
        ]

        ProjectOwnership.objects.create(
            project_id=self.project.id, schema=dump_schema(rules), fallthrough=True
        )

        event1 = self.store_event(
            data={"stacktrace": {"frames": [{"filename": "foo.py"}]}}, project_id=self.project.id
        )

        self.path = reverse(
            "sentry-api-0-event-owners",
            kwargs={
                "organization_slug": self.organization.slug,
                "project_slug": self.project.slug,
                "event_id": event1.event_id,
            },
        )

        resp = self.client.get(self.path)
        assert resp.status_code == 200
        assert len(resp.data["owners"]) == 6
        assert [o["id"] for o in resp.data["owners"]] == [str(o.id) for o in owners]
        assert [o["type"] for o in resp.data["owners"]] == ["user", "team"] * 3
        assert resp.data["rule"] == Matcher("path", "*.py")
        assert len(resp.data["rules"]) == 6
 def test_abs_path_when_filename_present(self):
     frame = {
         "filename": "computer.cpp",
         "abs_path": "C:\\My\\Path\\computer.cpp",
     }
     rule = Rule(Matcher("path", "*My\\Path*"),
                 [Owner("team", self.team.slug)])
     ProjectOwnership.objects.create(project_id=self.project.id,
                                     schema=dump_schema([rule]),
                                     fallthrough=True)
     assert ProjectOwnership.get_owners(
         self.project.id, {"stacktrace": {
             "frames": [frame]
         }}) == ([ActorTuple(self.team.id, Team)], [rule])
示例#22
0
def test_parse_rules():
    assert parse_rules(fixture_data) == [
        Rule(Matcher("path", "*.js"),
             [Owner("team", "frontend"),
              Owner("user", "*****@*****.**")]),
        Rule(Matcher("url", "http://google.com/*"),
             [Owner("team", "backend")]),
        Rule(Matcher("path", "src/sentry/*"),
             [Owner("user", "*****@*****.**")]),
        Rule(Matcher("tags.foo", "bar"),
             [Owner("user", "*****@*****.**")]),
        Rule(Matcher("tags.foo", "bar baz"),
             [Owner("user", "*****@*****.**")]),
        Rule(Matcher("module", "foo.bar"), [Owner("team", "workflow")]),
        Rule(Matcher("module", "foo bar"), [Owner("user", "*****@*****.**")]),
        Rule(Matcher("codeowners", "/src/components/"),
             [Owner("user", "*****@*****.**")]),
        Rule(Matcher("codeowners", "frontend/*.ts"),
             [Owner("user", "*****@*****.**")]),
    ]
示例#23
0
def test_load_schema():
    assert load_schema({
        '$version':
        1,
        'rules': [{
            'matcher': {
                'type': 'path',
                'pattern': '*.js',
            },
            'owners': [{
                'type': 'team',
                'identifier': 'frontend',
            }]
        }]
    }) == [Rule(Matcher('path', '*.js'), [Owner('team', 'frontend')])]
示例#24
0
    def test_get_owners_basic(self):
        matcher = Matcher('path', '*.py')

        ProjectOwnership.objects.create(
            project_id=self.project.id,
            schema=dump_schema([
                Rule(matcher, [
                    Owner('user', self.user.email),
                    Owner('team', self.team.slug),
                ]),
            ]),
            fallthrough=True,
        )

        # No data matches
        assert ProjectOwnership.get_owners(self.project.id,
                                           {}) == (ProjectOwnership.Everyone,
                                                   None)

        assert ProjectOwnership.get_owners(self.project.id, {
            'sentry.interfaces.Stacktrace': {
                'frames': [{
                    'filename': 'foo.py',
                }]
            }
        }) == ([Actor(self.user.id, User),
                Actor(self.team.id, Team)], matcher)

        assert ProjectOwnership.get_owners(self.project.id, {
            'sentry.interfaces.Stacktrace': {
                'frames': [{
                    'filename': 'xxxx',
                }]
            }
        }) == (ProjectOwnership.Everyone, None)

        # When fallthrough = False, we don't implicitly assign to Everyone
        ProjectOwnership.objects.filter(
            project_id=self.project.id, ).update(fallthrough=False)

        assert ProjectOwnership.get_owners(self.project.id, {
            'sentry.interfaces.Stacktrace': {
                'frames': [{
                    'filename': 'xxxx',
                }]
            }
        }) == ([], None)
示例#25
0
    def test_owner_assignment_existing_owners(self):
        extra_team = self.create_team()
        ProjectTeam.objects.create(team=extra_team, project=self.project)

        self.make_ownership([
            Rule(Matcher("path", "src/app/things/in/*"),
                 [Owner("team", extra_team.slug)])
        ], )
        GroupOwner.objects.create(
            group=self.group,
            project=self.project,
            organization=self.organization,
            user=self.user,
            type=GroupOwnerType.OWNERSHIP_RULE.value,
        )
        event = self.store_event(
            data={
                "message": "oh no",
                "platform": "python",
                "stacktrace": {
                    "frames": [{
                        "filename":
                        "src/app/things/in/a/path/example2.py"
                    }]
                },
            },
            project_id=self.project.id,
        )
        cache_key = write_event_to_cache(event)
        post_process_group(
            is_new=False,
            is_regression=False,
            is_new_group_environment=False,
            cache_key=cache_key,
            group_id=event.group_id,
        )
        assignee = event.group.assignee_set.first()
        assert assignee.user is None
        assert assignee.team == extra_team

        owners = list(GroupOwner.objects.filter(group=event.group))
        assert {(None, extra_team.id),
                (self.user.id, None)} == {(o.user_id, o.team_id)
                                          for o in owners}
示例#26
0
 def test_team_without_members(self):
     team = self.create_team()
     project = self.create_project(teams=[team], fire_project_created=True)
     ProjectOwnership.objects.create(
         project_id=project.id,
         schema=dump_schema([Rule(Matcher("path", "*.cpp"), [Owner("team", team.slug)])]),
         fallthrough=True,
     )
     rule = project.rule_set.all()[0]
     records = [
         event_to_record(event, (rule,))
         for event in self.create_events_from_filenames(
             project, ["hello.py", "goodbye.py", "hola.py", "adios.py"]
         )
     ]
     digest = build_digest(project, sort_records(records))
     user_ids = [member.user_id for member in team.member_set]
     assert not user_ids
     for user_id, user_digest in get_personalized_digests(project.id, digest, user_ids):
         assert False  # no users in this team no digests should be processed
示例#27
0
 def test_team_without_members(self):
     team = self.create_team()
     project = self.create_project(teams=[team], fire_project_created=True)
     ProjectOwnership.objects.create(
         project_id=project.id,
         schema=dump_schema([Rule(Matcher("path", "*.cpp"), [Owner("team", team.slug)])]),
         fallthrough=True,
     )
     rule = project.rule_set.all()[0]
     records = [
         event_to_record(event, (rule,))
         for event in self.create_events_from_filenames(
             project, ["hello.py", "goodbye.py", "hola.py", "adios.py"]
         )
     ]
     digest = build_digest(project, sort_records(records))[0]
     user_ids = [member.user_id for member in team.member_set]
     assert not user_ids
     participants_by_provider_by_event = get_participants_by_event(digest, project)
     assert not {
         actor for actors in participants_by_provider_by_event.values() for actor in actors
     }  # no users in this team no digests should be processed
 def test_team_without_members(self):
     team = self.create_team()
     project = self.create_project(teams=[team])
     ProjectOwnership.objects.create(
         project_id=project.id,
         schema=dump_schema([
             Rule(Matcher('path', '*.cpp'), [
                 Owner('team', team.slug),
             ]),
         ]),
         fallthrough=True,
     )
     rule = project.rule_set.all()[0]
     records = [
         event_to_record(event, (rule, ))
         for event in self.create_events(timezone.now(
         ), project, ['hello.py', 'goodbye.py', 'hola.py', 'adios.py'])
     ]
     digest = build_digest(project, sort_records(records))
     user_ids = [member.user_id for member in team.member_set]
     assert not user_ids
     for user_id, user_digest in get_personalized_digests(
             project.id, digest, user_ids):
         assert False  # no users in this team no digests should be processed
示例#29
0
    def setUp(self):
        self.user1 = self.create_user()
        self.user2 = self.create_user()
        self.user3 = self.create_user()
        self.user4 = self.create_user()
        self.user5 = self.create_user()  # this user has no events
        self.user_ids = [
            self.user1.id, self.user2.id, self.user3.id, self.user4.id,
            self.user5.id
        ]

        self.team1 = self.create_team()
        self.team2 = self.create_team()
        self.team3 = self.create_team()

        self.project = self.create_project(
            teams=[self.team1, self.team2, self.team3])

        self.create_member(user=self.user1,
                           organization=self.organization,
                           teams=[self.team1])
        self.create_member(user=self.user2,
                           organization=self.organization,
                           teams=[self.team2])
        self.create_member(user=self.user3,
                           organization=self.organization,
                           teams=[self.team1, self.team2])
        self.create_member(user=self.user4,
                           organization=self.organization,
                           teams=[self.team3])
        self.create_member(user=self.user5,
                           organization=self.organization,
                           teams=[self.team3])

        start_time = timezone.now()

        self.team1_events = self.create_events(
            start_time, self.project,
            ["hello.py", "goodbye.py", "hola.py", "adios.py"])
        self.team2_events = self.create_events(
            start_time, self.project,
            ["old.cbl", "retro.cbl", "cool.cbl", "gem.cbl"])

        self.user4_events = [
            self.create_event(
                group=self.create_group(project=self.project),
                data=self.create_event_data("foo.bar", "helloworld.org"),
            ),
            self.create_event(
                group=self.create_group(project=self.project),
                data=self.create_event_data("bar.foo", "helloworld.org"),
            ),
        ]
        self.team1_matcher = Matcher("path", "*.py")
        self.team2_matcher = Matcher("path", "*.cbl")
        self.user4_matcher = Matcher("url", "*.org")

        ProjectOwnership.objects.create(
            project_id=self.project.id,
            schema=dump_schema([
                Rule(
                    self.team1_matcher,
                    [
                        Owner("team", self.team1.slug),
                        Owner("user", self.user3.email)
                    ],
                ),
                Rule(self.team2_matcher, [Owner("team", self.team2.slug)]),
                Rule(self.user4_matcher, [Owner("user", self.user4.email)]),
            ]),
            fallthrough=True,
        )
示例#30
0
    def test_get_owners_basic(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]),
            fallthrough=True,
        )

        # No data matches
        assert ProjectOwnership.get_owners(self.project.id, {}) == (ProjectOwnership.Everyone, None)

        # Match only rule_a
        self.assert_ownership_equals(ProjectOwnership.get_owners(
            self.project.id, {
                'sentry.interfaces.Stacktrace': {
                    'frames': [{
                        'filename': 'foo.py',
                    }]
                }
            }
        ), ([Actor(self.team.id, Team)], [rule_a]))

        # Match only rule_b
        self.assert_ownership_equals(ProjectOwnership.get_owners(
            self.project.id, {
                'sentry.interfaces.Stacktrace': {
                    'frames': [{
                        'filename': 'src/thing.txt',
                    }]
                }
            }
        ), ([Actor(self.user.id, User)], [rule_b]))

        # Matches both rule_a and rule_b
        self.assert_ownership_equals(ProjectOwnership.get_owners(
            self.project.id, {
                'sentry.interfaces.Stacktrace': {
                    'frames': [{
                        'filename': 'src/foo.py',
                    }]
                }
            }
        ), ([Actor(self.user.id, User), Actor(self.team.id, Team)], [rule_a, rule_b]))

        assert ProjectOwnership.get_owners(
            self.project.id, {
                'sentry.interfaces.Stacktrace': {
                    'frames': [{
                        'filename': 'xxxx',
                    }]
                }
            }
        ) == (ProjectOwnership.Everyone, None)

        # When fallthrough = False, we don't implicitly assign to Everyone
        ProjectOwnership.objects.filter(
            project_id=self.project.id,
        ).update(fallthrough=False)

        assert ProjectOwnership.get_owners(
            self.project.id, {
                'sentry.interfaces.Stacktrace': {
                    'frames': [{
                        'filename': 'xxxx',
                    }]
                }
            }
        ) == ([], None)