Allow where clause in benchmarking (#6461)

* WIP

* handle where clause in benchmarking

* doc

* maybe better syntax

* line width
This commit is contained in:
Guillaume Thiolliere
2020-06-24 17:24:05 +02:00
committed by GitHub
parent fb56eacd8d
commit ff897c1acc
2 changed files with 251 additions and 141 deletions
+221 -126
View File
@@ -85,6 +85,8 @@ pub use paste;
/// Example:
/// ```ignore
/// benchmarks! {
/// where_clause { where T::A: From<u32> } // Optional line to give additional bound on `T`.
///
/// // common parameter; just one for this example.
/// // will be `1`, `MAX_LENGTH` or any value inbetween
/// _ {
@@ -173,6 +175,7 @@ pub use paste;
#[macro_export]
macro_rules! benchmarks {
(
$( where_clause { where $( $where_ty:ty: $where_bound:path ),* $(,)? } )?
_ {
$(
let $common:ident in $common_from:tt .. $common_to:expr => $common_instancer:expr;
@@ -182,6 +185,7 @@ macro_rules! benchmarks {
) => {
$crate::benchmarks_iter!(
NO_INSTANCE
{ $( $( $where_ty: $where_bound ),* )? }
{ $( { $common , $common_from , $common_to , $common_instancer } )* }
( )
$( $rest )*
@@ -189,9 +193,11 @@ macro_rules! benchmarks {
}
}
/// Same as [`benchmarks`] but for instantiable module.
#[macro_export]
macro_rules! benchmarks_instance {
(
$( where_clause { where $( $where_ty:ty: $where_bound:path ),* $(,)? } )?
_ {
$(
let $common:ident in $common_from:tt .. $common_to:expr => $common_instancer:expr;
@@ -201,6 +207,7 @@ macro_rules! benchmarks_instance {
) => {
$crate::benchmarks_iter!(
INSTANCE
{ $( $( $where_ty: $where_bound ),* )? }
{ $( { $common , $common_from , $common_to , $common_instancer } )* }
( )
$( $rest )*
@@ -209,11 +216,12 @@ macro_rules! benchmarks_instance {
}
#[macro_export]
#[allow(missing_docs)]
#[doc(hidden)]
macro_rules! benchmarks_iter {
// mutation arm:
(
$instance:ident
{ $( $where_clause:tt )* }
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* )
@@ -222,6 +230,7 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter! {
$instance
{ $( $where_clause )* }
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: $name ( $origin $( , $arg )* )
@@ -232,6 +241,7 @@ macro_rules! benchmarks_iter {
// no instance mutation arm:
(
NO_INSTANCE
{ $( $where_clause:tt )* }
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
@@ -240,6 +250,7 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter! {
NO_INSTANCE
{ $( $where_clause )* }
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: {
@@ -254,6 +265,7 @@ macro_rules! benchmarks_iter {
// instance mutation arm:
(
INSTANCE
{ $( $where_clause:tt )* }
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
@@ -262,6 +274,7 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter! {
INSTANCE
{ $( $where_clause )* }
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: {
@@ -276,6 +289,7 @@ macro_rules! benchmarks_iter {
// iteration arm:
(
$instance:ident
{ $( $where_clause:tt )* }
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $eval:block
@@ -285,29 +299,34 @@ macro_rules! benchmarks_iter {
$crate::benchmark_backend! {
$instance
$name
{ $( $where_clause )* }
{ $( $common )* }
{ }
{ $eval }
{ $( $code )* }
$postcode
}
#[cfg(test)]
$crate::impl_benchmark_test!( { $( $where_clause )* } $instance $name );
$crate::benchmarks_iter!(
$instance
{ $( $where_clause )* }
{ $( $common )* }
( $( $names )* $name )
$( $rest )*
);
};
// iteration-exit arm
( $instance:ident { $( $common:tt )* } ( $( $names:ident )* ) ) => {
$crate::selected_benchmark!( $instance $( $names ),* );
$crate::impl_benchmark!( $instance $( $names ),* );
#[cfg(test)]
$crate::impl_benchmark_tests!( $instance $( $names ),* );
( $instance:ident { $( $where_clause:tt )* } { $( $common:tt )* } ( $( $names:ident )* ) ) => {
$crate::selected_benchmark!( { $( $where_clause)* } $instance $( $names ),* );
$crate::impl_benchmark!( { $( $where_clause )* } $instance $( $names ),* );
};
// add verify block to _() format
(
$instance:ident
{ $( $where_clause:tt )* }
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* )
@@ -315,6 +334,7 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter! {
$instance
{ $( $where_clause )* }
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: _ ( $origin $( , $arg )* )
@@ -325,6 +345,7 @@ macro_rules! benchmarks_iter {
// add verify block to name() format
(
$instance:ident
{ $( $where_clause:tt )* }
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* )
@@ -332,6 +353,7 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter! {
$instance
{ $( $where_clause )* }
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: $dispatch ( $origin $( , $arg )* )
@@ -342,6 +364,7 @@ macro_rules! benchmarks_iter {
// add verify block to {} format
(
$instance:ident
{ $( $where_clause:tt )* }
{ $( $common:tt )* }
( $( $names:ident )* )
$name:ident { $( $code:tt )* }: $eval:block
@@ -349,6 +372,7 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter!(
$instance
{ $( $where_clause )* }
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: $eval
@@ -359,10 +383,12 @@ macro_rules! benchmarks_iter {
}
#[macro_export]
#[allow(missing_docs)]
#[doc(hidden)]
macro_rules! benchmark_backend {
// parsing arms
($instance:ident $name:ident {
$( $where_clause:tt )*
} {
$( $common:tt )*
} {
$( PRE { $( $pre_parsed:tt )* } )*
@@ -371,13 +397,15 @@ macro_rules! benchmark_backend {
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $name { $( $common )* } {
$instance $name { $( $where_clause )* } { $( $common )* } {
$( PRE { $( $pre_parsed )* } )*
PRE { $pre_id , $pre_ty , $pre_ex }
} { $eval } { $( $rest )* } $postcode
}
};
($instance:ident $name:ident {
$( $where_clause:tt )*
} {
$( $common:tt )*
} {
$( $parsed:tt )*
@@ -386,7 +414,7 @@ macro_rules! benchmark_backend {
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $name { $( $common )* } {
$instance $name { $( $where_clause )* } { $( $common )* } {
$( $parsed )*
PARAM { $param , $param_from , $param_to , $param_instancer }
} { $eval } { $( $rest )* } $postcode
@@ -394,6 +422,8 @@ macro_rules! benchmark_backend {
};
// mutation arm to look after defaulting to a common param
($instance:ident $name:ident {
$( $where_clause:tt )*
} {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( $parsed:tt )*
@@ -402,7 +432,7 @@ macro_rules! benchmark_backend {
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $name {
$instance $name { $( $where_clause )* } {
$( { $common , $common_from , $common_to , $common_instancer } )*
} {
$( $parsed )*
@@ -417,6 +447,8 @@ macro_rules! benchmark_backend {
};
// mutation arm to look after defaulting only the range to common param
($instance:ident $name:ident {
$( $where_clause:tt )*
} {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( $parsed:tt )*
@@ -425,7 +457,7 @@ macro_rules! benchmark_backend {
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $name {
$instance $name { $( $where_clause )* } {
$( { $common , $common_from , $common_to , $common_instancer } )*
} {
$( $parsed )*
@@ -440,6 +472,8 @@ macro_rules! benchmark_backend {
};
// mutation arm to look after a single tt for param_from.
($instance:ident $name:ident {
$( $where_clause:tt )*
} {
$( $common:tt )*
} {
$( $parsed:tt )*
@@ -448,7 +482,7 @@ macro_rules! benchmark_backend {
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $name { $( $common )* } { $( $parsed )* } { $eval } {
$instance $name { $( $where_clause )* } { $( $common )* } { $( $parsed )* } { $eval } {
let $param in ( $param_from ) .. $param_to => $param_instancer;
$( $rest )*
} $postcode
@@ -456,6 +490,8 @@ macro_rules! benchmark_backend {
};
// mutation arm to look after the default tail of `=> ()`
($instance:ident $name:ident {
$( $where_clause:tt )*
} {
$( $common:tt )*
} {
$( $parsed:tt )*
@@ -464,7 +500,7 @@ macro_rules! benchmark_backend {
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $name { $( $common )* } { $( $parsed )* } { $eval } {
$instance $name { $( $where_clause )* } { $( $common )* } { $( $parsed )* } { $eval } {
let $param in $param_from .. $param_to => ();
$( $rest )*
} $postcode
@@ -472,6 +508,8 @@ macro_rules! benchmark_backend {
};
// mutation arm to look after `let _ =`
($instance:ident $name:ident {
$( $where_clause:tt )*
} {
$( $common:tt )*
} {
$( $parsed:tt )*
@@ -480,7 +518,7 @@ macro_rules! benchmark_backend {
$( $rest:tt )*
} $postcode:block) => {
$crate::benchmark_backend! {
$instance $name { $( $common )* } { $( $parsed )* } { $eval } {
$instance $name { $( $where_clause )* } { $( $common )* } { $( $parsed )* } { $eval } {
let $pre_id : _ = $pre_ex;
$( $rest )*
} $postcode
@@ -488,6 +526,8 @@ macro_rules! benchmark_backend {
};
// no instance actioning arm
(NO_INSTANCE $name:ident {
$( $where_clause:tt )*
} {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )*
@@ -496,7 +536,9 @@ macro_rules! benchmark_backend {
#[allow(non_camel_case_types)]
struct $name;
#[allow(unused_variables)]
impl<T: Trait> $crate::BenchmarkingSetup<T> for $name {
impl<T: Trait> $crate::BenchmarkingSetup<T> for $name
where $( $where_clause )*
{
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
vec! [
$(
@@ -513,7 +555,9 @@ macro_rules! benchmark_backend {
)*
$(
// Prepare instance
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
let $param = components.iter()
.find(|&c| c.0 == $crate::BenchmarkParameter::$param)
.unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
@@ -532,7 +576,9 @@ macro_rules! benchmark_backend {
)*
$(
// Prepare instance
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
let $param = components.iter()
.find(|&c| c.0 == $crate::BenchmarkParameter::$param)
.unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
@@ -546,6 +592,8 @@ macro_rules! benchmark_backend {
};
// instance actioning arm
(INSTANCE $name:ident {
$( $where_clause:tt )*
} {
$( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )*
} {
$( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )*
@@ -554,7 +602,9 @@ macro_rules! benchmark_backend {
#[allow(non_camel_case_types)]
struct $name;
#[allow(unused_variables)]
impl<T: Trait<I>, I: Instance> $crate::BenchmarkingSetupInstance<T, I> for $name {
impl<T: Trait<I>, I: Instance> $crate::BenchmarkingSetupInstance<T, I> for $name
where $( $where_clause )*
{
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
vec! [
$(
@@ -571,7 +621,9 @@ macro_rules! benchmark_backend {
)*
$(
// Prepare instance
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
let $param = components.iter()
.find(|&c| c.0 == $crate::BenchmarkParameter::$param)
.unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
@@ -590,7 +642,9 @@ macro_rules! benchmark_backend {
)*
$(
// Prepare instance
let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1;
let $param = components.iter()
.find(|&c| c.0 == $crate::BenchmarkParameter::$param)
.unwrap().1;
)*
$(
let $pre_id : $pre_ty = $pre_ex;
@@ -604,23 +658,25 @@ macro_rules! benchmark_backend {
}
}
/// Creates a `SelectedBenchmark` enum implementing `BenchmarkingSetup`.
///
/// Every variant must implement [`BenchmarkingSetup`].
///
/// ```nocompile
///
/// struct Transfer;
/// impl BenchmarkingSetup for Transfer { ... }
///
/// struct SetBalance;
/// impl BenchmarkingSetup for SetBalance { ... }
///
/// selected_benchmark!(Transfer, SetBalance);
/// ```
// Creates a `SelectedBenchmark` enum implementing `BenchmarkingSetup`.
//
// Every variant must implement [`BenchmarkingSetup`].
//
// ```nocompile
//
// struct Transfer;
// impl BenchmarkingSetup for Transfer { ... }
//
// struct SetBalance;
// impl BenchmarkingSetup for SetBalance { ... }
//
// selected_benchmark!(Transfer, SetBalance);
// ```
#[macro_export]
#[doc(hidden)]
macro_rules! selected_benchmark {
(
{ $( $where_clause:tt )* }
NO_INSTANCE $( $bench:ident ),*
) => {
// The list of available benchmarks for this pallet.
@@ -630,7 +686,9 @@ macro_rules! selected_benchmark {
}
// Allow us to select a benchmark from the list of available benchmarks.
impl<T: Trait> $crate::BenchmarkingSetup<T> for SelectedBenchmark {
impl<T: Trait> $crate::BenchmarkingSetup<T> for SelectedBenchmark
where $( $where_clause )*
{
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetup<T>>::components(&$bench), )*
@@ -655,6 +713,7 @@ macro_rules! selected_benchmark {
}
};
(
{ $( $where_clause:tt )* }
INSTANCE $( $bench:ident ),*
) => {
// The list of available benchmarks for this pallet.
@@ -664,7 +723,9 @@ macro_rules! selected_benchmark {
}
// Allow us to select a benchmark from the list of available benchmarks.
impl<T: Trait<I>, I: Instance> $crate::BenchmarkingSetupInstance<T, I> for SelectedBenchmark {
impl<T: Trait<I>, I: Instance> $crate::BenchmarkingSetupInstance<T, I> for SelectedBenchmark
where $( $where_clause )*
{
fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> {
match self {
$( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance<T, I>>::components(&$bench), )*
@@ -691,12 +752,14 @@ macro_rules! selected_benchmark {
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_benchmark {
(
{ $( $where_clause:tt )* }
NO_INSTANCE $( $name:ident ),*
) => {
impl<T: Trait> $crate::Benchmarking<$crate::BenchmarkResults> for Module<T>
where T: frame_system::Trait
where T: frame_system::Trait, $( $where_clause )*
{
fn benchmarks() -> Vec<&'static [u8]> {
vec![ $( stringify!($name).as_ref() ),* ]
@@ -763,8 +826,11 @@ macro_rules! impl_benchmark {
// Run the benchmark `repeat` times.
for _ in 0..repeat {
// Set up the externalities environment for the setup we want to benchmark.
let closure_to_benchmark = <SelectedBenchmark as $crate::BenchmarkingSetup<T>>::instance(&selected_benchmark, &c)?;
// Set up the externalities environment for the setup we want to
// benchmark.
let closure_to_benchmark = <
SelectedBenchmark as $crate::BenchmarkingSetup<T>
>::instance(&selected_benchmark, &c)?;
// Set the block number to at least 1 so events are deposited.
if $crate::Zero::is_zero(&frame_system::Module::<T>::block_number()) {
@@ -776,12 +842,20 @@ macro_rules! impl_benchmark {
$crate::benchmarking::commit_db();
// Time the extrinsic logic.
frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value);
frame_support::debug::trace!(
target: "benchmark",
"Start Benchmark: {:?} {:?}", name, component_value
);
let start_extrinsic = $crate::benchmarking::current_time();
closure_to_benchmark()?;
let finish_extrinsic = $crate::benchmarking::current_time();
let elapsed_extrinsic = finish_extrinsic - start_extrinsic;
frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic);
frame_support::debug::trace!(
target: "benchmark",
"End Benchmark: {} ns", elapsed_extrinsic
);
// Time the storage root recalculation.
let start_storage_root = $crate::benchmarking::current_time();
@@ -801,10 +875,12 @@ macro_rules! impl_benchmark {
}
};
(
{ $( $where_clause:tt )* }
INSTANCE $( $name:ident ),*
) => {
impl<T: Trait<I>, I: Instance> $crate::Benchmarking<$crate::BenchmarkResults> for Module<T, I>
where T: frame_system::Trait
impl<T: Trait<I>, I: Instance> $crate::Benchmarking<$crate::BenchmarkResults>
for Module<T, I>
where T: frame_system::Trait, $( $where_clause )*
{
fn benchmarks() -> Vec<&'static [u8]> {
vec![ $( stringify!($name).as_ref() ),* ]
@@ -829,7 +905,9 @@ macro_rules! impl_benchmark {
$crate::benchmarking::commit_db();
$crate::benchmarking::wipe_db();
let components = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, I>>::components(&selected_benchmark);
let components = <
SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, I>
>::components(&selected_benchmark);
let mut results: Vec<$crate::BenchmarkResults> = Vec::new();
// Default number of steps for a component.
@@ -872,7 +950,9 @@ macro_rules! impl_benchmark {
// Run the benchmark `repeat` times.
for _ in 0..repeat {
// Set up the externalities environment for the setup we want to benchmark.
let closure_to_benchmark = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, I>>::instance(&selected_benchmark, &c)?;
let closure_to_benchmark = <
SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, I>
>::instance(&selected_benchmark, &c)?;
// Set the block number to at least 1 so events are deposited.
if $crate::Zero::is_zero(&frame_system::Module::<T>::block_number()) {
@@ -884,12 +964,20 @@ macro_rules! impl_benchmark {
$crate::benchmarking::commit_db();
// Time the extrinsic logic.
frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value);
frame_support::debug::trace!(
target: "benchmark",
"Start Benchmark: {:?} {:?}", name, component_value
);
let start_extrinsic = $crate::benchmarking::current_time();
closure_to_benchmark()?;
let finish_extrinsic = $crate::benchmarking::current_time();
let elapsed_extrinsic = finish_extrinsic - start_extrinsic;
frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic);
frame_support::debug::trace!(
target: "benchmark",
"End Benchmark: {} ns", elapsed_extrinsic
);
// Time the storage root recalculation.
let start_storage_root = $crate::benchmarking::current_time();
@@ -910,108 +998,115 @@ macro_rules! impl_benchmark {
}
}
// This creates unit tests from the main benchmark macro.
// They run the benchmark using the `high` and `low` value for each component
// This creates a unit test for one benchmark of the main benchmark macro.
// It runs the benchmark using the `high` and `low` value for each component
// and ensure that everything completes successfully.
#[macro_export]
macro_rules! impl_benchmark_tests {
#[doc(hidden)]
macro_rules! impl_benchmark_test {
(
{ $( $where_clause:tt )* }
NO_INSTANCE
$( $name:ident ),*
$name:ident
) => {
$(
$crate::paste::item! {
fn [<test_benchmark_ $name>] <T: Trait> () -> Result<(), &'static str>
where T: frame_system::Trait
{
let selected_benchmark = SelectedBenchmark::$name;
let components = <SelectedBenchmark as $crate::BenchmarkingSetup<T>>::components(&selected_benchmark);
$crate::paste::item! {
fn [<test_benchmark_ $name>] <T: Trait> () -> Result<(), &'static str>
where T: frame_system::Trait, $( $where_clause )*
{
let selected_benchmark = SelectedBenchmark::$name;
let components = <
SelectedBenchmark as $crate::BenchmarkingSetup<T>
>::components(&selected_benchmark);
assert!(
components.len() != 0,
"You need to add components to your benchmark!",
);
for (_, (name, low, high)) in components.iter().enumerate() {
// Test only the low and high value, assuming values in the middle won't break
for component_value in vec![low, high] {
// Select the max value for all the other components.
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(_, (n, _, h))|
if n == name {
(*n, *component_value)
} else {
(*n, *h)
}
)
.collect();
assert!(
components.len() != 0,
"You need to add components to your benchmark!",
);
for (_, (name, low, high)) in components.iter().enumerate() {
// Test only the low and high value, assuming values in the middle won't break
for component_value in vec![low, high] {
// Select the max value for all the other components.
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(_, (n, _, h))|
if n == name {
(*n, *component_value)
} else {
(*n, *h)
}
)
.collect();
// Set up the verification state
let closure_to_verify = <SelectedBenchmark as $crate::BenchmarkingSetup<T>>::verify(&selected_benchmark, &c)?;
// Set up the verification state
let closure_to_verify = <
SelectedBenchmark as $crate::BenchmarkingSetup<T>
>::verify(&selected_benchmark, &c)?;
// Set the block number to at least 1 so events are deposited.
if $crate::Zero::is_zero(&frame_system::Module::<T>::block_number()) {
frame_system::Module::<T>::set_block_number(1.into());
}
// Run verification
closure_to_verify()?;
// Reset the state
$crate::benchmarking::wipe_db();
// Set the block number to at least 1 so events are deposited.
if $crate::Zero::is_zero(&frame_system::Module::<T>::block_number()) {
frame_system::Module::<T>::set_block_number(1.into());
}
// Run verification
closure_to_verify()?;
// Reset the state
$crate::benchmarking::wipe_db();
}
Ok(())
}
Ok(())
}
)*
}
};
(
{ $( $where_clause:tt )* }
INSTANCE
$( $name:ident ),*
$name:ident
) => {
$(
$crate::paste::item! {
fn [<test_benchmark_ $name>] <T: Trait> () -> Result<(), &'static str>
where T: frame_system::Trait
{
let selected_benchmark = SelectedBenchmark::$name;
let components = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, _>>::components(&selected_benchmark);
$crate::paste::item! {
fn [<test_benchmark_ $name>] <T: Trait> () -> Result<(), &'static str>
where T: frame_system::Trait, $( $where_clause )*
{
let selected_benchmark = SelectedBenchmark::$name;
let components = <
SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, _>
>::components(&selected_benchmark);
for (_, (name, low, high)) in components.iter().enumerate() {
// Test only the low and high value, assuming values in the middle won't break
for component_value in vec![low, high] {
// Select the max value for all the other components.
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(_, (n, _, h))|
if n == name {
(*n, *component_value)
} else {
(*n, *h)
}
)
.collect();
for (_, (name, low, high)) in components.iter().enumerate() {
// Test only the low and high value, assuming values in the middle won't break
for component_value in vec![low, high] {
// Select the max value for all the other components.
let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter()
.enumerate()
.map(|(_, (n, _, h))|
if n == name {
(*n, *component_value)
} else {
(*n, *h)
}
)
.collect();
// Set up the verification state
let closure_to_verify = <SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, _>>::verify(&selected_benchmark, &c)?;
// Set up the verification state
let closure_to_verify = <
SelectedBenchmark as $crate::BenchmarkingSetupInstance<T, _>
>::verify(&selected_benchmark, &c)?;
// Set the block number to at least 1 so events are deposited.
if $crate::Zero::is_zero(&frame_system::Module::<T>::block_number()) {
frame_system::Module::<T>::set_block_number(1.into());
}
// Run verification
closure_to_verify()?;
// Reset the state
$crate::benchmarking::wipe_db();
// Set the block number to at least 1 so events are deposited.
if $crate::Zero::is_zero(&frame_system::Module::<T>::block_number()) {
frame_system::Module::<T>::set_block_number(1.into());
}
// Run verification
closure_to_verify()?;
// Reset the state
$crate::benchmarking::wipe_db();
}
Ok(())
}
Ok(())
}
)*
}
};
}
+30 -15
View File
@@ -30,13 +30,17 @@ use frame_support::{
use frame_system::{RawOrigin, ensure_signed, ensure_none};
decl_storage! {
trait Store for Module<T: Trait> as Test {
trait Store for Module<T: Trait> as Test where
<T as OtherTrait>::OtherEvent: Into<<T as Trait>::Event>
{
Value get(fn value): Option<u32>;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
pub struct Module<T: Trait> for enum Call where
origin: T::Origin, <T as OtherTrait>::OtherEvent: Into<<T as Trait>::Event>
{
#[weight = 0]
fn set_value(origin, n: u32) -> DispatchResult {
let _sender = ensure_signed(origin)?;
@@ -56,11 +60,16 @@ impl_outer_origin! {
pub enum Origin for Test where system = frame_system {}
}
pub trait Trait {
pub trait OtherTrait {
type OtherEvent;
}
pub trait Trait: OtherTrait where Self::OtherEvent: Into<Self::Event> {
type Event;
type BlockNumber;
type AccountId: 'static + Default + Decode;
type Origin: From<frame_system::RawOrigin<Self::AccountId>> + Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>;
type Origin: From<frame_system::RawOrigin<Self::AccountId>> +
Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>;
}
#[derive(Clone, Eq, PartialEq)]
@@ -100,6 +109,10 @@ impl Trait for Test {
type AccountId = u64;
}
impl OtherTrait for Test {
type OtherEvent = ();
}
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
fn new_test_ext() -> sp_io::TestExternalities {
@@ -107,6 +120,8 @@ fn new_test_ext() -> sp_io::TestExternalities {
}
benchmarks!{
where_clause { where <T as OtherTrait>::OtherEvent: Into<<T as Trait>::Event> }
_ {
// Define a common range for `b`.
let b in 1 .. 1000 => ();
@@ -156,13 +171,13 @@ benchmarks!{
#[test]
fn benchmarks_macro_works() {
// Check benchmark creation for `set_value`.
let selected_benchmark = SelectedBenchmark::set_value;
let selected = SelectedBenchmark::set_value;
let components = <SelectedBenchmark as BenchmarkingSetup<Test>>::components(&selected_benchmark);
let components = <SelectedBenchmark as BenchmarkingSetup<Test>>::components(&selected);
assert_eq!(components, vec![(BenchmarkParameter::b, 1, 1000)]);
let closure = <SelectedBenchmark as BenchmarkingSetup<Test>>::instance(
&selected_benchmark,
&selected,
&[(BenchmarkParameter::b, 1)],
).expect("failed to create closure");
@@ -174,12 +189,12 @@ fn benchmarks_macro_works() {
#[test]
fn benchmarks_macro_rename_works() {
// Check benchmark creation for `other_dummy`.
let selected_benchmark = SelectedBenchmark::other_name;
let components = <SelectedBenchmark as BenchmarkingSetup<Test>>::components(&selected_benchmark);
let selected = SelectedBenchmark::other_name;
let components = <SelectedBenchmark as BenchmarkingSetup<Test>>::components(&selected);
assert_eq!(components, vec![(BenchmarkParameter::b, 1, 1000)]);
let closure = <SelectedBenchmark as BenchmarkingSetup<Test>>::instance(
&selected_benchmark,
&selected,
&[(BenchmarkParameter::b, 1)],
).expect("failed to create closure");
@@ -190,13 +205,13 @@ fn benchmarks_macro_rename_works() {
#[test]
fn benchmarks_macro_works_for_non_dispatchable() {
let selected_benchmark = SelectedBenchmark::sort_vector;
let selected = SelectedBenchmark::sort_vector;
let components = <SelectedBenchmark as BenchmarkingSetup<Test>>::components(&selected_benchmark);
let components = <SelectedBenchmark as BenchmarkingSetup<Test>>::components(&selected);
assert_eq!(components, vec![(BenchmarkParameter::x, 1, 10000)]);
let closure = <SelectedBenchmark as BenchmarkingSetup<Test>>::instance(
&selected_benchmark,
&selected,
&[(BenchmarkParameter::x, 1)],
).expect("failed to create closure");
@@ -206,10 +221,10 @@ fn benchmarks_macro_works_for_non_dispatchable() {
#[test]
fn benchmarks_macro_verify_works() {
// Check postcondition for benchmark `set_value` is valid.
let selected_benchmark = SelectedBenchmark::set_value;
let selected = SelectedBenchmark::set_value;
let closure = <SelectedBenchmark as BenchmarkingSetup<Test>>::verify(
&selected_benchmark,
&selected,
&[(BenchmarkParameter::b, 1)],
).expect("failed to create closure");