зеркало из https://github.com/mozilla/treeherder.git
Add support for bug_open field to bug_job_map when create or reopen bug.
This commit is contained in:
Родитель
51715109c1
Коммит
7e5db45b91
|
@ -3,7 +3,7 @@ import pytest
|
|||
from django.urls import reverse
|
||||
|
||||
from treeherder.etl.bugzilla import BzApiBugProcess
|
||||
from treeherder.model.models import Bugscache
|
||||
from treeherder.model.models import Bugscache, BugJobMap
|
||||
|
||||
|
||||
@pytest.mark.django_db(transaction=True)
|
||||
|
@ -50,7 +50,12 @@ def test_bz_reopen_bugs(
|
|||
not_incomplete_bugs[0],
|
||||
not_incomplete_bugs[2],
|
||||
]:
|
||||
submit_obj = {"job_id": test_jobs[idx].id, "bug_id": bug.id, "type": "manual"}
|
||||
submit_obj = {
|
||||
"job_id": test_jobs[idx].id,
|
||||
"bug_id": bug.id,
|
||||
"type": "manual",
|
||||
"bug_open": False,
|
||||
}
|
||||
|
||||
client.post(
|
||||
reverse("bug-job-map-list", kwargs={"project": test_jobs[idx].repository.name}),
|
||||
|
@ -61,10 +66,29 @@ def test_bz_reopen_bugs(
|
|||
if idx % 11 == 0:
|
||||
idx = 0
|
||||
|
||||
# always closed
|
||||
# as we only reopen a single instance of a bug, we choose the most recent instance
|
||||
# since the reopen code queries and then `.order_by("-created")`
|
||||
bug_job_map = BugJobMap.objects.filter(job_id=test_jobs[4].id, bug_id=incomplete_bugs[0].id)[0]
|
||||
assert bug_job_map.bug_open is False
|
||||
|
||||
bug_job_map = BugJobMap.objects.filter(job_id=test_jobs[3].id, bug_id=incomplete_bugs[2].id)[0]
|
||||
assert bug_job_map.bug_open is False
|
||||
|
||||
process = BzApiBugProcess()
|
||||
process.minimum_failures_to_reopen = minimum_failures_to_reopen
|
||||
process.run()
|
||||
|
||||
# reopens based on minimum_failures_to_reopen
|
||||
bug_job_map = BugJobMap.objects.filter(job_id=test_jobs[4].id, bug_id=incomplete_bugs[0].id)[0]
|
||||
assert bug_job_map.bug_open is True
|
||||
|
||||
bug_job_map = BugJobMap.objects.filter(job_id=test_jobs[3].id, bug_id=incomplete_bugs[2].id)[0]
|
||||
if minimum_failures_to_reopen < 3:
|
||||
assert bug_job_map.bug_open is True
|
||||
else:
|
||||
assert bug_job_map.bug_open is False
|
||||
|
||||
reopened_bugs = request.config.cache.get("reopened_bugs", None)
|
||||
|
||||
import json
|
||||
|
|
|
@ -7,10 +7,11 @@ from treeherder.model.models import BugJobMap, Job
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_no_auth,test_duplicate_handling", [(True, False), (False, False), (False, True)]
|
||||
"test_no_auth,test_duplicate_handling,bug_open",
|
||||
[(True, False, False), (False, False, False), (False, True, True)],
|
||||
)
|
||||
def test_create_bug_job_map(
|
||||
client, test_job, test_user, bugs, test_no_auth, test_duplicate_handling
|
||||
client, test_job, test_user, bugs, test_no_auth, test_duplicate_handling, bug_open
|
||||
):
|
||||
"""
|
||||
test creating a single note via endpoint
|
||||
|
@ -19,7 +20,12 @@ def test_create_bug_job_map(
|
|||
if not test_no_auth:
|
||||
client.force_authenticate(user=test_user)
|
||||
|
||||
submit_obj = {"job_id": test_job.id, "bug_id": bug.id, "type": "manual"}
|
||||
submit_obj = {
|
||||
"job_id": test_job.id,
|
||||
"bug_id": bug.id,
|
||||
"type": "manual",
|
||||
"bug_open": bug_open,
|
||||
}
|
||||
|
||||
# if testing duplicate handling, submit twice
|
||||
if test_duplicate_handling:
|
||||
|
@ -43,6 +49,7 @@ def test_create_bug_job_map(
|
|||
assert bug_job_map.job_id == submit_obj["job_id"]
|
||||
assert bug_job_map.bug_id == submit_obj["bug_id"]
|
||||
assert bug_job_map.user == test_user
|
||||
assert bug_job_map.bug_open == bug_open
|
||||
|
||||
|
||||
def test_bug_job_map_list(client, test_repository, eleven_jobs_stored, test_user, bugs):
|
||||
|
|
|
@ -50,7 +50,10 @@ def reopen_intermittent_bugs(minimum_failures_to_reopen=1):
|
|||
|
||||
comment = {"body": "New failure instance: " + log_url}
|
||||
url = settings.BUGFILER_API_URL + "/rest/bug/" + str(bug_id)
|
||||
headers = {"x-bugzilla-api-key": settings.BUGFILER_API_KEY, "Accept": "application/json"}
|
||||
headers = {
|
||||
"x-bugzilla-api-key": settings.BUGFILER_API_KEY,
|
||||
"Accept": "application/json",
|
||||
}
|
||||
data = {
|
||||
"status": "REOPENED",
|
||||
"comment": comment,
|
||||
|
@ -59,6 +62,8 @@ def reopen_intermittent_bugs(minimum_failures_to_reopen=1):
|
|||
|
||||
try:
|
||||
reopen_request(url, method="PUT", headers=headers, json=data)
|
||||
# NOTE: this will only toggle 1 bug_job_map entry, not all (if there are retriggers)
|
||||
BugJobMap.objects.filter(job_id=job_id, bug_id=bug_id).update(bug_open=True)
|
||||
except requests.exceptions.HTTPError as e:
|
||||
try:
|
||||
message = e.response.json()["message"]
|
||||
|
|
|
@ -737,12 +737,12 @@ class BugJobMap(models.Model):
|
|||
return "autoclassifier"
|
||||
|
||||
@classmethod
|
||||
def create(cls, job_id, bug_id, user=None):
|
||||
def create(cls, job_id, bug_id, user=None, bug_open=False):
|
||||
bug_map = BugJobMap.objects.create(
|
||||
job_id=job_id,
|
||||
bug_id=bug_id,
|
||||
user=user,
|
||||
bug_open=False,
|
||||
bug_open=bug_open,
|
||||
)
|
||||
|
||||
if not user:
|
||||
|
|
|
@ -13,12 +13,14 @@ class BugJobMapViewSet(viewsets.ViewSet):
|
|||
"""Add a new relation between a job and a bug."""
|
||||
job_id = int(request.data["job_id"])
|
||||
bug_id = int(request.data["bug_id"])
|
||||
bug_open = bool(request.data["bug_open"])
|
||||
|
||||
try:
|
||||
BugJobMap.create(
|
||||
job_id=job_id,
|
||||
bug_id=bug_id,
|
||||
user=request.user,
|
||||
bug_open=bug_open,
|
||||
)
|
||||
message = "Bug job map saved"
|
||||
except IntegrityError:
|
||||
|
|
|
@ -150,13 +150,14 @@ class PinBoard extends React.Component {
|
|||
};
|
||||
|
||||
saveBugs = (job) => {
|
||||
const { pinnedJobBugs, notify } = this.props;
|
||||
const { pinnedJobBugs, newBug, notify } = this.props;
|
||||
|
||||
pinnedJobBugs.forEach((bugId) => {
|
||||
const bjm = new BugJobMapModel({
|
||||
bug_id: bugId,
|
||||
job_id: job.id,
|
||||
type: 'annotation',
|
||||
bug_open: newBug.has(bugId),
|
||||
});
|
||||
|
||||
bjm.create().catch((response) => {
|
||||
|
@ -703,6 +704,7 @@ PinBoard.propTypes = {
|
|||
isPinBoardVisible: PropTypes.bool.isRequired,
|
||||
pinnedJobs: PropTypes.shape({}).isRequired,
|
||||
pinnedJobBugs: PropTypes.shape({}).isRequired,
|
||||
newBug: PropTypes.string.isRequired,
|
||||
addBug: PropTypes.func.isRequired,
|
||||
removeBug: PropTypes.func.isRequired,
|
||||
unPinJob: PropTypes.func.isRequired,
|
||||
|
@ -733,6 +735,7 @@ const mapStateToProps = ({
|
|||
pinnedJobBugs,
|
||||
failureClassificationId,
|
||||
failureClassificationComment,
|
||||
newBug,
|
||||
},
|
||||
}) => ({
|
||||
revisionTips,
|
||||
|
@ -743,6 +746,7 @@ const mapStateToProps = ({
|
|||
pinnedJobBugs,
|
||||
failureClassificationId,
|
||||
failureClassificationComment,
|
||||
newBug,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
|
|
|
@ -108,13 +108,20 @@ export const pinJobs = (jobsToPin) => {
|
|||
export const addBug = (bug, job) => {
|
||||
return async (dispatch, getState) => {
|
||||
const {
|
||||
pinnedJobs: { pinnedJobBugs },
|
||||
pinnedJobs: { pinnedJobBugs, newBug },
|
||||
} = getState();
|
||||
|
||||
const bugId = bug.dupe_of ? bug.dupe_of : bug.id;
|
||||
if (!pinnedJobBugs.has(bugId)) {
|
||||
pinnedJobBugs.add(bugId);
|
||||
}
|
||||
|
||||
if ('newBug' in bug) {
|
||||
if (!newBug.has(bug.newBug)) {
|
||||
newBug.add(bug.newBug);
|
||||
}
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: SET_PINNED_JOB_BUGS,
|
||||
pinnedJobBugs: new Set(pinnedJobBugs),
|
||||
|
@ -148,6 +155,7 @@ export const unPinAll = () => ({
|
|||
payload: {
|
||||
failureClassificationId: 4,
|
||||
failureClassificationComment: '',
|
||||
newBug: new Set(),
|
||||
pinnedJobs: {},
|
||||
pinnedJobBugs: new Set(),
|
||||
},
|
||||
|
@ -171,6 +179,7 @@ const initialState = {
|
|||
pinnedJobs: {},
|
||||
pinnedJobBugs: new Set(),
|
||||
failureClassificationComment: '',
|
||||
newBug: new Set(),
|
||||
failureClassificationId: 4,
|
||||
isPinBoardVisible: false,
|
||||
};
|
||||
|
|
|
@ -61,7 +61,7 @@ class FailureSummaryTab extends React.Component {
|
|||
bugFilerCallback = (data) => {
|
||||
const { addBug } = this.props;
|
||||
|
||||
addBug({ id: data.id });
|
||||
addBug({ id: data.id, newBug: data.id });
|
||||
window.dispatchEvent(new CustomEvent(thEvents.saveClassification));
|
||||
// Open the newly filed bug in a new tab or window for further editing
|
||||
window.open(data.url);
|
||||
|
|
Загрузка…
Ссылка в новой задаче