Skip to content

Commit

Permalink
Filter out functions marked with #[test] attribute
Browse files Browse the repository at this point in the history
commit-id:183608fa
  • Loading branch information
ksew1 committed Sep 2, 2024
1 parent 3177d06 commit 6bbd6a3
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 32 deletions.
17 changes: 12 additions & 5 deletions crates/cairo-coverage/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ use anyhow::{ensure, Result};
use camino::Utf8PathBuf;
use clap::Parser;

pub const DEFAULT_OUTPUT_NAME: &str = "coverage";

#[derive(Parser, Debug)]
#[command(version)]
pub struct Cli {
/// Paths to the .json files with trace data.
#[arg(value_parser = parse_trace_file, num_args = 1.., required = true)]
pub trace_files: Vec<Utf8PathBuf>,

/// Path to the output file. [default: `coverage.lcov`]
#[arg(short, long)]
pub output_path: Option<Utf8PathBuf>,
/// Path to the output file.
#[arg(short, long, default_value = "coverage.lcov")]
pub output_path: Utf8PathBuf,

/// Run coverage on functions marked with `#[test]` attribute.
///
/// [default: false]
///
/// Note: We currently recommend setting this to false as there
/// might be issues with mappings for `#[test]` attribute.
#[arg(long, default_value_t = false)]
pub include_test_functions: bool,
}

fn parse_trace_file(path: &str) -> Result<Utf8PathBuf> {
Expand Down
24 changes: 16 additions & 8 deletions crates/cairo-coverage/src/input/data.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::input::test_function_filter::TestFunctionFilter;
use crate::input::{create_sierra_to_cairo_map, SierraToCairoMap, UniqueExecutedSierraIds};
use anyhow::{Context, Result};
use cairo_lang_sierra::program::{Program, ProgramArtifact, VersionedProgram};
Expand All @@ -8,15 +9,15 @@ use serde::de::DeserializeOwned;
use std::fs;
use trace_data::CallTrace;

const SNFORGE_TEST_EXECUTABLE: &str = "snforge_internal_test_executable";

pub struct InputData {
pub unique_executed_sierra_ids: UniqueExecutedSierraIds,
pub sierra_to_cairo_map: SierraToCairoMap,
}

impl TryFrom<&Utf8PathBuf> for InputData {
type Error = anyhow::Error;

fn try_from(call_trace_path: &Utf8PathBuf) -> Result<Self, Self::Error> {
impl InputData {
pub fn new(call_trace_path: &Utf8PathBuf, include_test_functions: bool) -> Result<Self> {
let call_trace: CallTrace = read_and_deserialize(call_trace_path)?;

let source_sierra_path = &call_trace
Expand All @@ -34,11 +35,18 @@ impl TryFrom<&Utf8PathBuf> for InputData {
..
} = read_and_deserialize(source_sierra_path)?;

let annotations = debug_info
.context(format!("Debug info not found in: {source_sierra_path}"))?
.annotations;
let debug_info =
debug_info.context(format!("Debug info not found in: {source_sierra_path}"))?;

let test_function_filter = TestFunctionFilter::new(
debug_info
.executables
.get(SNFORGE_TEST_EXECUTABLE)
.unwrap_or(&Vec::new()),
include_test_functions,
);

let sierra_to_cairo_map = create_sierra_to_cairo_map(&annotations)?;
let sierra_to_cairo_map = create_sierra_to_cairo_map(&debug_info, &test_function_filter)?;
let casm = compile_to_casm(&program)?;
let unique_executed_sierra_ids =
UniqueExecutedSierraIds::new(&casm, &call_trace, &sierra_to_cairo_map)?;
Expand Down
1 change: 1 addition & 0 deletions crates/cairo-coverage/src/input/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod data;
mod data_loader;
mod sierra_to_cairo_map;
mod test_function_filter;
mod unique_executed_sierra_ids;

pub use data::InputData;
Expand Down
15 changes: 11 additions & 4 deletions crates/cairo-coverage/src/input/sierra_to_cairo_map.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::input::data_loader::types::{
CodeLocation, CoverageAnnotations, LineRange, ProfilerAnnotations,
};
use crate::input::test_function_filter::TestFunctionFilter;
use crate::types::{FileLocation, FunctionName};
use anyhow::{Context, Result};
use cairo_lang_sierra::debug_info::Annotations;
use cairo_lang_sierra::debug_info::{Annotations, DebugInfo};
use cairo_lang_sierra::program::StatementIdx;
use derived_deref::Deref;
use regex::Regex;
Expand All @@ -23,14 +24,17 @@ pub struct StatementOrigin {
pub line_range: LineRange,
}

pub fn create_sierra_to_cairo_map(annotations: &Annotations) -> Result<SierraToCairoMap> {
pub fn create_sierra_to_cairo_map(
debug_info: &DebugInfo,
test_function_filter: &TestFunctionFilter,
) -> Result<SierraToCairoMap> {
let CoverageAnnotations {
statements_code_locations,
} = CoverageAnnotations::get_namespace(annotations)?;
} = CoverageAnnotations::get_namespace(&debug_info.annotations)?;

let ProfilerAnnotations {
statements_functions,
} = ProfilerAnnotations::get_namespace(annotations)?;
} = ProfilerAnnotations::get_namespace(&debug_info.annotations)?;

Ok(SierraToCairoMap(
statements_code_locations
Expand All @@ -41,6 +45,9 @@ pub fn create_sierra_to_cairo_map(annotations: &Annotations) -> Result<SierraToC
.and_then(|function_names| {
find_statement_origin(&code_locations, function_names)
})
.filter(|statement_origin| {
test_function_filter.should_include(&statement_origin.function_name)
})
.map(|statement_origin| (key, statement_origin))
})
.collect(),
Expand Down
27 changes: 27 additions & 0 deletions crates/cairo-coverage/src/input/test_function_filter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::types::FunctionName;
use cairo_lang_sierra::ids::FunctionId;
use std::collections::HashSet;

pub struct TestFunctionFilter {
include_test_functions: bool,
test_functions: HashSet<String>,
}

impl TestFunctionFilter {
pub fn new(
functions_marked_with_test_attribute: &[FunctionId],
include_test_functions: bool,
) -> Self {
Self {
include_test_functions,
test_functions: functions_marked_with_test_attribute
.iter()
.map(ToString::to_string)
.collect(),
}
}

pub fn should_include(&self, function_name: &FunctionName) -> bool {
self.include_test_functions || !self.test_functions.contains(function_name)
}
}
9 changes: 3 additions & 6 deletions crates/cairo-coverage/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ mod input;
mod output;
mod types;

use crate::cli::DEFAULT_OUTPUT_NAME;
use crate::coverage_data::create_files_coverage_data_with_hits;
use crate::input::InputData;
use crate::output::lcov::LcovFormat;
Expand All @@ -17,18 +16,16 @@ use std::io::Write;
fn main() -> Result<()> {
let cli = Cli::parse();

let output_path = cli
.output_path
.unwrap_or_else(|| format!("./{DEFAULT_OUTPUT_NAME}.lcov").into());
let output_path = &cli.output_path;

let mut file = OpenOptions::new()
.append(true)
.create(true)
.open(&output_path)
.open(output_path)
.context(format!("Failed to open output file at path: {output_path}"))?;

for trace_file in &cli.trace_files {
let input_data = InputData::try_from(trace_file)?;
let input_data = InputData::new(trace_file, cli.include_test_functions)?;
let coverage_data = create_files_coverage_data_with_hits(&input_data);
let output_data = LcovFormat::from(coverage_data);

Expand Down
42 changes: 33 additions & 9 deletions crates/cairo-coverage/tests/e2e.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
mod helpers;

use crate::helpers::run_test_project;
use crate::helpers::{run_test_project, run_test_project_with_args};
use indoc::indoc;
use snapbox::cmd::{cargo_bin, Command as SnapboxCommand};
use std::env;

#[test]
fn simple() {
let output = run_test_project("simple").unwrap();
assert_eq!(
output,
indoc! {
"
TN:
SF:tests/data/simple/src/lib.cairo
FN:7,8,simple::increase_by_one
FNDA:4,simple::increase_by_one
FN:2,3,simple::increase_by_two
FNDA:3,simple::increase_by_two
FNF:2
FNH:2
DA:2,1
DA:3,3
DA:7,2
DA:8,4
LF:4
LH:4
end_of_record
"
}
);
}

#[test]
fn simple_with_tests() {
let output = run_test_project_with_args("simple", &["--include-test-functions"]).unwrap();
assert_eq!(
output,
indoc! {
Expand Down Expand Up @@ -53,25 +80,22 @@ fn scarb_template() {
SF:tests/data/scarb_template/src/lib.cairo
FN:5,11,scarb_template::fib
FNDA:34,scarb_template::fib
FN:20,20,scarb_template::tests::it_works
FNDA:3,scarb_template::tests::it_works
FNF:2
FNH:2
FNF:1
FNH:1
DA:5,1
DA:8,34
DA:9,32
DA:11,32
DA:20,3
LF:5
LH:5
LF:4
LH:4
end_of_record
"
}
);
}

#[test]
#[ignore] // TODO: Fix in #26
#[ignore] // Output to big fix in next test
fn complex_calculator() {
let output = run_test_project("complex_calculator").unwrap();
assert_eq!(
Expand Down
6 changes: 6 additions & 0 deletions crates/cairo-coverage/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use std::{env, fs};

#[allow(clippy::missing_errors_doc)]
pub fn run_test_project(test_project_name: &str) -> Result<String> {
run_test_project_with_args(test_project_name, &[])
}

#[allow(clippy::missing_errors_doc)]
pub fn run_test_project_with_args(test_project_name: &str, args: &[&str]) -> Result<String> {
let temp_dir = TempDir::new().context("Failed to create a temporary directory")?;
temp_dir
.copy_from(
Expand All @@ -29,6 +34,7 @@ pub fn run_test_project(test_project_name: &str) -> Result<String> {
SnapboxCommand::new(cargo_bin!("cairo-coverage")),
Command::arg,
)
.args(args)
.current_dir(&temp_dir)
.assert()
.success();
Expand Down

0 comments on commit 6bbd6a3

Please sign in to comment.