Report BVT/Smoke tests results to TestRail
Add ability to report results of performed system tests (BVT and Smoke) of assembled Fuel iso image. Parse tests jobs from 'downstream build view' HTML page, because such info can't be fetched via Jenkins API (https://issues.jenkins-ci.org/browse/JENKINS-13314). Add '-m/--manual_run' flag to reporter script, which enables manual addition of tests cases to TestRun (only tests with results will be included instead of full tests Suite). Aslo add/modify some required methods to TestRail client and refactor reporter script. Change-Id: Ide72707efed4bc23082694409026526d2bb8b8fa Related-bug: #1415467
This commit is contained in:
parent
9aa8528f23
commit
763589613f
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import re
|
||||
import urllib2
|
||||
|
||||
from settings import JENKINS
|
||||
@ -33,6 +34,45 @@ def get_jobs_for_view(view):
|
||||
return jobs
|
||||
|
||||
|
||||
def get_downstream_builds_from_html(url):
|
||||
"""Return list of downstream jobs builds from specified job
|
||||
"""
|
||||
url = "/".join([url, 'downstreambuildview/'])
|
||||
logger.debug("Request downstream builds data from {}".format(url))
|
||||
req = urllib2.Request(url)
|
||||
opener = urllib2.build_opener(urllib2.HTTPHandler)
|
||||
s = opener.open(req).read()
|
||||
opener.close()
|
||||
jobs = []
|
||||
raw_downstream_builds = re.findall(
|
||||
'.*downstream-buildview.*href="(/job/\S+/[0-9]+/).*', s)
|
||||
for raw_build in raw_downstream_builds:
|
||||
sub_job_name = raw_build.split('/')[2]
|
||||
sub_job_build = raw_build.split('/')[3]
|
||||
build = Build(name=sub_job_name, number=sub_job_build)
|
||||
jobs.append(
|
||||
{
|
||||
'name': build.name,
|
||||
'number': build.number,
|
||||
'result': build.build_data['result']
|
||||
}
|
||||
)
|
||||
|
||||
return jobs
|
||||
|
||||
|
||||
def get_build_artifact(url, artifact):
|
||||
"""Return content of job build artifact
|
||||
"""
|
||||
url = "/".join([url, 'artifact', artifact])
|
||||
logger.debug("Request artifact content from {}".format(url))
|
||||
req = urllib2.Request(url)
|
||||
opener = urllib2.build_opener(urllib2.HTTPHandler)
|
||||
s = opener.open(req).read()
|
||||
opener.close()
|
||||
return s
|
||||
|
||||
|
||||
class Build():
|
||||
def __init__(self, name, number):
|
||||
"""Get build info via Jenkins API, get test info via direct HTTP
|
||||
|
@ -16,13 +16,17 @@
|
||||
|
||||
import functools
|
||||
import re
|
||||
import yaml
|
||||
|
||||
from logging import DEBUG
|
||||
from optparse import OptionParser
|
||||
|
||||
from builds import Build
|
||||
from builds import get_build_artifact
|
||||
from builds import get_downstream_builds_from_html
|
||||
from builds import get_jobs_for_view
|
||||
from launchpad_client import LaunchpadBug
|
||||
from settings import JENKINS
|
||||
from settings import LaunchpadSettings
|
||||
from settings import logger
|
||||
from settings import TestRailSettings
|
||||
@ -88,11 +92,23 @@ def retry(count=3):
|
||||
|
||||
|
||||
def get_downstream_builds(jenkins_build_data, status=None):
|
||||
if 'subBuilds' not in jenkins_build_data.keys():
|
||||
return get_downstream_builds_from_html(jenkins_build_data['url'])
|
||||
|
||||
return [{'name': b['jobName'], 'number': b['buildNumber'],
|
||||
'result': b['result']} for b in jenkins_build_data['subBuilds']]
|
||||
|
||||
|
||||
def get_version(jenkins_build_data):
|
||||
if any([artifact for artifact in jenkins_build_data['artifacts']
|
||||
if artifact['fileName'] == JENKINS['version_artifact']]):
|
||||
return get_version_from_artifacts(jenkins_build_data,
|
||||
artifact=JENKINS['version_artifact'])
|
||||
else:
|
||||
return get_version_from_magnet_link(jenkins_build_data)
|
||||
|
||||
|
||||
def get_version_from_magnet_link(jenkins_build_data):
|
||||
parameters = [a['parameters'] for a in jenkins_build_data['actions']
|
||||
if 'parameters' in a.keys()][0]
|
||||
iso_link = [p['value'] for p in parameters if
|
||||
@ -101,6 +117,13 @@ def get_version(jenkins_build_data):
|
||||
int(re.search(r'.*\bfuel-(\d+\.\d+)-(\d+)-.*', iso_link).group(2)))
|
||||
|
||||
|
||||
def get_version_from_artifacts(jenkins_build_data, artifact):
|
||||
version = yaml.load(get_build_artifact(
|
||||
url=jenkins_build_data['url'], artifact=JENKINS['version_artifact']))
|
||||
return version['VERSION']['release'], \
|
||||
int(version['VERSION']['build_number'])
|
||||
|
||||
|
||||
@retry(count=3)
|
||||
def get_tests_results(systest_build):
|
||||
tests_results = []
|
||||
@ -124,17 +147,22 @@ def get_tests_results(systest_build):
|
||||
|
||||
|
||||
def publish_results(project, milestone_id, test_plan,
|
||||
tests_suite, config_id, results):
|
||||
test_run_id = [run['id'] for run in test_plan['entries'][0]['runs'] if
|
||||
config_id in run['config_ids']][0]
|
||||
suite_id, config_id, results):
|
||||
test_run_ids = [run['id'] for entry in test_plan['entries']
|
||||
for run in entry['runs'] if suite_id == run['suite_id']
|
||||
and config_id in run['config_ids']]
|
||||
logger.debug('Looking for previous tests runs on "{0}" using tests suite '
|
||||
'"{1}"...'.format(project.get_config(config_id)['name'],
|
||||
project.get_suite(suite_id)['name']))
|
||||
previous_tests_runs = project.get_previous_runs(milestone_id=milestone_id,
|
||||
suite_id=suite_id,
|
||||
config_id=config_id)
|
||||
cases = project.get_cases(suite=tests_suite)
|
||||
tests = project.get_tests(run_id=test_run_id)
|
||||
cases = project.get_cases(suite_id=suite_id)
|
||||
tests = project.get_tests(run_id=test_run_ids[0])
|
||||
results_to_publish = []
|
||||
|
||||
for result in results:
|
||||
test = project.get_test_by_group(run_id=test_run_id,
|
||||
test = project.get_test_by_group(run_id=test_run_ids[0],
|
||||
group=result.group,
|
||||
tests=tests)
|
||||
if not test:
|
||||
@ -146,8 +174,9 @@ def publish_results(project, milestone_id, test_plan,
|
||||
if result.version in existing_results_versions:
|
||||
continue
|
||||
if result.status != 'passed':
|
||||
run_ids = [run['id'] for run in previous_tests_runs]
|
||||
case_id = project.get_case_by_group(suite=tests_suite,
|
||||
run_ids = [run['id'] for run in previous_tests_runs[0:
|
||||
int(TestRailSettings.previous_results_depth)]]
|
||||
case_id = project.get_case_by_group(suite_id=suite_id,
|
||||
group=result.group,
|
||||
cases=cases)['id']
|
||||
previous_results = project.get_all_results_for_case(
|
||||
@ -157,8 +186,8 @@ def publish_results(project, milestone_id, test_plan,
|
||||
results_to_publish.append(result)
|
||||
try:
|
||||
if len(results_to_publish) > 0:
|
||||
project.add_results_for_cases(run_id=test_run_id,
|
||||
tests_suite=tests_suite,
|
||||
project.add_results_for_cases(run_id=test_run_ids[0],
|
||||
suite_id=suite_id,
|
||||
tests_results=results_to_publish)
|
||||
except:
|
||||
logger.error('Failed to add new results for tests: {0}'.format(
|
||||
@ -201,8 +230,8 @@ def get_existing_bug_link(previous_results):
|
||||
def main():
|
||||
|
||||
parser = OptionParser(
|
||||
description="Publish results of Jenkins build to TestRail."
|
||||
" See conf.py for configuration."
|
||||
description="Publish results of system tests from Jenkins build to "
|
||||
"TestRail. See settings.py for configuration."
|
||||
)
|
||||
parser.add_option('-j', '--job-name', dest='job_name', default=None,
|
||||
help='Jenkins swarm runner job name')
|
||||
@ -213,6 +242,8 @@ def main():
|
||||
help="Get system tests jobs from Jenkins view")
|
||||
parser.add_option("-l", "--live", dest="live_report", action="store_true",
|
||||
help="Get tests results from running swarm")
|
||||
parser.add_option("-m", "--manual", dest="manual_run", action="store_true",
|
||||
help="Manually add tests cases to TestRun (tested only)")
|
||||
parser.add_option("-v", "--verbose",
|
||||
action="store_true", dest="verbose", default=False,
|
||||
help="Enable debug output")
|
||||
@ -222,13 +253,27 @@ def main():
|
||||
if options.verbose:
|
||||
logger.setLevel(DEBUG)
|
||||
|
||||
if options.live_report:
|
||||
if options.live_report and options.build_number == 'latest':
|
||||
options.build_number = 'latest_started'
|
||||
|
||||
tests_results_centos = []
|
||||
tests_results_ubuntu = []
|
||||
case_group = TestRailSettings.test_suite
|
||||
# STEP #1
|
||||
# Initialize TestRail Project and define configuration
|
||||
logger.info('Initializing TestRail Project configuration...')
|
||||
project = TestRailProject(url=TestRailSettings.url,
|
||||
user=TestRailSettings.user,
|
||||
password=TestRailSettings.password,
|
||||
project=TestRailSettings.project)
|
||||
|
||||
tests_suite = project.get_suite_by_name(TestRailSettings.tests_suite)
|
||||
operation_systems = [{'name': config['name'], 'id': config['id'],
|
||||
'distro': config['name'].split()[0].lower()}
|
||||
for config in project.get_config_by_name(
|
||||
'Operation System')['configs']]
|
||||
tests_results = {os['distro']: [] for os in operation_systems}
|
||||
|
||||
# STEP #2
|
||||
# Get tests results from Jenkins
|
||||
logger.info('Getting tests results from Jenkins...')
|
||||
if options.jenkins_view:
|
||||
jobs = get_jobs_for_view(options.jenkins_view)
|
||||
tests_jobs = [{'name': j, 'number': 'latest'}
|
||||
@ -243,88 +288,96 @@ def main():
|
||||
" or Jenkins view with system tests jobs (-w). Exiting..")
|
||||
return
|
||||
|
||||
milestone, iso_number = get_version(runner_build.build_data)
|
||||
|
||||
for systest_build in tests_jobs:
|
||||
if systest_build['result'] is None:
|
||||
logger.debug("Skipping '{0}' job (build #{1}) because it's still "
|
||||
"running...".format(systest_build['name'],
|
||||
systest_build['number'],))
|
||||
continue
|
||||
if 'centos' in systest_build['name'].lower():
|
||||
tests_results_centos.extend(get_tests_results(systest_build))
|
||||
elif 'ubuntu' in systest_build['name'].lower():
|
||||
tests_results_ubuntu.extend(get_tests_results(systest_build))
|
||||
if options.job_name:
|
||||
if 'result' not in systest_build.keys():
|
||||
logger.debug("Skipping '{0}' job because it does't run tests "
|
||||
"(build #{1} contains no results)".format(
|
||||
systest_build['name'],
|
||||
systest_build['number']))
|
||||
continue
|
||||
if systest_build['result'] is None:
|
||||
logger.debug("Skipping '{0}' job (build #{1}) because it's sti"
|
||||
"ll running...".format(systest_build['name'],
|
||||
systest_build['number'],))
|
||||
continue
|
||||
for os in tests_results.keys():
|
||||
if os in systest_build['name'].lower():
|
||||
tests_results[os].extend(get_tests_results(systest_build))
|
||||
|
||||
project = TestRailProject(url=TestRailSettings.url,
|
||||
user=TestRailSettings.user,
|
||||
password=TestRailSettings.password,
|
||||
project=TestRailSettings.project)
|
||||
# STEP #3
|
||||
# Create new TestPlan in TestRail (or get existing) and add TestRuns
|
||||
milestone, iso_number = get_version(runner_build.build_data)
|
||||
milestone = project.get_milestone_by_name(name=milestone)
|
||||
|
||||
milestone = project.get_milestone(name=milestone)
|
||||
|
||||
test_plan_name = '{milestone} {case_group} iso #{iso_number}'.format(
|
||||
test_plan_name = '{milestone} iso #{iso_number}'.format(
|
||||
milestone=milestone['name'],
|
||||
case_group=case_group,
|
||||
iso_number=iso_number)
|
||||
|
||||
operation_systems = [{'name': config['name'], 'id': config['id']}
|
||||
for config in project.get_config_by_name(
|
||||
'Operation System')['configs']]
|
||||
|
||||
if not project.get_plan_by_name(test_plan_name):
|
||||
plan_entries = [project.test_run_struct(
|
||||
name='{case_group}'.format(case_group=case_group),
|
||||
suite=case_group,
|
||||
milestone_id=milestone['id'],
|
||||
description='Results of system tests ({case_group}) on iso # '
|
||||
'"{iso_number}"'.format(case_group=case_group,
|
||||
iso_number=iso_number),
|
||||
config_ids=[os['id']],
|
||||
include_all=True) for os in operation_systems]
|
||||
|
||||
test_plan = project.get_plan_by_name(test_plan_name)
|
||||
if not test_plan:
|
||||
test_plan = project.add_plan(test_plan_name,
|
||||
description='',
|
||||
description='/'.join([
|
||||
JENKINS['url'],
|
||||
'job',
|
||||
'{0}.all'.format(milestone['name']),
|
||||
str(iso_number)]),
|
||||
milestone_id=milestone['id'],
|
||||
entires=[
|
||||
{
|
||||
'suite_id': project.get_suite(
|
||||
case_group)['id'],
|
||||
'config_ids': [os['id'] for os in
|
||||
operation_systems],
|
||||
'runs': plan_entries
|
||||
}
|
||||
])
|
||||
entries=[]
|
||||
)
|
||||
logger.info('Created new TestPlan "{0}".'.format(test_plan_name))
|
||||
else:
|
||||
test_plan = project.get_plan_by_name(test_plan_name)
|
||||
logger.info('Found existing TestPlan "{0}".'.format(test_plan_name))
|
||||
|
||||
logger.debug('Uploading tests results to TestRail...')
|
||||
plan_entries = []
|
||||
all_cases = project.get_cases(suite_id=tests_suite['id'])
|
||||
for os in operation_systems:
|
||||
if 'centos' in os['name'].lower():
|
||||
tests_results_centos = publish_results(
|
||||
project=project,
|
||||
cases_ids = []
|
||||
if options.manual_run:
|
||||
all_results_groups = [r.group for r in tests_results[os['distro']]]
|
||||
for case in all_cases:
|
||||
if case['custom_test_group'] in all_results_groups:
|
||||
cases_ids.append(case['id'])
|
||||
plan_entries.append(
|
||||
project.test_run_struct(
|
||||
name='{suite_name}'.format(suite_name=tests_suite['name']),
|
||||
suite_id=tests_suite['id'],
|
||||
milestone_id=milestone['id'],
|
||||
test_plan=test_plan,
|
||||
tests_suite=case_group,
|
||||
config_id=os['id'],
|
||||
results=tests_results_centos
|
||||
)
|
||||
if 'ubuntu' in os['name'].lower():
|
||||
tests_results_ubuntu = publish_results(
|
||||
project=project,
|
||||
milestone_id=milestone['id'],
|
||||
test_plan=test_plan,
|
||||
tests_suite=case_group,
|
||||
config_id=os['id'],
|
||||
results=tests_results_ubuntu
|
||||
description='Results of system tests ({tests_suite}) on is'
|
||||
'o #"{iso_number}"'.format(tests_suite=tests_suite['name'],
|
||||
iso_number=iso_number),
|
||||
config_ids=[os['id']],
|
||||
include_all=True,
|
||||
case_ids=cases_ids
|
||||
)
|
||||
)
|
||||
|
||||
if not any(entry['suite_id'] == tests_suite['id']
|
||||
for entry in test_plan['entries']):
|
||||
if project.add_plan_entry(plan_id=test_plan['id'],
|
||||
suite_id=tests_suite['id'],
|
||||
config_ids=[os['id'] for os
|
||||
in operation_systems],
|
||||
runs=plan_entries):
|
||||
test_plan = project.get_plan(test_plan['id'])
|
||||
|
||||
# STEP #4
|
||||
# Upload tests results to TestRail
|
||||
logger.info('Uploading tests results to TestRail...')
|
||||
for os in operation_systems:
|
||||
logger.info('Checking tests results for "{0}"...'.format(os['name']))
|
||||
tests_results[os['distro']] = publish_results(
|
||||
project=project,
|
||||
milestone_id=milestone['id'],
|
||||
test_plan=test_plan,
|
||||
suite_id=tests_suite['id'],
|
||||
config_id=os['id'],
|
||||
results=tests_results[os['distro']]
|
||||
)
|
||||
logger.debug('Added new results for tests ({os}): {tests}'.format(
|
||||
os=os['name'], tests=[r.group for r in tests_results[os['distro']]]
|
||||
))
|
||||
|
||||
logger.debug('Added new results for tests (CentOS): {tests}'.format(
|
||||
tests=[r.group for r in tests_results_centos]
|
||||
))
|
||||
logger.debug('Added new results for tests (Ubuntu): {tests}'.format(
|
||||
tests=[r.group for r in tests_results_ubuntu]
|
||||
))
|
||||
logger.info('Report URL: {0}'.format(test_plan['url']))
|
||||
|
||||
|
||||
|
@ -20,10 +20,13 @@ ch = logging.StreamHandler()
|
||||
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
||||
ch.setFormatter(formatter)
|
||||
logger.addHandler(ch)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
|
||||
JENKINS = {
|
||||
'url': os.environ.get('JENKINS_URL', 'http://localhost/'),
|
||||
'version_artifact': os.environ.get('JENKINS_VERSION_ARTIFACT',
|
||||
'version.yaml.txt')
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +44,8 @@ class TestRailSettings(object):
|
||||
password = os.environ.get('TESTRAIL_PASSWORD', 'password')
|
||||
project = os.environ.get('TESTRAIL_PROJECT', 'Mirantis OpenStack')
|
||||
milestone = os.environ.get('TESTRAIL_MILESTONE', '6.1')
|
||||
test_suite = os.environ.get('TESTRAIL_TEST_SUITE', 'Swarm')
|
||||
test_section = os.environ.get('TESTRAIL_TEST_SECTION', 'all cases')
|
||||
test_include = os.environ.get('TESTRAIL_TEST_INCLUDE', None)
|
||||
test_exclude = os.environ.get('TESTRAIL_TEST_EXCLUDE', None)
|
||||
tests_suite = os.environ.get('TESTRAIL_TEST_SUITE', 'Swarm')
|
||||
tests_section = os.environ.get('TESTRAIL_TEST_SECTION', 'all cases')
|
||||
tests_include = os.environ.get('TESTRAIL_TEST_INCLUDE', None)
|
||||
tests_exclude = os.environ.get('TESTRAIL_TEST_EXCLUDE', None)
|
||||
previous_results_depth = os.environ.get('TESTRAIL_TESTS_DEPTH', 5)
|
||||
|
@ -30,12 +30,12 @@ class TestRailProject():
|
||||
return project
|
||||
return None
|
||||
|
||||
def test_run_struct(self, name, suite, milestone_id, description,
|
||||
def test_run_struct(self, name, suite_id, milestone_id, description,
|
||||
config_ids, include_all=True, assignedto=None,
|
||||
case_ids=None):
|
||||
struct = {
|
||||
'name': name,
|
||||
'suite_id': self.get_suite(suite)['id'],
|
||||
'suite_id': suite_id,
|
||||
'milestone_id': milestone_id,
|
||||
'description': description,
|
||||
'include_all': include_all,
|
||||
@ -52,16 +52,26 @@ class TestRailProject():
|
||||
users_uri = 'get_users'
|
||||
return self.client.send_get(uri=users_uri)
|
||||
|
||||
def get_user(self, name):
|
||||
def get_user(self, user_id):
|
||||
user_uri = 'get_user/{user_id}'.format(user_id=user_id)
|
||||
return self.client.send_get(uri=user_uri)
|
||||
|
||||
def get_user_by_name(self, name):
|
||||
for user in self.get_users():
|
||||
if user['name'] == name:
|
||||
return user
|
||||
return self.get_user(user_id=user['id'])
|
||||
|
||||
def get_configs(self):
|
||||
configs_uri = 'get_configs/{project_id}'.format(
|
||||
project_id=self.project['id'])
|
||||
return self.client.send_get(configs_uri)
|
||||
|
||||
def get_config(self, config_id):
|
||||
for configs in self.get_configs():
|
||||
for config in configs['configs']:
|
||||
if config['id'] == int(config_id):
|
||||
return config
|
||||
|
||||
def get_config_by_name(self, name):
|
||||
for config in self.get_configs():
|
||||
if config['name'] == name:
|
||||
@ -72,24 +82,34 @@ class TestRailProject():
|
||||
project_id=self.project['id'])
|
||||
return self.client.send_get(uri=milestones_uri)
|
||||
|
||||
def get_milestone(self, name):
|
||||
def get_milestone(self, milestone_id):
|
||||
milestone_uri = 'get_milestone/{milestone_id}'.format(
|
||||
milestone_id=milestone_id)
|
||||
return self.client.send_get(uri=milestone_uri)
|
||||
|
||||
def get_milestone_by_name(self, name):
|
||||
for milestone in self.get_milestones():
|
||||
if milestone['name'] == name:
|
||||
return milestone
|
||||
return self.get_milestone(milestone_id=milestone['id'])
|
||||
|
||||
def get_suites(self):
|
||||
suites_uri = 'get_suites/{project_id}'.format(
|
||||
project_id=self.project['id'])
|
||||
return self.client.send_get(uri=suites_uri)
|
||||
|
||||
def get_suite(self, name):
|
||||
def get_suite(self, suite_id):
|
||||
suite_uri = 'get_suite/{suite_id}'.format(suite_id=suite_id)
|
||||
return self.client.send_get(uri=suite_uri)
|
||||
|
||||
def get_suite_by_name(self, name):
|
||||
for suite in self.get_suites():
|
||||
if suite['name'] == name:
|
||||
return suite
|
||||
return self.get_suite(suite_id=suite['id'])
|
||||
|
||||
def get_sections(self, suite):
|
||||
def get_sections(self, suite_id):
|
||||
sections_uri = 'get_sections/{project_id}&suite_id={suite_id}'.format(
|
||||
project_id=self.project['id'], suite_id=self.get_suite(suite)['id']
|
||||
project_id=self.project['id'],
|
||||
suite_id=suite_id
|
||||
)
|
||||
return self.client.send_get(sections_uri)
|
||||
|
||||
@ -97,14 +117,15 @@ class TestRailProject():
|
||||
section_uri = 'get_section/{section_id}'.format(section_id=section_id)
|
||||
return self.client.send_get(section_uri)
|
||||
|
||||
def get_section_by_name(self, suite, section_name):
|
||||
for section in self.get_sections(suite=suite):
|
||||
def get_section_by_name(self, suite_id, section_name):
|
||||
for section in self.get_sections(suite_id=suite_id):
|
||||
if section['name'] == section_name:
|
||||
return section
|
||||
return self.get_section(section_id=section['id'])
|
||||
|
||||
def get_cases(self, suite, section_id=None):
|
||||
def get_cases(self, suite_id, section_id=None):
|
||||
cases_uri = 'get_cases/{project_id}&suite_id={suite_id}'.format(
|
||||
project_id=self.project['id'], suite_id=self.get_suite(suite)['id']
|
||||
project_id=self.project['id'],
|
||||
suite_id=suite_id
|
||||
)
|
||||
if section_id:
|
||||
cases_uri = '{0}§ion_id={section_id}'.format(
|
||||
@ -112,15 +133,19 @@ class TestRailProject():
|
||||
)
|
||||
return self.client.send_get(cases_uri)
|
||||
|
||||
def get_case_by_name(self, suite, name, cases=None):
|
||||
for case in cases or self.get_cases(suite):
|
||||
if case['title'] == name:
|
||||
return case
|
||||
def get_case(self, case_id):
|
||||
case_uri = 'get_case/{case_id}'.format(case_id=case_id)
|
||||
return self.client.send_get(case_uri)
|
||||
|
||||
def get_case_by_group(self, suite, group, cases=None):
|
||||
for case in cases or self.get_cases(suite):
|
||||
def get_case_by_name(self, suite_id, name, cases=None):
|
||||
for case in cases or self.get_cases(suite_id):
|
||||
if case['title'] == name:
|
||||
return self.get_case(case_id=case['id'])
|
||||
|
||||
def get_case_by_group(self, suite_id, group, cases=None):
|
||||
for case in cases or self.get_cases(suite_id):
|
||||
if case['custom_test_group'] == group:
|
||||
return case
|
||||
return self.get_case(case_id=case['id'])
|
||||
|
||||
def add_case(self, section_id, case):
|
||||
add_case_uri = 'add_case/{section_id}'.format(section_id=section_id)
|
||||
@ -131,37 +156,39 @@ class TestRailProject():
|
||||
project_id=self.project['id'])
|
||||
return self.client.send_get(plans_uri)
|
||||
|
||||
def get_plans_by_milestone(self, milestone_id):
|
||||
plans = self.get_plans()
|
||||
return [plan for plan in plans if plan['milestone_id'] == milestone_id]
|
||||
|
||||
def get_plan(self, plan_id):
|
||||
plan_uri = 'get_plan/{plan_id}'.format(plan_id=plan_id)
|
||||
return self.client.send_get(plan_uri)
|
||||
|
||||
def get_plans_by_milestone(self, milestone_id):
|
||||
plans = self.get_plans()
|
||||
return [self.get_plan(plan['id']) for plan in plans
|
||||
if plan['milestone_id'] == milestone_id]
|
||||
|
||||
def get_plan_by_name(self, name):
|
||||
for plan in self.get_plans():
|
||||
if plan['name'] == name:
|
||||
return self.get_plan(plan['id'])
|
||||
|
||||
def add_plan(self, name, description, milestone_id, entires):
|
||||
def add_plan(self, name, description, milestone_id, entries):
|
||||
add_plan_uri = 'add_plan/{project_id}'.format(
|
||||
project_id=self.project['id'])
|
||||
new_plan = {
|
||||
'name': name,
|
||||
'description': description,
|
||||
'milestone_id': milestone_id,
|
||||
'entries': entires
|
||||
'entries': entries
|
||||
}
|
||||
return self.client.send_post(add_plan_uri, new_plan)
|
||||
|
||||
def add_plan_entry(self, plan_id, suite_id, runs):
|
||||
def add_plan_entry(self, plan_id, suite_id, config_ids, runs):
|
||||
add_plan_entry_uri = 'add_plan_entry/{plan_id}'.format(plan_id=plan_id)
|
||||
new_entry = {
|
||||
'suite_id': suite_id,
|
||||
'runs': runs
|
||||
'config_ids': config_ids,
|
||||
'runs': runs,
|
||||
}
|
||||
self.client.send_post(add_plan_entry_uri, new_entry)
|
||||
return self.client.send_post(add_plan_entry_uri, new_entry)
|
||||
|
||||
def delete_plan(self, plan_id):
|
||||
delete_plan_uri = 'delete_plan/{plan_id}'.format(plan_id=plan_id)
|
||||
@ -172,18 +199,23 @@ class TestRailProject():
|
||||
project_id=self.project['id'])
|
||||
return self.client.send_get(uri=runs_uri)
|
||||
|
||||
def get_run(self, name):
|
||||
def get_run(self, run_id):
|
||||
run_uri = 'get_run/{run_id}'.format(run_id=run_id)
|
||||
return self.client.send_get(uri=run_uri)
|
||||
|
||||
def get_run_by_name(self, name):
|
||||
for run in self.get_runs():
|
||||
if run['name'] == name:
|
||||
return run
|
||||
return self.get_run(run_id=run['id'])
|
||||
|
||||
def get_previous_runs(self, milestone_id, config_id):
|
||||
def get_previous_runs(self, milestone_id, suite_id, config_id):
|
||||
all_runs = []
|
||||
for plan in self.get_plans_by_milestone(milestone_id=milestone_id):
|
||||
run_ids = [run for run in
|
||||
self.get_plan(plan_id=plan['id'])['entries'][0]['runs']
|
||||
if config_id in run['config_ids']]
|
||||
all_runs.extend(run_ids)
|
||||
for entry in plan['entries']:
|
||||
if entry['suite_id'] == suite_id:
|
||||
run_ids = [run for run in entry['runs'] if
|
||||
config_id in run['config_ids']]
|
||||
all_runs.extend(run_ids)
|
||||
return all_runs
|
||||
|
||||
def add_run(self, new_run):
|
||||
@ -248,12 +280,12 @@ class TestRailProject():
|
||||
def get_test_by_name(self, run_id, name):
|
||||
for test in self.get_tests(run_id):
|
||||
if test['title'] == name:
|
||||
return test
|
||||
return self.get_test(test_id=test['id'])
|
||||
|
||||
def get_test_by_group(self, run_id, group, tests=None):
|
||||
for test in tests or self.get_tests(run_id):
|
||||
if test['custom_test_group'] == group:
|
||||
return test
|
||||
return self.get_test(test_id=test['id'])
|
||||
|
||||
def get_results_for_test(self, test_id, run_results=None):
|
||||
if run_results:
|
||||
@ -290,14 +322,14 @@ class TestRailProject():
|
||||
}
|
||||
return self.client.send_post(add_results_test_uri, new_results)
|
||||
|
||||
def add_results_for_cases(self, run_id, tests_suite, tests_results):
|
||||
def add_results_for_cases(self, run_id, suite_id, tests_results):
|
||||
add_results_test_uri = 'add_results_for_cases/{run_id}'.format(
|
||||
run_id=run_id)
|
||||
new_results = {'results': []}
|
||||
tests_cases = self.get_cases(tests_suite)
|
||||
tests_cases = self.get_cases(suite_id)
|
||||
for results in tests_results:
|
||||
new_result = {
|
||||
'case_id': self.get_case_by_group(suite=tests_suite,
|
||||
'case_id': self.get_case_by_group(suite_id=suite_id,
|
||||
group=results.group,
|
||||
cases=tests_cases)['id'],
|
||||
'status_id': self.get_status(results.status)['id'],
|
||||
|
@ -67,49 +67,51 @@ def get_tests_descriptions(milestone_id, tests_include, tests_exclude):
|
||||
|
||||
|
||||
def upload_tests_descriptions(testrail_project, section_id, tests):
|
||||
tests_suite = testrail_project.get_suite_by_name(
|
||||
TestRailSettings.tests_suite)
|
||||
existing_cases = [case['custom_test_group'] for case in
|
||||
testrail_project.get_cases(TestRailSettings.test_suite,
|
||||
testrail_project.get_cases(suite_id=tests_suite['id'],
|
||||
section_id=section_id)]
|
||||
for test_case in tests:
|
||||
if test_case['custom_test_group'] in existing_cases:
|
||||
logger.debug('Skipping uploading "{0}" test case because it '
|
||||
'already exists in "{1}" tests section.'.format(
|
||||
test_case['custom_test_group'],
|
||||
TestRailSettings.test_suite))
|
||||
TestRailSettings.tests_suite))
|
||||
continue
|
||||
|
||||
logger.debug('Uploading test "{0}" to TestRail project "{1}", '
|
||||
'suite "{2}", section "{3}"'.format(
|
||||
test_case["custom_test_group"],
|
||||
TestRailSettings.project,
|
||||
TestRailSettings.test_suite,
|
||||
TestRailSettings.test_section))
|
||||
TestRailSettings.tests_suite,
|
||||
TestRailSettings.tests_section))
|
||||
testrail_project.add_case(section_id=section_id, case=test_case)
|
||||
|
||||
|
||||
def main():
|
||||
testrail_project = TestRailProject(
|
||||
project = TestRailProject(
|
||||
url=TestRailSettings.url,
|
||||
user=TestRailSettings.user,
|
||||
password=TestRailSettings.password,
|
||||
project=TestRailSettings.project
|
||||
)
|
||||
|
||||
testrail_section = testrail_project.get_section_by_name(
|
||||
suite=TestRailSettings.test_suite,
|
||||
section_name=TestRailSettings.test_section
|
||||
testrail_section = project.get_section_by_name(
|
||||
suite_id=project.get_suite_by_name(TestRailSettings.tests_suite)['id'],
|
||||
section_name=TestRailSettings.tests_section
|
||||
)
|
||||
|
||||
testrail_milestone = testrail_project.get_milestone(
|
||||
name=TestRailSettings.milestone)['id']
|
||||
testrail_milestone = project.get_milestone_by_name(
|
||||
name=TestRailSettings.milestone)
|
||||
|
||||
tests_descriptions = get_tests_descriptions(
|
||||
milestone_id=testrail_milestone,
|
||||
tests_include=TestRailSettings.test_include,
|
||||
tests_exclude=TestRailSettings.test_exclude
|
||||
milestone_id=testrail_milestone['id'],
|
||||
tests_include=TestRailSettings.tests_include,
|
||||
tests_exclude=TestRailSettings.tests_exclude
|
||||
)
|
||||
|
||||
upload_tests_descriptions(testrail_project=testrail_project,
|
||||
upload_tests_descriptions(testrail_project=project,
|
||||
section_id=testrail_section['id'],
|
||||
tests=tests_descriptions)
|
||||
|
||||
|
@ -109,8 +109,9 @@ def upload_tests_descriptions(testrail_project, tests):
|
||||
else:
|
||||
test_suite = "OpenStack Components Functional Automated Tests"
|
||||
|
||||
suite = testrail_project.get_suite_by_name(test_suite)
|
||||
section = testrail_project.get_section_by_name(
|
||||
suite=test_suite, section_name=test_case["custom_test_group"])
|
||||
suite_id=suite['id'], section_name=test_case["custom_test_group"])
|
||||
|
||||
testrail_project.add_case(section_id=section["id"], case=test_case)
|
||||
|
||||
@ -123,13 +124,13 @@ def main():
|
||||
project=TestRailSettings.project
|
||||
)
|
||||
|
||||
testrail_milestone = testrail_project.get_milestone(
|
||||
name=TestRailSettings.milestone)['id']
|
||||
testrail_milestone = testrail_project.get_milestone_by_name(
|
||||
name=TestRailSettings.milestone)
|
||||
|
||||
tests_descriptions = get_tests_descriptions(
|
||||
milestone_id=testrail_milestone,
|
||||
tests_include=TestRailSettings.test_include,
|
||||
tests_exclude=TestRailSettings.test_exclude
|
||||
milestone_id=testrail_milestone['id'],
|
||||
tests_include=TestRailSettings.tests_include,
|
||||
tests_exclude=TestRailSettings.tests_exclude
|
||||
)
|
||||
|
||||
upload_tests_descriptions(testrail_project=testrail_project,
|
||||
|
Loading…
Reference in New Issue
Block a user