| #!/usr/bin/env python |
| |
| import argparse |
| import datetime |
| import decimal |
| import json |
| import logging |
| import os |
| import requests |
| from collections import OrderedDict |
| |
| |
| def parse_args(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument('-r', '--result-file', dest='result_file', |
| required=True, default='./result.json', |
| help='Specify test result file.') |
| parser.add_argument('-a', '--attachment', dest='attachment', |
| action='append', help='Specify attachment file.') |
| parser.add_argument('-t', '--team', dest='team', required=True, |
| help='Team identifier. Defaults to "erp"') |
| parser.add_argument('-p', '--project', dest='project', |
| help='Project identifier. Defaults to the name of the Linux distribution.') |
| parser.add_argument('-b', '--build', dest='build', required=True, |
| help='Build identifier.') |
| parser.add_argument('-e', '--test-env', dest='test_env', |
| help='Environment identifier. Defaults to board name.') |
| parser.add_argument('-u', '--url', dest='url', |
| default='https://qa-reports.linaro.org', |
| help='Dashboard URL. Defaults to https://qa-reports.linaro.org.') |
| parser.add_argument('-v', '--verbose', action='store_true', dest='verbose', |
| default=True, help='Set log level.') |
| |
| args = parser.parse_args() |
| return args |
| |
| |
| def squad_result(results): |
| squad_tests = OrderedDict() |
| squad_metrics = OrderedDict() |
| for result in results: |
| for metric in result['metrics']: |
| key = '%s/%s' % (result['name'], metric['test_case_id']) |
| if not metric['measurement']: |
| # Collect pass/fail test results. |
| squad_tests[key] = metric['result'] |
| else: |
| # Collect performance test results. |
| try: |
| measurement = decimal.Decimal(metric['measurement']) |
| squad_metrics[key] = float(measurement) |
| except decimal.InvalidOperation: |
| logger.info('Invalid measurement: %s' % metric['measurement']) |
| logger.info('Skipped adding: %s' % metric) |
| assert squad_tests or squad_metrics, 'No valid result found!' |
| return (squad_tests, squad_metrics) |
| |
| |
| def squad_metadata(results): |
| test_plan = list(set(i['test_plan'] for i in results)) |
| test_version = list(set(i['version'] for i in results)) |
| |
| assert len(test_plan) == 1, 'More then one test plan found!' |
| assert len(test_version) == 1, 'More then one test version found!' |
| |
| squad_metadata = OrderedDict() |
| test_plan = test_plan[0] |
| test_plan_name = os.path.splitext(os.path.basename(test_plan))[0] |
| squad_metadata['job_id'] = '{}_{}'.format(test_plan_name, datetime.datetime.utcnow().isoformat()) |
| squad_metadata['test_plan'] = test_plan |
| squad_metadata['test_version'] = test_version[0] |
| for key, value in results[-1]['environment'].items(): |
| if key != 'packages': |
| squad_metadata[key] = value |
| return squad_metadata |
| |
| |
| def main(): |
| auth_token = os.environ.get("SQUAD_AUTH_TOKEN") |
| assert auth_token, "SQUAD_AUTH_TOKEN not provided in environment" |
| |
| with open(args.result_file, 'r') as f: |
| results = json.load(f) |
| metadata = squad_metadata(results) |
| tests, metrics = squad_result(results) |
| |
| files = [('metadata', json.dumps(metadata)), |
| ('tests', json.dumps(tests)), |
| ('metrics', json.dumps(metrics)), |
| ('attachment', open(args.result_file, 'rb'))] |
| if args.attachment is not None: |
| for item in args.attachment: |
| if os.path.exists(item): |
| logger.info('Adding {} to attachment list...'.format(item)) |
| files.append(tuple(['attachment', open(item, 'rb')])) |
| else: |
| logger.info('Attachment %s Not found' % args.attachment) |
| logger.info('Skipped uploading %s' % args.attachment) |
| logger.debug('Data to post: %s' % files) |
| |
| project = args.project or metadata['linux_distribution'] |
| test_env = args.test_env or metadata['board_name'] |
| url = '{}/api/submit/{}/{}/{}/{}'.format(args.url, args.team, project, args.build, test_env) |
| logger.info('Posting to {}'.format(url)) |
| |
| headers = {'Auth-Token': auth_token} |
| r = requests.post(url, headers=headers, files=files) |
| print(r.text) |
| |
| if __name__ == "__main__": |
| args = parse_args() |
| |
| logger = logging.getLogger('post-to-squad') |
| logger.setLevel(logging.INFO) |
| if args.verbose: |
| logger.setLevel(logging.DEBUG) |
| ch = logging.StreamHandler() |
| ch.setLevel(logging.DEBUG) |
| formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
| ch.setFormatter(formatter) |
| logger.addHandler(ch) |
| |
| main() |