Compare commits

..

11 Commits

Author SHA1 Message Date
Omar Abdulla 63389ef199 Add information on the deployed contracts 2025-08-25 13:52:09 +03:00
Omar Abdulla 6443f52502 Cleanup report model 2025-08-25 05:06:11 +03:00
Omar Abdulla 3d198f4e71 Include contract compilation information in report 2025-08-25 05:02:19 +03:00
Omar Abdulla 7d87cb9ee8 Integrate the reporting infrastructure with the
CLI reporter used by the program.
2025-08-25 00:24:10 +03:00
Omar Abdulla 5d9075b389 Add case status information to the report 2025-08-24 23:38:50 +03:00
Omar Abdulla 4f55e8968d Update report to use better map data structures 2025-08-24 23:01:30 +03:00
Omar Abdulla 38e3915169 Add reporting infra for reporting ignored tests 2025-08-24 22:50:40 +03:00
Omar Abdulla 4d7d7ed843 Add more runner events to the reporter and refine the structure 2025-08-24 20:13:48 +03:00
Omar Abdulla cbb6a11404 Implement the initial set of reporter events 2025-08-24 19:45:01 +03:00
Omar Abdulla bd5ff6d75e Use the Test struct more in the code 2025-08-23 18:05:32 +03:00
Omar Abdulla c9303f0020 Remove the old reporting infra 2025-08-23 17:58:13 +03:00
4 changed files with 29 additions and 87 deletions
+17 -35
View File
@@ -181,41 +181,23 @@ impl SolidityCompiler for Resolc {
.evm .evm
.and_then(|evm| evm.bytecode.clone()) .and_then(|evm| evm.bytecode.clone())
.context("Unexpected - Contract compiled with resolc has no bytecode")?; .context("Unexpected - Contract compiled with resolc has no bytecode")?;
let abi = { let abi = contract_information
let metadata = contract_information .metadata
.metadata .as_ref()
.as_ref() .and_then(|metadata| metadata.as_object())
.context("No metadata found for the contract")?; .and_then(|metadata| metadata.get("solc_metadata"))
let solc_metadata_str = match metadata { .and_then(|solc_metadata| solc_metadata.as_str())
serde_json::Value::String(solc_metadata_str) => solc_metadata_str.as_str(), .and_then(|metadata| serde_json::from_str::<serde_json::Value>(metadata).ok())
serde_json::Value::Object(metadata_object) => { .and_then(|metadata| {
let solc_metadata_value = metadata_object metadata.get("output").and_then(|output| {
.get("solc_metadata") output
.context("Contract doesn't have a 'solc_metadata' field")?; .get("abi")
solc_metadata_value .and_then(|abi| serde_json::from_value::<JsonAbi>(abi.clone()).ok())
.as_str() })
.context("The 'solc_metadata' field is not a string")? })
} .context(
serde_json::Value::Null "Unexpected - Failed to get the ABI for a contract compiled with resolc",
| serde_json::Value::Bool(_) )?;
| serde_json::Value::Number(_)
| serde_json::Value::Array(_) => {
anyhow::bail!("Unsupported type of metadata {metadata:?}")
}
};
let solc_metadata =
serde_json::from_str::<serde_json::Value>(solc_metadata_str).context(
"Failed to deserialize the solc_metadata as a serde_json generic value",
)?;
let output_value = solc_metadata
.get("output")
.context("solc_metadata doesn't have an output field")?;
let abi_value = output_value
.get("abi")
.context("solc_metadata output doesn't contain an abi field")?;
serde_json::from_value::<JsonAbi>(abi_value.clone())
.context("ABI found in solc_metadata output is not valid ABI")?
};
map.insert(contract_name, (bytecode.object, abi)); map.insert(contract_name, (bytecode.object, abi));
} }
} }
-12
View File
@@ -115,18 +115,6 @@ pub struct Arguments {
#[arg(short, long = "kitchensink", default_value = "substrate-node")] #[arg(short, long = "kitchensink", default_value = "substrate-node")]
pub kitchensink: PathBuf, pub kitchensink: PathBuf,
/// The path to the `revive-dev-node` executable.
///
/// By default it uses `revive-dev-node` binary found in `$PATH`.
#[arg(long = "revive-dev-node", default_value = "revive-dev-node")]
pub revive_dev_node: PathBuf,
/// By default the tool uses the revive-dev-node when it's running differential tests against
/// PolkaVM since the dev-node is much faster than kitchensink. This flag allows the caller to
/// configure the tool to use kitchensink rather than the dev-node.
#[arg(long)]
pub use_kitchensink_not_dev_node: bool,
/// The path to the `eth_proxy` executable. /// The path to the `eth_proxy` executable.
/// ///
/// By default it uses `eth-rpc` binary found in `$PATH`. /// By default it uses `eth-rpc` binary found in `$PATH`.
+6 -14
View File
@@ -546,30 +546,22 @@ async fn start_cli_reporting_task(reporter: Reporter) {
number_of_successes += 1; number_of_successes += 1;
writeln!( writeln!(
buf, buf,
"{}{}Case Succeeded{} - Steps Executed: {}{}", "{}{}Case Succeeded{}{} - Steps Executed: {}",
GREEN, BOLD, BOLD_RESET, steps_executed, COLOR_RESET GREEN, BOLD, BOLD_RESET, COLOR_RESET, steps_executed
) )
} }
TestCaseStatus::Failed { reason } => { TestCaseStatus::Failed { reason } => {
number_of_failures += 1; number_of_failures += 1;
writeln!( writeln!(
buf, buf,
"{}{}Case Failed{} - Reason: {}{}", "{}{}Case Failed{}{} - Reason: {}",
RED, RED, BOLD, BOLD_RESET, COLOR_RESET, reason
BOLD,
BOLD_RESET,
reason.trim(),
COLOR_RESET,
) )
} }
TestCaseStatus::Ignored { reason, .. } => writeln!( TestCaseStatus::Ignored { reason, .. } => writeln!(
buf, buf,
"{}{}Case Ignored{} - Reason: {}{}", "{}{}Case Ignored{}{} - Reason: {}",
GREY, GREY, BOLD, BOLD_RESET, COLOR_RESET, reason
BOLD,
BOLD_RESET,
reason.trim(),
COLOR_RESET,
), ),
}; };
} }
+6 -26
View File
@@ -54,7 +54,6 @@ static NODE_COUNT: AtomicU32 = AtomicU32::new(0);
pub struct KitchensinkNode { pub struct KitchensinkNode {
id: u32, id: u32,
substrate_binary: PathBuf, substrate_binary: PathBuf,
dev_node_binary: PathBuf,
eth_proxy_binary: PathBuf, eth_proxy_binary: PathBuf,
rpc_url: String, rpc_url: String,
base_directory: PathBuf, base_directory: PathBuf,
@@ -64,7 +63,6 @@ pub struct KitchensinkNode {
wallet: Arc<EthereumWallet>, wallet: Arc<EthereumWallet>,
nonce_manager: CachedNonceManager, nonce_manager: CachedNonceManager,
chain_id_filler: ChainIdFiller, chain_id_filler: ChainIdFiller,
use_kitchensink_not_dev_node: bool,
/// This vector stores [`File`] objects that we use for logging which we want to flush when the /// This vector stores [`File`] objects that we use for logging which we want to flush when the
/// node object is dropped. We do not store them in a structured fashion at the moment (in /// node object is dropped. We do not store them in a structured fashion at the moment (in
/// separate fields) as the logic that we need to apply to them is all the same regardless of /// separate fields) as the logic that we need to apply to them is all the same regardless of
@@ -103,21 +101,11 @@ impl KitchensinkNode {
// Note: we do not pipe the logs of this process to a separate file since this is just a // Note: we do not pipe the logs of this process to a separate file since this is just a
// once-off export of the default chain spec and not part of the long-running node process. // once-off export of the default chain spec and not part of the long-running node process.
let output = if self.use_kitchensink_not_dev_node { let output = Command::new(&self.substrate_binary)
Command::new(&self.substrate_binary) .arg("export-chain-spec")
.arg("export-chain-spec") .arg("--chain")
.arg("--chain") .arg("dev")
.arg("dev") .output()?;
.output()
.context("Failed to export the chain-spec")?
} else {
Command::new(&self.dev_node_binary)
.arg("build-spec")
.arg("--chain")
.arg("dev")
.output()
.context("Failed to export the chain-spec")?
};
if !output.status.success() { if !output.status.success() {
anyhow::bail!( anyhow::bail!(
@@ -200,12 +188,7 @@ impl KitchensinkNode {
let kitchensink_stderr_logs_file = open_options let kitchensink_stderr_logs_file = open_options
.clone() .clone()
.open(self.kitchensink_stderr_log_file_path())?; .open(self.kitchensink_stderr_log_file_path())?;
let node_binary_path = if self.use_kitchensink_not_dev_node { self.process_substrate = Command::new(&self.substrate_binary)
self.substrate_binary.as_path()
} else {
self.dev_node_binary.as_path()
};
self.process_substrate = Command::new(node_binary_path)
.arg("--dev") .arg("--dev")
.arg("--chain") .arg("--chain")
.arg(chainspec_path) .arg(chainspec_path)
@@ -550,7 +533,6 @@ impl Node for KitchensinkNode {
Self { Self {
id, id,
substrate_binary: config.kitchensink.clone(), substrate_binary: config.kitchensink.clone(),
dev_node_binary: config.revive_dev_node.clone(),
eth_proxy_binary: config.eth_proxy.clone(), eth_proxy_binary: config.eth_proxy.clone(),
rpc_url: String::new(), rpc_url: String::new(),
base_directory, base_directory,
@@ -560,7 +542,6 @@ impl Node for KitchensinkNode {
wallet: Arc::new(wallet), wallet: Arc::new(wallet),
chain_id_filler: Default::default(), chain_id_filler: Default::default(),
nonce_manager: Default::default(), nonce_manager: Default::default(),
use_kitchensink_not_dev_node: config.use_kitchensink_not_dev_node,
// We know that we only need to be storing 4 files so we can specify that when creating // We know that we only need to be storing 4 files so we can specify that when creating
// the vector. It's the stdout and stderr of the substrate-node and the eth-rpc. // the vector. It's the stdout and stderr of the substrate-node and the eth-rpc.
logs_file_to_flush: Vec::with_capacity(4), logs_file_to_flush: Vec::with_capacity(4),
@@ -1078,7 +1059,6 @@ mod tests {
Arguments { Arguments {
kitchensink: PathBuf::from("substrate-node"), kitchensink: PathBuf::from("substrate-node"),
eth_proxy: PathBuf::from("eth-rpc"), eth_proxy: PathBuf::from("eth-rpc"),
use_kitchensink_not_dev_node: true,
..Default::default() ..Default::default()
} }
} }