From bd9d36d80691925d241f6a170f845e41a74092c1 Mon Sep 17 00:00:00 2001 From: grandizzy Date: Fri, 19 Sep 2025 22:03:42 +0300 Subject: [PATCH] chore: add invariant output test --- crates/forge/tests/cli/test_cmd.rs | 39 ++++++++ .../forge/tests/fixtures/invariant_traces.svg | 97 +++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 crates/forge/tests/fixtures/invariant_traces.svg diff --git a/crates/forge/tests/cli/test_cmd.rs b/crates/forge/tests/cli/test_cmd.rs index eb85ad5098801..daa7b7a397d5b 100644 --- a/crates/forge/tests/cli/test_cmd.rs +++ b/crates/forge/tests/cli/test_cmd.rs @@ -4104,3 +4104,42 @@ Encountered a total of 2 failing tests, 0 tests succeeded "#]]); }); + +// +#[cfg(not(feature = "isolate-by-default"))] +forgetest_init!(invariant_consistent_output, |prj, cmd| { + prj.update_config(|config| { + config.fuzz.seed = Some(U256::from(100u32)); + config.invariant.runs = 10; + config.invariant.depth = 100; + config.invariant.show_metrics = false; + }); + prj.add_test( + "InvariantOutputTest.t.sol", + r#" +import {Test} from "forge-std/Test.sol"; + +contract InvariantOutputTest is Test { + uint256 count; + + function setCond(uint256 cond) public { + if (cond > type(uint256).max / 2) { + count++; + } + } + + function setUp() public { + targetContract(address(this)); + } + + function invariant_check_count() public view { + require(count < 2, "failed invariant"); + } +} + "#, + ); + + cmd.args(["test", "--mt", "invariant_check_count", "--color", "always"]) + .assert_failure() + .stdout_eq(file!["../fixtures/invariant_traces.svg": TermSvg]); +}); diff --git a/crates/forge/tests/fixtures/invariant_traces.svg b/crates/forge/tests/fixtures/invariant_traces.svg new file mode 100644 index 0000000000000..2e82f2ed64d30 --- /dev/null +++ b/crates/forge/tests/fixtures/invariant_traces.svg @@ -0,0 +1,97 @@ + + + + + + + [COMPILING_FILES] with [SOLC_VERSION] + + [SOLC_VERSION] [ELAPSED] + + Compiler run successful! + + + + Ran 1 test for test/InvariantOutputTest.t.sol:InvariantOutputTest + + [FAIL: failed invariant] + + [Sequence] (original: 100, shrunk: 2) + + sender=0xC5Ef3CF3d36e514Df9597Bbf8A50302cB89aC113 addr=[test/InvariantOutputTest.t.sol:InvariantOutputTest]0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496 calldata=setCond(uint256) args=[115792089237316195423570985008687907853269984665640564039457584007913129639933 [1.157e77]] + + sender=0x0000000000000000000000000000000000000164 addr=[test/InvariantOutputTest.t.sol:InvariantOutputTest]0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496 calldata=setCond(uint256) args=[61678357398080765210293718086378416697372618187842506566286863523773954249006 [6.167e76]] + + invariant_check_count() (runs: 0, calls: 0, reverts: 0) + + Traces: + + [44571] InvariantOutputTest::setUp() + + └─ ← [Stop] + + + + [22881] InvariantOutputTest::setCond(115792089237316195423570985008687907853269984665640564039457584007913129639933 [1.157e77]) + + └─ ← [Stop] + + + + [5781] InvariantOutputTest::setCond(61678357398080765210293718086378416697372618187842506566286863523773954249006 [6.167e76]) + + └─ ← [Stop] + + + + [2594] InvariantOutputTest::invariant_check_count() + + └─ ← [Revert] failed invariant + + + + Suite result: FAILED. 0 passed; 1 failed; 0 skipped; [ELAPSED] + + + + Ran 1 test suite [ELAPSED]: 0 tests passed, 1 failed, 0 skipped (1 total tests) + + + + Failing tests: + + Encountered 1 failing test in test/InvariantOutputTest.t.sol:InvariantOutputTest + + [FAIL: failed invariant] + + [Sequence] (original: 100, shrunk: 2) + + sender=0xC5Ef3CF3d36e514Df9597Bbf8A50302cB89aC113 addr=[test/InvariantOutputTest.t.sol:InvariantOutputTest]0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496 calldata=setCond(uint256) args=[115792089237316195423570985008687907853269984665640564039457584007913129639933 [1.157e77]] + + sender=0x0000000000000000000000000000000000000164 addr=[test/InvariantOutputTest.t.sol:InvariantOutputTest]0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496 calldata=setCond(uint256) args=[61678357398080765210293718086378416697372618187842506566286863523773954249006 [6.167e76]] + + invariant_check_count() (runs: 0, calls: 0, reverts: 0) + + + + Encountered a total of 1 failing tests, 0 tests succeeded + + + + + +