Add defects mapping for reprod bugs function
Job: http://cz8133.bud.mirantis.net/view/report/job/mark-reports/
Testrail plugin: http://github.com/abaraniuk/testrail-python
Change-Id: I976fb7e8d5fed9486fac814625ac0516f66141a5
diff --git a/tcp_tests/report.py b/tcp_tests/report.py
index 03530d6..0bec6ef 100644
--- a/tcp_tests/report.py
+++ b/tcp_tests/report.py
@@ -9,6 +9,7 @@
from testrail import TestRail
from testrail.test import Test
+# from testrail_api import APIClient
from functools32 import lru_cache
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
@@ -28,6 +29,11 @@
"create-report",
help="Create summary report",
description="Create summary report")
+ cli_process_link = commands.add_parser(
+ "mark-fails",
+ help="Extract linked bugs from previous reports",
+ description="Extract linked bugs from previous reports"
+ " and mark current")
cli_process.add_argument(
"-T", "--testrail-host", dest="testrail_host",
required=True,
@@ -77,6 +83,39 @@
required=True,
help="JIRA user password")
+ # link fail bugs parameters
+ cli_process_link.add_argument(
+ "-T", "--testrail-host", dest="testrail_host",
+ required=True,
+ help="TestRail hostname")
+ cli_process_link.add_argument(
+ "-U", "--testrail-user", dest="testrail_user",
+ required=True,
+ help="TestRail user email")
+ cli_process_link.add_argument(
+ "-K", "--testrail-user-key", dest="testrail_user_key",
+ required=True,
+ help="TestRail user key")
+ cli_process_link.add_argument(
+ "-R", "--testrail-plan", dest="testrail_plan",
+ required=True,
+ help="TestRail test plan for analize")
+ cli_process_link.add_argument(
+ "-M", "--testrail-marked-plan", dest="testrail_marked_plan",
+ required=False,
+ help="TestRail test plan for parse")
+ cli_process_link.add_argument(
+ "-P", "--testrail-project", dest="testrail_project",
+ required=True,
+ help="TestRail project name")
+ cli_process_link.add_argument(
+ "--testrail-only-run", dest="testrail_only_run",
+ help="Name to update only specified run in selected plan")
+ cli_process_link.add_argument(
+ "--push-to-testrail", dest="update_report_flag", action="store_true",
+ default=False,
+ help="Save report in plan description")
+
if len(sys.argv) == 1:
cli.print_help()
sys.exit(1)
@@ -107,6 +146,19 @@
return ret
+def get_all_failed_results(t_client, list_of_runs, result_type):
+ """
+ returned result format:
+ [[run(id,name), result(id,status,defects...), test(id,name..)],
+ [run(id,name), result(id,status,defects...), test(id,name..)],
+ ...]
+ """
+ ret = []
+ for run in list_of_runs:
+ ret.extend(get_failed_results(t_client, run, result_type))
+ return ret
+
+
@lru_cache()
def fetch_test(api, test_id, run_id):
return Test(api.test_with_id(test_id, run_id))
@@ -126,6 +178,72 @@
return ret
+def get_failed_results(t_client, run, result_type):
+ """
+ returned result format:
+ [run(id,name),
+ result(id,status,defects...),
+ test(id,name..)]
+ """
+ LOG.info("Get results for run - {}".format(run.name))
+ results = t_client.results(run, result_type)
+ results_with_test = []
+ if result_type is '5':
+ ret = [(run, r) for r in results
+ if r.raw_data()['status_id'] is int(result_type) and
+ r.raw_data()['defects'] is None]
+ else:
+ ret = [(run, r) for r in results
+ if r.raw_data()['status_id'] is not None and
+ r.raw_data()['defects'] is not None]
+ for r in ret:
+ run, result = r
+ test = fetch_test(result.api, result.raw_data()['test_id'], run.id)
+ LOG.info("Test {} - {} - {} - {}"
+ .format(test.title, result.status.name,
+ result.raw_data()['status_id'],
+ ','.join(result.defects)))
+ results_with_test.append([run, result, test])
+ return results_with_test
+
+
+def mark_failed_results(t_cl, marked_res, failed_res, t_h):
+ """
+ Extract list tests with defect and compare it with tests to be marked,
+ and add defects and result from marked tests
+ Returned result format:
+ [[target_tests_to_update_with_defect, target_run_id],
+ [target_tests_to_update_with_defect, target_run_id],
+ ...]
+ """
+ LOG.info("Extract marked tests and attach to failed")
+
+ def generate_result(t_c, tst, m_r, m_t):
+ link_comment = "{url}/index.php?/tests/view/{uid}".format(
+ url=t_h, uid=m_t.id)
+ tmp_result = t_c.result()
+ tmp_result.test = tst
+ tmp_result.status = m_r.status
+ tmp_result.comment = "Result taked from: " + link_comment
+ tmp_result.defects = [str(m_r.defects[0])]
+ return tmp_result
+
+ # def check_if_marked():
+ # if ret.count()
+
+ ret = []
+ for run, result, test in failed_res:
+ for m_run, m_result, m_test in marked_res:
+ if run.name == m_run.name \
+ and test.title == m_test.title:
+ LOG.info(" MARKED FOUND: Run:{} test: .. {}-{}"
+ .format(run.id, test.title[-72:],
+ m_result.defects[0]))
+ ret.append([generate_result(t_cl, test, m_result,
+ m_test), run.id])
+ return ret
+
+
@lru_cache()
def get_defect_info(j_client, defect):
LOG.info("Get info about issue {}".format(defect))
@@ -230,7 +348,7 @@
"title": test.title.replace('[', '{').replace(']', '}'),
"uid": test.id,
"link": "{url}/index.php?/tests/view/{uid}".format(
- url=test.api._conf()['url'], uid=test.id)
+ url=test.api._conf()['url'], uid=test.id)
}
def list_of_defect_tests(results):
@@ -278,12 +396,12 @@
"title": test.title,
"uid": test.id,
"link": "{url}/index.php?/tests/view/{uid}".format(
- url=test.api._conf()['url'], uid=test.id)
+ url=test.api._conf()['url'], uid=test.id)
}
def list_of_defect_tests(results):
ret = ["<a href='{link}'>{title} #{uid}</a>".format(
- **title_uid_link(r)) for r in results]
+ **title_uid_link(r)) for r in results]
return ' '.join(ret)
for k in table:
@@ -318,8 +436,8 @@
text = "Bugs Statistics (generated on {date})\n" \
"=======================================================\n" \
"{table}".format(
- date=datetime.datetime.now().strftime("%a %b %d %H:%M:%S %Y"),
- table=get_md_table(table))
+ date=datetime.datetime.now().strftime("%a %b %d %H:%M:%S %Y"),
+ table=get_md_table(table))
plan = t_client.plan(plan_name)
if plan:
plan.description = text
@@ -332,6 +450,17 @@
})
+def update_report(t_client, plan_name, tests_table):
+ LOG.info("Update report table into plan - {}".format(plan_name)
+ + "\n===\nList tests to udate:")
+ plan = t_client.plan(plan_name)
+ if plan:
+ for r_test, run in tests_table:
+ t_client.add(r_test)
+ print(r_test.test.title)
+ LOG.info("\n===\nUpdate plan finished - {}".format(plan_name))
+
+
def create_report(**kwargs):
j_host = kwargs.get('jira_host')
j_user = kwargs.get('jira_user_id')
@@ -359,8 +488,50 @@
push_report(t_client, t_plan, table)
+def mark_fails(**kwargs):
+ testrail_host = kwargs.get('testrail_host')
+ testrail_user = kwargs.get('testrail_user')
+ testrail_user_key = kwargs.get('testrail_user_key')
+ testrail_plan = kwargs.get('testrail_plan')
+ testrail_m_plan = kwargs.get('testrail_marked_plan')
+ testrail_project = kwargs.get('testrail_project')
+ testrail_active_run = kwargs.get('testrail_only_run')
+ if testrail_active_run == '':
+ testrail_active_run = None
+ update_report_flag = kwargs.get('update_report_flag')
+
+ testrail_client = TestRail(email=testrail_user, key=testrail_user_key,
+ url=testrail_host)
+ testrail_client.set_project_id(testrail_client.project(
+ testrail_project).id)
+
+ # Get list runs with marked results
+ marked_runs = get_runs(testrail_client, testrail_m_plan,
+ testrail_active_run)
+
+ # Get list runs to update
+ runs = get_runs(testrail_client, testrail_plan, testrail_active_run)
+
+ # Get list (failed, prod_failed, test_failed,skipped..) tests with defects
+ marked_results = get_all_failed_results(testrail_client, marked_runs,
+ '2,3,4,5,6,7,8,9')
+
+ # Get list (failed) tests without defects to mark
+ failed_results = get_all_failed_results(testrail_client,
+ runs, '5') # 5-failed
+
+ # Generate list tests to update based on compare (defected
+ # results for tests with failed and not defected)
+ tests_to_update = mark_failed_results(testrail_client, marked_results,
+ failed_results, testrail_host)
+
+ if update_report_flag:
+ update_report(testrail_client, testrail_plan, tests_to_update)
+
+
COMMAND_MAP = {
- 'create-report': create_report
+ 'create-report': create_report,
+ 'mark-fails': mark_fails
}