Git Product home page Git Product logo

cargo-llvm-cov's Introduction

cargo-llvm-cov

crates.io license github actions

Cargo subcommand to easily use LLVM source-based code coverage.

This is a wrapper around rustc -C instrument-coverage and provides:

  • Generate very precise coverage data. (line, region, and branch coverage. branch coverage is currently optional and requires nightly, see #8 for more)
  • Support cargo test, cargo run, and cargo nextest with command-line interface compatible with cargo.
  • Support for proc-macro, including coverage of UI tests.
  • Support for doc tests. (this is currently optional and requires nightly, see #2 for more)
  • Fast because it does not introduce extra layers between rustc, cargo, and llvm-tools.

Table of Contents:

Usage

Basic usage

Click to show a complete list of options

(See docs directory for options of subcommands)

$ cargo llvm-cov --help
cargo-llvm-cov
Cargo subcommand to easily use LLVM source-based code coverage (-C instrument-coverage).

USAGE:
    cargo llvm-cov [SUBCOMMAND] [OPTIONS] [-- <args>...]

ARGS:
    <args>...
            Arguments for the test binary

OPTIONS:
        --json
            Export coverage data in "json" format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=text`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --lcov
            Export coverage data in "lcov" format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=lcov`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --cobertura
            Export coverage data in "cobertura" XML format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=lcov` and then converts to cobertura.xml.
            See <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --codecov
            Export coverage data in "Codecov Custom Coverage" format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=json` and then converts to codecov.json.
            See <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --text
            Generate coverage report in “text” format

            If --output-path or --output-dir is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov show -format=text`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.

        --html
            Generate coverage report in "html" format

            If --output-dir is not specified, the report will be generated in `target/llvm-cov/html`
            directory.

            This internally calls `llvm-cov show -format=html`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.

        --open
            Generate coverage reports in "html" format and open them in a browser after the
            operation.

            See --html for more.

        --summary-only
            Export only summary information for each file in the coverage data

            This flag can only be used together with --json, --lcov, or --cobertura.

        --output-path <PATH>
            Specify a file to write coverage data into.

            This flag can only be used together with --json, --lcov, --cobertura, or --text.
            See --output-dir for --html and --open.

        --output-dir <DIRECTORY>
            Specify a directory to write coverage report into (default to `target/llvm-cov`).

            This flag can only be used together with --text, --html, or --open. See also
            --output-path.

        --failure-mode <any|all>
            Fail if `any` or `all` profiles cannot be merged (default to `any`)

        --ignore-filename-regex <PATTERN>
            Skip source code files with file paths that match the given regular expression

        --show-instantiations
            Show instantiations in report

        --no-cfg-coverage
            Unset cfg(coverage), which is enabled when code is built using cargo-llvm-cov

        --no-cfg-coverage-nightly
            Unset cfg(coverage_nightly), which is enabled when code is built using cargo-llvm-cov
            and nightly compiler

        --no-report
            Run tests, but don't generate coverage report

        --no-clean
            Build without cleaning any old build artifacts

        --fail-under-functions <MIN>
            Exit with a status of 1 if the total function coverage is less than MIN percent

        --fail-under-lines <MIN>
            Exit with a status of 1 if the total line coverage is less than MIN percent

        --fail-under-regions <MIN>
            Exit with a status of 1 if the total region coverage is less than MIN percent

        --fail-uncovered-lines <MAX>
            Exit with a status of 1 if the uncovered lines are greater than MAX

        --fail-uncovered-regions <MAX>
            Exit with a status of 1 if the uncovered regions are greater than MAX

        --fail-uncovered-functions <MAX>
            Exit with a status of 1 if the uncovered functions are greater than MAX

        --show-missing-lines
            Show lines with no coverage

        --include-build-script
            Include build script in coverage report

        --dep-coverage <NAME>
            Show coverage of the specified dependency instead of the crates in the current workspace. (unstable)

        --skip-functions
            Skip exporting per-function coverage data.

            This flag can only be used together with --json, --lcov, or --cobertura.

        --branch
            Enable branch coverage. (unstable)

        --doctests
            Including doc tests (unstable)

            This flag is unstable. See <https://github.com/taiki-e/cargo-llvm-cov/issues/2> for
            more.

        --no-run
            Generate coverage report without running tests

        --no-fail-fast
            Run all tests regardless of failure

        --ignore-run-fail
            Run all tests regardless of failure and generate report

            If tests failed but report generation succeeded, exit with a status of 0.

    -q, --quiet
            Display one character per test instead of one line

        --lib
            Test only this package's library unit tests

        --bin <NAME>
            Test only the specified binary

        --bins
            Test all binaries

        --example <NAME>
            Test only the specified example

        --examples
            Test all examples

        --test <NAME>
            Test only the specified test target

        --tests
            Test all tests

        --bench <NAME>
            Test only the specified bench target

        --benches
            Test all benches

        --all-targets
            Test all targets

        --doc
            Test only this library's documentation (unstable)

            This flag is unstable because it automatically enables --doctests flag. See
            <https://github.com/taiki-e/cargo-llvm-cov/issues/2> for more.

    -p, --package <SPEC>
            Package to run tests for

        --workspace
            Test all packages in the workspace

        --all
            Alias for --workspace (deprecated)

        --exclude <SPEC>
            Exclude packages from both the test and report

        --exclude-from-test <SPEC>
            Exclude packages from the test (but not from the report)

        --exclude-from-report <SPEC>
            Exclude packages from the report (but not from the test)

    -j, --jobs <N>
            Number of parallel jobs, defaults to # of CPUs

    -r, --release
            Build artifacts in release mode, with optimizations

        --profile <PROFILE-NAME>
            Build artifacts with the specified profile

    -F, --features <FEATURES>
            Space or comma separated list of features to activate

        --all-features
            Activate all available features

        --no-default-features
            Do not activate the `default` feature

        --target <TRIPLE>
            Build for the target triple

            When this option is used, coverage for proc-macro and build script will not be displayed
            because cargo does not pass RUSTFLAGS to them.

        --coverage-target-only
            Activate coverage reporting only for the target triple

            Activate coverage reporting only for the target triple specified via `--target`. This is
            important, if the project uses multiple targets via the cargo bindeps feature, and not
            all targets can use `instrument-coverage`, e.g. a microkernel, or an embedded binary.

    -v, --verbose
            Use verbose output

            Use -vv (-vvv) to propagate verbosity to cargo.

        --color <WHEN>
            Coloring: auto, always, never

        --remap-path-prefix
            Use --remap-path-prefix for workspace root

            Note that this does not fully compatible with doctest.

        --include-ffi
            Include coverage of C/C++ code linked to Rust library/binary

            Note that `CC`/`CXX`/`LLVM_COV`/`LLVM_PROFDATA` environment variables must be set to
            Clang/LLVM compatible with the LLVM version used in rustc.

        --keep-going
            Do not abort the build as soon as there is an error (unstable)

        --ignore-rust-version
            Ignore `rust-version` specification in packages

        --manifest-path <PATH>
            Path to Cargo.toml

        --frozen
            Require Cargo.lock and cache are up to date

        --locked
            Require Cargo.lock is up to date

        --offline
            Run without accessing the network

    -Z <FLAG>
            Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for
            details

    -h, --help
            Print help information

    -V, --version
            Print version information

SUBCOMMANDS:
    test
            Run tests and generate coverage report
            This is equivalent to `cargo llvm-cov` without subcommand,
            except that test name filtering is supported.
    run
            Run a binary or example and generate coverage report
    report
            Generate coverage report
    show-env
            Output the environment set by cargo-llvm-cov to build Rust projects
    clean
            Remove artifacts that cargo-llvm-cov has generated in the past
    nextest
            Run tests with cargo nextest
            This internally calls `cargo nextest run`.

By default, run tests (via cargo test), and print the coverage summary to stdout.

cargo llvm-cov

Currently, doc tests are disabled by default because nightly-only features are required to make coverage work for doc tests. see #2 for more.

To run cargo run instead of cargo test, use run subcommand.

cargo llvm-cov run

With html report (the report will be generated to target/llvm-cov/html directory):

cargo llvm-cov --html
open target/llvm-cov/html/index.html

or

cargo llvm-cov --open

With plain text report (if --output-path is not specified, the report will be printed to stdout):

cargo llvm-cov --text | less -R

With json report (if --output-path is not specified, the report will be printed to stdout):

cargo llvm-cov --json --output-path cov.json

With lcov report (if --output-path is not specified, the report will be printed to stdout):

cargo llvm-cov --lcov --output-path lcov.info

You can get a coverage report in a different format based on the results of a previous run by using cargo llvm-cov report.

cargo llvm-cov --html          # run tests and generate html report
cargo llvm-cov report --lcov # generate lcov report

cargo llvm-cov/cargo llvm-cov run/cargo llvm-cov nextest cleans some build artifacts by default to avoid false positives/false negatives due to old build artifacts. This behavior is disabled when --no-clean, --no-report, or --no-run is passed, and old build artifacts are retained. When using these flags, it is recommended to first run cargo llvm-cov clean --workspace to remove artifacts that may affect the coverage results.

cargo llvm-cov clean --workspace # remove artifacts that may affect the coverage results
cargo llvm-cov --no-clean

Merge coverages generated under different test conditions

You can merge the coverages generated under different test conditions by using --no-report and cargo llvm-cov report.

cargo llvm-cov clean --workspace # remove artifacts that may affect the coverage results
cargo llvm-cov --no-report --features a
cargo llvm-cov --no-report --features b
cargo llvm-cov report --lcov # generate report without tests

Note: To include coverage for doctests you also need to pass --doctests to cargo llvm-cov report.

Get coverage of C/C++ code linked to Rust library/binary

Set CC, CXX, LLVM_COV, and LLVM_PROFDATA environment variables to Clang/LLVM compatible with the LLVM version used in rustc, and run cargo-llvm-cov with --include-ffi flag.

CC=<clang-path> \
CXX=<clang++-path> \
LLVM_COV=<llvm-cov-path> \
LLVM_PROFDATA=<llvm-profdata-path> \
  cargo llvm-cov --lcov --include-ffi

Get coverage of external tests

cargo test, cargo run, and cargo nextest are available as builtin, but cargo-llvm-cov can also be used for arbitrary binaries built using cargo (including other cargo subcommands or external tests that use make, xtask, etc.)

# Set the environment variables needed to get coverage.
source <(cargo llvm-cov show-env --export-prefix)
# Remove artifacts that may affect the coverage results.
# This command should be called after show-env.
cargo llvm-cov clean --workspace
# Above two commands should be called before build binaries.

cargo build # Build rust binaries.
# Commands using binaries in target/debug/*, including `cargo test` and other cargo subcommands.
# ...

cargo llvm-cov report --lcov # Generate report without tests.

Note: cargo-llvm-cov subcommands other than report and clean may not work correctly in the context where environment variables are set by show-env; consider using normal cargo/cargo-nextest commands.

Note: To include coverage for doctests you also need to pass --doctests to both cargo llvm-cov show-env and cargo llvm-cov report.

Exclude file from coverage

To exclude specific file patterns from the report, use the --ignore-filename-regex option.

cargo llvm-cov --open --ignore-filename-regex build

Exclude function from coverage

To exclude the specific function from coverage, use the #[coverage(off)] attribute.

Since #[coverage(off)] is unstable, it is recommended to use it together with cfg(coverage) or cfg(coverage_nightly) set by cargo-llvm-cov.

#![cfg_attr(coverage_nightly, feature(coverage_attribute))]

#[cfg_attr(coverage_nightly, coverage(off))]
fn exclude_from_coverage() {
    // ...
}

cfgs are set under the following conditions:

  • cfg(coverage) is always set when using cargo-llvm-cov (unless --no-cfg-coverage flag passed)
  • cfg(coverage_nightly) is set when using cargo-llvm-cov with nightly toolchain (unless --no-cfg-coverage-nightly flag passed)

If you want to ignore all #[test]-related code, consider using coverage-helper crate version 0.2+.

cargo-llvm-cov excludes code contained in the directory named tests from the report by default, so you can also use it instead of coverage-helper crate.

Note: #[coverage(off)] was previously named #[no_coverage]. When using #[no_coverage] in the old nightly, replace feature(coverage_attribute) with feature(no_coverage), coverage(off) with no_coverage, and coverage-helper 0.2+ with coverage-helper 0.1.

Continuous Integration

Here is an example of GitHub Actions workflow that uploads coverage to Codecov.

name: Coverage

on: [pull_request, push]

jobs:
  coverage:
    runs-on: ubuntu-latest
    env:
      CARGO_TERM_COLOR: always
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update stable
      - name: Install cargo-llvm-cov
        uses: taiki-e/install-action@cargo-llvm-cov
      - name: Generate code coverage
        run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
          files: lcov.info
          fail_ci_if_error: true

Currently, when using --lcov flag, only line coverage is available on Codecov.

By using --codecov flag instead of --lcov flag, you can use region coverage on Codecov:

- name: Generate code coverage
  run: cargo llvm-cov --all-features --workspace --codecov --output-path codecov.json
- name: Upload coverage to Codecov
  uses: codecov/codecov-action@v3
  with:
    token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
    files: codecov.json
    fail_ci_if_error: true

Note that the way Codecov shows region/branch coverage is not very good.

Display coverage in VS Code

You can display coverage in VS Code using Coverage Gutters.

Coverage Gutters supports lcov style coverage file and detects lcov.info files at the top level or in the coverage directory. Below is an example command to generate the coverage file.

cargo llvm-cov --lcov --output-path lcov.info

You may need to click the "Watch" label in the bottom bar of VS Code to display coverage.

Environment variables

You can override these environment variables to change cargo-llvm-cov's behavior on your system:

  • CARGO_LLVM_COV_TARGET_DIR -- Location of where to place all generated artifacts, relative to the current working directory. Default to <cargo_target_dir>/llvm-cov-target.
  • CARGO_LLVM_COV_SETUP -- Control behavior if llvm-tools-preview component is not installed. See #219 for more.
  • LLVM_COV -- Override the path to llvm-cov. You may need to specify both this and LLVM_PROFDATA environment variables if you are using --include-ffi flag or if you are using a toolchain installed without via rustup. llvm-cov version must be compatible with the LLVM version used in rustc.
  • LLVM_PROFDATA -- Override the path to llvm-profdata. See LLVM_COV environment variable for more.
  • LLVM_COV_FLAGS -- A space-separated list of additional flags to pass to all llvm-cov invocations that cargo-llvm-cov performs. See LLVM documentation for available options.
  • LLVM_PROFDATA_FLAGS -- A space-separated list of additional flags to pass to all llvm-profdata invocations that cargo-llvm-cov performs. See LLVM documentation for available options.
  • LLVM_PROFILE_FILE_NAME -- Override the file name (the final component of the path) of the LLVM_PROFILE_FILE. See LLVM documentation for available syntax.

See also environment variables that Cargo reads. cargo-llvm-cov respects many of them.

Additional JSON information

If JSON is selected as output format (with the --json flag), then cargo-llvm-cov will add additional contextual information at the root of the llvm-cov data. This can be helpful for programs that rely on the output of cargo-llvm-cov.

{
  // Other regular llvm-cov fields ...
  "cargo_llvm_cov": {
    "version": "0.0.0",
    "manifest_path": "/path/to/your/project/Cargo.toml"
  }
}
  • version specifies the version of cargo-llvm-cov that was used. This allows other programs to verify a certain version of it was used and make assertions of its behavior.
  • manifest_path defines the absolute path to the Rust project's Cargo.toml that cargo-llvm-cov was executed on. It can help to avoid repeating the same option on both programs.

For example, when forwarding the JSON output directly to another program:

cargo-llvm-cov --json | some-program

Installation

From source

cargo +stable install cargo-llvm-cov --locked

Currently, installing cargo-llvm-cov requires rustc 1.70+.

cargo-llvm-cov is usually runnable with Cargo versions older than the Rust version required for installation (e.g., cargo +1.60 llvm-cov). Currently, to run cargo-llvm-cov requires Cargo 1.60+.

From prebuilt binaries

You can download prebuilt binaries from the Release page. Prebuilt binaries are available for macOS, Linux (gnu and musl), and Windows (static executable).

Example of script to download cargo-llvm-cov
# Get host target
host=$(rustc -vV | grep '^host:' | cut -d' ' -f2)
# Download binary and install to $HOME/.cargo/bin
curl --proto '=https' --tlsv1.2 -fsSL https://github.com/taiki-e/cargo-llvm-cov/releases/latest/download/cargo-llvm-cov-$host.tar.gz | tar xzf - -C "$HOME/.cargo/bin"

On GitHub Actions

You can use taiki-e/install-action to install prebuilt binaries on Linux, macOS, and Windows. This makes the installation faster and may avoid the impact of problems caused by upstream changes.

- uses: taiki-e/install-action@cargo-llvm-cov

When used with nextest:

- uses: taiki-e/install-action@cargo-llvm-cov
- uses: taiki-e/install-action@nextest

Via Homebrew

You can install cargo-llvm-cov from the Homebrew tap maintained by us (x86_64/aarch64 macOS, x86_64/aarch64 Linux):

brew install taiki-e/tap/cargo-llvm-cov

Alternatively, you can install cargo-llvm-cov from homebrew-core (x86_64/aarch64 macOS, x86_64 Linux):

brew install cargo-llvm-cov

Via Scoop (Windows)

You can install cargo-llvm-cov from the Scoop bucket maintained by us:

scoop bucket add taiki-e https://github.com/taiki-e/scoop-bucket
scoop install cargo-llvm-cov

Via cargo-binstall

You can install cargo-llvm-cov using cargo-binstall:

cargo binstall cargo-llvm-cov

Via pacman (Arch Linux)

You can install cargo-llvm-cov from the extra repository:

pacman -S cargo-llvm-cov

Known limitations

See also the code-coverage-related issues reported in rust-lang/rust.

Related Projects

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

cargo-llvm-cov's People

Contributors

andrewgazelka avatar bors[bot] avatar boshen avatar cobaltcause avatar danieleades avatar davidhewitt avatar def- avatar dependabot[bot] avatar dnaka91 avatar frol avatar haraldh avatar larsluthman avatar ldm0 avatar maximkaaa avatar messense avatar michaelvlach avatar mike-kfed avatar mikedevresse avatar mlveggo avatar orhun avatar rhysd avatar rocketjas avatar romac avatar skyzh avatar smoelius avatar swatinem avatar taiki-e avatar tofay avatar vmiklos avatar weiznich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cargo-llvm-cov's Issues

Can't use with custom rustc

I'm trying to use cargo-llvm-cov with a custom built rust toolchain, but instead of using that toolchain cargo-llvm-cov is trying to run rustup run nightly rustc.

Would you accept a PR that detects if unstable features are available by running rustc -Z help or similar?

Usage in CI

codecov claims to support many formats, but it actually happens "There was an error processing coverage reports" errors on the server. It is necessary to understand which formats are actually supported and which ones are preferred to use.

I'm not sure about other code-coverage services as I have never used them.

Add support for printing out a summary

Hello,

I'm currently using cargo-llvm-cov on Gitlab CI. Gitlab CI has a neat feature where it can display the coverage percentage right next to a change if it can parse it from the CI log via Regex. As such it'd be nice if there was a command similar to llvm-cov report which just prints a quick overview of the per-file coverage and the total coverage.

Interoperability with trybuild

Currently, the trybuild crate does not contribute anything to the coverage report. I'm not sure whether this should be fixed in cargo-llvm-cov or trybuild. compiletest_rs, on the other hand, does contribute to the coverage report (but is far more finicky).

Error in loading coverage data, on nightly-2022-01-15 or later

Hey, we are using cargo-llvm-cov in our CI to get the coverage information, and for the last two days we are getting error saying failed to load the coverage information

info: when --target option is used, coverage for proc-macro and build script will not be displayed because cargo does not pass RUSTFLAGS to them
error: failed to generate report: process didn't exit successfully: `/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov export -format=lcov -instr-profile=/home/runner/work/youki/youki/target/llvm-cov-target/youki.profdata -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/integration_test-70ccadba5ff3eeb2 -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/integration_test-897d63685f9f06f0 -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/libcgroups-de8628be3307ab15 -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/libcontainer-69decfa1a73d5aab -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/liboci_cli-772485136e063db8 -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/libseccomp-c6eee5d114d66b56 -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/test_framework-672ff83324cabc04 -object /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/youki-894d6d4b690bb21f -ignore-filename-regex 'libseccomp/src|integration_test/src|test_framework/src|systemd_api.rs|(^|/)(rustc/[0-9a-f]+|tests|examples|benches|target/llvm-cov-target)/|^/home/runner($|/)|^/home/runner/.cargo($|/)|^/home/runner/.rustup($|/)'` (exit status: 1)
--- stderr
error: /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/integration_test-70ccadba5ff3eeb2, /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/integration_test-897d63685f9f06f0, /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/libcgroups-de8628be3307ab15, /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/libcontainer-69decfa1a73d5aab, /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/liboci_cli-772485136e063db8, /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/libseccomp-c6eee5d114d66b56, /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/test_framework-672ff83324cabc04, /home/runner/work/youki/youki/target/llvm-cov-target/x86_64-unknown-linux-gnu/debug/deps/youki-894d6d4b690bb21f: Failed to load coverage: Truncated coverage data
error: Could not load coverage information

Error: Process completed with exit code 1.

This is the exact error we are getting in our CI.

for reference, our CI yaml is https://github.com/containers/youki/blob/main/.github/workflows/main.yml#L68 and the PR where the CI is failing is https://github.com/containers/youki/runs/4832086318?check_suite_focus=true

The reason I suspect this is due to an error in nightly is that the same CI worked about 3 days ago, here https://github.com/containers/youki/runs/4817746220?check_suite_focus=true

To make sure it is not due to changes made in the PR, I tried puling the PR and running the steps for coverage manually with nightly version about ~1 month old, which generated coverage without any error. Then after updating rust using rustup on 16 Jan 2022 (yesterday) I got the exact same error on my local as well.

Can you please confirm that this is indeed some issue with nightly and not some accidental breakage from our side? And if so should I open an issue on rust repo?

Thanks for the help :)

Question: How do you exclude a line from the coverage report?

Normally there is a way to exclude a line from a coverage report using a comment on the line you want to exclude, or a command line option, or even a config option for a specific file, line to exclude. How is that done with this?

Awesome tool BTW. I cannot believe how easy it was. Totally blew my mind coming from C++ as it takes days to get code coverage working and this took literally minutes. What a game changer.

Exit code based on coverage percentage

Coverage tools for some other languages allow exiting with a non-0 exit code in case a certain type of coverage is below a specified minimum. For example:

  • python has: coverage report --fail-under=100 (statement coverage)

  • nodejs has: nyc report --statements 100 (statement coverage, also has other types of coverage)

The motivation for these flags is that they typically have some good way to exclude non-interesting code and then they can require good coverage for the rest of the code.

It seems to me that cargo-llvm-cov has no such feature and probably it would not be too complex to add one. Would a patch implementing this be accepted, after the usual review?

I think the closest in cargo-llvm-cov terms would be line coverage, perhaps something like:

cargo llvm-cov --fail-under-lines 100

could be a syntax to request non-0 exit code when line coverage is not 100%?

Thanks.

Why is the target directory cleared when CI is set?

I've just moved our projects from Tarpaulin to cargo-llvm-cov and coverage is much more accurate. I noticed however that our caching stopped working and it took me a good while to figure out why, but it seems to be due to this line which cleans the target directory when the CI environment variable is set.

Is there a particular reason for this? If I manually unset CI I am able to get caching working nicely again without recompiling hundreds of dependencies. Imho it would be better to leave it up to the user with an --always-clean flag or similar.

`CARGO_TARGET_DIR` -> `--target-dir`?

Would you be open to using cargo's --target-dir command line option instead of the CARG_TOARGET_DIR environment variable?

cmd.env("CARGO_TARGET_DIR", &cx.ws.target_dir);

The problem with using the environment variable is that it "infects" subordinate cargo invocations. I would expect that in most situations, one would only want to set the target directory for the initial invocation.

I could submit a PR if you like.

`object_files` includes upstream build scripts

Looking at the coverage failure in PyO3/pyo3#2356

I noticed that a lot of files passed as -object are build scripts for upstream dependencies:

target\debug\build\ahash-86b398e50bc5cdf8\build-script-build.exe
target\debug\build\ahash-86b398e50bc5cdf8\build_script_build-86b398e50bc5cdf8.exe
target\debug\build\anyhow-3ca1fe7ae176b565\build-script-build.exe
target\debug\build\anyhow-3ca1fe7ae176b565\build_script_build-3ca1fe7ae176b565.exe
target\debug\build\anyhow-3eee420b052878e1\build-script-build.exe
target\debug\build\anyhow-3eee420b052878e1\build_script_build-3eee420b052878e1.exe
target\debug\build\cast-91fd05a37bec76e5\build-script-build.exe
target\debug\build\cast-91fd05a37bec76e5\build_script_build-91fd05a37bec76e5.exe
target\debug\build\cast-998c8e4aafe34f1e\build-script-build.exe
target\debug\build\cast-998c8e4aafe34f1e\build_script_build-998c8e4aafe34f1e.exe
target\debug\build\crossbeam-epoch-842aa957d6ccdb11\build-script-build.exe
target\debug\build\crossbeam-epoch-842aa957d6ccdb11\build_script_build-842aa957d6ccdb11.exe
target\debug\build\crossbeam-utils-1bf3f6f44b031900\build-script-build.exe
target\debug\build\crossbeam-utils-1bf3f6f44b031900\build_script_build-1bf3f6f44b031900.exe
target\debug\build\eyre-0d0ae49eedee20b4\build-script-build.exe
target\debug\build\eyre-0d0ae49eedee20b4\build_script_build-0d0ae49eedee20b4.exe
target\debug\build\getrandom-39f03a4df4e08170\build-script-build.exe
target\debug\build\getrandom-39f03a4df4e08170\build_script_build-39f03a4df4e08170.exe
target\debug\build\indexmap-e74cbdf7d03137b1\build-script-build.exe
target\debug\build\indexmap-e74cbdf7d03137b1\build_script_build-e74cbdf7d03137b1.exe
target\debug\build\libc-309b983f2e20f08e\build-script-build.exe
target\debug\build\libc-309b983f2e20f08e\build_script_build-309b983f2e20f08e.exe
target\debug\build\libc-927850822b4d32e6\build-script-build.exe

I guess it must be impossible for these to actually contribute to coverage? I wonder if it makes sense in cargo-llvm-cov to filter out these build scripts? I don't think it's as trivial as filtering all build scripts, because it would be nice to include coverage from the build scripts of crates in the workspace.

0.1.0 release

Tracking issue for the first non-alpha release.

TODO:

  • #10
  • #34
  • #36
  • decide --output-dir related behavior #62
  • drop "[EXPERIMENTAL]"

... and more?

Merging coverage for multiple feature sets

PyO3 has a feature (--multiple-pymethods) which alters several code paths (such as inside a proc macro crate, the feature causes different generated code to be emitted).

Ideally I'd like to measure coverage combined from runs with and without this feature enabled. It's not immediately clear to me whether this is possible with cargo-llvm-cov at the moment. Do you think that's something which would make sense to support?

At the moment PyO3's CI just makes several different invocations to cargo test and then runs grcov once at the end.

I expect it's possible I could find an external tool to merge lcov output files for now, rather than making this a part of cargo-llvm-cov.

Ignore all `#[test]`-related code automatically

AFAIK this is not currently possible (though I would love to be proven wrong), so just filing this as a nice-to-have tracking issue.

What I would like is that only library code counts towards coverage. Having all of the #[test] and #[cfg(test)] code (fn and whole utility modules) count towards coverage metrics right now skews those numbers up quite a bit.

Right now cargo-llvm-cov automatically ignores all the examples and tests code via -ignore-filename-regex but unit test functions are still counted (and possibly doctests once those are being fixed [tentative fix in #122]).

Logic to detect rustc version is incomplete

The current way does not handle it correctly when the version is specified in a cargo or rustup specific way (e.g., cargo +nightly-..., rustup run +nightly-...).

let path = env.rustc.as_deref().unwrap_or_else(|| OsStr::new("rustc"));
let version = cmd!(path, "--version").dir(workspace_root).read()?;
let nightly = version.contains("-nightly") || version.contains("-dev");
let mut cmd = if nightly { cmd!(path) } else { cmd!("rustup", "run", "nightly", "rustc") };
cmd.args(&["--version", "--verbose"]);
let verbose_version = cmd.read()?;

Currently, the following heuristic is the only one that uses the retrieved rustc information, so it does not affect the coverage results, but it may accidentally remove dependency's build artifacts.

// - If there are old artifacts by a different version of rustc: remove all artifacts (handled in Context::new)

related(?): rust-lang/cargo#2833

Add `--workspace` flag to `clean` subcommand

It would be useful to have a flag to remove only artifacts that may affect the coverage results, using the same way as #79.

cargo llvm-cov clean --workspace # remove artifacts that may affect the coverage results
cargo llvm-cov --no-report --features a
cargo llvm-cov --no-report --features b
cargo llvm-cov --no-run --lcov

Option to show uncovered lines in the command-line output

Now that --fail-under-lines works, my only remaining pain point with cargo llvm-cov is that the iteration cycle (when writing tests for uncovered code) is a bit complex, compared to other coverage tools I saw before. The text output is nice, but it even shows covered lines, so it's very verbose. The command-line output is the other extreme: it's just a summary, it doesn't show you exactly what lines are uncovered.

E.g. Python's coverage.py has a simple way to just point out the uncovered lines, one line / filename, like this:

foo.py: 12, 22
bar.py: 32, 42

coverage.py calls this option --show-missing. I think that's a nice middle ground that is sometimes useful to people.

Would you accept a patch to add a --show-missing-lines (or similarly named) optional bool switch that would print such info at the end?

I expect doing such analysis based on the llvm-cov json output is not too hard (when limited to line coverage), we just would need to detect lines which have matching segments but all of them are the "could have a count, but doesn't" case.

Cobertura output

Hey! This is currently my favorite Rust coverage tool but I'm missing Cobertura output for GitLab. Currently, the only way seems to be to use the unmaintained Python package lcov-to-cobertura-xml but that seems annoying to me. Any chance we can get native GitLab-compatible Cobertura output in this tool? :)

Src file mapping not working properly with `trybuild` and proc-macro workspace member

When running integration tests (via trybuild) for a proc-macro crate that is a workspace member, the following warning is output:

error: dep/dep/src/lib.rs: No such file or directory
warning: The file 'dep/dep/src/lib.rs' isn't covered.

cmd run:

cargo llvm-cov --workspace --html

The report ends up showing 2 entries for the same src file as seen below

image

You can find a small reproducible sample here: test.tar.gz

This seems to be happening even if trybuild::TestCases::new() is the only thing in the test fn (no calls to pass or compile_fail).
It also seems to work fine if the crate is a normal lib instead of a proc-macro lib.

I wasn't sure if this is an issue with cargo-llvm-cov or trybuild but having tried tarpaulin with success (same setup), I thought it might be an issue with cargo-llvm-cov.

Add `cargo llvm-cov clean` subcommand

We use a subdirectory of the target directory as the actual target directory.
A subcommand to clean only this target directory would be nice.

// If we change RUSTFLAGS, all dependencies will be recompiled. Therefore,
// use a subdirectory of the target directory as the actual target directory.
let target_dir = cargo_target_dir.join("llvm-cov-target");

"report" subcommand on CLI?

This tool has been extremely useful, thanks! By far the simplest to get working tool for the instrument-coverage (I had some trouble getting grcov to work)

One thing I think could be improved is the command line args - mainly about generating reports (where quite a lot of the arguments are mutually exclusive, e.g --no-run and any of the arguments like --lib, --html and --output-file`)

I think to steal some ideas from coverage.py could work, specifically to have a report subcommand.

Main downside of this is obviously a common "run tests and open report" usage becomes two commands, so instead of just cargo llvm-cov --html --open it would become cargo llvm-cov && cargo llvm-cov html --open.

However the upsides are:

  1. the available options become smaller and more organised
  2. maybe be a tiny bit more intuitive to use (e.g first few times I accidentally reran my testsuite because I assumed cargo llvm-cov --open would only open the report)
  3. If gathering and reporting are two separate actions, it would be (if it's not already?) possible to gather coverage from multiple runs and report on them in one - e.g cargo llvm-cov test && cargo llvm-cov run --append-cov && cargo llvm-cov run --example blah --append-cov && cargo llvm-cov html which would run the tests and two executable, and generate a report of the combined coverage

I imagine the help output could look something like:

Example help output
$ cargo llvm-cov --help
cargo-llvm-cov

Cargo subcommand to easily use LLVM source-based code coverage (-Z instrument-coverage).

Use -h for short descriptions and --help for more details.

USAGE:
    cargo llvm-cov [OPTIONS] [-- <ARGS>...] [SUBCOMMAND]

ARGS:
    <ARGS>...
            Arguments for the test binary

GLOBAL OPTIONS:
    -h, --help
            Print help information

    -V, --version
            Print version information


    -v, --verbose
            Use verbose output

            Use -vv (-vvv) to propagate verbosity to cargo.

    --color <WHEN>
            Coloring [possible values: auto, always, never]

    --manifest-path <PATH>
            Path to Cargo.toml

    --frozen
            Require Cargo.lock and cache are up to date

    --locked
            Require Cargo.lock is up to date

    --offline
            Run without accessing the network

    -Z <FLAG>...
            Unstable (nightly-only) flags to Cargo

SUBCOMMANDS:
    clean
            Remove artifacts that cargo-llvm-cov has generated in the past

    help
            Print this message or the help of the given subcommand(s)

    report
        --ignore-filename-regex <PATTERN>
            Skip source code files with file paths that match the given regular expression

        --no-report
            Run tests, but don't generate coverage report

        --no-run
            Generate coverage report without running tests

        json <optional output file>
            Export coverage data in "json" format

            If output file is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=text`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        lcov <optional output file>
            Export coverage data in "lcov" format

            If output file is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=lcov`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        text <optional output directory>
            Generate coverage report in "text" format

            This internally calls `llvm-cov show -format=text`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.

        html <optional target directory>
            Generate coverage report in "html" format

            This internally calls `llvm-cov show -format=html`. See
            <https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.

        summary
            Display only summary information for each file in the coverage data

    run
        --bin <NAME>...
            Test only the specified binary

    test
        --doctests
            Including doc tests (unstable)

            This flag is unstable. See <https://github.com/taiki-e/cargo-llvm-cov/issues/2> for
            more.

        --no-fail-fast
            Run all tests regardless of failure

        -q, --quiet
            Display one character per test instead of one line

        --lib
            Test only this package's library unit tests

        --bins
            Test all binaries

        --example <NAME>...
            Test only the specified example

        --examples
            Test all examples

        --test <NAME>...
            Test only the specified test target

        --tests
            Test all tests

        --bench <NAME>...
            Test only the specified bench target

        --benches
            Test all benches

        --all-targets
            Test all targets

        --doc
            Test only this library's documentation (unstable)

            This flag is unstable because it automatically enables --doctests flag. See
            <https://github.com/taiki-e/cargo-llvm-cov/issues/2> for more.

        -p, --package <SPEC>...
            Package to run tests for

        --workspace
            Test all packages in the workspace [aliases: all]

        --exclude <SPEC>...
            Exclude packages from the test

        -j, --jobs <N>
            Number of parallel jobs, defaults to # of CPUs

        --release
            Build artifacts in release mode, with optimizations

        --profile <PROFILE-NAME>
            Build artifacts with the specified profile

        --features <FEATURES>...
            Space or comma separated list of features to activate

        --all-features
            Activate all available features

        --no-default-features
            Do not activate the `default` feature

        --target <TRIPLE>
            Build for the target triple

            When this option is used, coverage for proc-macro and build script will not be displayed
            because cargo does not pass RUSTFLAGS to them.

Support custom profiles

https://blog.rust-lang.org/2021/12/02/Rust-1.57.0.html#cargo-support-for-custom-profiles

Currently, this will build artifacts in a separate directory (target/production in this case), which means that artifacts are not shared between directories.

cargo-llvm-cov/src/cli.rs

Lines 316 to 321 in 1fc21dd

/// Build artifacts with the specified profile
// TODO: this option is not fully handled yet
// https://github.com/rust-lang/cargo/issues/6988
// https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#custom-named-profiles
#[clap(long, value_name = "PROFILE-NAME")]
pub(crate) profile: Option<String>,

Provide a way to output reports in multiple formats at the same time

Something like:

cargo llvm-cov --format html,json --output-dir coverage

#60 (comment)

In fact, there is already a way to do equivalent thing. The purpose of this problem is to make it easier to use that pattern.

cargo llvm-cov --html # generate html report
cargo llvm-cov report --lcov --output-path lcov.info # generate lcov report without running test

llvm-cov and nextest arguments in "inverted" positions

Heya, I'm trying cargo-llvm-cov 0.3.0 with nextest in a workspace, and it appears that:

  • arguments for the cargo llvm-cov application need to be after the nextest subcommand, and
  • arguments for nextest need to be passed before nextest

Example:

nextest_args=(--workspace)
llvm_cov_args=(--workspace --open --output-dir ./target/coverage)

# Passes llvm_cov_args through to nextest, doesn't do what is expected
# This is how I would expect to write the command
cargo llvm-cov $llvm_cov_args[@] nextest $nextest_args[@]

# This does what is expected
cargo llvm-cov $nextest_args[@] nextest $llvm_cov_args[@]

I haven't managed to figure out whether it's by design by clap.

Windows support

UPDATE: In the current main, the below error is no longer exists, but there is still a problem that the dependency files cannot be properly excluded from the report.

cargo-llvm-cov can be compiled on windows, but it is not working well yet.

https://github.com/taiki-e/cargo-llvm-cov/runs/2747955205?check_suite_focus=true

error: D:\a\cargo-llvm-cov\cargo-llvm-cov\easytime\target\llvm-cov-target\debug\deps\easytime-55f5f70e39c59f9b.exe, D:\a\cargo-llvm-cov\cargo-llvm-cov\easytime\target\llvm-cov-target\debug\deps\easytime-55f5f70e39c59f9b.pdb, D:\a\cargo-llvm-cov\cargo-llvm-cov\easytime\target\llvm-cov-target\debug\deps\duration-f109b2421656fc14.exe, D:\a\cargo-llvm-cov\cargo-llvm-cov\easytime\target\llvm-cov-target\debug\deps\duration-f109b2421656fc14.pdb, D:\a\cargo-llvm-cov\cargo-llvm-cov\easytime\target\llvm-cov-target\debug\deps\instant-fd5bd861f01c3046.exe, D:\a\cargo-llvm-cov\cargo-llvm-cov\easytime\target\llvm-cov-target\debug\deps\instant-fd5bd861f01c3046.pdb: Failed to load coverage: The file was not recognized as a valid object file

Add an option to merge coverage of generics in the summary

First, thanks for a very useful tool!

It would be nice if there was an command line option to merge the coverage of different instantiations of generic functions in the summary of the coverge of a file, so that it would show 100% coverage if the tests covered all of a generic function, even if different regions of the function were covered by different instantiations. Consider the following source file:

fn smaller_than_default<T: Default + PartialOrd>(t: T) -> bool {
    if t < T::default() { true }
    else { false }
}

#[test]
fn test_instantiations() {
    assert!(!smaller_than_default(56.4_f32));
    assert!(smaller_than_default(-56_i32));
}

With cargo-llvm-cov 0.1.0-alpha.4, the report will show a region coverage of 88.89% (8/9), even though all regions of the generic function are marked as covered. The current rule seems to be that there needs to be at least one instantiation with 100% coverage for the generic function to be counted as 100% covered. This is probably a good choice for some situations, but sometimes you have a generic function that is difficult to cover completely with a single instantiation and for those cases it would be nice to have an option to merge the coverage of all instantiations when computing the summary.

Can we use external tests to generate coverage report?

I do not know much about how the code coverage data generation works, so sorry if this is a stupid question, but can we use external programs that run our binary to generate coverage data?

To elaborate, I am contributing to https://github.com/containers/youki/ , where we use cargo-llvm-cov in CI to generate coverage report. As of now, we generate coverage using unit tests, which are Rust tests (marked with #[tests] attribute).

Now to validate that the runtime itself is consistent with OCI spec, OCI has validation tests which run youki binary and test it on various conditions : https://github.com/opencontainers/runtime-tools

My question is : is it possible to generate coverage data from those tests, and use that as well to find total coverage?

Thanks for you time.

Highlight covered lines green in html report

First of all, really nice project! I got it installed and running in my Windows environment with zero hassle. 👏

I've only used gcov in C++ based projects before, and so I've only seen that classical blocky html report. Gcov seems to render covered lines in green, and non-covered lines in red, in their html reports. As far as I can tell for the rust code that I've tested cargo-llvm-cov with, I'm only getting red lines.

image
image

Is it possible for cargo-llvm-cov to generate html reports that contain these green lines? Or does it already and I'm just perhaps having a config issue?

Ignore cargo registry from docker image

Hi,

When using this project inside the official rust docker image, the coverage report include stuff from /usr/local/cargo/registry/src/.

I'm not sure how to read the exclude regex in

r"(^|{0})(rustc{0}[0-9a-f]+|.cargo{0}(registry|git)|.rustup{0}toolchains|tests|examples|benches|target{0}llvm-cov-target){0}",

so I don't know if it's just me doing something wrong or not.

Is there a way to exclude everything from this path ?

Generating coverage report fails on Windows with too many objects

See this failed CI output from a coverage run: https://github.com/PyO3/pyo3/runs/4793968532?check_suite_focus=true

It seems this is a symptom of collecting coverage on a large number of output objects, and gives the error (never executed): The filename or extension is too long. (os error 206). I don't actually think it's the filename or extension, but rather the total length of the command. In this case I believe it's something like 34,565 characters long (!) and the limit in Windows is apparently 32,768.

I am happy to work on a fix/workaround if somebody knows one, but I also unfortunately don't have direct access to a Windows machine at the moment.

Add `cargo llvm-cov run` subcommand

We already support test coverage for binary crate (#1 (comment)), but it would be nice if we could support another way as well.

Something like the following:

cargo llvm-cov run --html -- args...

with --no-report/--no-run

cargo llvm-cov run --no-report -- args... # run
cargo llvm-cov --no-report # test

cargo llvm-cov --no-run --html # merge run and test's coverage

LLVM Profile Warning: Unable to merge profile data: source profile file is not compatible.

https://github.com/time-rs/time/runs/3271156683?check_suite_focus=true#step:6:717

LLVM Profile Warning: Unable to merge profile data: source profile file is not compatible.
LLVM Profile Error: Profile Merging of file $DIR/target/llvm-cov-target/time-13776624154103039134_0.profraw failed: File exists
LLVM Profile Error: Failed to write file "$DIR/target/llvm-cov-target/time-13776624154103039134_0.profraw": File exists

This is without a cache hit (I'm using a new key), so this isn't an incremental issue. I'm not able to reproduce this locally (Fedora 34, 64 bit).

llvm-cov breaks when using global allocator jemallocator

Adding the following to a newly created library crate breaks llvm-cov:

#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

With command:

cargo llvm-cov --html --open

With output:

...
Failed to load coverage: The file was not recognized as a valid object file
error: failed to generate report: process didn't exit successfully:
...

I initially thought that source based coverage was fundamentally incompatible with jemallocator, however I did some testing and found that it's possible to generate an lcov report with source based coverage on a project that uses jemallocator globally with the following, which leads me to believe it's an issue within llvm-cov:

rustup component add llvm-tools-preview --toolchain nightly
cargo install cargo-binutils

export RUSTFLAG="-Z instrument-coverage"
export LLVM_PROFILE_FILE="default-%m.profraw"
cargo test --tests

cargo profdata -- merge -sparse default-*.profraw -o default.profdata

cargo cov -- export --instr-profile=default.profdata --object target/debug/deps/<project-name>-<alphanumeric> --format=lcov

--show-missing-lines false alarm

Given a Cargo.toml:

[package]
name = "t"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.34"
[workspace]

and a src/lib.rs:

pub fn foo() -> anyhow::Result<()> {
    Ok(())
}

pub fn bar() -> anyhow::Result<()> {
    Ok(foo()?)
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn it_works() {
        bar().unwrap();
    }
}

When running:

cargo llvm-cov -v --show-missing-lines

Then llvm-cov report itself says that the line coverage is 100%, but our own analysis with --show-missing-lines still flags a line as missing:

src/lib.rs: 6

I'll try to investigate what's happening here, but if somebody has an idea, I'm interested to hear about it.

[question] generate code coverage badge

can i generate code coverage badge as support vector graphics format?

to put in the readme file

python has a code-coverage tool that generates a badge.

if this doesnt exist, then im suggesting a feature.

the badge should look like this
+---------------+
| code cov: %33 |
+---------------+
something similar, with percentage, thanks.

Generation fails due to "Truncated coverage data"

Have been using cargo-llvm-cov successfully in the past several times, and it just worked great. But recently it always fails with the error Failed to load coverage: Truncated coverage data.

Could this be some change that happened in the llvm-tools-preview package on nightly?

OS: MacOS
Project: dnaka91/obws
Rustc Version: rustc 1.60.0-nightly (f624427f8 2022-02-06)

This is the full error output:

error: target/llvm-cov-target/debug/build/anyhow-0deaec97327e4671/build-script-build, target/llvm-cov-target/debug/build/anyhow-0deaec97327e4671/build_script_build-0deaec97327e4671, target/llvm-cov-target/debug/build/anyhow-11757e37879e3e70/build-script-build, target/llvm-cov-target/debug/build/anyhow-11757e37879e3e70/build_script_build-11757e37879e3e70, target/llvm-cov-target/debug/build/futures-core-3a9d5930b2a841b2/build-script-build, target/llvm-cov-target/debug/build/futures-core-3a9d5930b2a841b2/build_script_build-3a9d5930b2a841b2, target/llvm-cov-target/debug/build/futures-core-3ddbaa07089d082d/build-script-build, target/llvm-cov-target/debug/build/futures-core-3ddbaa07089d082d/build_script_build-3ddbaa07089d082d, target/llvm-cov-target/debug/build/futures-task-109a30ae9b891e7b/build-script-build, target/llvm-cov-target/debug/build/futures-task-109a30ae9b891e7b/build_script_build-109a30ae9b891e7b, target/llvm-cov-target/debug/build/futures-task-1ab505591ec822c2/build-script-build, target/llvm-cov-target/debug/build/futures-task-1ab505591ec822c2/build_script_build-1ab505591ec822c2, target/llvm-cov-target/debug/build/futures-util-8faf909b5fb0152b/build-script-build, target/llvm-cov-target/debug/build/futures-util-8faf909b5fb0152b/build_script_build-8faf909b5fb0152b, target/llvm-cov-target/debug/build/futures-util-d399d88abf0e45cb/build-script-build, target/llvm-cov-target/debug/build/futures-util-d399d88abf0e45cb/build_script_build-d399d88abf0e45cb, target/llvm-cov-target/debug/build/generic-array-f6893c66a2b6ed4e/build-script-build, target/llvm-cov-target/debug/build/generic-array-f6893c66a2b6ed4e/build_script_build-f6893c66a2b6ed4e, target/llvm-cov-target/debug/build/httparse-c875addf0a93043d/build-script-build, target/llvm-cov-target/debug/build/httparse-c875addf0a93043d/build_script_build-c875addf0a93043d, target/llvm-cov-target/debug/build/libc-64dc221bb1a997ba/build-script-build, target/llvm-cov-target/debug/build/libc-64dc221bb1a997ba/build_script_build-64dc221bb1a997ba, target/llvm-cov-target/debug/build/libc-ab5a7f10f2043aab/build-script-build, target/llvm-cov-target/debug/build/libc-ab5a7f10f2043aab/build_script_build-ab5a7f10f2043aab, target/llvm-cov-target/debug/build/log-7aeff1f4899b7e98/build-script-build, target/llvm-cov-target/debug/build/log-7aeff1f4899b7e98/build_script_build-7aeff1f4899b7e98, target/llvm-cov-target/debug/build/memchr-befa59ac0d13a638/build-script-build, target/llvm-cov-target/debug/build/memchr-befa59ac0d13a638/build_script_build-befa59ac0d13a638, target/llvm-cov-target/debug/build/proc-macro2-12a08702f33cb4fd/build-script-build, target/llvm-cov-target/debug/build/proc-macro2-12a08702f33cb4fd/build_script_build-12a08702f33cb4fd, target/llvm-cov-target/debug/build/ring-4426400e214b13a0/build-script-build, target/llvm-cov-target/debug/build/ring-4426400e214b13a0/build_script_build-4426400e214b13a0, target/llvm-cov-target/debug/build/rustversion-0fcd536110f8cbf5/build-script-build, target/llvm-cov-target/debug/build/rustversion-0fcd536110f8cbf5/build_script_build-0fcd536110f8cbf5, target/llvm-cov-target/debug/build/semver-da5111e14fb7e53c/build-script-build, target/llvm-cov-target/debug/build/semver-da5111e14fb7e53c/build_script_build-da5111e14fb7e53c, target/llvm-cov-target/debug/build/semver-f147641bca290af3/build-script-build, target/llvm-cov-target/debug/build/semver-f147641bca290af3/build_script_build-f147641bca290af3, target/llvm-cov-target/debug/build/serde-7c630a0a879b3265/build-script-build, target/llvm-cov-target/debug/build/serde-7c630a0a879b3265/build_script_build-7c630a0a879b3265, target/llvm-cov-target/debug/build/serde-f9a70554b5c2b166/build-script-build, target/llvm-cov-target/debug/build/serde-f9a70554b5c2b166/build_script_build-f9a70554b5c2b166, target/llvm-cov-target/debug/build/serde_derive-2fbf478fecf7f47c/build-script-build, target/llvm-cov-target/debug/build/serde_derive-2fbf478fecf7f47c/build_script_build-2fbf478fecf7f47c, target/llvm-cov-target/debug/build/serde_derive-652ad15766278389/build-script-build, target/llvm-cov-target/debug/build/serde_derive-652ad15766278389/build_script_build-652ad15766278389, target/llvm-cov-target/debug/build/serde_json-966e673159dffa2a/build-script-build, target/llvm-cov-target/debug/build/serde_json-966e673159dffa2a/build_script_build-966e673159dffa2a, target/llvm-cov-target/debug/build/serde_json-f11470691e35515d/build-script-build, target/llvm-cov-target/debug/build/serde_json-f11470691e35515d/build_script_build-f11470691e35515d, target/llvm-cov-target/debug/build/serde_test-e21ca3889a7d1d00/build-script-build, target/llvm-cov-target/debug/build/serde_test-e21ca3889a7d1d00/build_script_build-e21ca3889a7d1d00, target/llvm-cov-target/debug/build/syn-00528ab57a5b399e/build-script-build, target/llvm-cov-target/debug/build/syn-00528ab57a5b399e/build_script_build-00528ab57a5b399e, target/llvm-cov-target/debug/build/syn-0b3cfe976b16a760/build-script-build, target/llvm-cov-target/debug/build/syn-0b3cfe976b16a760/build_script_build-0b3cfe976b16a760, target/llvm-cov-target/debug/build/typenum-b8ba57cb29bde287/build-script-main, target/llvm-cov-target/debug/build/typenum-b8ba57cb29bde287/build_script_main-b8ba57cb29bde287, target/llvm-cov-target/debug/deps/integration-3880f5b35cdcdbb2, target/llvm-cov-target/debug/deps/libasync_stream_impl-7bfb5b31af2a1a31.dylib, target/llvm-cov-target/debug/deps/libasync_stream_impl-8518d962c7f54acb.dylib, target/llvm-cov-target/debug/deps/libdarling_macro-7dc4982565f38e09.dylib, target/llvm-cov-target/debug/deps/libdarling_macro-8a8ebc326d2939cb.dylib, target/llvm-cov-target/debug/deps/libfutures_macro-7f174fc4124dbe57.dylib, target/llvm-cov-target/debug/deps/libfutures_macro-c652c3db5803fbea.dylib, target/llvm-cov-target/debug/deps/librustversion-66ee14ca3f11122e.dylib, target/llvm-cov-target/debug/deps/libserde_derive-1eed428c3ed71456.dylib, target/llvm-cov-target/debug/deps/libserde_derive-520e96e0545235ad.dylib, target/llvm-cov-target/debug/deps/libserde_repr-e55860a3ca1bce92.dylib, target/llvm-cov-target/debug/deps/libserde_repr-feaf066ef92ebba6.dylib, target/llvm-cov-target/debug/deps/libserde_with_macros-7a6f60b3f82f2a2d.dylib, target/llvm-cov-target/debug/deps/libserde_with_macros-cea2c2d0e3cbe043.dylib, target/llvm-cov-target/debug/deps/libthiserror_impl-252e3bf731fff8d2.dylib, target/llvm-cov-target/debug/deps/libthiserror_impl-b3037b7568fb3134.dylib, target/llvm-cov-target/debug/deps/libtokio_macros-46e476d1c00fb151.dylib, target/llvm-cov-target/debug/deps/libtokio_macros-ed658ef8ab058d52.dylib, target/llvm-cov-target/debug/deps/libtracing_attributes-9f400b99e42d2fe4.dylib, target/llvm-cov-target/debug/deps/libtracing_attributes-bfc2d791dbec8257.dylib, target/llvm-cov-target/debug/deps/obws-4b642cab3c4c801b: Failed to load coverage: Truncated coverage data
error: failed to generate report: process didn't exit successfully: `/Users/dnaka91/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/bin/llvm-cov report -instr-profile=/Users/dnaka91/Projects/public/obws/target/llvm-cov-target/obws.profdata -object target/llvm-cov-target/debug/build/anyhow-0deaec97327e4671/build-script-build -object target/llvm-cov-target/debug/build/anyhow-0deaec97327e4671/build_script_build-0deaec97327e4671 -object target/llvm-cov-target/debug/build/anyhow-11757e37879e3e70/build-script-build -object target/llvm-cov-target/debug/build/anyhow-11757e37879e3e70/build_script_build-11757e37879e3e70 -object target/llvm-cov-target/debug/build/futures-core-3a9d5930b2a841b2/build-script-build -object target/llvm-cov-target/debug/build/futures-core-3a9d5930b2a841b2/build_script_build-3a9d5930b2a841b2 -object target/llvm-cov-target/debug/build/futures-core-3ddbaa07089d082d/build-script-build -object target/llvm-cov-target/debug/build/futures-core-3ddbaa07089d082d/build_script_build-3ddbaa07089d082d -object target/llvm-cov-target/debug/build/futures-task-109a30ae9b891e7b/build-script-build -object target/llvm-cov-target/debug/build/futures-task-109a30ae9b891e7b/build_script_build-109a30ae9b891e7b -object target/llvm-cov-target/debug/build/futures-task-1ab505591ec822c2/build-script-build -object target/llvm-cov-target/debug/build/futures-task-1ab505591ec822c2/build_script_build-1ab505591ec822c2 -object target/llvm-cov-target/debug/build/futures-util-8faf909b5fb0152b/build-script-build -object target/llvm-cov-target/debug/build/futures-util-8faf909b5fb0152b/build_script_build-8faf909b5fb0152b -object target/llvm-cov-target/debug/build/futures-util-d399d88abf0e45cb/build-script-build -object target/llvm-cov-target/debug/build/futures-util-d399d88abf0e45cb/build_script_build-d399d88abf0e45cb -object target/llvm-cov-target/debug/build/generic-array-f6893c66a2b6ed4e/build-script-build -object target/llvm-cov-target/debug/build/generic-array-f6893c66a2b6ed4e/build_script_build-f6893c66a2b6ed4e -object target/llvm-cov-target/debug/build/httparse-c875addf0a93043d/build-script-build -object target/llvm-cov-target/debug/build/httparse-c875addf0a93043d/build_script_build-c875addf0a93043d -object target/llvm-cov-target/debug/build/libc-64dc221bb1a997ba/build-script-build -object target/llvm-cov-target/debug/build/libc-64dc221bb1a997ba/build_script_build-64dc221bb1a997ba -object target/llvm-cov-target/debug/build/libc-ab5a7f10f2043aab/build-script-build -object target/llvm-cov-target/debug/build/libc-ab5a7f10f2043aab/build_script_build-ab5a7f10f2043aab -object target/llvm-cov-target/debug/build/log-7aeff1f4899b7e98/build-script-build -object target/llvm-cov-target/debug/build/log-7aeff1f4899b7e98/build_script_build-7aeff1f4899b7e98 -object target/llvm-cov-target/debug/build/memchr-befa59ac0d13a638/build-script-build -object target/llvm-cov-target/debug/build/memchr-befa59ac0d13a638/build_script_build-befa59ac0d13a638 -object target/llvm-cov-target/debug/build/proc-macro2-12a08702f33cb4fd/build-script-build -object target/llvm-cov-target/debug/build/proc-macro2-12a08702f33cb4fd/build_script_build-12a08702f33cb4fd -object target/llvm-cov-target/debug/build/ring-4426400e214b13a0/build-script-build -object target/llvm-cov-target/debug/build/ring-4426400e214b13a0/build_script_build-4426400e214b13a0 -object target/llvm-cov-target/debug/build/rustversion-0fcd536110f8cbf5/build-script-build -object target/llvm-cov-target/debug/build/rustversion-0fcd536110f8cbf5/build_script_build-0fcd536110f8cbf5 -object target/llvm-cov-target/debug/build/semver-da5111e14fb7e53c/build-script-build -object target/llvm-cov-target/debug/build/semver-da5111e14fb7e53c/build_script_build-da5111e14fb7e53c -object target/llvm-cov-target/debug/build/semver-f147641bca290af3/build-script-build -object target/llvm-cov-target/debug/build/semver-f147641bca290af3/build_script_build-f147641bca290af3 -object target/llvm-cov-target/debug/build/serde-7c630a0a879b3265/build-script-build -object target/llvm-cov-target/debug/build/serde-7c630a0a879b3265/build_script_build-7c630a0a879b3265 -object target/llvm-cov-target/debug/build/serde-f9a70554b5c2b166/build-script-build -object target/llvm-cov-target/debug/build/serde-f9a70554b5c2b166/build_script_build-f9a70554b5c2b166 -object target/llvm-cov-target/debug/build/serde_derive-2fbf478fecf7f47c/build-script-build -object target/llvm-cov-target/debug/build/serde_derive-2fbf478fecf7f47c/build_script_build-2fbf478fecf7f47c -object target/llvm-cov-target/debug/build/serde_derive-652ad15766278389/build-script-build -object target/llvm-cov-target/debug/build/serde_derive-652ad15766278389/build_script_build-652ad15766278389 -object target/llvm-cov-target/debug/build/serde_json-966e673159dffa2a/build-script-build -object target/llvm-cov-target/debug/build/serde_json-966e673159dffa2a/build_script_build-966e673159dffa2a -object target/llvm-cov-target/debug/build/serde_json-f11470691e35515d/build-script-build -object target/llvm-cov-target/debug/build/serde_json-f11470691e35515d/build_script_build-f11470691e35515d -object target/llvm-cov-target/debug/build/serde_test-e21ca3889a7d1d00/build-script-build -object target/llvm-cov-target/debug/build/serde_test-e21ca3889a7d1d00/build_script_build-e21ca3889a7d1d00 -object target/llvm-cov-target/debug/build/syn-00528ab57a5b399e/build-script-build -object target/llvm-cov-target/debug/build/syn-00528ab57a5b399e/build_script_build-00528ab57a5b399e -object target/llvm-cov-target/debug/build/syn-0b3cfe976b16a760/build-script-build -object target/llvm-cov-target/debug/build/syn-0b3cfe976b16a760/build_script_build-0b3cfe976b16a760 -object target/llvm-cov-target/debug/build/typenum-b8ba57cb29bde287/build-script-main -object target/llvm-cov-target/debug/build/typenum-b8ba57cb29bde287/build_script_main-b8ba57cb29bde287 -object target/llvm-cov-target/debug/deps/integration-3880f5b35cdcdbb2 -object target/llvm-cov-target/debug/deps/libasync_stream_impl-7bfb5b31af2a1a31.dylib -object target/llvm-cov-target/debug/deps/libasync_stream_impl-8518d962c7f54acb.dylib -object target/llvm-cov-target/debug/deps/libdarling_macro-7dc4982565f38e09.dylib -object target/llvm-cov-target/debug/deps/libdarling_macro-8a8ebc326d2939cb.dylib -object target/llvm-cov-target/debug/deps/libfutures_macro-7f174fc4124dbe57.dylib -object target/llvm-cov-target/debug/deps/libfutures_macro-c652c3db5803fbea.dylib -object target/llvm-cov-target/debug/deps/librustversion-66ee14ca3f11122e.dylib -object target/llvm-cov-target/debug/deps/libserde_derive-1eed428c3ed71456.dylib -object target/llvm-cov-target/debug/deps/libserde_derive-520e96e0545235ad.dylib -object target/llvm-cov-target/debug/deps/libserde_repr-e55860a3ca1bce92.dylib -object target/llvm-cov-target/debug/deps/libserde_repr-feaf066ef92ebba6.dylib -object target/llvm-cov-target/debug/deps/libserde_with_macros-7a6f60b3f82f2a2d.dylib -object target/llvm-cov-target/debug/deps/libserde_with_macros-cea2c2d0e3cbe043.dylib -object target/llvm-cov-target/debug/deps/libthiserror_impl-252e3bf731fff8d2.dylib -object target/llvm-cov-target/debug/deps/libthiserror_impl-b3037b7568fb3134.dylib -object target/llvm-cov-target/debug/deps/libtokio_macros-46e476d1c00fb151.dylib -object target/llvm-cov-target/debug/deps/libtokio_macros-ed658ef8ab058d52.dylib -object target/llvm-cov-target/debug/deps/libtracing_attributes-9f400b99e42d2fe4.dylib -object target/llvm-cov-target/debug/deps/libtracing_attributes-bfc2d791dbec8257.dylib -object target/llvm-cov-target/debug/deps/obws-4b642cab3c4c801b -ignore-filename-regex '(^|/)(rustc/[0-9a-f]+|tests|examples|benches|target/llvm-cov-target)/|^/Users/dnaka91($|/)|^/Users/dnaka91/.cargo($|/)|^/Users/dnaka91/.rustup($|/)'` (exit status: 1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.