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

mozilla / relman-auto-nag / #5381

02 Jan 2025 02:16PM CUT coverage: 21.261% (+0.009%) from 21.252%
#5381

push

coveralls-python

benjaminmah
Removed deletion of bugs, now limiting

426 of 2942 branches covered (14.48%)

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

1942 of 9134 relevant lines covered (21.26%)

0.21 hits per line

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

0.0
/bugbot/rules/workflow/no_severity_ni.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

6
import numpy
×
7
from libmozdata import utils as lmdutils
×
8

9
from bugbot import utils
×
10
from bugbot.bzcleaner import BzCleaner
×
11
from bugbot.escalation import Escalation
×
12
from bugbot.nag_me import Nag
×
13
from bugbot.round_robin import RoundRobin
×
14
from bugbot.user_activity import UserActivity
×
15

16

17
class NoSeverityNeedInfo(BzCleaner, Nag):
×
18
    def __init__(self, inactivity_days: int = 4):
×
19
        """Constructor
20

21
        Args:
22
            inactivity_days: number of days that a bug should be inactive before
23
                being considered.
24
        """
25
        super(NoSeverityNeedInfo, self).__init__()
×
26
        self.lookup = utils.get_config(self.name(), "weeks_lookup", 2)
×
27
        self.lookup_nag = utils.get_config("NoSeverityNag", "weeks_lookup", 4)
×
28
        self.escalation = Escalation(
×
29
            self.people,
30
            data=utils.get_config(self.name(), "escalation"),
31
            skiplist=utils.get_config("workflow", "supervisor_skiplist", []),
32
        )
33
        self.round_robin = RoundRobin.get_instance()
×
34
        self.components_skiplist = utils.get_config("workflow", "components_skiplist")
×
35
        self.activity_date = str(
×
36
            numpy.busday_offset(lmdutils.get_date("today"), -inactivity_days)
37
        )
38

39
    def description(self):
×
40
        return "Bugs without a severity or statuses set"
×
41

42
    def nag_template(self):
×
43
        return self.template()
×
44

45
    def nag_preamble(self):
×
46
        return """<p>
×
47
  <ul>
48
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/policies/triage-bugzilla.html#why-triage">Why triage?</a></li>
49
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/policies/triage-bugzilla.html#what-do-you-triage">What do you triage?</a></li>
50
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/guides/priority.html">Priority definitions</a></li>
51
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/guides/severity.html">Severity definitions</a></li>
52
  </ul>
53
</p>"""
54

55
    def get_extra_for_template(self):
×
56
        return {"nweeks": self.lookup}
×
57

58
    def get_extra_for_needinfo_template(self):
×
59
        return self.get_extra_for_template()
×
60

61
    def get_extra_for_nag_template(self):
×
62
        return self.get_extra_for_template()
×
63

64
    def has_product_component(self):
×
65
        return True
×
66

67
    def ignore_meta(self):
×
68
        return True
×
69

70
    def columns(self):
×
71
        return ["product", "component", "id", "summary"]
×
72

73
    def handle_bug(self, bug, data):
×
74
        if (
×
75
            # check if the product::component is in the list
76
            utils.check_product_component(self.components_skiplist, bug)
77
            or utils.get_last_no_bot_comment_date(bug) > self.activity_date
78
        ):
79
            return None
×
80

81
        bugid = str(bug["id"])
×
82

83
        data[bugid] = {
×
84
            "triage_owner": bug["triage_owner"],
85
        }
86

87
        return bug
×
88

89
    def get_mail_to_auto_ni(self, bug):
×
90
        mail, nick = self.round_robin.get(bug, self.date)
×
91
        if mail and nick:
×
92
            return {"mail": mail, "nickname": nick}
×
93

94
        return None
×
95

96
    def set_people_to_nag(self, bug, buginfo):
×
97
        priority = "default"
×
98
        if not self.filter_bug(priority):
×
99
            return None
×
100

101
        return bug
×
102

103
    def get_bz_params(self, date):
×
104
        fields = [
×
105
            "triage_owner",
106
            "flags",
107
            "comments.creator",
108
            "comments.creation_time",
109
        ]
110
        lookup = f"-{self.lookup * 7}d"
×
111
        lookup_nag = f"-{self.lookup_nag * 7}d"
×
112

113
        # TODO: change this when https://bugzilla.mozilla.org/1543984 will be fixed
114
        # Here we have to get bugs where product/component have been set (bug has been triaged)
115
        # between 4 and 2 weeks
116
        # If the product/component never changed after bug creation, we need to get them too
117
        # (second < p < first && c < first) ||
118
        # (second < c < first && p < first) ||
119
        # ((second < creation < first) && pc never changed)
120
        params = {
×
121
            "include_fields": fields,
122
            "keywords": "intermittent-failure",
123
            "keywords_type": "nowords",
124
            "email2": "wptsync@mozilla.bugs",
125
            "emailreporter2": "1",
126
            "emailtype2": "notequals",
127
            "resolution": "---",
128
            "f31": "bug_type",
129
            "o31": "equals",
130
            "v31": "defect",
131
            "f32": "flagtypes.name",
132
            "o32": "notsubstring",
133
            "v32": "needinfo?",
134
            "f33": "bug_severity",
135
            "o33": "anyexact",
136
            "v33": "--, n/a",
137
            "f2": "flagtypes.name",
138
            "o2": "notequals",
139
            "v2": "needinfo?",
140
            "j3": "OR",
141
            "f3": "OP",
142
            "j4": "AND",
143
            "f4": "OP",
144
            "n5": 1,
145
            "f5": "product",
146
            "o5": "changedafter",
147
            "v5": lookup,
148
            "f6": "product",
149
            "o6": "changedafter",
150
            "v6": lookup_nag,
151
            "n7": 1,
152
            "f7": "component",
153
            "o7": "changedafter",
154
            "v7": lookup,
155
            "f8": "CP",
156
            "j9": "AND",
157
            "f9": "OP",
158
            "n10": 1,
159
            "f10": "component",
160
            "o10": "changedafter",
161
            "v10": lookup,
162
            "f11": "component",
163
            "o11": "changedafter",
164
            "v11": lookup_nag,
165
            "n12": 1,
166
            "f12": "product",
167
            "o12": "changedafter",
168
            "v12": lookup,
169
            "f13": "CP",
170
            "j14": "AND",
171
            "f14": "OP",
172
            "f15": "creation_ts",
173
            "o15": "lessthaneq",
174
            "v15": lookup,
175
            "f16": "creation_ts",
176
            "o16": "greaterthan",
177
            "v16": lookup_nag,
178
            "n17": 1,
179
            "f17": "product",
180
            "o17": "everchanged",
181
            "n18": 1,
182
            "f18": "component",
183
            "o18": "everchanged",
184
            "f19": "CP",
185
            "j20": "OR",
186
            "f20": "OP",
187
            "f21": "bug_severity",
188
            "o21": "changedfrom",
189
            "v21": "critical",
190
            "f22": "bug_severity",
191
            "o22": "changedfrom",
192
            "v22": "major",
193
            "f23": "bug_severity",
194
            "o23": "changedfrom",
195
            "v23": "blocker",
196
            "f24": "CP",
197
            "f30": "CP",
198
        }
199

200
        self.date = lmdutils.get_date_ymd(date)
×
201

202
        return params
×
203

204
    def filter_bugs(self, bugs):
×
205
        users_info = UserActivity(include_fields=["groups", "requests"]).check_users(
×
206
            set(bug["triage_owner"] for bug in bugs.values()),
207
            keep_active=True,
208
            fetch_employee_info=True,
209
        )
210

211
        # for bug_id, bug in list(bugs.items()):
212
        #     user_info = users_info[bug["triage_owner"]]
213
        #     if "requests" in user_info:
214
        #         if user_info["requests"]["needinfo"]["blocked"]:
215
        #             del bugs[bug_id]
NEW
216
        filtered_bugs = {
×
217
            bug_id: bug
218
            for bug_id, bug in bugs.items()
219
            if not users_info[bug["triage_owner"]]["requests"]["needinfo"]["blocked"]
220
        }
NEW
221
        return filtered_bugs
×
222

223
    def get_bugs(self, *args, **kwargs):
×
224
        bugs = super().get_bugs(*args, **kwargs)
×
225
        bugs = self.filter_bugs(bugs)
×
226
        return bugs
×
227

228

229
if __name__ == "__main__":
×
230
    NoSeverityNeedInfo().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