Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Improved election pallet testing #12327

Merged
merged 22 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from 19 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
150 changes: 133 additions & 17 deletions frame/election-provider-multi-phase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1842,9 +1842,9 @@ mod tests {
use super::*;
use crate::{
mock::{
multi_phase_events, raw_solution, roll_to, AccountId, ExtBuilder, MockWeightInfo,
MockedWeightInfo, MultiPhase, Runtime, RuntimeOrigin, SignedMaxSubmissions, System,
TargetIndex, Targets,
multi_phase_events, raw_solution, roll_to, roll_to_signed, roll_to_unsigned, AccountId,
ExtBuilder, MockWeightInfo, MockedWeightInfo, MultiPhase, Runtime, RuntimeOrigin,
SignedMaxSubmissions, System, TargetIndex, Targets,
},
Phase,
};
Expand All @@ -1868,7 +1868,7 @@ mod tests {
assert!(MultiPhase::snapshot().is_none());
assert_eq!(MultiPhase::round(), 1);

roll_to(15);
roll_to_signed();
assert_eq!(MultiPhase::current_phase(), Phase::Signed);
assert_eq!(multi_phase_events(), vec![Event::SignedPhaseStarted { round: 1 }]);
assert!(MultiPhase::snapshot().is_some());
Expand All @@ -1879,7 +1879,7 @@ mod tests {
assert!(MultiPhase::snapshot().is_some());
assert_eq!(MultiPhase::round(), 1);

roll_to(25);
roll_to_unsigned();
Copy link
Contributor

@Ank4n Ank4n Oct 3, 2022

Choose a reason for hiding this comment

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

Referring to line 1877.

I think if we are using this pattern then we should not use the exact block numbers explicitly in the code anymore.
What I mean is, the test should read something like this

roll_to_signed();
some_assertions();

roll_by(9); // instead of roll_to(24), go forward by 9 blocks
assertions_phase_still_signed();

roll_to_unsigned();
some_assertions();

My reasoning for this is, if we still have to keep track of block numbers, it defeats the purpose of using the pattern roll_to_event()

Since we are actively moving forward till a certain phase is reached, we probably don't need this assertions at block 24 anyway. If there is a logical assertion needed here, may be it could be done a bit differently. For example, block_unsigned_phase - block_signed_phase == 10

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

The goal is to have as much "separation of concerns" as possible. There is one tests somewhere in there that checks roll_to(x) manually (called phase_rotation_works). All other tests should spend the minimum amount of mental effort to deal with phase related stuff, so I would stick to roll_to_signed and roll_to_unsigned for the sake of simplicity.

Copy link
Contributor

@Ank4n Ank4n Oct 4, 2022

Choose a reason for hiding this comment

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

I am agreeing with the pattern. I agree we can keep manual roll over for this test. There are still few more roll_to() checks that I think we can get rid of.

assert_eq!(MultiPhase::current_phase(), Phase::Unsigned((true, 25)));
assert_eq!(
multi_phase_events(),
Expand Down Expand Up @@ -1912,11 +1912,29 @@ mod tests {
roll_to(44);
assert!(MultiPhase::current_phase().is_off());

roll_to(45);
roll_to_signed();
assert!(MultiPhase::current_phase().is_signed());

roll_to(55);
assert!(MultiPhase::current_phase().is_unsigned_open_at(55));

assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
minimal_stake: 0,
sum_stake: 0,
sum_stake_squared: 0
}
},
Event::SignedPhaseStarted { round: 2 },
Event::UnsignedPhaseStarted { round: 2 }
]
);
})
}

Expand All @@ -1940,6 +1958,21 @@ mod tests {

assert!(MultiPhase::current_phase().is_off());
assert!(MultiPhase::snapshot().is_none());

assert_eq!(
multi_phase_events(),
vec![
Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
minimal_stake: 0,
sum_stake: 0,
sum_stake_squared: 0
}
}
]
);
});
}

Expand All @@ -1952,7 +1985,7 @@ mod tests {
roll_to(19);
assert!(MultiPhase::current_phase().is_off());

roll_to(20);
roll_to_signed();
assert!(MultiPhase::current_phase().is_signed());
assert!(MultiPhase::snapshot().is_some());

Expand All @@ -1963,6 +1996,21 @@ mod tests {

assert!(MultiPhase::current_phase().is_off());
assert!(MultiPhase::snapshot().is_none());

assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
minimal_stake: 0,
sum_stake: 0,
sum_stake_squared: 0
}
}
]
)
});
}

Expand All @@ -1985,6 +2033,14 @@ mod tests {
assert_ok!(MultiPhase::elect());

assert!(MultiPhase::current_phase().is_off());

assert_eq!(
multi_phase_events(),
vec![Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore { minimal_stake: 0, sum_stake: 0, sum_stake_squared: 0 }
}]
);
});
}

Expand All @@ -1996,7 +2052,7 @@ mod tests {
roll_to(14);
assert_eq!(MultiPhase::current_phase(), Phase::Off);

roll_to(15);
roll_to_signed();
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
assert_eq!(multi_phase_events(), vec![Event::SignedPhaseStarted { round: 1 }]);
assert_eq!(MultiPhase::current_phase(), Phase::Signed);
assert_eq!(MultiPhase::round(), 1);
Expand Down Expand Up @@ -2034,7 +2090,7 @@ mod tests {
roll_to(14);
assert_eq!(MultiPhase::current_phase(), Phase::Off);

roll_to(15);
roll_to_signed();
assert_eq!(multi_phase_events(), vec![Event::SignedPhaseStarted { round: 1 }]);
assert_eq!(MultiPhase::current_phase(), Phase::Signed);
assert_eq!(MultiPhase::round(), 1);
Expand Down Expand Up @@ -2062,6 +2118,31 @@ mod tests {
assert!(MultiPhase::desired_targets().is_none());
assert!(MultiPhase::queued_solution().is_none());
assert!(MultiPhase::signed_submissions().is_empty());

assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::Slashed { account: 99, value: 5 },
Event::Slashed { account: 99, value: 5 },
Event::Slashed { account: 99, value: 5 },
Event::Slashed { account: 99, value: 5 },
Event::Slashed { account: 99, value: 5 },
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
minimal_stake: 0,
sum_stake: 0,
sum_stake_squared: 0
}
}
]
);
})
}

Expand All @@ -2071,7 +2152,7 @@ mod tests {
roll_to(14);
assert_eq!(MultiPhase::current_phase(), Phase::Off);

roll_to(15);
roll_to_signed();
assert!(MultiPhase::current_phase().is_signed());

let solution = raw_solution();
Expand Down Expand Up @@ -2106,7 +2187,7 @@ mod tests {
#[test]
fn check_events_with_compute_unsigned() {
ExtBuilder::default().build_and_execute(|| {
roll_to(25);
roll_to_unsigned();
assert!(MultiPhase::current_phase().is_unsigned());

// ensure we have snapshots in place.
Expand Down Expand Up @@ -2153,7 +2234,7 @@ mod tests {
#[test]
fn fallback_strategy_works() {
ExtBuilder::default().onchain_fallback(true).build_and_execute(|| {
roll_to(25);
roll_to_unsigned();
assert_eq!(MultiPhase::current_phase(), Phase::Unsigned((true, 25)));

// Zilch solutions thus far, but we get a result.
Expand All @@ -2166,25 +2247,50 @@ mod tests {
(30, Support { total: 40, voters: vec![(2, 5), (4, 5), (30, 30)] }),
(40, Support { total: 60, voters: vec![(2, 5), (3, 10), (4, 5), (40, 40)] })
]
)
);

assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
minimal_stake: 0,
sum_stake: 0,
sum_stake_squared: 0
}
}
]
);
});

ExtBuilder::default().onchain_fallback(false).build_and_execute(|| {
roll_to(25);
roll_to_unsigned();
assert_eq!(MultiPhase::current_phase(), Phase::Unsigned((true, 25)));

// Zilch solutions thus far.
assert!(MultiPhase::queued_solution().is_none());
assert_eq!(MultiPhase::elect().unwrap_err(), ElectionError::Fallback("NoFallback."));
// phase is now emergency.
assert_eq!(MultiPhase::current_phase(), Phase::Emergency);

assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFailed
]
);
})
}

#[test]
fn governance_fallback_works() {
ExtBuilder::default().onchain_fallback(false).build_and_execute(|| {
roll_to(25);
roll_to_unsigned();
assert_eq!(MultiPhase::current_phase(), Phase::Unsigned((true, 25)));

// Zilch solutions thus far.
Expand Down Expand Up @@ -2246,6 +2352,14 @@ mod tests {
roll_to(29);
let supports = MultiPhase::elect().unwrap();
assert!(supports.len() > 0);

assert_eq!(
multi_phase_events(),
vec![Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore { minimal_stake: 0, sum_stake: 0, sum_stake_squared: 0 }
}]
);
});
}

Expand All @@ -2269,6 +2383,8 @@ mod tests {
let err = MultiPhase::elect().unwrap_err();
assert_eq!(err, ElectionError::Fallback("NoFallback."));
assert_eq!(MultiPhase::current_phase(), Phase::Emergency);

assert_eq!(multi_phase_events(), vec![Event::ElectionFailed]);
});
}

Expand All @@ -2282,7 +2398,7 @@ mod tests {
crate::mock::MaxElectingVoters::set(2);

// Signed phase opens just fine.
roll_to(15);
roll_to_signed();
assert_eq!(MultiPhase::current_phase(), Phase::Signed);

assert_eq!(
Expand All @@ -2295,7 +2411,7 @@ mod tests {
#[test]
fn untrusted_score_verification_is_respected() {
ExtBuilder::default().build_and_execute(|| {
roll_to(15);
roll_to_signed();
assert_eq!(MultiPhase::current_phase(), Phase::Signed);

// set the solution balancing to get the desired score.
Expand Down
11 changes: 11 additions & 0 deletions frame/election-provider-multi-phase/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ pub fn roll_to(n: BlockNumber) {
}
}

pub fn roll_to_unsigned() {
while !matches!(MultiPhase::current_phase(), Phase::Unsigned(_)) {
roll_to(System::block_number() + 1);
}
}
pub fn roll_to_signed() {
while !matches!(MultiPhase::current_phase(), Phase::Signed) {
roll_to(System::block_number() + 1);
}
}

pub fn roll_to_with_ocw(n: BlockNumber) {
let now = System::block_number();
for i in now + 1..=n {
Expand Down
Loading