Open Swatinem opened 3 years ago
Here is some example code: https://github.com/Swatinem/fucov And here are some examples how I try to invoke the tools: https://github.com/Swatinem/fucov/runs/1454817756
Hi @Swatinem !
Thanks for your patience.
It would be great if you could work on this! (I will probably not be able to work on it any time soon.)
I was able to reproduce this issue as well. Your instructions above are great. Another way to see these results, using cargo commands similar to what's in the updated "Rust Unstable Book" documentation (just for comparison and context) is:
$ rm -rf target/debug/doctestbins/*
$ RUSTFLAGS="-Zinstrument-coverage" RUSTDOCFLAGS="-Zinstrument-coverage -Z unstable-options \
--persist-doctests target/debug/doctestbins" LLVM_PROFILE_FILE="json5format-%m.profraw" \
cargo test --doc
# or full coverage status after running both doc and non-doc tests:
# $ RUSTFLAGS="-Zinstrument-coverage" RUSTDOCFLAGS="-Zinstrument-coverage -Z unstable-options \
# --persist-doctests target/debug/doctestbins" LLVM_PROFILE_FILE="json5format-%m.profraw" \
# cargo test # (default: both --tests and --doc)
$ cargo profdata -- merge -sparse json5format-*.profraw -o json5format.profdata
$ cargo cov -- show --color -Xdemangler=rustfilt --instr-profile=json5format.profdata \
$(for file in target/debug/build/* target/debug/doctestbins/*/*; \
do [[ ! -d $file && -x $file ]] && echo $file; done) \
--show-line-counts-or-regions --show-instantiations | less -R
When I ran this, I saw (for example) the large test block in json5format/src/lib.rs
was apparently executed (3 times, for some reason), but the line numbers were clearly off. Since that test is near the top of the source, the line counters started just a few lines too high, for the reasons you described (I assume).
If you do work on this, I'm happy to try to help and answer questions if you have them, either via this issue (for more strategic issues in particular) or via a Zulip topic.
I don't know how rustdoc does its remapping specifically, but that sounds like a good place to start looking.
The InstrumentCoverage
MIR pass uses the Rust compiler's default session SourceMap
, via:
tcx.sess.source_map();
to get the file name, line, and column.
One nice thing about that is, I know there are ways to remap the source directly in the SourceMap
, so the coverage code doesn't even need to be aware.
I know this works for file names, at least.
If I add the following to RUSTFLAGS
and RUSTDOCFLAGS
, for example:
--remap-path-prefix=$HOME/.cargo/registry/src/github.com-1ecc6299db9ec823=/tmp/s"
the coverage map embedded in the binary will use the /tmp/s/
file prefix instead of the very long absolute path prefix I get by default for the cargo build dependency crates' sources.
Maybe there's already support for remapping line numbers. If not, that may still be the place to implement a line mapping feature.
Obviously a command line flag is not the right approach for line number mapping. You would need to derive the line number offset from the line position of each test, and you would only apply that offset to the test code, without changing the line numbers of other "real" functions in the source file. So, a bit different, but it should be possible.
Thanks for pointing me to SourceMap
.
Indeed it has a method that re-maps lines specifically for doctests:
Just for reference, this was added here: https://github.com/rust-lang/rust/pull/47274 and later passed via unstable env vars here: https://github.com/rust-lang/rust/pull/63827
I’m playing around with this a bit and it seems like I have found a way to re-map the lines, however there is still other problems related to rustdoc that I would have to fix separately.
I will test a bit more locally and then open a PR :-)
https://github.com/rust-lang/cargo/pull/8954 is a change to cargo that should make rustdoc use the correct filenames for workspace crates. I think that will solve the filename problem, although I haven’t tested that directly yet.
This Issue is partially resolved by #79762. (Thanks @Swatinem!)
There are some known issues still to resolve:
cargo
, to support #79762, included a side-effect that needs to be resolved. An issue was filed by @Swatinem, which has been discussed, and there is a proposed solution here: https://github.com/rust-lang/cargo/issues/8993#issuecomment-753001081
I have a workspace with
crate_a
(andcrate_b
, but its not used for this example), and use the following env vars set to have my rustdoc tests run through code coverage:RUSTDOCFLAGS="-Z instrument-coverage -Z unstable-options --persist-doctests=C:\Users\swatinem\AppData\Local\Temp\_rustdoc
Running the result later through
llvm-cov
gives me errors for my rustdocs, and unexpected results:When using
export -format=lcov
, I get the following:This is not really a problem per-se, but note that the filename is not relative to my workspace, but to the crate inside the workspace, which creates problems down the road, because uploading that report to
codecov
actually finds the correct file for some reason, but then highlights lines 3 and 4.So ideally, the coverage support should similarly re-map line numbers such as compile errors in doctests do, and the filename should be relative to the workspace (but that seems to be a separate issue with rustdoc I guess).
@richkadel I guess you know the code the best: Is such a re-mapping that I propose possible at all? If so, I would be happy to work on this if you point me in the right direction and would be willing to mentor me ;-)