diff --git a/crates/runner/src/lib.rs b/crates/runner/src/lib.rs index b992145..6aae33b 100644 --- a/crates/runner/src/lib.rs +++ b/crates/runner/src/lib.rs @@ -127,7 +127,7 @@ impl ExtBuilder { } } -/// Expectation for a call +/// Expectation for a call. This struct is initialized by the user and compared to the actual call result. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct VerifyCallExpectation { /// When provided, the expected gas consumed @@ -135,7 +135,7 @@ pub struct VerifyCallExpectation { /// When provided, the expected output #[serde(default, with = "hex")] pub output: OptionalHex>, - ///Expected call result + /// Expected call result pub success: bool, } @@ -190,6 +190,7 @@ impl Default for VerifyCallExpectation { impl VerifyCallExpectation { /// Verify that the expectations are met fn verify(self, result: &CallResult) { + // Check if the call was successful. Here `self.success` is an expectation given by the user and `result` is the actual call result. assert_eq!( self.success, !result.did_revert(), diff --git a/crates/runner/src/main.rs b/crates/runner/src/main.rs index b48c71e..45daa60 100644 --- a/crates/runner/src/main.rs +++ b/crates/runner/src/main.rs @@ -1,8 +1,20 @@ +use std::collections::HashSet; use std::path::PathBuf; use clap::Parser; -use revive_runner::{Code, OptionalHex, Specs, SpecsAction::*, TestAddress}; +use revive_runner::{Code, OptionalHex, Specs, SpecsAction::*, TestAddress, VerifyCallExpectation}; + +/// The action which is expected to fail. +/// +/// If neither is provided (default), instantiation and call are both expected to succeed. +#[derive(clap::ValueEnum, Clone, PartialEq, Hash, Eq)] +enum VerifyActionFailure { + /// The contract instantiation must fail + Instantiate, + /// The contract execution must fail + Call, +} /// Execute revive PolkaVM contracts locally. #[derive(Parser)] @@ -35,6 +47,14 @@ struct Arguments { /// The value the deploy transaction is endowed with. #[arg(long)] deploy_value: Option, + + /// The expected call result of the contract execution. + #[arg(long, value_delimiter=',', num_args=1..2)] + verify_failure: Vec, + + /// The expected amount of consumed gas by the contract execution. + #[arg(long)] + verify_call_gas_consumed: Option, } fn main() -> anyhow::Result<()> { @@ -62,6 +82,8 @@ fn main() -> anyhow::Result<()> { }; let origin = arguments.origin.unwrap_or(TestAddress::Alice); + let verify_failure: HashSet = HashSet::from_iter(arguments.verify_failure); + let actions = vec![ Instantiate { origin: origin.clone(), @@ -72,6 +94,11 @@ fn main() -> anyhow::Result<()> { data: deploy_calldata, salt: OptionalHex::default(), }, + VerifyCall(VerifyCallExpectation { + gas_consumed: None, + output: OptionalHex::default(), + success: !verify_failure.contains(&VerifyActionFailure::Instantiate), + }), Call { origin, dest: TestAddress::Instantiated(0), @@ -80,6 +107,11 @@ fn main() -> anyhow::Result<()> { storage_deposit_limit: None, data: calldata, }, + VerifyCall(VerifyCallExpectation { + gas_consumed: arguments.verify_call_gas_consumed, + output: OptionalHex::default(), + success: !verify_failure.contains(&VerifyActionFailure::Call), + }), ]; Specs {