Skip to content

Commit

Permalink
Add option for generating coverage reports
Browse files Browse the repository at this point in the history
Add a `--coverage` option in the `test` subcommand of the miri script.
This option, when set, will generate a coverage report after running the
tests.

`cargo-binutils` is needed as a dependency to generate the reports.
  • Loading branch information
Mandragorian committed Oct 9, 2024
1 parent 9045930 commit 5b1666a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
42 changes: 40 additions & 2 deletions miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl Command {
Command::Install { flags } => Self::install(flags),
Command::Build { flags } => Self::build(flags),
Command::Check { flags } => Self::check(flags),
Command::Test { bless, flags, target } => Self::test(bless, flags, target),
Command::Test { bless, flags, target, coverage } => Self::test(bless, flags, target, coverage),
Command::Run { dep, verbose, many_seeds, target, edition, flags } =>
Self::run(dep, verbose, many_seeds, target, edition, flags),
Command::Doc { flags } => Self::doc(flags),
Expand Down Expand Up @@ -458,7 +458,7 @@ impl Command {
Ok(())
}

fn test(bless: bool, mut flags: Vec<String>, target: Option<String>) -> Result<()> {
fn test(bless: bool, mut flags: Vec<String>, target: Option<String>, coverage: bool) -> Result<()> {
let mut e = MiriEnv::new()?;

// Prepare a sysroot. (Also builds cargo-miri, which we need.)
Expand All @@ -468,6 +468,9 @@ impl Command {
if bless {
e.sh.set_var("RUSTC_BLESS", "Gesundheit");
}
if coverage {
e.sh.set_var("RUSTFLAGS", "-C instrument-coverage");
}
if let Some(target) = target {
// Tell the harness which target to test.
e.sh.set_var("MIRI_TEST_TARGET", target);
Expand All @@ -479,6 +482,41 @@ impl Command {
// Then test, and let caller control flags.
// Only in root project as `cargo-miri` has no tests.
e.test(".", &flags)?;

if coverage {
Self::show_coverage_report(&e)?;
}
Ok(())
}

fn show_coverage_report(e: &MiriEnv) -> Result<()> {
let profraw_files: Vec<_> = std::fs::read_dir(".")?
.filter_map(|r| r.ok())
.map(|e| e.path())
.filter(|p| p.extension().map(|e| e == "profraw").unwrap_or(false))
.map(|p| p.as_os_str().to_os_string())
.collect();

// Merge the profraw files
let profraw_files_cloned= profraw_files.iter();
cmd!(
e.sh,
"cargo-profdata -- merge -sparse {profraw_files_cloned...} -o merged.profdata"
).quiet().run()?;

// Create the coverage report.
let home = std::env::var("HOME")?;
let ignored = format!("{home}/*|miri/target/*|target/debug/*|rust/deps/*");
cmd!(
e.sh,
"cargo-cov -- report --instr-profile=merged.profdata --object target/debug/miri -ignore-filename-regex={ignored}"
).run()?;

// Delete artifacts.
cmd!(
e.sh,
"rm {profraw_files...} merged.profdata"
).quiet().run()?;
Ok(())
}

Expand Down
7 changes: 6 additions & 1 deletion miri-script/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub enum Command {
/// The cross-interpretation target.
/// If none then the host is the target.
target: Option<String>,
/// Produce coverage report if set.
coverage: bool,
/// Flags that are passed through to the test harness.
flags: Vec<String>,
},
Expand Down Expand Up @@ -158,9 +160,12 @@ fn main() -> Result<()> {
let mut target = None;
let mut bless = false;
let mut flags = Vec::new();
let mut coverage = false;
loop {
if args.get_long_flag("bless")? {
bless = true;
} else if args.get_long_flag("coverage")? {
coverage = true;
} else if let Some(val) = args.get_long_opt("target")? {
target = Some(val);
} else if let Some(flag) = args.get_other() {
Expand All @@ -169,7 +174,7 @@ fn main() -> Result<()> {
break;
}
}
Command::Test { bless, flags, target }
Command::Test { bless, flags, target, coverage }
}
Some("run") => {
let mut dep = false;
Expand Down

0 comments on commit 5b1666a

Please sign in to comment.