9a93e7b5创建于 2018年11月4日历史提交
import subprocess
import sys
import os
import shutil


builds = []
coverages = set()


def add_build(mark):
    global builds
    args, kwargs = list(mark.args), mark.kwargs.copy()
    kwargs.pop('coverage', None)
    cfg = args, kwargs
    if cfg not in builds:
        builds.append(cfg)


def execute_builds():
    common_options = ['--coverage', '-d', '--sanitize']
    for args, kwargs in builds:
        build_options = args[:]
        build_options.extend(['--dest', kwargs.get('dest', '.test')])
        if 'kit' not in kwargs:
            build_options.extend(['--kit', 'platform'])
        build_options.extend(common_options)

        print('Executing build', *build_options)
        subprocess.check_call([sys.executable, 'build.py', *build_options])


def add_coverage(mark):
    dest = mark.kwargs.get('dest', '.test')
    coverages.add(dest)


def setup_coverage():
    if coverages:
        print('Setting up C coverage for', *coverages)

    for dest in coverages:
        subprocess.check_call([
             'lcov', '--base-directory', '.', '--directory',
             dest + '/.build/temp', '--zerocounters', '-q'])


def make_coverage():
    for dest in coverages:
        try:
            os.unlink(dest + '/coverage.info')
        except FileNotFoundError:
            pass

        subprocess.check_call([
            'lcov', '--base-directory', '.', '--directory',
            dest + '/.build/temp', '-c', '-o', dest + '/coverage.info', '-q'])
        subprocess.check_call([
            'lcov', '--remove', dest + '/coverage.info',
            '/usr*', '-o', 'coverage.info', '-q'])

        try:
            shutil.rmtree(dest + '/coverage_report')
        except FileNotFoundError:
            pass

        subprocess.check_call([
            'genhtml', '-o', dest + '/coverage_report',
            dest + '/coverage.info', '-q'
        ])

        print('C coverage report saved in',
              dest + '/coverage_report/index.html')


def pytest_itemcollected(item):
    needs_build = item.get_closest_marker('needs_build')
    if needs_build:
        add_build(needs_build)
    if needs_build and needs_build.kwargs.get('coverage'):
        add_coverage(needs_build)


def pytest_collection_modifyitems(config, items):
    execute_builds()
    setup_coverage()


def pytest_unconfigure():
    make_coverage()