diff --git a/fuelweb_test/testrail/upload_tempest_test_suite.py b/fuelweb_test/testrail/upload_tempest_test_suite.py index 9d092ab8d..d4458b486 100644 --- a/fuelweb_test/testrail/upload_tempest_test_suite.py +++ b/fuelweb_test/testrail/upload_tempest_test_suite.py @@ -14,12 +14,17 @@ from __future__ import unicode_literals +from logging import DEBUG import subprocess - +from optparse import OptionParser from joblib import Parallel, delayed +from fuelweb_test.helpers.decorators import retry from fuelweb_test.testrail.settings import TestRailSettings from fuelweb_test.testrail.testrail_client import TestRailProject +from fuelweb_test.testrail.settings import logger +from fuelweb_test.testrail.upload_cases_description \ + import _get_custom_cases_fields TEST_GROUPS = ["API", "CLI", "Scenario", "ThirdParty"] @@ -51,45 +56,61 @@ def generate_groups(line): return section -def get_tests_descriptions(milestone_id, tests_include, tests_exclude): +def get_tests_descriptions(milestone_id, testrail_default_test_priority, + testrail_project): # To get the Tempest tests list, need to execute the following commands: - # git clone https://github.com/openstack/tempest & cd tempest & tox -venv - get_tempest_tests = """cd tempest && .tox/venv/bin/nosetests \\ - --collect-only tempest/{0} -v 2>&1 | grep 'id-.*'""" - - tests = [] + # git clone https://github.com/openstack/tempest & cd tempest & tox -evenv + # .tox/venv/bin/pip install nose + get_tempest_tests = ("cd tempest && .tox/venv/bin/nosetests " + "--collect-only tempest/{0} -v 2>&1 | grep 'id-.*'") + get_commit = "cd tempest && git rev-parse HEAD" + commit = subprocess.Popen(get_commit, shell=True, stdout=subprocess.PIPE) + logger.info("Generate test suite for tempest" + " commit:{}".format(commit.stdout.readline())) + custom_cases_fields = _get_custom_cases_fields( + case_fields=testrail_project.get_case_fields(), + project_id=testrail_project.project['id']) + tests = {} for group in TEST_GROUPS: p = subprocess.Popen(get_tempest_tests.format(group.lower()), shell=True, stdout=subprocess.PIPE) for line in iter(p.stdout.readline, b''): - if "id-" in line: - section = generate_groups(line) if group == "API" else group + section = generate_groups(line) if group == "API" else group - test_class = [] - for r in line.split("."): - if "id-" in r: - title = r.strip() - break - else: - test_class.append(r) + test_class = [] + for r in line.split("."): + if "id-" in r: + title = r.strip() + break + else: + test_class.append(r) - steps = [{"run this tempest test": "passed"}, ] - test_case = { - "title": title, - "type_id": 1, - "priority_id": 5, - "estimate": "1m", - "refs": "", - "milestone_id": milestone_id, - "custom_test_group": ".".join(test_class), - "custom_test_case_description": title, - "custom_test_case_steps": steps, - "section": section - } - tests.append(test_case) + steps = [{"run this tempest test": "passed"}, ] + test_case = { + "title": title, + "type_id": 1, + "milestone_id": milestone_id, + "priority_id": testrail_default_test_priority, + "estimate": "1m", + "refs": "", + "custom_report_label": title.split('id-')[1][:-1], + "custom_test_group": ".".join(test_class), + "custom_test_case_description": title, + "custom_test_case_steps": steps, + "section": section + } + for case_field, default_value in custom_cases_fields.items(): + if case_field not in test_case: + test_case[case_field] = default_value + if section not in tests: + tests[section] = [] + tests[section].append(test_case) + logger.debug(tests) + logger.info("total test cases: " + "{}".format(sum(map(lambda x: len(x), tests.values())))) return tests @@ -97,14 +118,19 @@ def delete_case(testrail_project, test_id): testrail_project.delete_case(test_id) -def add_case(testrail_project, test_suite, test_case): - suite = testrail_project.get_suite_by_name(test_suite) - section = testrail_project.get_section_by_name( - suite_id=suite['id'], section_name=test_case["section"]) +@retry(3, 60) +def add_case(testrail_project, suite, test_case, section, do_check=False): + try_msg = "try to add test: {} to section: {}" + miss_msg = "test: {} is already on section: {}" + if do_check and testrail_project.get_case_by_name(suite['id'], + test_case['title']): + logger.debug(miss_msg.format(test_case["title"], test_case["section"])) + return + logger.debug(try_msg.format(test_case["title"], test_case["section"])) testrail_project.add_case(section_id=section["id"], case=test_case) -def upload_tests_descriptions(testrail_project, tests): +def rewrite_tests_descriptions(testrail_project, tests): test_suite = TestRailSettings.tests_suite suite = testrail_project.get_suite_by_name(test_suite) @@ -123,12 +149,59 @@ def upload_tests_descriptions(testrail_project, tests): testrail_project.create_section(suite["id"], section, api_group["id"]) # add test cases to test suite in 100 parallel threads - Parallel(n_jobs=100)(delayed(add_case) - (testrail_project, test_suite, test_case) - for test_case in tests) + logger.info("Add cases") + for test_section, test_list in tests.iteritems(): + section = testrail_project.get_section_by_name( + suite_id=suite['id'], section_name=test_section) + Parallel(n_jobs=100)(delayed(add_case) + (testrail_project, suite, test_case, section) + for test_case in test_list) + + +def add_new_tests_description(testrail_project, tests): + test_suite = TestRailSettings.tests_suite + suite = testrail_project.get_suite_by_name(test_suite) + logger.info("Update suite sections") + for group in TEST_GROUPS: + if not testrail_project.get_section_by_name(suite["id"], group): + testrail_project.create_section(suite["id"], group) + api_group = testrail_project.get_section_by_name(suite["id"], "API") + for section in TEST_SECTIONS: + if not testrail_project.get_section_by_name(suite["id"], section): + testrail_project.create_section(suite["id"], section, + api_group["id"]) + + # add test cases to test suite in 100 parallel threads + logger.info("Add cases") + for test_section, test_list in tests.iteritems(): + section = testrail_project.get_section_by_name( + suite_id=suite['id'], section_name=test_section) + Parallel(n_jobs=100)(delayed(add_case) + (testrail_project, suite, test_case, + section, True) + for test_case in test_list) def main(): + + parser = OptionParser( + description="Upload tests cases to TestRail. " + "See settings.py for configuration." + ) + parser.add_option("-v", "--verbose", + action="store_true", dest="verbose", default=False, + help="Enable debug output") + parser.add_option("-r", "--rewrite", action="store_true", + dest="rewrite", default=False, help="Rewrite all suite") + parser.add_option("-u", "--update", action="store_true", + dest="update", default=False, + help="Update new cases to suite") + + (options, _) = parser.parse_args() + + if options.verbose: + logger.setLevel(DEBUG) + testrail_project = TestRailProject( url=TestRailSettings.url, user=TestRailSettings.user, @@ -139,14 +212,20 @@ def main(): testrail_milestone = testrail_project.get_milestone_by_name( name=TestRailSettings.milestone) - tests_descriptions = get_tests_descriptions( - milestone_id=testrail_milestone['id'], - tests_include=TestRailSettings.tests_include, - tests_exclude=TestRailSettings.tests_exclude - ) + testrail_default_test_priority = [priority['id'] for priority in + testrail_project.get_priorities() if + priority['is_default'] is True][0] - upload_tests_descriptions(testrail_project=testrail_project, - tests=tests_descriptions) + tests_descriptions = get_tests_descriptions(testrail_milestone['id'], + testrail_default_test_priority, + testrail_project) + + if options.rewrite: + rewrite_tests_descriptions(testrail_project=testrail_project, + tests=tests_descriptions) + if options.update: + add_new_tests_description(testrail_project=testrail_project, + tests=tests_descriptions) if __name__ == '__main__':