Ejemplo n.º 1
0
def try_run(id, gpr):
    """gnatcov run with common set of options & variations via gpr."""
    log = id + '.rlog'
    xrun(['-P%s' % gpr, exe, '-o', '%s.trace' % id],
         out=log,
         register_failure=False)
    return contents_of(log)
Ejemplo n.º 2
0
    def xcov_run(self, main):
        """run MAIN through "xcov run" to produce an execution trace."""

        # Feed xcov run with full path (absolute dir) of the program so we
        # can directly get to the binary from the trace when reading it from
        # a different directory, such as in consolidation tests.

        ofile = "xcov_run_%s.out" % main

        # Some execution engines (e.g. valgrind) do not let us distinguish
        # executed program errors from engine errors. Because of them, we
        # ignore here any kind of execution error for tests expected to trigger
        # failures (such as harness tests), assuming that they will perform
        # further checks that are bound to fail if the execution doesn't
        # proceed as expected somehow (e.g. not producing a trace).

        xrun([
            self.abdir_for(main) + exename_for(main),
            "--level=%s" % self.xcovlevel
        ] + self.scoptions,
             out=ofile,
             register_failure=not self.testcase.expect_failures)

        thistest.fail_if(
            match(
                "(!!! EXCEPTION RAISED !!!"
                "|raised [A-Z_]+ : [-._a-zA-Z]+:[0-9]+ \w+)", ofile),
            "exception raised while running '%s'." % main)
Ejemplo n.º 3
0
def _run_and_cov(pgm, level, sco_args):
    """
    Execute gnatcov run then gnatcov coverage for the provided
    program `pgm`, expected to be the base name of without extension
    of an executable file. Pass `level` as --level to both commands
    and the provided `sco_args` to gnatcov coverage, and gnatcov run
    if we are doing mcdc.
    """

    level_arg = '--level=%s' % level

    # gnatcov run

    run_args = [exepath_to(pgm), level_arg]
    if 'mcdc' in level_arg:
        run_args.extend(sco_args)

    xrun(run_args)

    # gnatcov coverage

    cov_args = [
        '--annotate=xcov',
        '--trace=%s' % tracename_for(os.path.basename(pgm)), level_arg
    ] + sco_args

    xcov(['coverage'] + cov_args)
Ejemplo n.º 4
0
def check(explicit_exe):

    outbase = explicit_exe if explicit_exe else "noexe"
    trace = '%s.trace' % outbase
    dump = '%s.dt' % outbase

    runcmd = ['-P', gprname, '-o', trace]
    if explicit_exe:
        runcmd.append(explicit_exe)

    xrun(runcmd)
    xcov(['dump-trace', trace], out=dump)

    thistest.fail_if(
        len(re.findall('t block$', contents_of(dump), flags=re.M)) < 1,
        'with %s, no block trace entry found in %s' % (outbase, trace))
Ejemplo n.º 5
0
    def mode_execute(self, main):

        out_file = 'xrun_{}.out'.format(main)

        # Feed xcov run with full path (absolute dir) of the program so we
        # can directly get to the binary from the trace when reading it from
        # a different directory, such as in consolidation tests.
        main_path = self.abdir_for(main) + exename_for(main)

        # Some execution engines (e.g. valgrind) do not let us distinguish
        # executed program errors from engine errors. Because of them, we
        # ignore here any kind of execution error for tests expected to trigger
        # failures (such as harness tests), assuming that they will perform
        # further checks that are bound to fail if the execution doesn't
        # proceed as expected somehow (e.g. not producing a trace).
        xrun([main_path, "--level=%s" % self.xcovlevel] +
             self.mode_coverage_sco_options(),
             out=out_file,
             register_failure=not self.testcase.expect_failures)

        return out_file
Ejemplo n.º 6
0
def build_and_run(gprsw,
                  covlevel,
                  mains,
                  extra_coverage_args,
                  scos=None,
                  gpr_obj_dir=None,
                  gpr_exe_dir=None,
                  ignored_source_files=[],
                  separate_coverage=None,
                  extra_args=[],
                  extra_run_args=None,
                  extra_instr_args=None,
                  extra_gprbuild_args=[],
                  extra_gprbuild_cargs=[],
                  absolute_paths=False,
                  dump_trigger="auto",
                  dump_channel="auto",
                  check_gprbuild_output=False,
                  trace_mode=None,
                  runtime_project=None,
                  gprsw_for_coverage=None,
                  scos_for_run=True,
                  register_failure=True,
                  program_env=None,
                  instrument_warnings_as_errors=True,
                  exec_args=None):
    """
    Prepare a project to run a coverage analysis on it.

    This is a wrapper around gprbuild/xrun/xcov_instrument to do whatever is
    necessary for the current trace mode to run "gnatcov coverage". It lets one
    write concise testcases that handle both binary and source trace modes.

    :param SUITE.gprutils.GPRswitches gprsw: GPRswitches instance used to
        describe the project and units of interest to analyze.
    :param None|str covlevel: Coverage level (as passed with gnatcov's --level=
        argument) for the coverage analysis. Not passed if None.
    :param list[str] mains: List of names for the various mains to run. These
        are lower-case names without extension, for instance "foo" for the
        "foo.adb" main source file.
    :param list[str] extra_coverage_args: List of arguments to append to the
        "gnatcov coverage" command-line returned. This is just for convenience:
        one can pass an empty list here and manually append extra arguments to
        the result.
    :param None|list[str] scos: Optional list of SCOs files (ALI or SID) must
        be passed to gnatcov. These files must have no extension (for instance:
        'obj/foo' instead of 'obj/foo.ali'. If absent, we pass "-P" to "gnatcov
        coverage"/"gnatcov instrument" so that it automatically discovers the
        units of interest from projects.
    :param None|str gpr_obj_dir: Optional name of the directory where gprbuild
        will create build artifacts. If left to None, assume they are produced
        in "$gpr_exe_dir/obj".
    :param None|str gpr_exe_dir: Optional name of the directory where gprbuild
        will create executables to run. If left to None, assume they are
        produced in the current directory.
    :param list[str] ignored_source_files: List of file patterns to pass using
        the --ignore-source-files option.
    :param None|str separate_coverage: If provided, the argument is forwarded
        to gnatcov using the -S option.
    :param list[str] extra_args: List of arguments to pass to any
        execution of gnatcov (gnatcov run|instrument|coverage).
    :param list[str] extra_run_args: List of arguments to pass to all
        executions of "gnatcov run".
    :param list[str] extra_instr_args: List of arguments to pass to all
        executions of "gnatcov instrument".
    :param list[str] extra_gprbuild_args: List of arguments to pass to
        gprbuild.
    :param list[str] extra_gprbuild_cargs: List of arguments to pass to
        gprbuild's -cargs section.
    :param bool absolute_paths: If true, use absolute paths in the result.
    :param None|str dump_trigger: See xcov_instrument.
    :param None|str dump_channel: See xcov_instrument.
    :param bool check_gprbuild_output: If true, check that gprbuild's output is
        empty.
    :param None|str trace_mode: If None, use the testsuite's trace mode.
        Otherwise, use the given trace mode ('bin', or 'src').
    :param None|str runtime_project: If None, use the default name for the
        instrumentation runtime project. Otherwise, use the name given for this
        option.
    :param None|SUITE.gprutils.GPRswitches gprsw_for_coverage: GPRswitches
        instance used to describe the project and units of interest to analyze
        in "gnatcov coverage". If left to None, use "gprsw".
    :param bool scos_for_run: Whether to pass SCOs/project information to
        "gnatcov run".
    :param bool register_failure: If true and the execution of one of the mains
        exits with a non-zero status code, stop with a FatalError.
    :param None|dict[str, str] program_env: If not none, environment variables
        for the program to run.
    :param bool instrument_warnings_as_errors: Whether to make the test fail if
        there are warnings in the output of "gnatcov instrument".
    :param None|list[str] exec_args: List of arguments to pass to the
        executable. This will only work for native configurations.

    :rtype: list[str]
    :return: Incomplete list of arguments to pass to `xcov` in order to run
        "gnatcov coverage". The only mandatory argument that is missing is the
        annotation format. The last N arguments correspond to trace files for
        the given N mains.
    """
    def abspath(path):
        return os.path.abspath(path) if absolute_paths else path

    def exepath(main):
        main = os.path.join(
            gpr_exe_dir,
            (os.path.join(gprsw.subdirs, main) if gprsw.subdirs else main))
        return abspath(exepath_to(main))

    def gprbuild_wrapper(root_project):

        # Honor build relevant switches from gprsw here
        gprbuild(root_project,
                 gargs=gprsw.build_switches + extra_gprbuild_args,
                 extracargs=extra_gprbuild_cargs,
                 trace_mode=trace_mode,
                 runtime_project=runtime_project)

        if check_gprbuild_output:
            gprbuild_out = contents_of('gprbuild.out')
            thistest.fail_if(
                gprbuild_out,
                "gprbuild's output (gprbuild.out) is not empty:\n{}".format(
                    indent(gprbuild_out)))

    # When instrumenting, we expect units of interest to be provided
    # through GPR switches:
    assert not (scos and trace_mode == 'src')

    gpr_exe_dir = gpr_exe_dir or '.'
    gpr_obj_dir = gpr_obj_dir or os.path.join(gpr_exe_dir, 'obj')

    trace_mode = trace_mode or thistest.options.trace_mode

    # Use a --level=<l> form for --level to faciliate locating and
    # replacing the switch at once as a whole if need be.
    covlevel_args = [] if covlevel is None else ['--level={}'.format(covlevel)]

    xcov_args = ['coverage'] + covlevel_args
    trace_files = []

    # Arguments to pass to "gnatcov coverage" (bin trace mode) or "gnatcov
    # instrument" (src trace mode), in addition to those conveyed by gprsw.
    cov_or_instr_args = (extra_args + [
        '--ignore-source-files={}'.format(pattern)
        for pattern in ignored_source_files
    ])
    if separate_coverage:
        cov_or_instr_args.extend(['-S', separate_coverage])

    # Compute arguments to specify units of interest.
    if trace_mode == 'bin':
        scos_arg = '--scos'
        scos_ext = 'ali'
    else:
        scos_arg = '--sid'
        scos_ext = 'sid'
    scos = (['{}={}.{}'.format(scos_arg, abspath(a), scos_ext)
             for a in scos] if scos else gprsw.cov_switches)

    if trace_mode == 'bin':
        # Build and run each main
        gprbuild_wrapper(gprsw.root_project)
        run_args = covlevel_args + extra_args

        if scos_for_run:
            run_args.extend(scos)
        if extra_run_args:
            run_args.extend(extra_run_args)

        eargs = []
        if exec_args:
            eargs = ["-eargs"] + exec_args

        for m in mains:
            xrun(run_args + [exepath(m)] + eargs,
                 out='run.log',
                 env=program_env,
                 register_failure=register_failure)
        trace_files = [abspath(tracename_for(m)) for m in mains]

        xcov_args.extend(cov_or_instr_args)

    elif trace_mode == 'src':
        if dump_channel == "auto":
            dump_channel = default_dump_channel()

        # Instrument the project and build the result
        extra_instr_args = cov_or_instr_args + list(extra_instr_args or [])
        xcov_instrument(gprsw,
                        covlevel,
                        extra_args=extra_instr_args,
                        gpr_obj_dir=gpr_obj_dir,
                        dump_trigger=dump_trigger,
                        dump_channel=dump_channel,
                        runtime_project=runtime_project,
                        out='instrument.log',
                        register_failure=register_failure,
                        warnings_as_errors=instrument_warnings_as_errors)
        gprbuild_wrapper(gprsw.root_project)

        # If an explicit dump channel was requested, check that "gnatcov
        # instrument" used it. In case it was implicit, get the one that was
        # used.
        #
        # The mode in which we do not register failures is tricky: in this case
        # we may not have an actual dump channel because instrumentation did
        # not complete. In that case we cannot use source traces, but we must
        # build and run programs nonetheless.
        params_file_dir = gpr_obj_dir
        if gprsw.subdirs:
            params_file_dir = os.path.join(params_file_dir, gprsw.subdirs)
        params_file = os.path.join(params_file_dir, "gnatcov-instr.json")
        try:
            f = open(params_file)
        except FileNotFoundError:
            if register_failure:
                raise
            else:
                actual_dump_channel = None
        else:
            with f:
                params = json.load(f)
            actual_dump_channel = params["dump-channel"]

        if dump_channel in (None, "auto"):
            dump_channel = actual_dump_channel
        elif dump_channel and actual_dump_channel:
            thistest.fail_if_not_equal("actual dump channel", dump_channel,
                                       actual_dump_channel)

        # Then execute each main and collect trace files
        trace_files = []
        for m in mains:
            # Remove potential existing source trace files: the name is
            # non-deterministic by default, so we want to avoid getting
            # multiple traces in the current directory.
            rm(srctrace_pattern_for(m))

            out_file = '{}_output.txt'.format(m)
            run_cov_program(exepath(m),
                            out=out_file,
                            env=program_env,
                            register_failure=register_failure,
                            exec_args=exec_args)

            # Depending on the dump channel, we also may have to create the
            # trace file. If we could not determine the actually used dump
            # channel (see above), do not collect the trace file.
            if dump_channel is None:
                continue

            elif dump_channel == 'bin-file':
                trace_file = srctracename_for(
                    m, register_failure=register_failure)
                if trace_file is None:
                    continue

            elif dump_channel == 'base64-stdout':
                # Create a trace name that is compatible with srctracename_for
                trace_file = srctrace_pattern_for(m).replace("*", "unique")

                xcov_convert_base64(out_file,
                                    trace_file,
                                    register_failure=register_failure)

            else:
                raise ValueError(
                    'Invalid dump channel: {}'.format(dump_channel))

            trace_files.append(abspath(trace_file))

        xcov_args.extend(cov_or_instr_args)

    else:
        assert False, 'Unknown trace mode: {}'.format(trace_mode)

    # If provided, pass "gnatcov coverage"-specific project arguments, which
    # replace the list of SCOS.
    if gprsw_for_coverage:
        xcov_args.extend(gprsw_for_coverage.cov_switches)
    elif scos:
        xcov_args.extend(scos)

    return xcov_args + extra_coverage_args + trace_files
Ejemplo n.º 7
0
def build_and_run(gprsw, covlevel, mains, extra_coverage_args, scos=None,
                  gpr_obj_dir=None, gpr_exe_dir=None, ignored_source_files=[],
                  separate_coverage=None, extra_args=[],
                  extra_gprbuild_args=[], extra_gprbuild_cargs=[],
                  absolute_paths=False, dump_trigger=None,
                  dump_channel=None, check_gprbuild_output=False,
                  trace_mode=None, gprsw_for_coverage=None, scos_for_run=True,
                  register_failure=True):
    """
    Prepare a project to run a coverage analysis on it.

    This is a wrapper around gprbuild/xrun/xcov_instrument to do whatever is
    necessary for the current trace mode to run "gnatcov coverage". It lets one
    write concise testcases that handle both binary and source trace modes.

    :param SUITE.gprutils.GPRswitches gprsw: GPRswitches instance used to
        describe the project and units of interest to analyze.
    :param None|str covlevel: Coverage level (as passed with gnatcov's --level=
        argument) for the coverage analysis. Not passed if None.
    :param list[str] mains: List of names for the various mains to run. These
        are lower-case names without extension, for instance "foo" for the
        "foo.adb" main source file.
    :param list[str] extra_coverage_args: List of arguments to append to the
        "gnatcov coverage" command-line returned. This is just for convenience:
        one can pass an empty list here and manually append extra arguments to
        the result.
    :param None|list[str] scos: Optional list of SCOs files (ALI or SID) must
        be passed to gnatcov. These files must have no extension (for instance:
        'obj/foo' instead of 'obj/foo.ali'. If absent, we pass "-P" to "gnatcov
        coverage"/"gnatcov instrument" so that it automatically discovers the
        units of interest from projects.
    :param None|str gpr_obj_dir: Optional name of the directory where gprbuild
        will create build artifacts. If left to None, assume they are produced
        in "$gpr_exe_dir/obj".
    :param None|str gpr_exe_dir: Optional name of the directory where gprbuild
        will create executables to run. If left to None, assume they are
        produced in the current directory.
    :param list[str] ignored_source_files: List of file patterns to pass using
        the --ignore-source-files option.
    :param None|str separate_coverage: If provided, the argument is forwarded
        to gnatcov using the -S option.
    :param list[str] extra_args: List of arguments to pass to any
        execution of gnatcov (gnatcov run|instrument|coverage).
    :param list[str] extra_gprbuild_args: List of arguments to pass to
        gprbuild.
    :param list[str] extra_gprbuild_cargs: List of arguments to pass to
        gprbuild's -cargs section.
    :param bool absolute_paths: If true, use absolute paths in the result.
    :param None|str dump_trigger: Trigger to dump coverage buffers
        (--dump-trigger argument). If left to None,
        use SCOV.instr.default_dump_trigger.
    :param None|str dump_channel: Channel to dump coverage buffers
        (--dump-channel argument). If left to None,
        use SCOV.instr.default_dump_channel.
    :param bool check_gprbuild_output: If true, check that gprbuild's output is
        empty.
    :param None|str trace_mode: If None, use the testsuite's trace mode.
        Otherwise, use the given trace mode ('bin', or 'src').
    :param None|SUITE.gprutils.GPRswitches gprsw_for_coverage: GPRswitches
        instance used to describe the project and units of interest to analyze
        in "gnatcov coverage". If left to None, use "gprsw".
    :param bool scos_for_run: Whether to pass SCOs/project information to
        "gnatcov run".
    :param bool register_failure: If true and the execution of one of the mains
        exits with a non-zero status code, stop with a FatalError.

    :rtype: list[str]
    :return: Incomplete list of arguments to pass to `xcov` in order to run
        "gnatcov coverage". The only mandatory argument that is missing is the
        annotation format. The last N arguments correspond to trace files for
        the given N mains.
    """
    def abspath(path):
        return os.path.abspath(path) if absolute_paths else path

    def exepath(main):
        main = os.path.join(
            gpr_exe_dir,
            (os.path.join(gprsw.subdirs, m) if gprsw.subdirs else m))
        return abspath(exepath_to(main))

    def gprbuild_wrapper(root_project, gargs):

        # Honor build relevant switches from gprsw here
        gprbuild(root_project,
                 gargs=gprsw.build_switches + gargs + extra_gprbuild_args,
                 extracargs=extra_gprbuild_cargs,
                 trace_mode=trace_mode)

        if check_gprbuild_output:
            gprbuild_out = contents_of('gprbuild.out')
            thistest.fail_if(
                gprbuild_out,
                "gprbuild's output (gprbuild.out) is not empty:\n{}"
                .format(indent(gprbuild_out)))

    # When instrumenting, we expect units of interest to be provided
    # through GPR switches:
    assert not (scos and trace_mode == 'src')

    gpr_exe_dir = gpr_exe_dir or '.'
    gpr_obj_dir = gpr_obj_dir or os.path.join(gpr_exe_dir, 'obj')

    trace_mode = trace_mode or thistest.options.trace_mode
    covlevel_args = [] if covlevel is None else ['--level', covlevel]
    xcov_args = ['coverage'] + covlevel_args
    trace_files = []

    # Arguments to pass to "gnatcov coverage" (bin trace mode) or "gnatcov
    # instrument" (src trace mode), in addition to those conveyed by gprsw.
    cov_or_instr_args = (
        extra_args +
        ['--ignore-source-files={}'.format(pattern)
         for pattern in ignored_source_files])
    if separate_coverage:
        cov_or_instr_args.extend(['-S', separate_coverage])

    # Compute arguments to specify units of interest.
    if trace_mode == 'bin':
        scos_arg = '--scos'
        scos_ext = 'ali'
    else:
        scos_arg = '--sid'
        scos_ext = 'sid'
    scos = (['{}={}.{}'.format(scos_arg, abspath(a), scos_ext)
             for a in scos]
            if scos else
            gprsw.cov_switches)

    if trace_mode == 'bin':
        # Build and run each main
        gprbuild_wrapper(gprsw.root_project, gargs=[])
        run_args = covlevel_args + extra_args
        if scos_for_run:
            run_args.extend(scos)
        for m in mains:
            xrun(run_args + [exepath(m)], out='run.log',
                 register_failure=register_failure)
        trace_files = [abspath(tracename_for(m)) for m in mains]

        xcov_args.extend(cov_or_instr_args)

    elif trace_mode == 'src':
        dump_channel = dump_channel or default_dump_channel()

        # Instrument the project and build the result
        xcov_instrument(gprsw, covlevel, extra_args=cov_or_instr_args,
                        gpr_obj_dir=gpr_obj_dir, dump_trigger=dump_trigger,
                        dump_channel=dump_channel, out='instrument.log',
                        register_failure=register_failure)
        gprbuild_wrapper(gprsw.root_project,
                         gargs=['--src-subdirs=gnatcov-instr'])

        # Then execute each main and collect trace files
        trace_files = []
        for m in mains:
            out_file = '{}_output.txt'.format(m)
            trace_file = abspath(srctracename_for(m))
            run_cov_program(exepath(m), out=out_file,
                            register_failure=register_failure)
            trace_files.append(trace_file)

            # Depending on the dump channel, we also may have to create the
            # trace file.
            if dump_channel == 'bin-file':
                pass
            elif dump_channel == 'base64-stdout':
                xcov_convert_base64(out_file, trace_file,
                                    register_failure=register_failure)
            else:
                raise ValueError('Invalid dump channel: {}'
                                 .format(dump_channel))

        xcov_args.extend(cov_or_instr_args)

    else:
        assert False, 'Unknown trace mode: {}'.format(trace_mode)

    # If provided, pass "gnatcov coverage"-specific project arguments, which
    # replace the list of SCOS.
    if gprsw_for_coverage:
        xcov_args.extend(gprsw_for_coverage.cov_switches)
    elif scos:
        xcov_args.extend(scos)

    return xcov_args + extra_coverage_args + trace_files
Ejemplo n.º 8
0
gprname = 'gen'
mainbases = ['test_tt', 'test_tf']
mainunits = [base + '.adb' for base in mainbases]

gprbuild(
    gprfor(prjid=gprname,
           srcdirs=['../../../../src', '../../src'],
           mains=mainunits))

# We expect this to work. The multiple mains in the gpr file are just ignored
# when there is an exe on the command line.
exe = exepath_to('test_tt')
trace = 'tt.trace0'
dump = 'tt.dump0'

xrun(['-P', gprname, '-o', trace, exe])
xcov(['dump-trace', trace], out=dump)
thistest.fail_if(
    len(re.findall('t block$', contents_of(dump), flags=re.M)) < 1,
    'with exe, no block execution trace found in %s' % trace)

# Again, _not_ providing the executable. Expected to fail
# from missing command line argument.
trace = 'oops.trace0'
dump = 'oops.dump'
xrun(['-P', gprname, '-o', trace], out=dump, register_failure=False)

thistest.fail_if(
    not match(': Please specify an executable to run', dump),
    'missing expected error diag on main-less invocation of gnatcov run')
Ejemplo n.º 9
0
 def _run(self, test_driver):
     xrun(unixpath_to(test_driver))
Ejemplo n.º 10
0
def build_and_run(gprsw,
                  covlevel,
                  mains,
                  extra_coverage_args,
                  scos=None,
                  gpr_obj_dir=None,
                  gpr_exe_dir=None,
                  ignored_source_files=[],
                  separate_coverage=None,
                  extra_args=[],
                  extra_gprbuild_args=[],
                  absolute_paths=False):
    """
    Prepare a project to run a coverage analysis on it.

    This is a wrapper around gprbuild/xrun/xcov_instrument to do whatever is
    necessary for the current trace mode to run "gnatcov coverage". It lets one
    write concise testcases that handle both binary and source trace modes.

    :param SUITE.gprutils.GPRswitches gprsw: GPRswitches instance used to
        describe the project and units of interest to analyze.
    :param str covlevel: Coverage level (as passed with gnatcov's --level=
        argument) for the coverage analysis.
    :param list[str] mains: List of names for the various mains to run. These
        are lower-case names without extension, for instance "foo" for the
        "foo.adb" main source file.
    :param list[str] extra_coverage_args: List of arguments to append to the
        "gnatcov coverage" command-line returned. This is just for convenience:
        one can pass an empty list here and manually append extra arguments to
        the result.
    :param None|list[str] scos: Optional list of SCOs to pass to gnatcov, if
        the current trace mode is binary. If absent, we pass "-P" to "gnatcov
        coverage"/"gnatcov instrument" so that it automatically discovers the
        units of interest.
    :param None|str gpr_obj_dir: Optional name of the directory where gprbuild
        will create build artifacts. If left to None, assume they are produced
        in "$gpr_exe_dir/obj".
    :param None|str gpr_exe_dir: Optional name of the directory where gprbuild
        will create executables to run. If left to None, assume they are
        produced in the current directory.
    :param list[str] ignored_source_files: List of file patterns to pass using
        the --ignore-source-files option.
    :param None|str separate_coverage: If provided, the argument is forwarded
        to gnatcov using the -S option.
    :param list[str] extra_args: List of arguments to pass to any
        execution of gnatcov (gnatcov run|instrument|coverage).
    :param list[str] extra_gprbuild_args: List of arguments to pass to
        gprbuild.
    :param bool absolute_paths: If true, use absolute paths in the result.

    :rtype: list[str]
    :return: Incomplete list of arguments to pass to `xcov` in order to run
        "gnatcov coverage". The only mandatory argument that is missing is the
        annotation format. The last N arguments correspond to trace files for
        the given N mains.
    """
    def abspath(path):
        return os.path.abspath(path) if absolute_paths else path

    def exepath(main):
        if gpr_exe_dir:
            main = os.path.join(gpr_exe_dir, m)
        return abspath(exepath_to(main))

    def gprbuild_wrapper(root_project, gargs=[]):
        gprbuild(root_project, gargs=gargs + extra_gprbuild_args)

    gpr_exe_dir = gpr_exe_dir or '.'
    gpr_obj_dir = gpr_obj_dir or os.path.join(gpr_exe_dir, 'obj')

    trace_mode = thistest.options.trace_mode
    xcov_args = ['coverage', '--level', covlevel]
    trace_files = []

    # Arguments to pass to "gnatcov coverage" (bin trace mode) or "gnatcov
    # instrument" (src trace mode).
    cov_or_instr_args = (extra_args + [
        '--ignore-source-files={}'.format(pattern)
        for pattern in ignored_source_files
    ])
    if separate_coverage:
        cov_or_instr_args.extend(['-S', separate_coverage])

    if trace_mode == 'bin':
        # Compute arguments to specify units of interest
        scos = (['--scos={}'.format(abspath(a))
                 for a in scos] if scos else gprsw.as_strings)
        cov_or_instr_args.extend(scos)

        # Build and run each main
        gprbuild_wrapper(gprsw.root_project)
        for m in mains:
            xrun(['--level', covlevel, exepath(m)] + scos + extra_args,
                 out='run.log')
        trace_files = [abspath(tracename_for(m)) for m in mains]

        xcov_args.extend(cov_or_instr_args)

    elif trace_mode == 'src':
        # Instrument the project and build the result
        isi_file = abspath('instr.isi')
        xcov_instrument(gprsw,
                        covlevel,
                        isi_file,
                        extra_args=cov_or_instr_args,
                        gpr_obj_dir=gpr_obj_dir,
                        out='instrument.log')
        xcov_args.extend(['--isi', isi_file])
        gprbuild_wrapper(gprsw.root_project,
                         gargs=['--src-subdirs=gnatcov-instr'])

        # Then execute each main
        for m in mains:
            Run([exepath(m)])
        trace_files = [abspath(srctracename_for(m)) for m in mains]

        # If we would have passed the project to "gnatcov coverage" in binary
        # trace mode, pass it here too. This is necessary for instance to
        # select the default output directory for coverage reports.
        if not scos:
            xcov_args.extend(['-P', gprsw.root_project])

        xcov_args.extend(extra_args)

    else:
        assert False, 'Unknown trace mode: {}'.format(trace_mode)

    return xcov_args + extra_coverage_args + trace_files
Ejemplo n.º 11
0
    trace = tracename_for(mainbase)

    # Build with the real target as the Target attribute.
    instantiate_gpr(target)
    gprbuild(os.path.abspath(gpr_basename))

    argv = ['-P{}'.format(gprname), '-o', trace, exe]

    # Run with a bad target as the Target attribute in order to check that the
    # --target argument actually takes precedence.
    with_target_arg = mode == 'with_arg'
    if with_target_arg:
        instantiate_gpr('this_target_does_not_exist')

        # Force the passing of --target in the native case, as xrun() does not
        # pass it when it is the default.
        if not env.is_cross:
            argv.append('--target={}'.format(target))

    xrun(argv, auto_config_args=False, auto_target_args=with_target_arg)

    dump = 'dump.txt'
    xcov('dump-trace {}'.format(trace), out=dump)
    thistest.fail_if(
        len(re.findall('t block$', contents_of(dump), flags=re.M)) < 1,
        'with exe, no block execution trace found in {}'.format(trace))

    wd.to_homedir()

thistest.result()