• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / relman-auto-nag / #5359

27 Nov 2024 05:21PM UTC coverage: 21.298%. Remained the same
#5359

push

coveralls-python

web-flow
Mention resolving perfalert as WONTFIX, and don't needinfo on bugs with backlog-deferred keyword (#2545)

426 of 2942 branches covered (14.48%)

0 of 1 new or added line in 1 file covered. (0.0%)

1943 of 9123 relevant lines covered (21.3%)

0.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/bugbot/rules/perfalert_inactive_regression.py
1
# This Source Code Form is subject to the terms of the Mozilla Public
2
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
# You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
import collections
×
6

7
from libmozdata.bugzilla import Bugzilla
×
8

9
from bugbot import logger, utils
×
10
from bugbot.bzcleaner import BzCleaner
×
11
from bugbot.user_activity import UserActivity, UserStatus
×
12

13

14
class PerfAlertInactiveRegression(BzCleaner):
×
15
    def __init__(self, nweeks=1):
×
16
        super().__init__()
×
17
        self.nweeks = nweeks
×
18
        self.extra_ni = {"nweeks": self.nweeks}
×
19
        self.private_regressor_ids: set[str] = set()
×
20

21
    def description(self):
×
22
        return f"PerfAlert regressions with {self.nweeks} week(s) of inactivity"
×
23

24
    def handle_bug(self, bug, data):
×
25
        if len(bug["regressed_by"]) != 1:
×
26
            # either we don't have access to the regressor,
27
            # or there's more than one, either way leave things alone
28
            return
×
29

30
        data[str(bug["id"])] = {
×
31
            "regressor_id": bug["regressed_by"][0],
32
        }
33

34
        return bug
×
35

36
    def get_bz_params(self, date):
×
37
        start_date, _ = self.get_dates(date)
×
38

39
        fields = [
×
40
            "id",
41
            "regressed_by",
42
        ]
43

44
        # Find all bugs that have perf-alert, and regression in their keywords. Only
45
        # look for bugs after October 1st, 2024 to prevent triggering comments on older
46
        # performance regressions
47
        params = {
×
48
            "include_fields": fields,
49
            "f1": "creation_ts",
50
            "o1": "greaterthan",
51
            "v1": "2024-10-01T00:00:00Z",
52
            "f2": "regressed_by",
53
            "o2": "isnotempty",
54
            "f3": "keywords",
55
            "o3": "allwords",
56
            "v3": ["regression", "perf-alert"],
57
            "f4": "keywords",
58
            "o4": "nowords",
59
            "v4": "backlog-deferred",
60
            "f5": "days_elapsed",
61
            "o5": "greaterthan",
62
            "v5": self.nweeks * 7,
63
            "status": ["UNCONFIRMED", "NEW", "REOPENED"],
64
            "resolution": ["---"],
65
        }
66

67
        return params
×
68

69
    def retrieve_regressors(self, bugs):
×
70
        regressor_to_bugs = collections.defaultdict(list)
×
71
        for bug in bugs.values():
×
72
            regressor_to_bugs[bug["regressor_id"]].append(bug)
×
73

74
        def bug_handler(regressor_bug):
×
75
            if regressor_bug.get("groups"):
×
76
                regressor_bug_id = str(regressor_bug["id"])
×
77
                self.private_regressor_ids.add(regressor_bug_id)
×
78

79
            for bug in regressor_to_bugs[regressor_bug["id"]]:
×
80
                bug["regressor_author_email"] = regressor_bug["assigned_to"]
×
81
                bug["regressor_author_nickname"] = regressor_bug["assigned_to_detail"][
×
82
                    "nick"
83
                ]
84

85
        Bugzilla(
×
86
            bugids={bug["regressor_id"] for bug in bugs.values()},
87
            bughandler=bug_handler,
88
            include_fields=["id", "assigned_to", "groups"],
89
        ).get_data().wait()
90

91
    def filter_bugs(self, bugs):
×
92
        # TODO: Attempt to needinfo the triage owner instead of ignoring the bugs
93
        # Exclude bugs whose regressor author is nobody.
94
        for bug in list(bugs.values()):
×
NEW
95
            if utils.is_no_assignee(bug.get("regressor_author_email", "")):
×
96
                logger.warning(
×
97
                    "Bug {}, regressor of bug {}, doesn't have an author".format(
98
                        bug["regressor_id"], bug["id"]
99
                    )
100
                )
101
                del bugs[bug["id"]]
×
102

103
        # Exclude bugs where the regressor author is inactive or blocked needinfo.
104
        # TODO: We can drop this when https://github.com/mozilla/bugbot/issues/1465 is implemented.
105
        users_info = UserActivity(include_fields=["groups", "requests"]).check_users(
×
106
            set(bug["regressor_author_email"] for bug in bugs.values()),
107
            keep_active=True,
108
            fetch_employee_info=True,
109
        )
110

111
        for bug_id, bug in list(bugs.items()):
×
112
            user_info = users_info[bug["regressor_author_email"]]
×
113
            if (
×
114
                user_info["status"] != UserStatus.ACTIVE
115
                or user_info["requests"]["needinfo"]["blocked"]
116
            ):
117
                del bugs[bug_id]
×
118

119
        return bugs
×
120

121
    def get_extra_for_needinfo_template(self):
×
122
        return self.extra_ni
×
123

124
    def get_extra_for_template(self):
×
125
        return self.extra_ni
×
126

127
    def set_autofix(self, bugs):
×
128
        for bugid, info in bugs.items():
×
129
            self.extra_ni[bugid] = {"regressor_id": str(info["regressor_id"])}
×
130
            self.add_auto_ni(
×
131
                bugid,
132
                {
133
                    "mail": info["regressor_author_email"],
134
                    "nickname": info["regressor_author_nickname"],
135
                },
136
            )
137

138
    def get_bugs(self, *args, **kwargs):
×
139
        bugs = super().get_bugs(*args, **kwargs)
×
140
        self.retrieve_regressors(bugs)
×
141
        bugs = self.filter_bugs(bugs)
×
142
        self.set_autofix(bugs)
×
143
        return bugs
×
144

145
    def set_needinfo(self):
×
146
        res = super().set_needinfo()
×
147
        for bug_id, needinfo_action in res.items():
×
148
            needinfo_action["comment"]["is_private"] = (
×
149
                bug_id in self.private_regressor_ids
150
            )
151

152
        return res
×
153

154

155
if __name__ == "__main__":
×
156
    PerfAlertInactiveRegression().run()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc