Skip to content

Commit

Permalink
Calculate the time to burn down all the defects backlog
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-c committed Oct 13, 2023
1 parent a12f47f commit febce44
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 21 deletions.
58 changes: 50 additions & 8 deletions bugbug/bugzilla.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import collections
import csv
import math
import re
from datetime import datetime
from logging import INFO, basicConfig, getLogger
Expand Down Expand Up @@ -444,6 +445,7 @@ def calculate_maintenance_effectiveness_indicator(
components=None,
):
data: dict[str, dict[str, int]] = {
"open": {},
"opened": {},
"closed": {},
}
Expand All @@ -460,8 +462,6 @@ def calculate_maintenance_effectiveness_indicator(
"count_only": 1,
"type": "defect",
"team_name": team,
"chfieldfrom": from_date.strftime("%Y-%m-%d"),
"chfieldto": to_date.strftime("%Y-%m-%d"),
}

if severity != "--":
Expand All @@ -470,8 +470,24 @@ def calculate_maintenance_effectiveness_indicator(
if components is not None:
params["component"] = components

for query_type in ("opened", "closed"):
if query_type == "opened":
for query_type in data.keys():
if query_type in ("opened", "closed"):
params.update(
{
"chfieldfrom": from_date.strftime("%Y-%m-%d"),
"chfieldto": to_date.strftime("%Y-%m-%d"),
}
)

if query_type == "open":
params.update(
{
"f1": "resolution",
"o1": "equals",
"v1": "---",
}
)
elif query_type == "opened":
params["chfield"] = "[Bug creation]"
elif query_type == "closed":
params.update(
Expand All @@ -493,17 +509,21 @@ def calculate_maintenance_effectiveness_indicator(
data[query_type][severity] = r.json()["bug_count"]

# Calculate number of bugs without severity set.
for query_type in ("opened", "closed"):
for query_type in data.keys():
data[query_type]["--"] = data[query_type]["--"] - sum(
data[query_type][s]
for s in MAINTENANCE_EFFECTIVENESS_SEVERITY_WEIGHTS.keys()
if s != "--"
)

open_defects = sum(data["open"].values())
opened_defects = sum(data["opened"].values())
closed_defects = sum(data["closed"].values())

print("Before applying weights:")
print(data)

for query_type in ("opened", "closed"):
for query_type in data.keys():
# Apply weights.
for (
severity,
Expand All @@ -514,9 +534,31 @@ def calculate_maintenance_effectiveness_indicator(
print("After applying weights:")
print(data)

weighed_open_defects = sum(data["open"].values())
weighed_opened_defects = sum(data["opened"].values())
weighed_closed_defects = sum(data["closed"].values())

if weighed_opened_defects > 0:
return 100 * weighed_closed_defects / weighed_opened_defects
mei = 100 * weighed_closed_defects / weighed_opened_defects
else:
mei = 100 * (weighed_closed_defects + 1)

duration = (to_date - from_date).total_seconds() / 86400

if closed_defects > opened_defects:
bdtime = duration * (open_defects / (closed_defects - opened_defects))
else:
return 100 * (weighed_closed_defects + 1)
bdtime = math.inf

if weighed_closed_defects > weighed_opened_defects:
wbdtime = duration * (
weighed_open_defects / (weighed_closed_defects - weighed_opened_defects)
)
else:
wbdtime = math.inf

return {
"ME%": mei,
"BDTime": bdtime,
"WBDTime": wbdtime,
}
10 changes: 7 additions & 3 deletions scripts/generate_landings_risk_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -1786,12 +1786,16 @@ def calculate_maintenance_effectiveness(period):
2,
)

def format_maintenance_effectiveness(period):
me = calculate_maintenance_effectiveness(period)
return ", ".join(f"{factor}: {value}" for factor, value in me.items())

maintenance_effectiveness_section = f"""<b>MAINTENANCE EFFECTIVENESS</b>
<br />
Last week: {calculate_maintenance_effectiveness(relativedelta(weeks=1))}
Last month: {calculate_maintenance_effectiveness(relativedelta(months=1))}
Last year: {calculate_maintenance_effectiveness(relativedelta(years=1))}
Last week: {format_maintenance_effectiveness(relativedelta(weeks=1))}
Last month: {format_maintenance_effectiveness(relativedelta(months=1))}
Last year: {format_maintenance_effectiveness(relativedelta(years=1))}
"""

sections = [
Expand Down
19 changes: 9 additions & 10 deletions scripts/maintenance_effectiveness_indicator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# You can obtain one at http://mozilla.org/MPL/2.0/.

import argparse
import math
from logging import INFO, basicConfig, getLogger

import dateutil.parser
Expand Down Expand Up @@ -45,18 +46,16 @@ def main():
"If you want to include security bugs too, please set the BUGBUG_BUGZILLA_TOKEN environment variable to your Bugzilla API key."
)

logger.info(
round(
bugzilla.calculate_maintenance_effectiveness_indicator(
args.team,
dateutil.parser.parse(args.start_date),
dateutil.parser.parse(args.end_date),
args.components,
),
2,
)
result = bugzilla.calculate_maintenance_effectiveness_indicator(
args.team,
dateutil.parser.parse(args.start_date),
dateutil.parser.parse(args.end_date),
args.components,
)

for factor, value in result.items():
logger.info(f"{factor}: {round(value, 2) if value != math.inf else value}")


if __name__ == "__main__":
main()

0 comments on commit febce44

Please sign in to comment.