Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions crates/forge-runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use foundry_ui::UI;
use foundry_ui::components::warning::WarningMessage;
use futures::StreamExt;
use futures::stream::FuturesUnordered;
use package_tests::with_config_resolved::TestCaseWithResolvedConfig;
use profiler_api::run_profiler;
use rand::SeedableRng;
use rand::prelude::StdRng;
Expand Down Expand Up @@ -58,9 +57,9 @@ const BUILTINS: [&str; 11] = [
];

pub trait TestCaseFilter {
fn should_be_run<T>(&self, test_case: &TestCase<T>) -> bool
where
T: TestCaseIsIgnored;
fn should_be_run(&self, test_case: &TestCase) -> bool;

fn should_run_test(&self, test_case_config: bool) -> bool;
}

pub trait TestCaseIsIgnored {
Expand Down Expand Up @@ -113,7 +112,7 @@ pub fn maybe_generate_coverage(
#[must_use]
#[tracing::instrument(skip_all, level = "debug")]
pub fn run_for_test_case(
case: Arc<TestCaseWithResolvedConfig>,
case: Arc<TestCase>,
casm_program: Arc<RawCasmProgram>,
forge_config: Arc<ForgeConfig>,
versioned_program_path: Arc<Utf8PathBuf>,
Expand Down Expand Up @@ -148,7 +147,7 @@ pub fn run_for_test_case(

#[tracing::instrument(skip_all, level = "debug")]
fn run_with_fuzzing(
case: Arc<TestCaseWithResolvedConfig>,
case: Arc<TestCase>,
casm_program: Arc<RawCasmProgram>,
forge_config: Arc<ForgeConfig>,
versioned_program_path: Arc<Utf8PathBuf>,
Expand Down
115 changes: 108 additions & 7 deletions crates/forge-runner/src/package_tests.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
use crate::package_tests::raw::TestTargetRaw;
use crate::package_tests::with_config_resolved::TestCaseResolvedConfig;
use crate::running::hints_to_params;
use anyhow::Result;
use anyhow::{Result, anyhow};
use cairo_lang_sierra::extensions::NamedType;
use cairo_lang_sierra::extensions::bitwise::BitwiseType;
use cairo_lang_sierra::extensions::circuit::{AddModType, MulModType};
use cairo_lang_sierra::extensions::core::{CoreLibfunc, CoreType};
use cairo_lang_sierra::extensions::ec::EcOpType;
use cairo_lang_sierra::extensions::pedersen::PedersenType;
use cairo_lang_sierra::extensions::poseidon::PoseidonType;
use cairo_lang_sierra::extensions::range_check::{RangeCheck96Type, RangeCheckType};
use cairo_lang_sierra::extensions::segment_arena::SegmentArenaType;
use cairo_lang_sierra::ids::GenericTypeId;
use cairo_lang_sierra::program::ProgramArtifact;
use cairo_lang_sierra::ids::{ConcreteTypeId, GenericTypeId};
use cairo_lang_sierra::program::{GenFunction, ProgramArtifact, StatementIdx, TypeDeclaration};
use cairo_lang_sierra::program_registry::ProgramRegistry;
use cairo_lang_sierra_type_size::get_type_size_map;
use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
use cairo_vm::serde::deserialize_program::ReferenceManager;
use cairo_vm::types::builtin_name::BuiltinName;
use cairo_vm::types::program::Program;
use cairo_vm::types::relocatable::MaybeRelocatable;
use camino::Utf8PathBuf;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use serde::Serialize;
use starknet_types_core::felt::Felt;
use std::collections::HashMap;
Expand Down Expand Up @@ -66,6 +73,30 @@ impl TestDetails {
builtins
}

#[tracing::instrument(skip_all, level = "debug")]
fn build(
func: &GenFunction<StatementIdx>,
type_declarations: &HashMap<u64, &TypeDeclaration>,
type_size_map: &UnorderedHashMap<ConcreteTypeId, i16>,
) -> Self {
let map_types = |concrete_types: &[ConcreteTypeId]| {
concrete_types
.iter()
.map(|ty| {
let ty = type_declarations[&ty.id];

(ty.long_id.generic_id.clone(), type_size_map[&ty.id])
})
.collect()
};

Self {
sierra_entry_point_statement_idx: func.entry_point.0,
parameter_types: map_types(&func.signature.param_types),
return_types: map_types(&func.signature.ret_types),
}
}

pub fn try_into_program(&self, casm_program: &RawCasmProgram) -> Result<Program> {
let builtins = self.builtins();

Expand Down Expand Up @@ -95,17 +126,87 @@ impl TestDetails {
}

#[derive(Debug, Clone)]
pub struct TestTarget<C> {
pub struct TestTarget {
pub tests_location: TestTargetLocation,
pub sierra_program: ProgramArtifact,
pub sierra_program_path: Arc<Utf8PathBuf>,
pub test_cases: Vec<TestCandidate>,
}

impl TestTarget {
#[tracing::instrument(skip_all, level = "debug")]
pub fn from_raw(test_target_raw: TestTargetRaw) -> Result<TestTarget> {
macro_rules! by_id {
($field:ident) => {{
let temp: HashMap<_, _> = test_target_raw
.sierra_program
.program
.$field
.iter()
.map(|f| (f.id.id, f))
.collect();

temp
}};
}
let funcs = by_id!(funcs);
let type_declarations = by_id!(type_declarations);

let sierra_program_registry =
ProgramRegistry::<CoreType, CoreLibfunc>::new(&test_target_raw.sierra_program.program)?;
let type_size_map = get_type_size_map(
&test_target_raw.sierra_program.program,
&sierra_program_registry,
)
.ok_or_else(|| anyhow!("can not get type size map"))?;

let default_executables = vec![];
let debug_info = test_target_raw.sierra_program.debug_info.clone();
let executables = debug_info
.as_ref()
.and_then(|info| info.executables.get("snforge_internal_test_executable"))
.unwrap_or(&default_executables);

let test_cases = executables
.par_iter()
.map(|case| -> Result<TestCandidate> {
let func = funcs[&case.id];
let test_details = TestDetails::build(func, &type_declarations, &type_size_map);

Ok(TestCandidate {
name: case.debug_name.clone().unwrap().into(),
test_details,
})
})
.collect::<Result<_>>()?;

Ok(TestTarget {
tests_location: test_target_raw.tests_location,
test_cases,
sierra_program: test_target_raw.sierra_program,
sierra_program_path: test_target_raw.sierra_program_path.into(),
})
}
}

#[derive(Debug, Clone)]
pub struct TestTargetResolved {
pub tests_location: TestTargetLocation,
pub sierra_program: ProgramArtifact,
pub sierra_program_path: Arc<Utf8PathBuf>,
pub casm_program: Arc<RawCasmProgram>,
pub test_cases: Vec<TestCase<C>>,
pub test_cases: Vec<TestCase>,
}

#[derive(Debug, Clone, PartialEq)]
pub struct TestCase<C> {
pub struct TestCandidate {
pub name: String,
pub test_details: TestDetails,
}

#[derive(Debug, Clone, PartialEq)]
pub struct TestCase {
pub name: String,
pub config: C,
pub test_details: TestDetails,
pub config: TestCaseResolvedConfig,
}
22 changes: 1 addition & 21 deletions crates/forge-runner/src/package_tests/with_config.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
use super::{TestCase, TestTarget};
use crate::{
TestCaseIsIgnored,
expected_result::{ExpectedPanicValue, ExpectedTestResult},
};
use cheatnet::runtime_extensions::forge_config_extension::config::{
Expected, RawAvailableResourceBoundsConfig, RawForgeConfig, RawForkConfig, RawFuzzerConfig,
Expected, RawAvailableResourceBoundsConfig, RawForkConfig, RawFuzzerConfig,
RawShouldPanicConfig,
};
use conversions::serde::serialize::SerializeToFeltVec;

pub type TestTargetWithConfig = TestTarget<TestCaseConfig>;

pub type TestCaseWithConfig = TestCase<TestCaseConfig>;

/// Test case with config that has not yet been resolved
/// see [`super::with_config_resolved::TestCaseResolvedConfig`] for more info
#[derive(Debug, Clone)]
Expand All @@ -31,21 +26,6 @@ impl TestCaseIsIgnored for TestCaseConfig {
}
}

impl From<RawForgeConfig> for TestCaseConfig {
fn from(value: RawForgeConfig) -> Self {
Self {
available_gas: value.available_gas,
ignored: value.ignore.is_some_and(|v| v.is_ignored),
expected_result: value.should_panic.into(),
fork_config: value.fork,
fuzzer_config: value.fuzzer,
disable_predeployed_contracts: value
.disable_predeployed_contracts
.is_some_and(|v| v.is_disabled),
}
}
}

impl From<Option<RawShouldPanicConfig>> for ExpectedTestResult {
fn from(value: Option<RawShouldPanicConfig>) -> Self {
match value {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{TestCase, TestTarget};
use super::TestCase;
use crate::{TestCaseIsIgnored, expected_result::ExpectedTestResult, package_tests::TestDetails};
use anyhow::Result;
use cairo_vm::types::program::Program;
Expand All @@ -9,17 +9,13 @@ use starknet_api::block::BlockNumber;
use universal_sierra_compiler_api::representation::RawCasmProgram;
use url::Url;

pub type TestTargetWithResolvedConfig = TestTarget<TestCaseResolvedConfig>;

pub type TestCaseWithResolvedConfig = TestCase<TestCaseResolvedConfig>;

fn sanitize_test_case_name(name: &str) -> String {
// Test names generated by `#[test]` and `#[fuzzer]` macros contain internal suffixes
name.replace("__snforge_internal_test_generated", "")
.replace("__snforge_internal_fuzzer_generated", "")
}

impl TestCaseWithResolvedConfig {
impl TestCase {
#[must_use]
pub fn new(name: &str, test_details: TestDetails, config: TestCaseResolvedConfig) -> Self {
Self {
Expand Down
11 changes: 6 additions & 5 deletions crates/forge-runner/src/running.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::backtrace::add_backtrace_footer;
use crate::forge_config::{ForgeConfig, RuntimeConfig};
use crate::gas::calculate_used_gas;
use crate::package_tests::with_config_resolved::{ResolvedForkConfig, TestCaseWithResolvedConfig};
use crate::package_tests::TestCase;
use crate::package_tests::with_config_resolved::ResolvedForkConfig;
use crate::test_case_summary::{Single, TestCaseSummary};
use anyhow::{Result, bail};
use blockifier::execution::call_info::CallInfo;
Expand Down Expand Up @@ -62,7 +63,7 @@ pub use syscall_handler::syscall_handler_offset;
#[must_use]
#[tracing::instrument(skip_all, level = "debug")]
pub fn run_test(
case: Arc<TestCaseWithResolvedConfig>,
case: Arc<TestCase>,
casm_program: Arc<RawCasmProgram>,
forge_config: Arc<ForgeConfig>,
versioned_program_path: Arc<Utf8PathBuf>,
Expand Down Expand Up @@ -98,7 +99,7 @@ pub fn run_test(
#[tracing::instrument(skip_all, level = "debug")]
#[allow(clippy::too_many_arguments)]
pub(crate) fn run_fuzz_test(
case: Arc<TestCaseWithResolvedConfig>,
case: Arc<TestCase>,
program: Program,
casm_program: Arc<RawCasmProgram>,
forge_config: Arc<ForgeConfig>,
Expand Down Expand Up @@ -165,7 +166,7 @@ pub enum RunResult {
#[expect(clippy::too_many_lines)]
#[tracing::instrument(skip_all, level = "debug")]
pub fn run_test_case(
case: &TestCaseWithResolvedConfig,
case: &TestCase,
program: &Program,
casm_program: &RawCasmProgram,
runtime_config: &RuntimeConfig,
Expand Down Expand Up @@ -395,7 +396,7 @@ pub fn run_test_case(

fn extract_test_case_summary(
run_result: Result<RunResult>,
case: &TestCaseWithResolvedConfig,
case: &TestCase,
forge_config: &ForgeConfig,
versioned_program_path: &Utf8Path,
) -> TestCaseSummary<Single> {
Expand Down
Loading
Loading