1# resulttool - store test results 2# 3# Copyright (c) 2019, Intel Corporation. 4# Copyright (c) 2019, Linux Foundation 5# 6# SPDX-License-Identifier: GPL-2.0-only 7# 8 9import tempfile 10import os 11import subprocess 12import json 13import shutil 14import scriptpath 15scriptpath.add_bitbake_lib_path() 16scriptpath.add_oe_lib_path() 17import resulttool.resultutils as resultutils 18import oeqa.utils.gitarchive as gitarchive 19 20 21def store(args, logger): 22 tempdir = tempfile.mkdtemp(prefix='testresults.') 23 try: 24 configvars = resultutils.extra_configvars.copy() 25 if args.executed_by: 26 configvars['EXECUTED_BY'] = args.executed_by 27 if args.extra_test_env: 28 configvars['EXTRA_TEST_ENV'] = args.extra_test_env 29 results = {} 30 logger.info('Reading files from %s' % args.source) 31 if resultutils.is_url(args.source) or os.path.isfile(args.source): 32 resultutils.append_resultsdata(results, args.source, configvars=configvars) 33 else: 34 for root, dirs, files in os.walk(args.source): 35 for name in files: 36 f = os.path.join(root, name) 37 if name == "testresults.json": 38 resultutils.append_resultsdata(results, f, configvars=configvars) 39 elif args.all: 40 dst = f.replace(args.source, tempdir + "/") 41 os.makedirs(os.path.dirname(dst), exist_ok=True) 42 shutil.copyfile(f, dst) 43 44 revisions = {} 45 46 if not results and not args.all: 47 if args.allow_empty: 48 logger.info("No results found to store") 49 return 0 50 logger.error("No results found to store") 51 return 1 52 53 # Find the branch/commit/commit_count and ensure they all match 54 for suite in results: 55 for result in results[suite]: 56 config = results[suite][result]['configuration']['LAYERS']['meta'] 57 revision = (config['commit'], config['branch'], str(config['commit_count'])) 58 if revision not in revisions: 59 revisions[revision] = {} 60 if suite not in revisions[revision]: 61 revisions[revision][suite] = {} 62 revisions[revision][suite][result] = results[suite][result] 63 64 logger.info("Found %d revisions to store" % len(revisions)) 65 66 for r in revisions: 67 results = revisions[r] 68 keywords = {'commit': r[0], 'branch': r[1], "commit_count": r[2]} 69 subprocess.check_call(["find", tempdir, "!", "-path", "./.git/*", "-delete"]) 70 resultutils.save_resultsdata(results, tempdir, ptestlogs=True) 71 72 logger.info('Storing test result into git repository %s' % args.git_dir) 73 74 gitarchive.gitarchive(tempdir, args.git_dir, False, False, 75 "Results of {branch}:{commit}", "branch: {branch}\ncommit: {commit}", "{branch}", 76 False, "{branch}/{commit_count}-g{commit}/{tag_number}", 77 'Test run #{tag_number} of {branch}:{commit}', '', 78 [], [], False, keywords, logger) 79 80 finally: 81 subprocess.check_call(["rm", "-rf", tempdir]) 82 83 return 0 84 85def register_commands(subparsers): 86 """Register subcommands from this plugin""" 87 parser_build = subparsers.add_parser('store', help='store test results into a git repository', 88 description='takes a results file or directory of results files and stores ' 89 'them into the destination git repository, splitting out the results ' 90 'files as configured', 91 group='setup') 92 parser_build.set_defaults(func=store) 93 parser_build.add_argument('source', 94 help='source file/directory/URL that contain the test result files to be stored') 95 parser_build.add_argument('git_dir', 96 help='the location of the git repository to store the results in') 97 parser_build.add_argument('-a', '--all', action='store_true', 98 help='include all files, not just testresults.json files') 99 parser_build.add_argument('-e', '--allow-empty', action='store_true', 100 help='don\'t error if no results to store are found') 101 parser_build.add_argument('-x', '--executed-by', default='', 102 help='add executed-by configuration to each result file') 103 parser_build.add_argument('-t', '--extra-test-env', default='', 104 help='add extra test environment data to each result file configuration') 105