Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: openshift/release-tests
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: dbbcd7055c60c6d35221c357c20ccaef40c55ac0
Choose a base ref
..
head repository: openshift/release-tests
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0600f60fb5d57219d477aaf4e909b2a221e891e2
Choose a head ref
Showing with 333 additions and 85 deletions.
  1. +4 −4 oar/cli/cmd_drop_bugs.py
  2. +11 −3 oar/cli/cmd_update_bug_list.py
  3. +26 −41 oar/core/advisory.py
  4. +53 −3 oar/core/jira.py
  5. +78 −27 oar/core/notification.py
  6. +8 −0 oar/core/worksheet.py
  7. +138 −1 tests/test_jira.py
  8. +15 −6 tests/test_notification.py
8 changes: 4 additions & 4 deletions oar/cli/cmd_drop_bugs.py
Original file line number Diff line number Diff line change
@@ -26,16 +26,16 @@ def drop_bugs(ctx):
report.update_task_status(LABEL_TASK_DROP_BUGS, TASK_STATUS_INPROGRESS)
# check doc and product security approval advisories
approved_doc_ads, approved_prodsec_ads = am.get_doc_prodsec_approved_ads()
dropped_bugs, must_verify_bugs = am.drop_bugs()
dropped_bugs, high_severity_bugs = am.drop_bugs()
# check if all bugs are verified
nm = NotificationManager(cs)
requested_doc_ads = []
requested_prodsec_ads = []
if len(dropped_bugs) or len(must_verify_bugs):
if len(dropped_bugs) or len(high_severity_bugs):
logger.info("updating test report")
report.update_bug_list(am.get_jira_issues())
NotificationManager(cs).share_dropped_and_must_verify_bugs(
dropped_bugs, must_verify_bugs
NotificationManager(cs).share_dropped_and_high_severity_bugs(
dropped_bugs, high_severity_bugs
)
if len(approved_doc_ads):
for ad in approved_doc_ads:
14 changes: 11 additions & 3 deletions oar/cli/cmd_update_bug_list.py
Original file line number Diff line number Diff line change
@@ -13,11 +13,15 @@

@click.command()
@click.pass_context
@click.option("--notify/--no-notify", default=True, help="Send notification to bug owner, default value is true")
def update_bug_list(ctx, notify):
@click.option("--notify/--no-notify", default=True, help="Send notification to bug owners, default value is true")
@click.option("--confirm-droppable", is_flag=True, default=False,
help="Send notification only to bug owners with critical and higher issue severity, default value is false")
def update_bug_list(ctx, notify, confirm_droppable):
"""
Update bug status listed in report, update existing bug status and append new ON_QA bug
"""
if not notify and confirm_droppable:
raise click.UsageError("Error: --no-notify and --confirm-droppable cannot be used together")
# get config store from context
cs = ctx.obj["cs"]
try:
@@ -30,7 +34,11 @@ def update_bug_list(ctx, notify):
report.update_bug_list(jira_issues)
# send notification
if notify:
NotificationManager(cs).share_bugs_to_be_verified(jira_issues)
if confirm_droppable:
high_severity_issues, _ = JiraManager(cs).get_high_severity_and_can_drop_issues(jira_issues)
NotificationManager(cs).share_high_severity_bugs(high_severity_issues)
else:
NotificationManager(cs).share_bugs_to_be_verified(jira_issues)
# check if all bugs are verified
if report.are_all_bugs_verified():
report.update_task_status(LABEL_TASK_BUGS_TO_VERIFY, TASK_STATUS_PASS)
67 changes: 26 additions & 41 deletions oar/core/advisory.py
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ def get_advisories(self):
Get all advisories
Returns:
List[Advisory] : all advisory wrappers
list: all advisory wrappers
"""
ads = []
for k, v in self._cs.get_advisories().items():
@@ -51,7 +51,7 @@ def get_jira_issues(self):
Get all jira issues from advisories in a release
Returns:
List: all jira issues from advisories
list: all jira issues from advisories
"""
all_jira_issues = []
try:
@@ -193,56 +193,41 @@ def change_advisory_status(self, target_status=AD_STATUS_REL_PREP):

def drop_bugs(self):
"""
Go thru all attached bugs. Drop the not verified bugs if they're not critical/blocker/customer_case
Go through all attached bugs. Drop the not verified bugs if they're not critical/blocker/customer_case/CVE
Raises:
AdvisoryException: error when dropping bugs from advisory
Returns:
Tuple [list, list]: bugst to be dropped, bugs cannot be dropped
tuple[list[str], list[str]]: list of jira keys that were dropped, list of high severity jira keys that are still to be verified
"""
jm = JiraManager(self._cs)
ads = self.get_advisories()
all_dropped_bugs = []
all_must_verify_bugs = []
all_high_severity_bugs = []
for ad in ads:
bug_list = []
issues = ad.jira_issues
if len(issues):
for key in issues:
issue = jm.get_issue(key)
if issue.is_verified() or issue.is_closed():
continue
else:
# check whether the issue must be verified
if (
issue.is_critical_issue()
or issue.is_customer_case()
or issue.is_cve_tracker()
):
logger.warning(
f"jira issue {key} is critical: {issue.is_critical_issue()} or customer case: {issue.is_customer_case()} or cve tracker: {issue.is_cve_tracker()}, it must be verified"
)
all_must_verify_bugs.append(key)
else:
# issue can be dropped
logger.info(
f"jira issue {key} is {issue.get_status()} will be dropped from advisory {ad.errata_id}"
)
bug_list.append(key)
high_severity_bugs, drop_bug_list = jm.get_high_severity_and_can_drop_issues(issues)
all_high_severity_bugs.extend(high_severity_bugs)

if len(bug_list):
all_dropped_bugs += bug_list
ad.remove_bugs(bug_list)
logger.info(
f"not verified and non-critical bugs are dropped from advisory {ad.errata_id}"
)
else:
logger.info(
f"there is no bug in advisory {ad.errata_id} can be dropped"
)
if drop_bug_list:
all_dropped_bugs.extend(drop_bug_list)
for key in drop_bug_list:
issue = jm.get_issue(key)
# issue can be dropped
logger.info(
f"jira issue {key} is {issue.get_status()}, it will be dropped from advisory {ad.errata_id}"
)
ad.remove_bugs(drop_bug_list)
logger.info(
f"not verified and non-critical bugs are dropped from advisory {ad.errata_id}"
)
else:
logger.info(
f"there is no bug in advisory {ad.errata_id} that can be dropped"
)

return all_dropped_bugs, all_must_verify_bugs
return all_dropped_bugs, all_high_severity_bugs

def check_cve_tracker_bug(self):
"""
@@ -252,7 +237,7 @@ def check_cve_tracker_bug(self):
AdvisoryException: error when invoke elliott cmd
Returns:
List[str]: missed CVE tracker bugs
list: CVE tracker bugs not found in RHSA advisories
"""
cmd = [
"elliott",
@@ -806,6 +791,6 @@ def check_kernel_tag(self):
logger.info("kernel tag early-kernel-stop-ship is detected")
return True
return False

def is_rhsa(self):
return self.errata_type == 'RHSA'
56 changes: 53 additions & 3 deletions oar/core/jira.py
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ def get_issue(self, key):
key (str): JIRA issue key
Returns:
JiraIssue: object of JiraIssue
list: object of JiraIssue
"""
try:
issue = self._svc.issue(key)
@@ -135,7 +135,7 @@ def get_sub_tasks(self, parent_key):
parent_key (str): parent issue key
Returns:
List [JiraIssue]: jira subtask list
list: jira subtask list
"""
subtasks = []
if not parent_key:
@@ -206,6 +206,31 @@ def add_comment(self, key, comment):
raise JiraException(
"invalid input argument key or comment is empty")

def get_high_severity_and_can_drop_issues(self, jira_issue_keys):
"""
Get list of critical, blocker, customer or CVE issues and list of issues that can be dropped without confirming
Args:
jira_issue_keys (list[str]): jira issues keys to be processed
Returns:
tuple[list[str], list[str]]: list of high severity jira keys that are still to be verified, list of jira keys that can be dropped
"""
high_severity_issues = []
can_drop_issues = []
if jira_issue_keys:
for key in jira_issue_keys:
issue = self.get_issue(key)
if issue.is_verified() or issue.is_closed():
continue
else:
if issue.is_high_severity_issue():
high_severity_issues.append(key)
else:
can_drop_issues.append(key)

return high_severity_issues, can_drop_issues


class JiraIssue:
"""
@@ -226,7 +251,13 @@ def get_qa_contact(self):
Get issue field `QA Contact`
"""
field = self._issue.fields.customfield_12315948
return field.emailAddress if field else "Unknown"
if field:
return field.emailAddress
else:
logger.warning(
f"jira issue {self.get_key()} does not have assigned QA contact, please contact responsible team to find it"
)
return "Unknown"

def get_status(self):
"""
@@ -359,3 +390,22 @@ def is_qe_subtask(self):
check whether the issue is QE subtask.
"""
return self.get_summary() in JIRA_QE_TASK_SUMMARIES

def is_high_severity_issue(self):
"""
Check if the issue is critical, blocker, customer case, or CVE
Returns:
bool: True if the issue has high severity
"""
if self.is_cve_tracker():
logger.warning(
f"jira issue {self.get_key()} is cve tracker: {self.is_cve_tracker()}, it must be verified"
)
return True
if self.is_critical_issue() or self.is_customer_case():
logger.warning(
f"jira issue {self.get_key()} is critical: {self.is_critical_issue()} or customer case: {self.is_customer_case()}, it should be verified"
)
return True
return False
Loading