diff --git a/crates/evm/evm/src/executors/fuzz/mod.rs b/crates/evm/evm/src/executors/fuzz/mod.rs index dfe969ea2c193..435bdcba1ace7 100644 --- a/crates/evm/evm/src/executors/fuzz/mod.rs +++ b/crates/evm/evm/src/executors/fuzz/mod.rs @@ -46,7 +46,8 @@ struct FuzzTestData { breakpoints: Option, // Stores coverage information for all fuzz cases. coverage: Option, - // Stores logs for all fuzz cases + // Stores logs for all fuzz cases (when show_logs is true) or just the last run (when show_logs + // is false) logs: Vec, // Deprecated cheatcodes mapped to their replacements. deprecated_cheatcodes: HashMap<&'static str, Option<&'static str>>, @@ -198,8 +199,13 @@ impl FuzzedExecutor { test_data.breakpoints.replace(case.breakpoints); } + // Always store logs from the last run in test_data.logs for display at + // verbosity >= 2. When show_logs is true, + // accumulate all logs. When false, only keep the last run's logs. if self.config.show_logs { test_data.logs.extend(case.logs); + } else { + test_data.logs = case.logs; } HitMaps::merge_opt(&mut test_data.coverage, case.coverage); @@ -255,6 +261,12 @@ impl FuzzedExecutor { (call.traces.clone(), call.cheatcodes.map(|c| c.breakpoints)) }; + // test_data.logs already contains the appropriate logs: + // - For failed tests: logs from the counterexample + // - For successful tests with show_logs=true: all logs from all runs + // - For successful tests with show_logs=false: logs from the last run only + let result_logs = test_data.logs; + let mut result = FuzzTestResult { first_case: test_data.first_case.unwrap_or_default(), gas_by_case: test_data.gas_by_case, @@ -262,7 +274,7 @@ impl FuzzedExecutor { skipped: false, reason: None, counterexample: None, - logs: test_data.logs, + logs: result_logs, labels: call.labels, traces: last_run_traces, breakpoints: last_run_breakpoints, diff --git a/crates/forge/tests/cli/test_cmd/mod.rs b/crates/forge/tests/cli/test_cmd/mod.rs index bd2360e5434e6..af30d70b90b01 100644 --- a/crates/forge/tests/cli/test_cmd/mod.rs +++ b/crates/forge/tests/cli/test_cmd/mod.rs @@ -1126,8 +1126,8 @@ Ran 1 test suite [ELAPSED]: 1 tests passed, 0 failed, 0 skipped (1 total tests) "#]]); }); -// tests that `forge test` with config `show_logs: false` for fuzz tests will not display -// `console.log` info +// tests that `forge test` with config `show_logs: false` for fuzz tests will +// still display `console.log` from the last run at verbosity >= 2 (issue #11039) forgetest_init!(should_not_show_logs_when_fuzz_test, |prj, cmd| { // run fuzz test 3 times prj.update_config(|config| { @@ -1149,6 +1149,7 @@ forgetest_init!(should_not_show_logs_when_fuzz_test, |prj, cmd| { } "#, ); + // At verbosity >= 2, logs from the last run should be shown even when show_logs is false cmd.args(["test", "-vv"]).assert_success().stdout_eq(str![[r#" [COMPILING_FILES] with [SOLC_VERSION] [SOLC_VERSION] [ELAPSED] @@ -1156,6 +1157,9 @@ Compiler run successful! Ran 1 test for test/ContractFuzz.t.sol:ContractFuzz [PASS] testFuzzConsoleLog(uint256) (runs: 3, [AVG_GAS]) +Logs: + inside fuzz test, x is: [..] + Suite result: ok. 1 passed; 0 failed; 0 skipped; [ELAPSED] Ran 1 test suite [ELAPSED]: 1 tests passed, 0 failed, 0 skipped (1 total tests) @@ -1163,8 +1167,8 @@ Ran 1 test suite [ELAPSED]: 1 tests passed, 0 failed, 0 skipped (1 total tests) "#]]); }); -// tests that `forge test` with inline config `show_logs = false` for fuzz tests will not -// display `console.log` info +// tests that `forge test` with inline config `show_logs = false` for fuzz tests will +// still display `console.log` from the last run at verbosity >= 2 (issue #11039) forgetest_init!(should_not_show_logs_when_fuzz_test_inline_config, |prj, cmd| { // run fuzz test 3 times prj.update_config(|config| { @@ -1186,6 +1190,7 @@ contract ContractFuzz is Test { } "#, ); + // At verbosity >= 2, logs from the last run should be shown even when show_logs is false cmd.args(["test", "-vv"]).assert_success().stdout_eq(str![[r#" [COMPILING_FILES] with [SOLC_VERSION] [SOLC_VERSION] [ELAPSED] @@ -1193,6 +1198,9 @@ Compiler run successful! Ran 1 test for test/ContractFuzz.t.sol:ContractFuzz [PASS] testFuzzConsoleLog(uint256) (runs: 3, [AVG_GAS]) +Logs: + inside fuzz test, x is: [..] + Suite result: ok. 1 passed; 0 failed; 0 skipped; [ELAPSED] Ran 1 test suite [ELAPSED]: 1 tests passed, 0 failed, 0 skipped (1 total tests)