86 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
# SPDX-License-Identifier: GPL-2.0+
 | 
						|
#
 | 
						|
# Copyright (c) 2016 Google, Inc
 | 
						|
#
 | 
						|
 | 
						|
from contextlib import contextmanager
 | 
						|
import glob
 | 
						|
import os
 | 
						|
import sys
 | 
						|
 | 
						|
import command
 | 
						|
 | 
						|
try:
 | 
						|
  from StringIO import StringIO
 | 
						|
except ImportError:
 | 
						|
  from io import StringIO
 | 
						|
 | 
						|
 | 
						|
def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None):
 | 
						|
    """Run tests and check that we get 100% coverage
 | 
						|
 | 
						|
    Args:
 | 
						|
        prog: Program to run (with be passed a '-t' argument to run tests
 | 
						|
        filter_fname: Normally all *.py files in the program's directory will
 | 
						|
            be included. If this is not None, then it is used to filter the
 | 
						|
            list so that only filenames that don't contain filter_fname are
 | 
						|
            included.
 | 
						|
        exclude_list: List of file patterns to exclude from the coverage
 | 
						|
            calculation
 | 
						|
        build_dir: Build directory, used to locate libfdt.py
 | 
						|
        required: List of modules which must be in the coverage report
 | 
						|
 | 
						|
    Raises:
 | 
						|
        ValueError if the code coverage is not 100%
 | 
						|
    """
 | 
						|
    # This uses the build output from sandbox_spl to get _libfdt.so
 | 
						|
    path = os.path.dirname(prog)
 | 
						|
    if filter_fname:
 | 
						|
        glob_list = glob.glob(os.path.join(path, '*.py'))
 | 
						|
        glob_list = [fname for fname in glob_list if filter_fname in fname]
 | 
						|
    else:
 | 
						|
        glob_list = []
 | 
						|
    glob_list += exclude_list
 | 
						|
    glob_list += ['*libfdt.py', '*site-packages*']
 | 
						|
    cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools python-coverage run '
 | 
						|
           '--omit "%s" %s -P1 -t' % (build_dir, ','.join(glob_list), prog))
 | 
						|
    os.system(cmd)
 | 
						|
    stdout = command.Output('python-coverage', 'report')
 | 
						|
    lines = stdout.splitlines()
 | 
						|
    if required:
 | 
						|
        # Convert '/path/to/name.py' just the module name 'name'
 | 
						|
        test_set = set([os.path.splitext(os.path.basename(line.split()[0]))[0]
 | 
						|
                        for line in lines if '/etype/' in line])
 | 
						|
        missing_list = required
 | 
						|
        missing_list.difference_update(test_set)
 | 
						|
        if missing_list:
 | 
						|
            print 'Missing tests for %s' % (', '.join(missing_list))
 | 
						|
            print stdout
 | 
						|
            ok = False
 | 
						|
 | 
						|
    coverage = lines[-1].split(' ')[-1]
 | 
						|
    ok = True
 | 
						|
    print coverage
 | 
						|
    if coverage != '100%':
 | 
						|
        print stdout
 | 
						|
        print ("Type 'python-coverage html' to get a report in "
 | 
						|
               'htmlcov/index.html')
 | 
						|
        print 'Coverage error: %s, but should be 100%%' % coverage
 | 
						|
        ok = False
 | 
						|
    if not ok:
 | 
						|
        raise ValueError('Test coverage failure')
 | 
						|
 | 
						|
 | 
						|
# Use this to suppress stdout/stderr output:
 | 
						|
# with capture_sys_output() as (stdout, stderr)
 | 
						|
#   ...do something...
 | 
						|
@contextmanager
 | 
						|
def capture_sys_output():
 | 
						|
    capture_out, capture_err = StringIO(), StringIO()
 | 
						|
    old_out, old_err = sys.stdout, sys.stderr
 | 
						|
    try:
 | 
						|
        sys.stdout, sys.stderr = capture_out, capture_err
 | 
						|
        yield capture_out, capture_err
 | 
						|
    finally:
 | 
						|
        sys.stdout, sys.stderr = old_out, old_err
 |