From a868e1bb75987119c87112d08a194564d84b53ee Mon Sep 17 00:00:00 2001 From: Cédric Ollivier Date: Fri, 19 Aug 2016 17:39:50 +0200 Subject: Add reporting to DB in OpenDaylightTesting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It now relies on Robotframework API instead of parsing output.xml. The type of critical and elapsedime fields are now bool and int respectively. start_date and stop_date has been fixed too. JIRA: FUNCTEST-367 Change-Id: I59f3ad2109345395ccf01a714301a14f9323f088 Signed-off-by: Cédric Ollivier --- testcases/Controllers/ODL/OpenDaylightTesting.py | 63 +++++++++-- testcases/Controllers/ODL/odlreport2db.py | 133 ----------------------- 2 files changed, 56 insertions(+), 140 deletions(-) delete mode 100644 testcases/Controllers/ODL/odlreport2db.py (limited to 'testcases/Controllers') diff --git a/testcases/Controllers/ODL/OpenDaylightTesting.py b/testcases/Controllers/ODL/OpenDaylightTesting.py index 79e385a2d..0e38d04d8 100755 --- a/testcases/Controllers/ODL/OpenDaylightTesting.py +++ b/testcases/Controllers/ODL/OpenDaylightTesting.py @@ -8,8 +8,32 @@ import shutil import sys from robot import run +from robot.api import ExecutionResult, ResultVisitor +from robot.utils.robottime import timestamp_to_secs import functest.utils.functest_logger as ft_logger +import functest.utils.functest_utils as ft_utils + + +class ODLResultVisitor(ResultVisitor): + + def __init__(self): + self._data = [] + + def visit_test(self, test): + output = {} + output['name'] = test.name + output['parent'] = test.parent.name + output['status'] = test.status + output['startime'] = test.starttime + output['endtime'] = test.endtime + output['critical'] = test.critical + output['text'] = test.message + output['elapsedtime'] = test.elapsedtime + self._data.append(output) + + def get_data(self): + return self._data class ODLTestCases: @@ -18,6 +42,7 @@ class ODLTestCases: odl_test_repo = repos + "odl_test/" neutron_suite_dir = odl_test_repo + "csit/suites/openstack/neutron/" basic_suite_dir = odl_test_repo + "csit/suites/integration/basic/" + res_dir = '/home/opnfv/functest/results/odl/' logger = ft_logger.Logger("opendaylight").getLogger() @classmethod @@ -70,19 +95,18 @@ class ODLTestCases: except KeyError as e: cls.logger.error("Cannot run ODL testcases. Please check", e) return False - res_dir = '/home/opnfv/functest/results/odl/' if (cls.copy_opnf_testcases() and cls.set_robotframework_vars(odlusername, odlpassword)): try: - os.makedirs(res_dir) + os.makedirs(cls.res_dir) except OSError: pass - stdout_file = res_dir + 'stdout.txt' + stdout_file = cls.res_dir + 'stdout.txt' with open(stdout_file, 'w') as stdout: result = run(*dirs, variable=variables, - output=res_dir + 'output.xml', - log=res_dir + 'log.html', - report=res_dir + 'report.html', + output=cls.res_dir + 'output.xml', + log=cls.res_dir + 'log.html', + report=cls.res_dir + 'report.html', stdout=stdout) with open(stdout_file, 'r') as stdout: @@ -92,6 +116,24 @@ class ODLTestCases: else: return False + @classmethod + def push_to_db(cls): + result = ExecutionResult(cls.res_dir + 'output.xml') + visitor = ODLResultVisitor() + result.visit(visitor) + start_time = timestamp_to_secs(result.suite.starttime) + stop_time = timestamp_to_secs(result.suite.endtime) + details = {} + details['description'] = result.suite.name + details['tests'] = visitor.get_data() + if not ft_utils.push_results_to_db( + "functest", "odl", None, start_time, stop_time, + result.suite.status, details): + cls.logger.error("Cannot push ODL results to DB") + return False + else: + return True + if __name__ == '__main__': parser = argparse.ArgumentParser() @@ -125,5 +167,12 @@ if __name__ == '__main__': parser.add_argument('-e', '--odlpassword', help='Password for ODL', default='admin') + parser.add_argument('-p', '--pushtodb', + help='Push results to DB', + action='store_true') + args = vars(parser.parse_args()) - sys.exit(ODLTestCases.run(**args)) + ODLTestCases.run(**args) + if args['pushtodb']: + sys.exit(not ODLTestCases.push_to_db()) + sys.exit(os.EX_OK) diff --git a/testcases/Controllers/ODL/odlreport2db.py b/testcases/Controllers/ODL/odlreport2db.py deleted file mode 100644 index 6b3fb913d..000000000 --- a/testcases/Controllers/ODL/odlreport2db.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/python -# -# Authors: -# - peter.bandzi@cisco.com -# - morgan.richomme@orange.com -# -# src: Peter Bandzi -# https://github.com/pbandzi/parse-robot/blob/master/convert_robot_to_json.py -# -# Copyright (c) 2015 All rights reserved -# This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# - -import getopt -import json -import sys -import time -import xmltodict - -import functest.utils.functest_utils as functest_utils - - -def usage(): - print """Usage: - python odlreport2db.py --xml= --help - -x, --xml xml file generated by robot test - -h, --help this message - """ - sys.exit(2) - - -def populate_detail(test): - detail = {} - detail['name'] = test['@name'] - for x in ['status', 'critical', 'starttime', 'endtime']: - detail[x] = test['status']['@' + x] - if '#text' in test['status']: - detail['text'] = test['status']['#text'] - return detail - - -def parse_test(tests, details): - try: - for test in tests: - details.append(populate_detail(test)) - except TypeError: - # tests is not iterable - details.append(populate_detail(tests)) - return details - - -def parse_suites(suites): - data = {} - details = [] - for suite in suites: - a = suite['suite'] - if type(a) == list: - for b in a: - data['tests'] = parse_test(b['test'], details) - else: - data['tests'] = parse_test(a['test'], details) - - # data['details'] = parse_test(suite['test'], details) - # suites is not iterable - return data - - -def main(argv): - xml_file = None - try: - opts, args = getopt.getopt(argv, - 'x:h', - ['xml=', 'help']) - except getopt.GetoptError: - usage() - - for opt, arg in opts: - if opt in ('-x', '--xml'): - xml_file = arg - else: - usage() - - if xml_file is None: - usage() - - with open(xml_file, "r") as myfile: - xml_input = myfile.read().replace('\n', '') - - # dictionary populated with data from xml file - all_data = xmltodict.parse(xml_input)['robot'] - - try: - data = parse_suites(all_data['suite']['suite']) - data['description'] = all_data['suite']['@name'] - data['generator'] = all_data['@generator'] - - json.dumps(data, indent=4, separators=(',', ': ')) - - # success criteria for ODL = 100% of tests OK - status = "FAIL" - # TODO as part of the tests are executed before in the bash - # start and stoptime have no real meaning - start_time = time.time() - stop_time = start_time - tests_passed = 0 - tests_failed = 0 - for v in data['tests']: - if v['status'] == "PASS": - tests_passed += 1 - else: - tests_failed += 1 - - if (tests_failed < 1): - status = "PASS" - - functest_utils.push_results_to_db("functest", - "odl", - None, - start_time, - stop_time, - status, - data) - - except: - print("Error pushing ODL results into DB '%s'" % sys.exc_info()[0]) - - -if __name__ == "__main__": - main(sys.argv[1:]) -- cgit 1.2.3-korg