From 78a322d7be402a5b9b5abf26ad35670a8535408a Mon Sep 17 00:00:00 2001 From: Yeoh Ee Peng Date: Thu, 14 Feb 2019 13:50:37 +0800 Subject: resulttool: enable merge, store, report and regression analysis OEQA outputs test results into json files and these files were archived by Autobuilder during QA releases. Example: each oe-selftest run by Autobuilder for different host distro generate a testresults.json file. These scripts were developed as a test result tools to manage these testresults.json file. Using the "store" operation, user can store multiple testresults.json files as well as the pre-configured directories used to hold those files. Using the "merge" operation, user can merge multiple testresults.json files to a target file. Using the "report" operation, user can view the test result summary for all available testresults.json files inside a ordinary directory or a git repository. Using the "regression-file" operation, user can perform regression analysis on testresults.json files specified. Using the "regression-dir" and "regression-git" operations, user can perform regression analysis on directory and git accordingly. These resulttool operations expect the testresults.json file to use the json format below. { "": { "configuration": { "": "", "": "", ... "": "", }, "result": { "": { "status": "", "log": "" }, "": { "status": "", "log": "" }, ... "": { "status": "", "log": "" }, } }, ... "": { "configuration": { "": "", "": "", ... "": "", }, "result": { "": { "status": "", "log": "" }, "": { "status": "", "log": "" }, ... "": { "status": "", "log": "" }, } }, } To use these scripts, first source oe environment, then run the entry point script to look for help. $ resulttool To store test result from oeqa automated tests, execute the below $ resulttool store To merge multiple testresults.json files, execute the below $ resulttool merge To report test report, execute the below $ resulttool report To perform regression file analysis, execute the below $ resulttool regression-file To perform regression dir analysis, execute the below $ resulttool regression-dir To perform regression git analysis, execute the below $ resulttool regression-git [YOCTO# 13012] [YOCTO# 12654] Signed-off-by: Yeoh Ee Peng Signed-off-by: Richard Purdie --- meta/lib/oeqa/files/testresults/testresults.json | 40 +++++++++ meta/lib/oeqa/selftest/cases/resulttooltests.py | 104 +++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 meta/lib/oeqa/files/testresults/testresults.json create mode 100644 meta/lib/oeqa/selftest/cases/resulttooltests.py (limited to 'meta') diff --git a/meta/lib/oeqa/files/testresults/testresults.json b/meta/lib/oeqa/files/testresults/testresults.json new file mode 100644 index 0000000000..1a62155618 --- /dev/null +++ b/meta/lib/oeqa/files/testresults/testresults.json @@ -0,0 +1,40 @@ +{ + "runtime_core-image-minimal_qemuarm_20181225195701": { + "configuration": { + "DISTRO": "poky", + "HOST_DISTRO": "ubuntu-16.04", + "IMAGE_BASENAME": "core-image-minimal", + "IMAGE_PKGTYPE": "rpm", + "LAYERS": { + "meta": { + "branch": "master", + "commit": "801745d918e83f976c706f29669779f5b292ade3", + "commit_count": 52782 + }, + "meta-poky": { + "branch": "master", + "commit": "801745d918e83f976c706f29669779f5b292ade3", + "commit_count": 52782 + }, + "meta-yocto-bsp": { + "branch": "master", + "commit": "801745d918e83f976c706f29669779f5b292ade3", + "commit_count": 52782 + } + }, + "MACHINE": "qemuarm", + "STARTTIME": "20181225195701", + "TEST_TYPE": "runtime" + }, + "result": { + "apt.AptRepoTest.test_apt_install_from_repo": { + "log": "Test requires apt to be installed", + "status": "PASSED" + }, + "buildcpio.BuildCpioTest.test_cpio": { + "log": "Test requires autoconf to be installed", + "status": "ERROR" + } + } + } +} \ No newline at end of file diff --git a/meta/lib/oeqa/selftest/cases/resulttooltests.py b/meta/lib/oeqa/selftest/cases/resulttooltests.py new file mode 100644 index 0000000000..7bf1ec60c1 --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/resulttooltests.py @@ -0,0 +1,104 @@ +import os +import sys +basepath = os.path.abspath(os.path.dirname(__file__) + '/../../../../../') +lib_path = basepath + '/scripts/lib' +sys.path = sys.path + [lib_path] +from resulttool.report import ResultsTextReport +from resulttool.regression import ResultsRegressionSelector, ResultsRegression +from resulttool.merge import ResultsMerge +from resulttool.store import ResultsGitStore +from resulttool.resultsutils import checkout_git_dir +from oeqa.selftest.case import OESelftestTestCase + +class ResultToolTests(OESelftestTestCase): + + def test_report_can_aggregate_test_result(self): + result_data = {'result': {'test1': {'status': 'PASSED'}, + 'test2': {'status': 'PASSED'}, + 'test3': {'status': 'FAILED'}, + 'test4': {'status': 'ERROR'}, + 'test5': {'status': 'SKIPPED'}}} + report = ResultsTextReport() + result_report = report.get_aggregated_test_result(None, result_data) + self.assertTrue(result_report['passed'] == 2, msg="Passed count not correct:%s" % result_report['passed']) + self.assertTrue(result_report['failed'] == 2, msg="Failed count not correct:%s" % result_report['failed']) + self.assertTrue(result_report['skipped'] == 1, msg="Skipped count not correct:%s" % result_report['skipped']) + + def test_regression_can_get_regression_base_target_pair(self): + base_results_data = {'base_result1': {'configuration': {"TEST_TYPE": "oeselftest", + "HOST": "centos-7"}}, + 'base_result2': {'configuration': {"TEST_TYPE": "oeselftest", + "HOST": "centos-7", + "MACHINE": "qemux86-64"}}} + target_results_data = {'target_result1': {'configuration': {"TEST_TYPE": "oeselftest", + "HOST": "centos-7"}}, + 'target_result2': {'configuration': {"TEST_TYPE": "oeselftest", + "HOST": "centos-7", + "MACHINE": "qemux86"}}, + 'target_result3': {'configuration': {"TEST_TYPE": "oeselftest", + "HOST": "centos-7", + "MACHINE": "qemux86-64"}}} + regression = ResultsRegressionSelector() + pair = regression.get_regression_base_target_pair(self.logger, base_results_data, target_results_data) + self.assertTrue('target_result1' in pair['base_result1'], msg="Pair not correct:%s" % pair['base_result1']) + self.assertTrue('target_result3' in pair['base_result2'], msg="Pair not correct:%s" % pair['base_result2']) + + def test_regrresion_can_get_regression_result(self): + base_result_data = {'result': {'test1': {'status': 'PASSED'}, + 'test2': {'status': 'PASSED'}, + 'test3': {'status': 'FAILED'}, + 'test4': {'status': 'ERROR'}, + 'test5': {'status': 'SKIPPED'}}} + target_result_data = {'result': {'test1': {'status': 'PASSED'}, + 'test2': {'status': 'FAILED'}, + 'test3': {'status': 'PASSED'}, + 'test4': {'status': 'ERROR'}, + 'test5': {'status': 'SKIPPED'}}} + regression = ResultsRegression() + result = regression.get_regression_result(self.logger, base_result_data, target_result_data) + self.assertTrue(result['test2']['base'] == 'PASSED', + msg="regression not correct:%s" % result['test2']['base']) + self.assertTrue(result['test2']['target'] == 'FAILED', + msg="regression not correct:%s" % result['test2']['target']) + self.assertTrue(result['test3']['base'] == 'FAILED', + msg="regression not correct:%s" % result['test3']['base']) + self.assertTrue(result['test3']['target'] == 'PASSED', + msg="regression not correct:%s" % result['test3']['target']) + + def test_merge_can_merged_results(self): + base_results_data = {'base_result1': {}, + 'base_result2': {}} + target_results_data = {'target_result1': {}, + 'target_result2': {}, + 'target_result3': {}} + + merge = ResultsMerge() + results = merge.merge_results(base_results_data, target_results_data) + self.assertTrue(len(results.keys()) == 5, msg="merge not correct:%s" % len(results.keys())) + + def test_store_can_store_to_new_git_repository(self): + basepath = os.path.abspath(os.path.dirname(__file__) + '/../../') + source_dir = basepath + '/files/testresults' + git_branch = 'qa-cycle-2.7' + store = ResultsGitStore() + output_dir = store.store_to_new(self.logger, source_dir, git_branch) + self.assertTrue(checkout_git_dir(output_dir, git_branch), msg="store to new git repository failed:%s" % + output_dir) + store._remove_temporary_workspace_dir(output_dir) + + def test_store_can_store_to_existing(self): + basepath = os.path.abspath(os.path.dirname(__file__) + '/../../') + source_dir = basepath + '/files/testresults' + git_branch = 'qa-cycle-2.6' + store = ResultsGitStore() + output_dir = store.store_to_new(self.logger, source_dir, git_branch) + self.assertTrue(checkout_git_dir(output_dir, git_branch), msg="store to new git repository failed:%s" % + output_dir) + git_branch = 'qa-cycle-2.7' + output_dir = store.store_to_existing_with_new_branch(self.logger, source_dir, output_dir, git_branch) + self.assertTrue(checkout_git_dir(output_dir, git_branch), msg="store to existing git repository failed:%s" % + output_dir) + output_dir = store.store_to_existing(self.logger, source_dir, output_dir, git_branch) + self.assertTrue(checkout_git_dir(output_dir, git_branch), msg="store to existing git repository failed:%s" % + output_dir) + store._remove_temporary_workspace_dir(output_dir) -- cgit 1.2.3-korg