Skip to content

Commit 9d61091

Browse files
committed
Cleanup after review
1 parent 566fd49 commit 9d61091

File tree

4 files changed

+28
-27
lines changed

4 files changed

+28
-27
lines changed

crates/evm/evm/src/executors/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,7 @@ impl FuzzTestTimer {
11151115
}
11161116

11171117
/// Helper struct to enable fail fast behavior: when one test fails, all other tests stop early.
1118+
#[derive(Clone)]
11181119
pub struct FailFast {
11191120
/// Shared atomic flag set to `true` when a failure occurs.
11201121
/// None if fail-fast is disabled.

crates/forge/src/cmd/test/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ impl TestArgs {
355355
.sender(evm_opts.sender)
356356
.with_fork(evm_opts.get_fork(&config, env.clone()))
357357
.enable_isolation(evm_opts.isolate)
358+
.fail_fast(self.fail_fast)
358359
.odyssey(evm_opts.odyssey)
359360
.build::<MultiCompiler>(project_root, &output, env, evm_opts)?;
360361

@@ -509,10 +510,9 @@ impl TestArgs {
509510
let (tx, rx) = channel::<(String, SuiteResult)>();
510511
let timer = Instant::now();
511512
let show_progress = config.show_progress;
512-
let fail_fast = self.fail_fast;
513513
let handle = tokio::task::spawn_blocking({
514514
let filter = filter.clone();
515-
move || runner.test(&filter, tx, show_progress, fail_fast)
515+
move || runner.test(&filter, tx, show_progress)
516516
});
517517

518518
// Set up trace identifiers.

crates/forge/src/multi_runner.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl MultiContractRunner {
153153
filter: &dyn TestFilter,
154154
) -> Result<impl Iterator<Item = (String, SuiteResult)>> {
155155
let (tx, rx) = mpsc::channel();
156-
self.test(filter, tx, false, false)?;
156+
self.test(filter, tx, false)?;
157157
Ok(rx.into_iter())
158158
}
159159

@@ -168,7 +168,6 @@ impl MultiContractRunner {
168168
filter: &dyn TestFilter,
169169
tx: mpsc::Sender<(String, SuiteResult)>,
170170
show_progress: bool,
171-
fail_fast: bool,
172171
) -> Result<()> {
173172
let tokio_handle = tokio::runtime::Handle::current();
174173
trace!("running all tests");
@@ -186,8 +185,6 @@ impl MultiContractRunner {
186185
find_time,
187186
);
188187

189-
let fail_fast = FailFast::new(fail_fast);
190-
191188
if show_progress {
192189
let tests_progress = TestsProgress::new(contracts.len(), rayon::current_num_threads());
193190
// Collect test suite results to stream at the end of test run.
@@ -204,7 +201,6 @@ impl MultiContractRunner {
204201
filter,
205202
&tokio_handle,
206203
Some(&tests_progress),
207-
&fail_fast,
208204
);
209205

210206
tests_progress
@@ -224,16 +220,14 @@ impl MultiContractRunner {
224220
} else {
225221
contracts.par_iter().for_each(|&(id, contract)| {
226222
let _guard = tokio_handle.enter();
227-
let result =
228-
self.run_test_suite(id, contract, &db, filter, &tokio_handle, None, &fail_fast);
223+
let result = self.run_test_suite(id, contract, &db, filter, &tokio_handle, None);
229224
let _ = tx.send((id.identifier(), result));
230225
})
231226
}
232227

233228
Ok(())
234229
}
235230

236-
#[allow(clippy::too_many_arguments)]
237231
fn run_test_suite(
238232
&self,
239233
artifact_id: &ArtifactId,
@@ -242,7 +236,6 @@ impl MultiContractRunner {
242236
filter: &dyn TestFilter,
243237
tokio_handle: &tokio::runtime::Handle,
244238
progress: Option<&TestsProgress>,
245-
fail_fast: &FailFast,
246239
) -> SuiteResult {
247240
let identifier = artifact_id.identifier();
248241
let mut span_name = identifier.as_str();
@@ -266,7 +259,7 @@ impl MultiContractRunner {
266259
span,
267260
self,
268261
);
269-
let r = runner.run_tests(filter, fail_fast);
262+
let r = runner.run_tests(filter);
270263

271264
debug!(duration=?r.duration, "executed all tests in contract");
272265

@@ -303,6 +296,8 @@ pub struct TestRunnerConfig {
303296
pub isolation: bool,
304297
/// Whether to enable Odyssey features.
305298
pub odyssey: bool,
299+
/// Whether to exit early on test failure.
300+
pub fail_fast: FailFast,
306301
}
307302

308303
impl TestRunnerConfig {
@@ -411,6 +406,8 @@ pub struct MultiContractRunnerBuilder {
411406
pub isolation: bool,
412407
/// Whether to enable Odyssey features.
413408
pub odyssey: bool,
409+
/// Whether to exit early on test failure.
410+
pub fail_fast: bool,
414411
}
415412

416413
impl MultiContractRunnerBuilder {
@@ -426,6 +423,7 @@ impl MultiContractRunnerBuilder {
426423
isolation: Default::default(),
427424
decode_internal: Default::default(),
428425
odyssey: Default::default(),
426+
fail_fast: false,
429427
}
430428
}
431429

@@ -464,6 +462,11 @@ impl MultiContractRunnerBuilder {
464462
self
465463
}
466464

465+
pub fn fail_fast(mut self, fail_fast: bool) -> Self {
466+
self.fail_fast = fail_fast;
467+
self
468+
}
469+
467470
pub fn enable_isolation(mut self, enable: bool) -> Self {
468471
self.isolation = enable;
469472
self
@@ -545,15 +548,14 @@ impl MultiContractRunnerBuilder {
545548
env,
546549
spec_id: self.evm_spec.unwrap_or_else(|| self.config.evm_spec_id()),
547550
sender: self.sender.unwrap_or(self.config.sender),
548-
549551
line_coverage: self.line_coverage,
550552
debug: self.debug,
551553
decode_internal: self.decode_internal,
552554
inline_config: Arc::new(InlineConfig::new_parsed(output, &self.config)?),
553555
isolation: self.isolation,
554556
odyssey: self.odyssey,
555-
556557
config: self.config,
558+
fail_fast: FailFast::new(self.fail_fast),
557559
},
558560
})
559561
}

crates/forge/src/runner.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use foundry_evm::{
1818
constants::CALLER,
1919
decode::RevertDecoder,
2020
executors::{
21-
CallResult, EvmError, Executor, FailFast, ITest, RawCallResult,
21+
CallResult, EvmError, Executor, ITest, RawCallResult,
2222
fuzz::FuzzedExecutor,
2323
invariant::{
2424
InvariantExecutor, InvariantFuzzError, check_sequence, replay_error, replay_run,
@@ -279,7 +279,7 @@ impl<'a> ContractRunner<'a> {
279279
}
280280

281281
/// Runs all tests for a contract whose names match the provided regular expression
282-
pub fn run_tests(mut self, filter: &dyn TestFilter, fail_fast: &FailFast) -> SuiteResult {
282+
pub fn run_tests(mut self, filter: &dyn TestFilter) -> SuiteResult {
283283
let start = Instant::now();
284284
let mut warnings = Vec::new();
285285

@@ -401,6 +401,8 @@ impl<'a> ContractRunner<'a> {
401401
return SuiteResult::new(start.elapsed(), [(instances, fail)].into(), warnings);
402402
}
403403

404+
let fail_fast = &self.tcfg.fail_fast;
405+
404406
let test_results = functions
405407
.par_iter()
406408
.map(|&func| {
@@ -434,7 +436,6 @@ impl<'a> ContractRunner<'a> {
434436
kind,
435437
call_after_invariant,
436438
identified_contracts.as_ref(),
437-
fail_fast,
438439
);
439440
res.duration = start.elapsed();
440441

@@ -512,7 +513,6 @@ impl<'a> FunctionRunner<'a> {
512513
kind: TestFunctionKind,
513514
call_after_invariant: bool,
514515
identified_contracts: Option<&ContractsByAddress>,
515-
fail_fast: &FailFast,
516516
) -> TestResult {
517517
if let Err(e) = self.apply_function_inline_config(func) {
518518
self.result.single_fail(Some(e.to_string()));
@@ -521,16 +521,15 @@ impl<'a> FunctionRunner<'a> {
521521

522522
match kind {
523523
TestFunctionKind::UnitTest { .. } => self.run_unit_test(func),
524-
TestFunctionKind::FuzzTest { .. } => self.run_fuzz_test(func, fail_fast),
525-
TestFunctionKind::TableTest => self.run_table_test(func, fail_fast),
524+
TestFunctionKind::FuzzTest { .. } => self.run_fuzz_test(func),
525+
TestFunctionKind::TableTest => self.run_table_test(func),
526526
TestFunctionKind::InvariantTest => {
527527
let test_bytecode = &self.cr.contract.bytecode;
528528
self.run_invariant_test(
529529
func,
530530
call_after_invariant,
531531
identified_contracts.unwrap(),
532532
test_bytecode,
533-
fail_fast,
534533
)
535534
}
536535
_ => unreachable!(),
@@ -586,7 +585,7 @@ impl<'a> FunctionRunner<'a> {
586585
/// - `uint256[] public fixtureAmount = [2, 5]`
587586
/// - `bool[] public fixtureSwap = [true, false]` The `table_test` is then called with the pair
588587
/// of args `(2, true)` and `(5, false)`.
589-
fn run_table_test(mut self, func: &Function, fail_fast: &FailFast) -> TestResult {
588+
fn run_table_test(mut self, func: &Function) -> TestResult {
590589
// Prepare unit test execution.
591590
if self.prepare_test(func).is_err() {
592591
return self.result;
@@ -642,7 +641,7 @@ impl<'a> FunctionRunner<'a> {
642641
);
643642

644643
for i in 0..fixtures_len {
645-
if fail_fast.should_stop() {
644+
if self.tcfg.fail_fast.should_stop() {
646645
return self.result;
647646
}
648647

@@ -703,7 +702,6 @@ impl<'a> FunctionRunner<'a> {
703702
call_after_invariant: bool,
704703
identified_contracts: &ContractsByAddress,
705704
test_bytecode: &Bytes,
706-
fail_fast: &FailFast,
707705
) -> TestResult {
708706
// First, run the test normally to see if it needs to be skipped.
709707
if let Err(EvmError::Skip(reason)) = self.executor.call(
@@ -818,7 +816,7 @@ impl<'a> FunctionRunner<'a> {
818816
&self.setup.fuzz_fixtures,
819817
&self.setup.deployed_libs,
820818
progress.as_ref(),
821-
fail_fast,
819+
&self.tcfg.fail_fast,
822820
) {
823821
Ok(x) => x,
824822
Err(e) => {
@@ -929,7 +927,7 @@ impl<'a> FunctionRunner<'a> {
929927
/// (therefore the fuzz test will use the modified state).
930928
/// State modifications of before test txes and fuzz test are discarded after test ends,
931929
/// similar to `eth_call`.
932-
fn run_fuzz_test(mut self, func: &Function, fail_fast: &FailFast) -> TestResult {
930+
fn run_fuzz_test(mut self, func: &Function) -> TestResult {
933931
// Prepare fuzz test execution.
934932
if self.prepare_test(func).is_err() {
935933
return self.result;
@@ -969,7 +967,7 @@ impl<'a> FunctionRunner<'a> {
969967
self.address,
970968
&self.cr.mcr.revert_decoder,
971969
progress.as_ref(),
972-
fail_fast,
970+
&self.tcfg.fail_fast,
973971
) {
974972
Ok(x) => x,
975973
Err(e) => {

0 commit comments

Comments
 (0)