Allow for bugzilla management to use a minimum threshold for 'reopened bugs' (#8144)

This commit is contained in:
Joel Maher 2024-08-05 17:48:55 -07:00 коммит произвёл GitHub
Родитель abe2ae2a0d
Коммит f24ee11fb6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 51 добавлений и 19 удалений

Просмотреть файл

@ -324,6 +324,11 @@ def test_job(eleven_job_blobs, create_jobs):
return create_jobs([job])[0]
@pytest.fixture
def test_jobs(eleven_job_blobs_new_date, create_jobs):
return create_jobs(eleven_job_blobs_new_date)
@pytest.fixture
def test_two_jobs_tc_metadata(eleven_job_blobs_new_date, create_jobs):
job_1, job_2 = eleven_job_blobs_new_date[0:2]

Просмотреть файл

@ -19,29 +19,50 @@ def test_bz_api_process(mock_bugzilla_api_request):
assert Bugscache.objects.count() == 28
def test_bz_reopen_bugs(request, mock_bugzilla_reopen_request, client, test_job, test_user, bugs):
@pytest.mark.parametrize(
"minimum_failures_to_reopen",
[1, 3],
)
def test_bz_reopen_bugs(
request,
mock_bugzilla_reopen_request,
client,
test_jobs,
test_user,
bugs,
minimum_failures_to_reopen,
):
"""
Test expected bugs get reopened.
"""
bug = bugs[0]
client.force_authenticate(user=test_user)
request.config.cache.set("reopened_bugs", {})
incomplete_bugs = [bug for bug in bugs if bug.resolution == "INCOMPLETE"]
not_incomplete_bugs = [bug for bug in bugs if bug.resolution != "INCOMPLETE"]
idx = 0
for bug in [
not_incomplete_bugs[0],
not_incomplete_bugs[2],
incomplete_bugs[0],
incomplete_bugs[2],
incomplete_bugs[0],
incomplete_bugs[2],
incomplete_bugs[0],
not_incomplete_bugs[0],
not_incomplete_bugs[2],
]:
submit_obj = {"job_id": test_job.id, "bug_id": bug.id, "type": "manual"}
submit_obj = {"job_id": test_jobs[idx].id, "bug_id": bug.id, "type": "manual"}
client.post(
reverse("bug-job-map-list", kwargs={"project": test_job.repository.name}),
reverse("bug-job-map-list", kwargs={"project": test_jobs[idx].repository.name}),
data=submit_obj,
)
idx += 1
if idx % 11 == 0:
idx = 0
process = BzApiBugProcess()
process.minimum_failures_to_reopen = minimum_failures_to_reopen
process.run()
reopened_bugs = request.config.cache.get("reopened_bugs", None)
@ -53,19 +74,21 @@ def test_bz_reopen_bugs(request, mock_bugzilla_reopen_request, client, test_job,
{
"status": "REOPENED",
"comment": {
"body": "New failure instance: https://treeherder.mozilla.org/logviewer?job_id=1&repo=mozilla-central"
"body": "New failure instance: https://treeherder.mozilla.org/logviewer?job_id=5&repo=mozilla-central"
},
"comment_tags": "treeherder",
}
},
),
"https://thisisnotbugzilla.org/rest/bug/404": json.dumps(
}
if process.minimum_failures_to_reopen == 1:
expected_reopen_attempts["https://thisisnotbugzilla.org/rest/bug/404"] = json.dumps(
{
"status": "REOPENED",
"comment": {
"body": "New failure instance: https://treeherder.mozilla.org/logviewer?job_id=1&repo=mozilla-central"
"body": "New failure instance: https://treeherder.mozilla.org/logviewer?job_id=4&repo=mozilla-central"
},
"comment_tags": "treeherder",
}
),
}
},
)
assert reopened_bugs == expected_reopen_attempts

Просмотреть файл

@ -4,7 +4,7 @@ import requests
import dateutil.parser
from datetime import datetime, timedelta
from django.conf import settings
from django.db.models import Max
from django.db.models import Count, Max
from treeherder.model.models import Bugscache, BugJobMap
from treeherder.utils.github import fetch_json
@ -17,7 +17,7 @@ def reopen_request(url, method, headers, json):
make_request(url, method=method, headers=headers, json=json)
def reopen_intermittent_bugs():
def reopen_intermittent_bugs(minimum_failures_to_reopen=1):
# Don't reopen bugs from non-production deployments.
if settings.BUGFILER_API_KEY is None:
return
@ -29,9 +29,11 @@ def reopen_intermittent_bugs():
# https://github.com/mozilla/relman-auto-nag/blob/c7439e247677333c1cd8c435234b3ef3adc49680/auto_nag/scripts/close_intermittents.py#L17
recent_days = 7
recently_used_bugs = set(
BugJobMap.objects.filter(created__gt=datetime.now() - timedelta(recent_days)).values_list(
"bug_id", flat=True
)
BugJobMap.objects.filter(created__gt=(datetime.now() - timedelta(recent_days)))
.values("bug_id")
.annotate(num_failures=Count("bug_id"))
.filter(num_failures__gte=minimum_failures_to_reopen)
.values_list("bug_id", flat=True)
)
bugs_to_reopen = incomplete_bugs & recently_used_bugs
@ -90,6 +92,8 @@ def fetch_intermittent_bugs(additional_params, limit, duplicate_chain_length):
class BzApiBugProcess:
minimum_failures_to_reopen = 1
def run(self):
year_ago = datetime.utcnow() - timedelta(days=365)
last_change_time_max = (
@ -302,4 +306,4 @@ class BzApiBugProcess:
modified=last_change_time_max
)
reopen_intermittent_bugs()
reopen_intermittent_bugs(self.minimum_failures_to_reopen)