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

mozilla / relman-auto-nag / #4349

pending completion
#4349

push

coveralls-python

sosa-e
Revert "Minimizing config file"

This reverts commit 614159597.

564 of 3081 branches covered (18.31%)

24 of 24 new or added lines in 24 files covered. (100.0%)

1804 of 7980 relevant lines covered (22.61%)

0.23 hits per line

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

0.0
/auto_nag/scripts/spambug.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
from auto_nag import people
×
6
from auto_nag.bugbug_utils import get_bug_ids_classification
×
7
from auto_nag.bzcleaner import BzCleaner
×
8
from auto_nag.utils import nice_round
×
9

10
COMMENT = """
×
11
The [Bugbug](https://github.com/mozilla/bugbug/) bot thinks this bug is invalid.
12
If you think the bot is wrong, please reopen the bug and move it back to its prior component.
13
If your bug description is written in a non-English language, please use Google Translate or a similar service to translate it.
14

15
Please note that this is a production bug database used by the Mozilla community to develop Firefox, Thunderbird and other products.
16
Filing test bugs here will waste the time of our contributors, volunteers and employees.
17
Accounts that abuse bugzilla.mozilla.org will be disabled.
18
""".strip()
19

20

21
class SpamBug(BzCleaner):
×
22
    def __init__(self):
×
23
        super().__init__()
×
24
        self.autofix_bugs = {}
×
25
        self.people = people.People.get_instance()
×
26

27
    def description(self):
×
28
        return "[Using ML] Detect spam bugs"
×
29

30
    def has_default_products(self):
×
31
        return False
×
32

33
    def columns(self):
×
34
        return ["id", "summary", "confidence"]
×
35

36
    def sort_columns(self):
×
37
        return lambda p: (-p[2], -int(p[0]))
×
38

39
    def handle_bug(self, bug, data):
×
40
        reporter = bug["creator"]
×
41
        if self.people.is_mozilla(reporter):
×
42
            return None
×
43

44
        return bug
×
45

46
    def get_bz_params(self, date):
×
47
        start_date, _ = self.get_dates(date)
×
48

49
        return {
×
50
            "include_fields": ["id", "groups", "summary", "creator"],
51
            "bug_status": "UNCONFIRMED",
52
            "f1": "reporter",
53
            "v1": "%group.editbugs%",
54
            "o1": "notsubstring",
55
            "f2": "creation_ts",
56
            "o2": "greaterthan",
57
            "v2": start_date,
58
            "n3": 1,
59
            "f3": "product",
60
            "o3": "changedfrom",
61
            "v3": "Invalid Bugs",
62
        }
63

64
    def get_bugs(self, date="today", bug_ids=[]):
×
65
        # Retrieve the bugs with the fields defined in get_bz_params
66
        raw_bugs = super().get_bugs(date=date, bug_ids=bug_ids, chunk_size=7000)
×
67

68
        if len(raw_bugs) == 0:
×
69
            return {}
×
70

71
        # Extract the bug ids
72
        bug_ids = list(raw_bugs.keys())
×
73

74
        # Classify those bugs
75
        bugs = get_bug_ids_classification("spambug", bug_ids)
×
76

77
        for bug_id in sorted(bugs.keys()):
×
78
            bug_data = bugs[bug_id]
×
79

80
            if not bug_data.get("available", True):
×
81
                # The bug was not available, it was either removed or is a
82
                # security bug
83
                continue
×
84

85
            if not {"prob", "index"}.issubset(bug_data.keys()):
×
86
                raise Exception(f"Invalid bug response {bug_id}: {bug_data!r}")
×
87

88
            bug = raw_bugs[bug_id]
×
89
            prob = bug_data["prob"]
×
90

91
            if prob[1] < self.get_config("confidence_threshold"):
×
92
                continue
×
93

94
            self.autofix_bugs[bug_id] = {
×
95
                "id": bug_id,
96
                "summary": bug["summary"],
97
                "confidence": nice_round(prob[1]),
98
            }
99

100
        return self.autofix_bugs
×
101

102
    def get_autofix_change(self):
×
103
        result = {}
×
104
        for bug_id in self.autofix_bugs:
×
105
            result[bug_id] = {
×
106
                "comment": {
107
                    "body": COMMENT.format(self.autofix_bugs[bug_id]["confidence"])
108
                },
109
                "product": "Invalid Bugs",
110
                "component": "General",
111
                "version": "unspecified",
112
                "milestone": "---",
113
                "status": "RESOLVED",
114
                "resolution": "INVALID",
115
            }
116
        return result
×
117

118

119
if __name__ == "__main__":
×
120
    SpamBug().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