Impl integrity test for runtime (#6356)

* impl integrity test for runtime

* Update frame/support/src/traits.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update frame/support/procedural/src/construct_runtime/mod.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* use thread local

* update doc

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Gavin Wood <gavin@parity.io>
This commit is contained in:
Guillaume Thiolliere
2020-06-16 13:10:10 +02:00
committed by GitHub
parent 34f496eb3d
commit 622dff9ca7
6 changed files with 175 additions and 5 deletions
+125 -4
View File
@@ -269,8 +269,11 @@ impl<T> Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {}
/// * `fn on_finalize() -> frame_support::weights::Weight`
///
/// * `offchain_worker`: Executes at the beginning of a block and produces extrinsics for a future block
/// upon completion. Using this function will implement the
/// [`OffchainWorker`](./traits/trait.OffchainWorker.html) trait.
/// upon completion. Using this function will implement the
/// [`OffchainWorker`](./traits/trait.OffchainWorker.html) trait.
/// * `integrity_test`: Executes in a test generated by `construct_runtime`, note it doesn't
/// execute in an externalities-provided environment. Implement
/// [`IntegrityTest`](./trait.IntegrityTest.html) trait.
#[macro_export]
macro_rules! decl_module {
// Entry point #1.
@@ -298,6 +301,7 @@ macro_rules! decl_module {
{}
{}
{}
{}
[]
$($t)*
);
@@ -331,6 +335,7 @@ macro_rules! decl_module {
{}
{}
{}
{}
[]
$($t)*
);
@@ -349,6 +354,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$vis:vis fn deposit_event() = default;
@@ -366,6 +372,7 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
[ $( $dispatchables )* ]
$($rest)*
);
@@ -382,6 +389,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$vis:vis fn deposit_event
@@ -404,6 +412,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
@@ -423,6 +432,7 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
[ $( $dispatchables )* ]
$($rest)*
);
@@ -440,6 +450,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
@@ -466,6 +477,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
@@ -490,6 +502,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
@@ -516,6 +529,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* }
@@ -535,6 +549,48 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
[ $( $dispatchables )* ]
$($rest)*
);
};
// Add integrity_test
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{}
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn integrity_test() { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{
$(#[doc = $doc_attr])*
fn integrity_test() { $( $impl)* }
}
[ $( $dispatchables )* ]
$($rest)*
);
@@ -554,6 +610,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
@@ -578,6 +635,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
@@ -604,6 +662,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* }
@@ -623,6 +682,7 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
[ $( $dispatchables )* ]
$($rest)*
);
@@ -642,6 +702,7 @@ macro_rules! decl_module {
{ }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn offchain_worker( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
@@ -661,6 +722,7 @@ macro_rules! decl_module {
{ fn offchain_worker( $( $param_name : $param ),* ) { $( $impl )* } }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
[ $( $dispatchables )* ]
$($rest)*
);
@@ -682,6 +744,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$( #[doc = $doc_attr:tt] )*
const $name:ident: $ty:ty = $value:expr;
@@ -706,6 +769,7 @@ macro_rules! decl_module {
$name: $ty = $value;
}
{ $( $error_type )* }
{ $( $integrity_test)* }
[ $( $dispatchables )* ]
$($rest)*
);
@@ -727,6 +791,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
type Error = $error_type:ty;
@@ -746,6 +811,7 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ $error_type }
{ $( $integrity_test)* }
[ $( $dispatchables )* ]
$($rest)*
);
@@ -766,6 +832,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ }
{ $( $integrity_test:tt )* }
[ $($t:tt)* ]
$($rest:tt)*
) => {
@@ -783,6 +850,7 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ &'static str }
{ $( $integrity_test)* }
[ $($t)* ]
$($rest)*
);
@@ -804,6 +872,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $error_type:ty }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
@@ -826,6 +895,7 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ $error_type }
{ $( $integrity_test)* }
[
$( $dispatchables )*
$(#[doc = $doc_attr])*
@@ -854,6 +924,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$fn_vis:vis fn $fn_name:ident(
@@ -880,6 +951,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[weight = $weight:expr])?
@@ -906,6 +978,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[weight = $weight:expr])?
@@ -932,6 +1005,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[weight = $weight:expr])?
@@ -959,6 +1033,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
[ $( $dispatchables:tt )* ]
) => {
$crate::decl_module!(@imp
@@ -975,6 +1050,7 @@ macro_rules! decl_module {
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
);
};
@@ -1081,6 +1157,32 @@ macro_rules! decl_module {
{}
};
(@impl_integrity_test
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
$(#[doc = $doc_attr:tt])*
fn integrity_test() { $( $impl:tt )* }
) => {
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::IntegrityTest
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
$(#[doc = $doc_attr])*
fn integrity_test() {
$( $impl )*
}
}
};
(@impl_integrity_test
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::IntegrityTest
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{}
};
(@impl_on_finalize
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
@@ -1340,6 +1442,7 @@ macro_rules! decl_module {
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $error_type:ty }
{ $( $integrity_test:tt )* }
) => {
$crate::__check_reserved_fn_name! { $( $fn_name )* }
@@ -1366,7 +1469,6 @@ macro_rules! decl_module {
$( $on_runtime_upgrade )*
}
$crate::decl_module! {
@impl_on_finalize
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
@@ -1388,6 +1490,13 @@ macro_rules! decl_module {
$( $deposit_event )*
}
$crate::decl_module! {
@impl_integrity_test
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $integrity_test )*
}
/// Can also be called using [`Call`].
///
/// [`Call`]: enum.Call.html
@@ -2015,6 +2124,9 @@ macro_rules! __check_reserved_fn_name {
(offchain_worker $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error offchain_worker);
};
(integrity_test $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error integrity_test);
};
($t:ident $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!($( $rest )*);
};
@@ -2050,7 +2162,8 @@ mod tests {
use super::*;
use crate::weights::{DispatchInfo, DispatchClass, Pays};
use crate::traits::{
CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade
CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade,
IntegrityTest,
};
pub trait Trait: system::Trait + Sized where Self::AccountId: From<u32> {
@@ -2112,6 +2225,8 @@ mod tests {
fn on_finalize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_finalize") } }
fn on_runtime_upgrade() -> Weight { 10 }
fn offchain_worker() {}
/// Some doc
fn integrity_test() { panic!("integrity_test") }
}
}
@@ -2303,4 +2418,10 @@ mod tests {
let module_names = OuterCall::get_module_names();
assert_eq!(["Test"], module_names);
}
#[test]
#[should_panic(expected = "integrity_test")]
fn integrity_test_should_work() {
<Module<TraitImpl> as IntegrityTest>::integrity_test();
}
}
+11
View File
@@ -192,6 +192,17 @@ macro_rules! impl_filter_stack {
}
}
/// Type that provide some integrity tests.
///
/// This implemented for modules by `decl_module`.
#[impl_for_tuples(30)]
pub trait IntegrityTest {
/// Run integrity test.
///
/// The test is not executed in a externalities provided environment.
fn integrity_test() {}
}
#[cfg(test)]
mod test_impl_filter_stack {
use super::*;