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

mozilla / relman-auto-nag / #5180

26 Jul 2024 05:41PM UTC coverage: 21.581% (-0.03%) from 21.607%
#5180

push

coveralls-python

benjaminmah
Working first step of `no_severity` rule

585 of 3503 branches covered (16.7%)

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

7 existing lines in 1 file now uncovered.

1933 of 8957 relevant lines covered (21.58%)

0.22 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

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

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

15

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

20
        Args:
21
            typ: the mode that the rule should run with (first or second). Nag
22
                emails will be sent only if `typ` is second.
23
            inactivity_days: number of days that a bug should be inactive before
24
                being considered.
25
        """
26
        super(NoSeverityNeedInfo, self).__init__()
×
27
        self.lookup_first = utils.get_config(self.name(), "weeks_lookup", 2)
×
NEW
28
        self.lookup_second = utils.get_config("NoSeverityNag", "weeks_lookup", 4)
×
NEW
29
        self.escalation = Escalation(
×
30
            self.people,
31
            data=utils.get_config(self.name(), "escalation"),
32
            skiplist=utils.get_config("workflow", "supervisor_skiplist", []),
33
        )
34
        self.round_robin = RoundRobin.get_instance()
×
35
        self.components_skiplist = utils.get_config("workflow", "components_skiplist")
×
36
        self.activity_date = str(
×
37
            numpy.busday_offset(lmdutils.get_date("today"), -inactivity_days)
38
        )
39

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

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

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

NEW
56
    def get_extra_for_template(self):
×
NEW
57
        return {"nweeks": self.lookup_first}
×
58

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

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

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

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

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

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

83
    def get_mail_to_auto_ni(self, bug):
×
84
        mail, nick = self.round_robin.get(bug, self.date)
×
UNCOV
85
        if mail and nick:
×
86
            return {"mail": mail, "nickname": nick}
×
87

UNCOV
88
        return None
×
89

NEW
90
    def set_people_to_nag(self, bug, buginfo):
×
NEW
91
        priority = "default"
×
NEW
92
        if not self.filter_bug(priority):
×
NEW
93
            return None
×
94

NEW
95
        return bug
×
96

97
    def get_bz_params(self, date):
×
98
        fields = [
×
99
            "triage_owner",
100
            "flags",
101
            "comments.creator",
102
            "comments.creation_time",
103
        ]
UNCOV
104
        params = {
×
105
            "include_fields": fields,
106
            "keywords": "intermittent-failure",
107
            "keywords_type": "nowords",
108
            "email2": "wptsync@mozilla.bugs",
109
            "emailreporter2": "1",
110
            "emailtype2": "notequals",
111
            "resolution": "---",
112
            "f31": "bug_type",
113
            "o31": "equals",
114
            "v31": "defect",
115
            "f32": "flagtypes.name",
116
            "o32": "notsubstring",
117
            "v32": "needinfo?",
118
            "f33": "bug_severity",
119
            "o33": "anyexact",
120
            "v33": "--, n/a",
121
        }
122
        self.date = lmdutils.get_date_ymd(date)
×
123
        first = f"-{self.lookup_first * 7}d"
×
NEW
124
        second = f"-{self.lookup_second * 7}d"
×
125

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

UNCOV
199
        return params
×
200

201

202
if __name__ == "__main__":
×
203
    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