Edit

kc3-lang/libxkbcommon/scripts/meson-junit-report.py

Branch :

  • Show log

    Commit

  • Author : Adrian Perez de Castro
    Date : 2019-08-06 18:59:10
    Hash : c408adc2
    Message : CI: Publish test results from Meson

  • scripts/meson-junit-report.py
  • #!/usr/bin/env python3
    
    import argparse
    import json
    import sys
    import unicodedata
    import xml.etree.ElementTree as ET
    from datetime import datetime
    
    
    aparser = argparse.ArgumentParser(
        description='Convert Meson test log into JUnit report')
    aparser.add_argument('--project-name', metavar='NAME',
                         help='The project name',
                         default='unknown')
    aparser.add_argument('--job-id', metavar='ID',
                         help='The job ID for the report',
                         default='Unknown')
    aparser.add_argument('--branch', metavar='NAME',
                         help='Branch of the project being tested',
                         default='master')
    aparser.add_argument('--output', metavar='FILE',
                         help='The output file, stdout by default',
                         type=argparse.FileType('w', encoding='UTF-8'),
                         default=sys.stdout)
    aparser.add_argument('infile', metavar='FILE',
                         help='The input testlog.json, stdin by default',
                         type=argparse.FileType('r', encoding='UTF-8'),
                         default=sys.stdin)
    args = aparser.parse_args()
    
    outfile = args.output
    
    testsuites = ET.Element('testsuites')
    testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
    testsuites.set('package', args.project_name)
    testsuites.set('timestamp', datetime.utcnow().isoformat(timespec='minutes'))
    
    testsuite = ET.SubElement(testsuites, 'testsuite')
    testsuite.set('name', args.project_name)
    
    successes = 0
    failures = 0
    skips = 0
    
    
    def escape_control_chars(text):
        return "".join(c if unicodedata.category(c)[0] != "C" else
                       "<{:02x}>".format(ord(c)) for c in text)
    
    
    for line in args.infile:
        unit = json.loads(line)
    
        testcase = ET.SubElement(testsuite, 'testcase')
        testcase.set('classname', '{}/{}'.format(args.project_name, unit['name']))
        testcase.set('name', unit['name'])
        testcase.set('time', str(unit['duration']))
    
        stdout = escape_control_chars(unit.get('stdout', ''))
        stderr = escape_control_chars(unit.get('stderr', ''))
        if stdout:
            ET.SubElement(testcase, 'system-out').text = stdout
        if stderr:
            ET.SubElement(testcase, 'system-out').text = stderr
    
        result = unit['result'].lower()
        if result == 'skip':
            skips += 1
            ET.SubElement(testcase, 'skipped')
        elif result == 'fail':
            failures += 1
            failure = ET.SubElement(testcase, 'failure')
            failure.set('message', "{} failed".format(unit['name']))
            failure.text = "### stdout\n{}\n### stderr\n{}\n".format(stdout,
                                                                     stderr)
        else:
            successes += 1
            assert unit['returncode'] == 0
    
    testsuite.set('tests', str(successes + failures + skips))
    testsuite.set('skipped', str(skips))
    testsuite.set('errors', str(failures))
    testsuite.set('failures', str(failures))
    
    print('{}: {} pass, {} fail, {} skip'.format(args.project_name,
                                                 successes,
                                                 failures,
                                                 skips))
    
    output = ET.tostring(testsuites, encoding='unicode')
    outfile.write(output)