Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix assert_expected_events macro #7913

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ fn hop_assertions(test: ParaToParaThroughAHTest) {
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
AssetHubRococo::assert_xcmp_queue_success(None);

println!("expected amount: {}", test.args.amount);
assert_expected_events!(
AssetHubRococo,
vec![
RuntimeEvent::Balances(
pallet_balances::Event::Burned { amount, .. }
) => {
amount: *amount == test.args.amount,
amount: *amount > test.args.amount * 90/100,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@franciscoaguirre for multi_hop_pay_fees_works, the expected amount for the burn event is 1000000000000, but the actual amount in the event is 966873920000. Probably a part of it was used to pay for fees? I want to update the tests but just make sure with you if it is OK. I want to remove the amount or change it to something like: amount: *amount >= test.args.amount *.9 (i.e. the amount burned should at least be higher than 90% of the test amount).

},
]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ fn send_wnds_from_penpal_westend_through_asset_hub_westend_to_asset_hub_rococo()
vec![
// issue WNDs on AHR
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => {
asset_id: *asset_id == wnd_at_westend_parachains.clone(),
asset_id: *asset_id == wnd_at_asset_hub_rococo.clone(),
owner: owner == &receiver,
},
// message processed successfully
Expand Down
56 changes: 30 additions & 26 deletions cumulus/xcm/xcm-emulator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1253,62 +1253,69 @@ macro_rules! __impl_check_assertion {

#[macro_export]
macro_rules! assert_expected_events {
( $chain:ident, vec![$( $event_pat:pat => { $($attr:ident : $condition:expr, )* }, )*] ) => {
( $chain:ident, vec![$( $event_pat:pat => { $($attr:ident : $condition:expr, )* }, )*] ) => {
let mut message: Vec<String> = Vec::new();
let mut events = <$chain as $crate::Chain>::events();

$(
let mut event_received = false;
let mut meet_conditions = true;
let mut index_match = 0;
let mut event_message: Vec<String> = Vec::new();
// For each event pattern, we try to find a matching event.
let mut perfect_match_index: Option<usize> = None;
let mut failure_messages: Option<Vec<String>> = None;
// We'll store a string representation of the first partially matching event.
let mut partial_event_str: Option<String> = None;

for (index, event) in events.iter().enumerate() {
// Have to reset the variable to override a previous partial match
meet_conditions = true;
match event {
$event_pat => {
event_received = true;
let mut event_meets_conditions = true;
let mut conditions_message: Vec<String> = Vec::new();

$(
// We only want to record condition error messages in case it did not happened before
// Only the first partial match is recorded
if !$condition && event_message.is_empty() {
if !$condition {
conditions_message.push(
format!(
" - The attribute {:?} = {:?} did not met the condition {:?}\n",
" - The attribute {} = {:?} did not meet the condition {}\n",
stringify!($attr),
$attr,
stringify!($condition)
)
);
}
meet_conditions &= $condition;
event_meets_conditions &= $condition;
)*

// Set the index where we found a perfect match
if event_received && meet_conditions {
index_match = index;
if event_meets_conditions {
// Found an event where all conditions hold.
perfect_match_index = Some(index);
break;
} else {
event_message.extend(conditions_message);
} else if failure_messages.is_none() {
// Record the failure messages and capture the event string.
failure_messages = Some(conditions_message);
partial_event_str = Some(format!("{:#?}", event));
}
},
_ => {}
}
}

if event_received && !meet_conditions {
if let Some(index) = perfect_match_index {
// Remove the matching event so it's not checked again.
events.remove(index);
} else if let Some(failure) = failure_messages {
// A matching event was found but it failed some conditions.
message.push(
format!(
"\n\n{}::\x1b[31m{}\x1b[0m was received but some of its attributes did not meet the conditions:\n{}",
"\n\n{}::\x1b[31m{}\x1b[0m was received but some of its attributes did not meet the conditions.\n\
Actual event:\n{}\n\
Failures:\n{}",
stringify!($chain),
stringify!($event_pat),
event_message.concat()
partial_event_str.unwrap_or_else(|| "Event not captured".to_string()),
failure.concat()
)
);
} else if !event_received {
} else {
// No event matching the pattern was found.
message.push(
format!(
"\n\n{}::\x1b[31m{}\x1b[0m was never received. All events:\n{:#?}",
Expand All @@ -1317,14 +1324,11 @@ macro_rules! assert_expected_events {
<$chain as $crate::Chain>::events(),
)
);
} else {
// If we find a perfect match we remove the event to avoid being potentially assessed multiple times
events.remove(index_match);
}
)*

if !message.is_empty() {
// Log events as they will not be logged after the panic
// Log all events (since they won't be logged after the panic).
<$chain as $crate::Chain>::events().iter().for_each(|event| {
$crate::log::info!(target: concat!("events::", stringify!($chain)), "{:?}", event);
});
Expand Down
Loading