mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-30 02:27:59 +00:00
Add a way to skip tests if they don't match the target
This commit is contained in:
@@ -26,6 +26,7 @@ use revive_dt_format::case::CaseIdx;
|
||||
use revive_dt_format::input::{Calldata, Expected, ExpectedOutput, Method};
|
||||
use revive_dt_format::metadata::{ContractInstance, ContractPathAndIdentifier};
|
||||
use revive_dt_format::{input::Input, metadata::Metadata, mode::SolcMode};
|
||||
use revive_dt_node::Node;
|
||||
use revive_dt_node_interaction::EthereumNode;
|
||||
use revive_dt_report::reporter::{CompilationTask, Report, Span};
|
||||
use revive_solc_json_interface::SolcStandardJsonOutput;
|
||||
@@ -435,16 +436,15 @@ where
|
||||
// Additionally, what happens if the compiler filter doesn't match? Do we consider that the
|
||||
// transaction should succeed? Do we just ignore the expectation?
|
||||
|
||||
let error_span =
|
||||
tracing::error_span!("Exception failed", ?tracing_result, ?execution_receipt,);
|
||||
let _guard = error_span.enter();
|
||||
|
||||
// Handling the receipt state assertion.
|
||||
let expected = !expectation.exception;
|
||||
let actual = execution_receipt.status();
|
||||
if actual != expected {
|
||||
tracing::error!(
|
||||
?execution_receipt,
|
||||
expected,
|
||||
actual,
|
||||
"Transaction status assertion failed",
|
||||
);
|
||||
tracing::error!(expected, actual, "Transaction status assertion failed",);
|
||||
anyhow::bail!(
|
||||
"Transaction status assertion failed - Expected {expected} but got {actual}",
|
||||
);
|
||||
@@ -457,7 +457,11 @@ where
|
||||
.map(Bytes::from)?;
|
||||
let actual = tracing_result.output.clone().unwrap_or_default();
|
||||
if !expected.starts_with(&actual) {
|
||||
tracing::error!(?execution_receipt, %expected, %actual, "Calldata assertion failed");
|
||||
tracing::error!(
|
||||
%expected,
|
||||
%actual,
|
||||
"Calldata assertion failed"
|
||||
);
|
||||
anyhow::bail!("Calldata assertion failed - Expected {expected} but got {actual}",);
|
||||
}
|
||||
}
|
||||
@@ -468,12 +472,7 @@ where
|
||||
let expected = expected_events.len();
|
||||
let actual = execution_receipt.logs().len();
|
||||
if actual != expected {
|
||||
tracing::error!(
|
||||
?execution_receipt,
|
||||
expected,
|
||||
actual,
|
||||
"Event count assertion failed",
|
||||
);
|
||||
tracing::error!(expected, actual, "Event count assertion failed",);
|
||||
anyhow::bail!(
|
||||
"Event count assertion failed - Expected {expected} but got {actual}",
|
||||
);
|
||||
@@ -489,7 +488,6 @@ where
|
||||
let actual = actual_event.address();
|
||||
if actual != expected {
|
||||
tracing::error!(
|
||||
?execution_receipt,
|
||||
%expected,
|
||||
%actual,
|
||||
"Event emitter assertion failed",
|
||||
@@ -511,12 +509,7 @@ where
|
||||
.calldata(self.deployed_contracts.entry(case_idx).or_default(), node)?;
|
||||
let actual = actual_topic.to_vec();
|
||||
if actual != expected {
|
||||
tracing::error!(
|
||||
?execution_receipt,
|
||||
?expected,
|
||||
?actual,
|
||||
"Event topics assertion failed",
|
||||
);
|
||||
tracing::error!(?expected, ?actual, "Event topics assertion failed",);
|
||||
anyhow::bail!(
|
||||
"Event topics assertion failed - Expected {expected:?} but got {actual:?}",
|
||||
);
|
||||
@@ -530,12 +523,7 @@ where
|
||||
.map(Bytes::from)?;
|
||||
let actual = &actual_event.data().data;
|
||||
if !expected.starts_with(actual) {
|
||||
tracing::error!(
|
||||
?execution_receipt,
|
||||
?expected,
|
||||
?actual,
|
||||
"Event value assertion failed",
|
||||
);
|
||||
tracing::error!(?expected, ?actual, "Event value assertion failed",);
|
||||
anyhow::bail!(
|
||||
"Event value assertion failed - Expected {expected:?} but got {actual:?}",
|
||||
);
|
||||
@@ -649,6 +637,22 @@ where
|
||||
let tracing_span = tracing::info_span!("Handling metadata file");
|
||||
let _guard = tracing_span.enter();
|
||||
|
||||
// We only execute this input if it's valid for the leader and the follower. Otherwise, we
|
||||
// skip it with a warning.
|
||||
if !self
|
||||
.leader_node
|
||||
.matches_target(self.metadata.targets.as_deref())
|
||||
|| !self
|
||||
.follower_node
|
||||
.matches_target(self.metadata.targets.as_deref())
|
||||
{
|
||||
tracing::warn!(
|
||||
targets = ?self.metadata.targets,
|
||||
"Either the leader or follower node do not support the targets of the file"
|
||||
);
|
||||
return execution_result;
|
||||
}
|
||||
|
||||
for mode in self.metadata.solc_modes() {
|
||||
let tracing_span = tracing::info_span!("With solc mode", solc_mode = ?mode);
|
||||
let _guard = tracing_span.enter();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use revive_dt_compiler::{SolidityCompiler, revive_resolc, solc};
|
||||
use revive_dt_config::TestingPlatform;
|
||||
use revive_dt_node::{geth, kitchensink::KitchensinkNode};
|
||||
use revive_dt_node::{Node, geth, kitchensink::KitchensinkNode};
|
||||
use revive_dt_node_interaction::EthereumNode;
|
||||
|
||||
pub mod common;
|
||||
@@ -15,7 +15,7 @@ pub mod driver;
|
||||
///
|
||||
/// For this we need a blockchain node implementation and a compiler.
|
||||
pub trait Platform {
|
||||
type Blockchain: EthereumNode;
|
||||
type Blockchain: EthereumNode + Node;
|
||||
type Compiler: SolidityCompiler;
|
||||
|
||||
/// Returns the matching [TestingPlatform] of the [revive_dt_config::Arguments].
|
||||
|
||||
@@ -26,7 +26,15 @@ impl Case {
|
||||
.enumerate()
|
||||
.map(move |(idx, mut input)| {
|
||||
if idx + 1 == inputs_len {
|
||||
input.expected = self.expected.clone();
|
||||
if input.expected.is_none() {
|
||||
input.expected = self.expected.clone();
|
||||
}
|
||||
|
||||
// TODO: What does it mean for us to have an `expected` field on the case itself
|
||||
// but the final input also has an expected field that doesn't match the one on
|
||||
// the case? What are we supposed to do with that final expected field on the
|
||||
// case?
|
||||
|
||||
input
|
||||
} else {
|
||||
input
|
||||
|
||||
@@ -324,7 +324,7 @@ impl Input {
|
||||
chain_state_provider: &impl EthereumNode,
|
||||
) -> anyhow::Result<TransactionRequest> {
|
||||
let input_data = self.encoded_input(deployed_contracts, chain_state_provider)?;
|
||||
let transaction_request = TransactionRequest::default();
|
||||
let transaction_request = TransactionRequest::default().from(self.caller);
|
||||
match self.method {
|
||||
Method::Deployer => Ok(transaction_request.with_deploy_code(input_data)),
|
||||
_ => Ok(transaction_request
|
||||
|
||||
@@ -48,6 +48,7 @@ impl Deref for MetadataFile {
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Clone, Eq, PartialEq)]
|
||||
pub struct Metadata {
|
||||
pub targets: Option<Vec<String>>,
|
||||
pub cases: Vec<Case>,
|
||||
pub contracts: Option<BTreeMap<ContractInstance, ContractPathAndIdentifier>>,
|
||||
// TODO: Convert into wrapper types for clarity.
|
||||
|
||||
@@ -510,6 +510,14 @@ impl Node for Instance {
|
||||
.stdout;
|
||||
Ok(String::from_utf8_lossy(&output).into())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all, fields(geth_node_id = self.id))]
|
||||
fn matches_target(&self, targets: Option<&[String]>) -> bool {
|
||||
match targets {
|
||||
None => true,
|
||||
Some(targets) => targets.iter().any(|str| str.as_str() == "evm"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Instance {
|
||||
|
||||
@@ -584,6 +584,14 @@ impl Node for KitchensinkNode {
|
||||
.stdout;
|
||||
Ok(String::from_utf8_lossy(&output).into())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all, fields(kitchensink_node_id = self.id))]
|
||||
fn matches_target(&self, targets: Option<&[String]>) -> bool {
|
||||
match targets {
|
||||
None => true,
|
||||
Some(targets) => targets.iter().any(|str| str.as_str() == "pvm"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for KitchensinkNode {
|
||||
|
||||
@@ -35,4 +35,8 @@ pub trait Node: EthereumNode {
|
||||
|
||||
/// Returns the node version.
|
||||
fn version(&self) -> anyhow::Result<String>;
|
||||
|
||||
/// Given a list of targets from the metadata file, this function determines if the metadata
|
||||
/// file can be ran on this node or not.
|
||||
fn matches_target(&self, targets: Option<&[String]>) -> bool;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user