Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 54 additions & 15 deletions src/tool/subcommands/api_cmd/test_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,49 @@ fn backfill_eth_mappings(db: &MemoryDB, index: Option<Index>) -> anyhow::Result<
Ok(())
}

/// JSON fields filtered from both actual and expected responses
/// before strict raw-JSON snapshot comparison, scoped to the methods whose
/// responses actually contain them.
fn fields_to_filter(method: &str) -> &'static [&'static str] {
match method {
// Skip time taken and duration as they are non-deterministic.
"Filecoin.StateCall" | "Filecoin.StateReplay" | "Filecoin.StateCompute" => {
&["Duration", "tt"]
}
// Skip `accessList` as it is known-divergent from Lotus.
// See <https://github.com/filecoin-project/lotus/issues/12214>.
"Filecoin.EthGetBlockByHash"
| "Filecoin.EthGetBlockByNumber"
| "Filecoin.EthGetTransactionByHash"
| "Filecoin.EthGetTransactionByHashLimited"
| "Filecoin.EthGetTransactionByBlockHashAndIndex"
| "Filecoin.EthGetTransactionByBlockNumberAndIndex" => &["accessList"],
_ => &[],
}
}

/// Recursively filters `fields` from a JSON value so the strict raw-JSON
/// snapshot comparison ignores them.
fn filter_out_fields(value: &mut serde_json::Value, fields: &[&str]) {
if fields.is_empty() {
return;
}
match value {
serde_json::Value::Object(map) => {
for field in fields {
map.remove(*field);
}
for val in map.values_mut() {
filter_out_fields(val, fields);
}
}
serde_json::Value::Array(items) => {
items.iter_mut().for_each(|v| filter_out_fields(v, fields));
Comment thread
sudo-shashank marked this conversation as resolved.
}
_ => {}
}
}

pub async fn run_test_from_snapshot(path: &Path) -> anyhow::Result<()> {
let mut run = false;
let snapshot_bytes = std::fs::read(path)?;
Expand Down Expand Up @@ -135,22 +178,18 @@ pub async fn run_test_from_snapshot(path: &Path) -> anyhow::Result<()> {
{
let params = <$ty>::parse_params(params_raw.clone(), ParamStructure::Either)
.context("failed to parse params")?;
let result = <$ty>::handle(ctx.clone(), params, &ext)
let mut result = <$ty>::handle(ctx.clone(), params, &ext)
.await
.map(|r| {
let lotus_json = r.into_lotus_json();
// Normalize through the same serde round-trip the golden is read with
// below, so a response Forest generated reproduces itself.
// A more strict approach would be to compare JSONs directly, tracked in https://github.com/ChainSafe/forest/issues/7313
serde_json::to_value(&lotus_json)
.and_then(serde_json::from_value)
.unwrap_or(lotus_json)
})
.map_err(|e| e.deref().to_string());
let expected = match expected_response.clone() {
Ok(v) => serde_json::from_value(v).map_err(|e| e.to_string()),
Err(e) => Err(e),
};
.map_err(|e| e.deref().to_string())
.and_then(|r| r.into_lotus_json_value().map_err(|e| e.to_string()));
let mut expected = expected_response.clone();
let fields = fields_to_filter(<$ty>::NAME);
if let Ok(v) = result.as_mut() {
filter_out_fields(v, fields);
}
if let Ok(v) = expected.as_mut() {
filter_out_fields(v, fields);
}
pretty_assertions::assert_eq!(result, expected);
run = true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/tool/subcommands/api_cmd/test_snapshots.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ filecoin_chaingetfinalizedtipset_1776082510830037.rpcsnap.json.zst
filecoin_chaingetgenesis_1736937286915866.rpcsnap.json.zst
filecoin_chaingetmessage_1758734340836824.rpcsnap.json.zst
filecoin_chaingetmessagesintipset_1758734696116136.rpcsnap.json.zst
filecoin_chaingetparentmessages_1736937305551928.rpcsnap.json.zst
filecoin_chaingetparentmessages_1783660760016875.rpcsnap.json.zst
filecoin_chaingetparentreceipts_1736937305550289.rpcsnap.json.zst
filecoin_chaingetpath_1736937942817384.rpcsnap.json.zst
filecoin_chaingettipset_1736937942817675.rpcsnap.json.zst
Expand Down
Loading