@@ -23,7 +23,7 @@ use foundry_cli::{
2323use foundry_common:: { EmptyTestFilter , TestFunctionExt , compile:: ProjectCompiler , fs, shell} ;
2424use foundry_compilers:: {
2525 ProjectCompileOutput ,
26- artifacts:: output_selection:: OutputSelection ,
26+ artifacts:: { Libraries , output_selection:: OutputSelection } ,
2727 compilers:: {
2828 Language ,
2929 multi:: { MultiCompiler , MultiCompilerLanguage } ,
@@ -40,11 +40,15 @@ use foundry_config::{
4040} ;
4141use foundry_debugger:: Debugger ;
4242use foundry_evm:: {
43+ core:: evm:: {
44+ BlockEnvFor , EthEvmNetwork , FoundryEvmNetwork , SpecFor , TempoEvmNetwork , TxEnvFor ,
45+ } ,
4346 opts:: EvmOpts ,
4447 traces:: { backtrace:: BacktraceBuilder , identifier:: TraceIdentifiers , prune_trace_depth} ,
4548} ;
4649use rand:: Rng ;
4750use regex:: Regex ;
51+ use revm:: context:: Transaction ;
4852use std:: {
4953 collections:: { BTreeMap , BTreeSet } ,
5054 fmt:: Write ,
@@ -315,14 +319,11 @@ impl TestArgs {
315319 let should_debug = self . debug ;
316320 let should_draw = self . flamegraph || self . flamechart ;
317321
318- // Determine print verbosity and executor verbosity.
319- let verbosity = evm_opts. verbosity ;
322+ // Determine executor verbosity.
320323 if ( self . gas_report && evm_opts. verbosity < 3 ) || self . flamegraph || self . flamechart {
321324 evm_opts. verbosity = 3 ;
322325 }
323326
324- let ( evm_env, tx_env, fork_block) = evm_opts. env ( ) . await ?;
325-
326327 // Enable internal tracing for more informative flamegraph.
327328 if should_draw && !self . decode_internal {
328329 self . decode_internal = true ;
@@ -337,23 +338,30 @@ impl TestArgs {
337338 InternalTraceMode :: None
338339 } ;
339340
340- // Prepare the test builder.
341- let config = Arc :: new ( config) ;
342- let runner = MultiContractRunnerBuilder :: new ( config. clone ( ) )
343- . set_debug ( should_debug)
344- . set_decode_internal ( decode_internal)
345- . initial_balance ( evm_opts. initial_balance )
346- . evm_spec ( config. evm_spec_id ( ) )
347- . sender ( evm_opts. sender )
348- . with_fork ( evm_opts. get_fork ( & config, evm_env. cfg_env . chain_id , fork_block) )
349- . enable_isolation ( evm_opts. isolate )
350- . networks ( evm_opts. networks )
351- . fail_fast ( self . fail_fast )
352- . set_coverage ( coverage)
353- . build :: < MultiCompiler > ( output, evm_env, tx_env, evm_opts) ?;
354-
355- let libraries = runner. libraries . clone ( ) ;
356- let mut outcome = self . run_tests_inner ( runner, config, verbosity, filter, output) . await ?;
341+ // Dispatch based on network type.
342+ let ( libraries, mut outcome) = if evm_opts. networks . is_tempo ( ) {
343+ self . build_and_run_tests :: < TempoEvmNetwork > (
344+ config,
345+ evm_opts,
346+ output,
347+ filter,
348+ coverage,
349+ should_debug,
350+ decode_internal,
351+ )
352+ . await ?
353+ } else {
354+ self . build_and_run_tests :: < EthEvmNetwork > (
355+ config,
356+ evm_opts,
357+ output,
358+ filter,
359+ coverage,
360+ should_debug,
361+ decode_internal,
362+ )
363+ . await ?
364+ } ;
357365
358366 if should_draw {
359367 let ( suite_name, test_name, mut test_result) =
@@ -427,10 +435,44 @@ impl TestArgs {
427435 Ok ( outcome)
428436 }
429437
438+ /// Build the test runner and execute tests for a specific network type.
439+ #[ allow( clippy:: too_many_arguments) ]
440+ async fn build_and_run_tests < FEN : FoundryEvmNetwork > (
441+ & self ,
442+ config : Config ,
443+ evm_opts : EvmOpts ,
444+ output : & ProjectCompileOutput ,
445+ filter : & ProjectPathsAwareFilter ,
446+ coverage : bool ,
447+ should_debug : bool ,
448+ decode_internal : InternalTraceMode ,
449+ ) -> eyre:: Result < ( Libraries , TestOutcome ) > {
450+ let verbosity = evm_opts. verbosity ;
451+ let ( evm_env, tx_env, fork_block) =
452+ evm_opts. env :: < SpecFor < FEN > , BlockEnvFor < FEN > , TxEnvFor < FEN > > ( ) . await ?;
453+
454+ let config = Arc :: new ( config) ;
455+ let runner = MultiContractRunnerBuilder :: new ( config. clone ( ) )
456+ . set_debug ( should_debug)
457+ . set_decode_internal ( decode_internal)
458+ . initial_balance ( evm_opts. initial_balance )
459+ . sender ( evm_opts. sender )
460+ . with_fork ( evm_opts. get_fork ( & config, evm_env. cfg_env . chain_id , fork_block) )
461+ . enable_isolation ( evm_opts. isolate )
462+ . networks ( evm_opts. networks )
463+ . fail_fast ( self . fail_fast )
464+ . set_coverage ( coverage)
465+ . build :: < FEN , MultiCompiler > ( output, evm_env, tx_env, evm_opts) ?;
466+
467+ let libraries = runner. libraries . clone ( ) ;
468+ let outcome = self . run_tests_inner ( runner, config, verbosity, filter, output) . await ?;
469+ Ok ( ( libraries, outcome) )
470+ }
471+
430472 /// Run all tests that matches the filter predicate from a test runner
431- async fn run_tests_inner (
473+ async fn run_tests_inner < FEN : FoundryEvmNetwork > (
432474 & self ,
433- mut runner : MultiContractRunner ,
475+ mut runner : MultiContractRunner < FEN > ,
434476 config : Arc < Config > ,
435477 verbosity : u8 ,
436478 filter : & ProjectPathsAwareFilter ,
@@ -470,7 +512,7 @@ impl TestArgs {
470512 }
471513 sh_warn ! ( "{msg}" ) ?;
472514 }
473- return Ok ( TestOutcome :: empty ( Some ( runner) , false ) ) ;
515+ return Ok ( TestOutcome :: empty ( Some ( runner. known_contracts . clone ( ) ) , false ) ) ;
474516 }
475517
476518 if num_filtered != 1 && ( self . debug || self . flamegraph || self . flamechart ) {
@@ -512,17 +554,19 @@ impl TestArgs {
512554 }
513555 } ) ;
514556 sh_println ! ( "{}" , serde_json:: to_string( & results) ?) ?;
515- return Ok ( TestOutcome :: new ( Some ( runner) , results, self . allow_failure , fuzz_seed) ) ;
557+ let kc = runner. known_contracts . clone ( ) ;
558+ return Ok ( TestOutcome :: new ( Some ( kc) , results, self . allow_failure , fuzz_seed) ) ;
516559 }
517560
518561 if self . junit {
519562 let results = runner. test_collect ( filter) ?;
520563 sh_println ! ( "{}" , junit_xml_report( & results, verbosity) . to_string( ) ?) ?;
521- return Ok ( TestOutcome :: new ( Some ( runner) , results, self . allow_failure , fuzz_seed) ) ;
564+ let kc = runner. known_contracts . clone ( ) ;
565+ return Ok ( TestOutcome :: new ( Some ( kc) , results, self . allow_failure , fuzz_seed) ) ;
522566 }
523567
524568 let remote_chain =
525- if runner. fork . is_some ( ) { runner. tx_env . chain_id . map ( Into :: into) } else { None } ;
569+ if runner. fork . is_some ( ) { runner. tx_env . chain_id ( ) . map ( Into :: into) } else { None } ;
526570 let known_contracts = runner. known_contracts . clone ( ) ;
527571
528572 let libraries = runner. libraries . clone ( ) ;
@@ -865,7 +909,10 @@ impl TestArgs {
865909
866910 // Reattach the task.
867911 match handle. await {
868- Ok ( result) => outcome. runner = Some ( result?) ,
912+ Ok ( result) => {
913+ let runner = result?;
914+ outcome. known_contracts = Some ( runner. known_contracts ) ;
915+ }
869916 Err ( e) => match e. try_into_panic ( ) {
870917 Ok ( payload) => std:: panic:: resume_unwind ( payload) ,
871918 Err ( e) => return Err ( e. into ( ) ) ,
@@ -947,7 +994,10 @@ impl Provider for TestArgs {
947994}
948995
949996/// Lists all matching tests
950- fn list ( runner : MultiContractRunner , filter : & ProjectPathsAwareFilter ) -> Result < TestOutcome > {
997+ fn list < FEN : FoundryEvmNetwork > (
998+ runner : MultiContractRunner < FEN > ,
999+ filter : & ProjectPathsAwareFilter ,
1000+ ) -> Result < TestOutcome > {
9511001 let results = runner. list ( filter) ;
9521002
9531003 if shell:: is_json ( ) {
@@ -961,7 +1011,7 @@ fn list(runner: MultiContractRunner, filter: &ProjectPathsAwareFilter) -> Result
9611011 }
9621012 }
9631013 }
964- Ok ( TestOutcome :: empty ( Some ( runner) , false ) )
1014+ Ok ( TestOutcome :: empty ( Some ( runner. known_contracts ) , false ) )
9651015}
9661016
9671017/// Load persisted filter (with last test run failures) from file.
0 commit comments