takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers coverage.py Source File

coverage.py

00001 """
00002 Copyright (c) 2018, Arm Limited
00003 SPDX-License-Identifier: Apache-2.0
00004 
00005 Licensed under the Apache License, Version 2.0 (the "License");
00006 you may not use this file except in compliance with the License.
00007 You may obtain a copy of the License at
00008 
00009     http://www.apache.org/licenses/LICENSE-2.0
00010 
00011 Unless required by applicable law or agreed to in writing, software
00012 distributed under the License is distributed on an "AS IS" BASIS,
00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 See the License for the specific language governing permissions and
00015 limitations under the License.
00016 
00017 
00018 GENERATE TEST CODE COVERAGE
00019 """
00020 
00021 import os
00022 import logging
00023 import posixpath
00024 import re
00025 
00026 from .utils import execute_program
00027 from .get_tools import get_gcov_program, \
00028     get_gcovr_program
00029 from .settings import COVERAGE_OUTPUT_TYPES
00030 
00031 
00032 class CoverageAPI (object):
00033     """
00034     Generate code coverage reports for unit tests.
00035     """
00036 
00037     def __init__(self, mbed_os_root=None, build_dir=None):
00038         self.root  = mbed_os_root
00039 
00040         if not self.root :
00041             self.root  = os.path.normpath(os.path.join(
00042                 os.path.dirname(os.path.realpath(__file__)),
00043                 "../.."))
00044 
00045         self.build_dir  = build_dir
00046 
00047         if not self.build_dir :
00048             logging.error("No build directory given for CoverageAPI.")
00049 
00050     def _gen_cmd(self, coverage_type, excludes, filter_regex):
00051         # Generate coverage generation command:
00052         args = [get_gcovr_program(),
00053                 "--gcov-executable",
00054                 get_gcov_program(),
00055                 "-r",
00056                 os.path.relpath(self.root , self.build_dir ),
00057                 "."]
00058 
00059         if coverage_type == "html":
00060             args.extend(["--html",
00061                          "--html-detail",
00062                          "-o",
00063                          "./coverage/index.html"])
00064         elif coverage_type == "xml":
00065             args.extend(["-x",
00066                          "-o",
00067                          "./coverage.xml"])
00068         else:
00069             logging.error("Invalid coverage output type: %s" % coverage_type)
00070 
00071         # Add exclude filters:
00072         for path in excludes:
00073             # Use posix separators if path is string
00074             if isinstance(path, ("".__class__, u"".__class__)):
00075                 path = path.replace("\\", "/")
00076                 args.extend(["-e", path])
00077             # Use regular expressions as is
00078             elif isinstance(path, type(re.compile(""))):
00079                 args.extend(["-e", path.pattern])
00080 
00081         # Add include filters:
00082         if filter_regex:
00083             filters = filter_regex.split(",")
00084 
00085             for filt in filters:
00086                 regex = "(.+/)?%s" % filt.replace("-", "/")
00087                 args.extend(["-f", regex])
00088 
00089         if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
00090             args.append("-v")
00091 
00092         return args
00093 
00094     def generate_reports (self,
00095                          outputs,
00096                          excludes=None,
00097                          filter_regex=None,
00098                          build_path=None):
00099         """
00100         Run tests to generate coverage data, and generate coverage reports.
00101 
00102         Positional arguments:
00103         outputs - list of types to generate
00104 
00105         Keyword arguments:
00106         excludes - list of paths to exclude from the report
00107         filter_regex - comma-separated string to use for test filtering
00108         build_path - build path
00109         """
00110 
00111         # Check for the tool
00112         if get_gcovr_program() is None:
00113             logging.error(
00114                 "No gcovr tool found in path. " +
00115                 "Cannot generate coverage reports.")
00116             return
00117 
00118         if build_path is None:
00119             build_path = os.getcwd()
00120 
00121         if outputs is None:
00122             outputs = []
00123 
00124         if excludes is None:
00125             excludes = []
00126 
00127         for output in outputs:
00128             # Skip if invalid/unsupported output type
00129             if output not in COVERAGE_OUTPUT_TYPES:
00130                 logging.warning(
00131                     "Invalid output type. " +
00132                     "Skip coverage report for type: %s." % output.upper())
00133                 continue
00134 
00135             if output == "html":
00136                 # Create a build directory if not exist
00137                 coverage_path = os.path.join(build_path, "coverage")
00138                 if not os.path.exists(coverage_path):
00139                     os.mkdir(coverage_path)
00140 
00141             # Generate the command
00142             args = self._gen_cmd (output, excludes, filter_regex)
00143 
00144             # Run the coverage tool
00145             execute_program(
00146                 args,
00147                 "%s code coverage report generation failed." % output.upper(),
00148                 "%s code coverage report created." % output.upper())