2018-04-26 12:34:15 +00:00
|
|
|
import json
|
|
|
|
import requests
|
2019-07-03 15:28:16 +00:00
|
|
|
import logging
|
2019-10-10 17:38:50 +00:00
|
|
|
import itertools
|
2018-05-20 16:34:22 +00:00
|
|
|
import emoji
|
2018-04-26 12:34:15 +00:00
|
|
|
import base64
|
|
|
|
from os import environ
|
|
|
|
from support.base_test_report import BaseTestReport
|
|
|
|
|
|
|
|
|
|
|
|
class TestrailReport(BaseTestReport):
|
|
|
|
|
2018-10-26 13:32:05 +00:00
|
|
|
def __init__(self):
|
|
|
|
super(TestrailReport, self).__init__()
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
self.password = environ.get('TESTRAIL_PASS')
|
|
|
|
self.user = environ.get('TESTRAIL_USER')
|
|
|
|
|
|
|
|
self.run_id = None
|
2018-09-28 15:30:06 +00:00
|
|
|
self.suite_id = 48
|
|
|
|
self.project_id = 14
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
self.outcomes = {
|
|
|
|
'passed': 1,
|
|
|
|
'undefined_fail': 10}
|
|
|
|
|
|
|
|
self.headers = dict()
|
|
|
|
self.headers['Authorization'] = 'Basic %s' % str(
|
|
|
|
base64.b64encode(bytes('%s:%s' % (self.user, self.password), 'utf-8')), 'ascii').strip()
|
|
|
|
self.headers['Content-Type'] = 'application/json'
|
|
|
|
|
2018-10-26 13:32:05 +00:00
|
|
|
self.url = 'https://ethstatus.testrail.net/index.php?/'
|
|
|
|
self.api_url = self.url + 'api/v2/'
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
def get(self, method):
|
2019-06-17 16:36:28 +00:00
|
|
|
rval = requests.get(self.api_url + method, headers=self.headers).json()
|
|
|
|
if 'error' in rval:
|
2019-07-03 15:28:16 +00:00
|
|
|
logging.error("Failed TestRail request: %s" % rval['error'])
|
2019-06-17 16:36:28 +00:00
|
|
|
return rval
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
def post(self, method, data):
|
|
|
|
data = bytes(json.dumps(data), 'utf-8')
|
2018-10-26 13:32:05 +00:00
|
|
|
return requests.post(self.api_url + method, data=data, headers=self.headers).json()
|
2018-04-26 12:34:15 +00:00
|
|
|
|
|
|
|
def get_suites(self):
|
|
|
|
return self.get('get_suites/%s' % self.project_id)
|
|
|
|
|
|
|
|
def get_tests(self):
|
|
|
|
return self.get('get_tests/%s' % self.run_id)
|
|
|
|
|
|
|
|
def get_milestones(self):
|
|
|
|
return self.get('get_milestones/%s' % self.project_id)
|
|
|
|
|
2018-08-07 16:38:12 +00:00
|
|
|
def get_runs(self, pr_number):
|
|
|
|
return [i for i in self.get('get_runs/%s' % self.project_id) if 'PR-%s ' % pr_number in i['name']]
|
|
|
|
|
|
|
|
def get_run(self, run_id: int):
|
|
|
|
return self.get('get_run/%s' % run_id)
|
|
|
|
|
|
|
|
def get_last_pr_run(self, pr_number):
|
|
|
|
run_id = max([run['id'] for run in self.get_runs(pr_number)])
|
|
|
|
return self.get_run(run_id=run_id)
|
|
|
|
|
2018-04-26 12:34:15 +00:00
|
|
|
@property
|
|
|
|
def actual_milestone_id(self):
|
|
|
|
return self.get_milestones()[-1]['id']
|
|
|
|
|
|
|
|
def add_run(self, run_name):
|
|
|
|
request_body = {'suite_id': self.suite_id,
|
|
|
|
'name': run_name,
|
2018-06-30 12:17:38 +00:00
|
|
|
'milestone_id': self.actual_milestone_id,
|
2020-09-04 15:34:58 +00:00
|
|
|
'case_ids': self.get_regression_cases(),
|
2018-06-30 12:17:38 +00:00
|
|
|
'include_all': False}
|
2018-04-26 12:34:15 +00:00
|
|
|
run = self.post('add_run/%s' % self.project_id, request_body)
|
|
|
|
self.run_id = run['id']
|
|
|
|
|
2019-10-10 17:38:50 +00:00
|
|
|
def get_cases(self, section_ids):
|
|
|
|
test_cases = list()
|
|
|
|
for section_id in section_ids:
|
|
|
|
test_cases.append(self.get('get_cases/%s&suite_id=%s§ion_id=%s' % (self.project_id, self.suite_id, section_id)))
|
|
|
|
return itertools.chain.from_iterable(test_cases)
|
2018-06-30 12:17:38 +00:00
|
|
|
|
2020-09-04 15:34:58 +00:00
|
|
|
def get_regression_cases(self):
|
2018-06-30 12:17:38 +00:00
|
|
|
test_cases = dict()
|
2018-09-28 15:30:06 +00:00
|
|
|
test_cases['critical'] = 734
|
|
|
|
test_cases['high'] = 735
|
|
|
|
test_cases['medium'] = 736
|
|
|
|
test_cases['low'] = 737
|
2018-06-30 12:17:38 +00:00
|
|
|
case_ids = list()
|
2020-09-04 15:34:58 +00:00
|
|
|
for phase in test_cases:
|
|
|
|
for case in self.get_cases([test_cases[phase]]):
|
|
|
|
case_ids.append(case['id'])
|
2018-06-30 12:17:38 +00:00
|
|
|
return case_ids
|
|
|
|
|
2018-04-26 12:34:15 +00:00
|
|
|
def add_results(self):
|
|
|
|
for test in self.get_all_tests():
|
|
|
|
test_steps = "# Steps: \n"
|
|
|
|
devices = str()
|
|
|
|
method = 'add_result_for_case/%s/%s' % (self.run_id, test.testrail_case_id)
|
2018-04-28 09:02:39 +00:00
|
|
|
last_testrun = test.testruns[-1]
|
|
|
|
for step in last_testrun.steps:
|
2018-04-26 12:34:15 +00:00
|
|
|
test_steps += step + "\n"
|
2018-04-28 09:02:39 +00:00
|
|
|
for i, device in enumerate(last_testrun.jobs):
|
2018-04-26 12:34:15 +00:00
|
|
|
devices += "# [Device %d](%s) \n" % (i + 1, self.get_sauce_job_url(device))
|
2018-04-28 09:02:39 +00:00
|
|
|
data = {'status_id': self.outcomes['undefined_fail'] if last_testrun.error else self.outcomes['passed'],
|
2018-05-20 16:34:22 +00:00
|
|
|
'comment': '%s' % ('# Error: \n %s \n' % emoji.demojize(last_testrun.error)) + devices + test_steps if last_testrun.error
|
2018-04-26 12:34:15 +00:00
|
|
|
else devices + test_steps}
|
|
|
|
self.post(method, data=data)
|
2018-10-26 13:32:05 +00:00
|
|
|
|
2018-11-24 16:18:31 +00:00
|
|
|
def get_run_results(self):
|
|
|
|
return self.get('get_results_for_run/%s' % self.run_id)
|
|
|
|
|
|
|
|
def is_run_successful(self):
|
|
|
|
for test in self.get_run_results():
|
|
|
|
if test['status_id'] != 1:
|
|
|
|
return False
|
|
|
|
else:
|
|
|
|
return True
|
|
|
|
|
2018-10-26 13:32:05 +00:00
|
|
|
def get_test_result_link(self, test_run_id, test_case_id):
|
|
|
|
try:
|
|
|
|
test_id = self.get('get_results_for_case/%s/%s' % (test_run_id, test_case_id))[0]['test_id']
|
|
|
|
return '%stests/view/%s' % (self.url, test_id)
|
|
|
|
except KeyError:
|
|
|
|
return None
|