Generate Unit Tests for Benchmarks (#5527)

* Update to latest staking

* generate tests for benchmarking

* add tests, fix warnings

* starting on democracy

* impl_benchmark_tests

* Way more readable

* add test feature flag (does this work?)

* Fix `successful_origin` impl

* democracry benchmark tests

* Fix example benchmarks, add tests

* identity benchmark tests

* Update im-online benchmark tests

* try to add session benchmarking tests (problem with mock)

* staking and timestamp

* add test for treasury, issue with dynamic contains

* utility

* Vesting

* test instead of check

* hide until we figure out what is wrong

* add docs

* close code

* Create custom mock for session-pallet-benchmarking

* Use refcell pattern

* make un-pub

* test-linux-stable includes `runtime-benchmarks` feature

* Revert "test-linux-stable includes `runtime-benchmarks` feature"

This reverts commit a2dab38abd18ac3eb8a6220e4a00e687740bd38c.

* run tests in `--release`

* undo balance change

* build wasm
This commit is contained in:
Shawn Tabrizi
2020-04-07 11:35:00 +02:00
committed by GitHub
parent 3e9e5e1bac
commit d3cc051419
28 changed files with 667 additions and 116 deletions
+1 -1
View File
@@ -287,7 +287,7 @@ test-runtime-benchmarks:
- $DEPLOY_TAG
script:
- cd bin/node/cli
- BUILD_DUMMY_WASM_BINARY=1 time cargo check --verbose --features runtime-benchmarks
- WASM_BUILD_NO_COLOR=1 time cargo test --release --verbose --features runtime-benchmarks
- sccache -s
test-linux-stable-int:
+9
View File
@@ -1436,6 +1436,7 @@ dependencies = [
"frame-system",
"linregress",
"parity-scale-codec",
"paste",
"sp-api",
"sp-io",
"sp-runtime",
@@ -4433,9 +4434,17 @@ name = "pallet-session-benchmarking"
version = "2.0.0-alpha.5"
dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
"pallet-balances",
"pallet-session",
"pallet-staking",
"pallet-staking-reward-curve",
"pallet-timestamp",
"parity-scale-codec",
"serde",
"sp-core",
"sp-io",
"sp-runtime",
"sp-std",
]
@@ -119,3 +119,45 @@ benchmarks! {
let _ = <Balances<T> as Currency<_>>::make_free_balance_be(&user, balance_amount);
}: set_balance(RawOrigin::Root, user_lookup, 0.into(), 0.into())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests_composite::{ExtBuilder, Test};
use frame_support::assert_ok;
#[test]
fn transfer() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(test_benchmark_transfer::<Test>());
});
}
#[test]
fn transfer_best_case() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(test_benchmark_transfer_best_case::<Test>());
});
}
#[test]
fn transfer_keep_alive() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(test_benchmark_transfer_keep_alive::<Test>());
});
}
#[test]
fn transfer_set_balance() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(test_benchmark_set_balance::<Test>());
});
}
#[test]
fn transfer_set_balance_killing() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(test_benchmark_set_balance_killing::<Test>());
});
}
}
+1
View File
@@ -10,6 +10,7 @@ description = "Macro for benchmarking a FRAME runtime."
[dependencies]
linregress = "0.1"
paste = "0.1"
codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false }
sp-api = { version = "2.0.0-alpha.5", path = "../../primitives/api", default-features = false }
sp-runtime-interface = { version = "2.0.0-alpha.5", path = "../../primitives/runtime-interface", default-features = false }
+110 -13
View File
@@ -29,6 +29,7 @@ pub use analysis::Analysis;
#[doc(hidden)]
pub use sp_io::storage::root as storage_root;
pub use sp_runtime::traits::Dispatchable;
pub use paste;
/// Construct pallet benchmarks for weighing dispatchables.
///
@@ -124,6 +125,26 @@ pub use sp_runtime::traits::Dispatchable;
/// }: { m.into_iter().collect::<BTreeSet>() }
/// }
/// ```
///
/// Test functions are automatically generated for each benchmark and are accessible to you when you
/// run `cargo test`. All tests are named `test_benchmark_<benchmark_name>`, expect you to pass them
/// the Runtime Trait, and run them in a test externalities environment. The test function runs your
/// benchmark just like a regular benchmark, but only testing at the lowest and highest values for
/// each component. The function will return `Ok(())` if the benchmarks return no errors.
///
/// You can construct benchmark tests like so:
///
/// ```ignore
/// #[test]
/// fn test_benchmarks() {
/// new_test_ext().execute_with(|| {
/// assert_ok!(test_benchmark_dummy::<Test>());
/// assert_err!(test_benchmark_other_name::<Test>(), "Bad origin");
/// assert_ok!(test_benchmark_sort_vector::<Test>());
/// assert_err!(test_benchmark_broken_benchmark::<Test>(), "You forgot to sort!");
/// });
/// }
/// ```
#[macro_export]
macro_rules! benchmarks {
(
@@ -134,9 +155,12 @@ macro_rules! benchmarks {
}
$( $rest:tt )*
) => {
$crate::benchmarks_iter!(NO_INSTANCE {
$( { $common , $common_from , $common_to , $common_instancer } )*
} ( ) $( $rest )* );
$crate::benchmarks_iter!(
NO_INSTANCE
{ $( { $common , $common_from , $common_to , $common_instancer } )* }
( )
$( $rest )*
);
}
}
@@ -150,9 +174,12 @@ macro_rules! benchmarks_instance {
}
$( $rest:tt )*
) => {
$crate::benchmarks_iter!(INSTANCE {
$( { $common , $common_from , $common_to , $common_instancer } )*
} ( ) $( $rest )* );
$crate::benchmarks_iter!(
INSTANCE
{ $( { $common , $common_from , $common_to , $common_instancer } )* }
( )
$( $rest )*
);
}
}
@@ -168,7 +195,11 @@ macro_rules! benchmarks_iter {
$( $rest:tt )*
) => {
$crate::benchmarks_iter! {
$instance { $( $common )* } ( $( $names )* ) $name { $( $code )* }: $name ( $origin $( , $arg )* ) $( $rest )*
$instance
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: $name ( $origin $( , $arg )* )
$( $rest )*
}
};
// no instance mutation arm:
@@ -181,9 +212,12 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter! {
NO_INSTANCE
{ $( $common )* } ( $( $names )* ) $name { $( $code )* }: {
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: {
<Call<T> as $crate::Dispatchable>::dispatch(Call::<T>::$dispatch($($arg),*), $origin.into())?;
} $( $rest )*
}
$( $rest )*
}
};
// instance mutation arm:
@@ -196,9 +230,12 @@ macro_rules! benchmarks_iter {
) => {
$crate::benchmarks_iter! {
INSTANCE
{ $( $common )* } ( $( $names )* ) $name { $( $code )* }: {
{ $( $common )* }
( $( $names )* )
$name { $( $code )* }: {
<Call<T, I> as $crate::Dispatchable>::dispatch(Call::<T, I>::$dispatch($($arg),*), $origin.into())?;
} $( $rest )*
}
$( $rest )*
}
};
// iteration arm:
@@ -210,14 +247,26 @@ macro_rules! benchmarks_iter {
$( $rest:tt )*
) => {
$crate::benchmark_backend! {
$instance $name { $( $common )* } { } { $eval } { $( $code )* }
$instance
$name
{ $( $common )* }
{ }
{ $eval }
{ $( $code )* }
}
$crate::benchmarks_iter!( $instance { $( $common )* } ( $( $names )* $name ) $( $rest )* );
$crate::benchmarks_iter!(
$instance
{ $( $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!( $( $names ),* );
}
}
@@ -703,6 +752,54 @@ 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
// and ensure that everything completes successfully.
#[macro_export]
macro_rules! impl_benchmark_tests {
(
$( $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);
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 the block number to 1 so events are deposited.
frame_system::Module::<T>::set_block_number(1.into());
// 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)?;
// Run the benchmark
closure_to_benchmark()?;
// Reset the state
$crate::benchmarking::wipe_db();
}
}
Ok(())
}
}
)*
}
}
/// This macro adds pallet benchmarks to a `Vec<BenchmarkBatch>` object.
///
+27 -4
View File
@@ -22,7 +22,9 @@ use super::*;
use codec::Decode;
use sp_std::prelude::*;
use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::{H256, Header}};
use frame_support::{dispatch::DispatchResult, decl_module, impl_outer_origin};
use frame_support::{
dispatch::DispatchResult, decl_module, impl_outer_origin, assert_ok, assert_err, ensure
};
use frame_system::{RawOrigin, ensure_signed, ensure_none};
decl_module! {
@@ -107,13 +109,24 @@ benchmarks!{
}: other_dummy (RawOrigin::Signed(caller), b.into())
sort_vector {
let x in 0 .. 10000;
let x in 1 .. 10000;
let mut m = Vec::<u32>::new();
for i in 0..x {
for i in (0..x).rev() {
m.push(i);
}
}: {
m.sort();
ensure!(m[0] == 0, "You forgot to sort!")
}
broken_benchmark {
let x in 1 .. 10000;
let mut m = Vec::<u32>::new();
for i in (0..x).rev() {
m.push(i);
}
}: {
ensure!(m[0] == 0, "You forgot to sort!")
}
}
@@ -157,7 +170,7 @@ fn benchmarks_macro_works_for_non_dispatchable() {
let selected_benchmark = SelectedBenchmark::sort_vector;
let components = <SelectedBenchmark as BenchmarkingSetup<Test>>::components(&selected_benchmark);
assert_eq!(components, vec![(BenchmarkParameter::x, 0, 10000)]);
assert_eq!(components, vec![(BenchmarkParameter::x, 1, 10000)]);
let closure = <SelectedBenchmark as BenchmarkingSetup<Test>>::instance(
&selected_benchmark,
@@ -166,3 +179,13 @@ fn benchmarks_macro_works_for_non_dispatchable() {
assert_eq!(closure(), Ok(()));
}
#[test]
fn benchmarks_generate_unit_tests() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_dummy::<Test>());
assert_err!(test_benchmark_other_name::<Test>(), "Bad origin");
assert_ok!(test_benchmark_sort_vector::<Test>());
assert_err!(test_benchmark_broken_benchmark::<Test>(), "You forgot to sort!");
});
}
@@ -445,3 +445,44 @@ benchmarks! {
}: _(RawOrigin::Signed(proxy), referendum_index)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{new_test_ext, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_propose::<Test>());
assert_ok!(test_benchmark_second::<Test>());
assert_ok!(test_benchmark_vote::<Test>());
assert_ok!(test_benchmark_proxy_vote::<Test>());
assert_ok!(test_benchmark_emergency_cancel::<Test>());
assert_ok!(test_benchmark_external_propose::<Test>());
assert_ok!(test_benchmark_external_propose_majority::<Test>());
assert_ok!(test_benchmark_external_propose_default::<Test>());
assert_ok!(test_benchmark_fast_track::<Test>());
assert_ok!(test_benchmark_veto_external::<Test>());
assert_ok!(test_benchmark_cancel_referendum::<Test>());
assert_ok!(test_benchmark_cancel_queued::<Test>());
assert_ok!(test_benchmark_open_proxy::<Test>());
assert_ok!(test_benchmark_activate_proxy::<Test>());
assert_ok!(test_benchmark_close_proxy::<Test>());
assert_ok!(test_benchmark_deactivate_proxy::<Test>());
assert_ok!(test_benchmark_delegate::<Test>());
assert_ok!(test_benchmark_undelegate::<Test>());
assert_ok!(test_benchmark_clear_public_proposals::<Test>());
assert_ok!(test_benchmark_note_preimage::<Test>());
assert_ok!(test_benchmark_note_imminent_preimage::<Test>());
assert_ok!(test_benchmark_reap_preimage::<Test>());
assert_ok!(test_benchmark_unlock::<Test>());
assert_ok!(test_benchmark_remove_vote::<Test>());
assert_ok!(test_benchmark_remove_other_vote::<Test>());
assert_ok!(test_benchmark_proxy_delegate::<Test>());
assert_ok!(test_benchmark_proxy_undelegate::<Test>());
assert_ok!(test_benchmark_proxy_remove_vote::<Test>());
});
}
}
+3 -1
View File
@@ -126,6 +126,8 @@ impl Contains<u64> for OneToFive {
fn sorted_members() -> Vec<u64> {
vec![1, 2, 3, 4, 5]
}
#[cfg(feature = "runtime-benchmarks")]
fn add(_m: &u64) {}
}
thread_local! {
static PREIMAGE_BYTE_DEPOSIT: RefCell<u64> = RefCell::new(0);
@@ -162,7 +164,7 @@ impl super::Trait for Test {
type Scheduler = Scheduler;
}
fn new_test_ext() -> sp_io::TestExternalities {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test>{
balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
+21 -6
View File
@@ -671,26 +671,41 @@ mod benchmarking {
// This will measure the execution time of `set_dummy` for b in [1..1000] range.
set_dummy {
let b in ...;
let caller = account("caller", 0, 0);
}: set_dummy (RawOrigin::Signed(caller), b.into())
}: set_dummy (RawOrigin::Root, b.into())
// This will measure the execution time of `set_dummy` for b in [1..10] range.
another_set_dummy {
let b in 1 .. 10;
let caller = account("caller", 0, 0);
}: set_dummy (RawOrigin::Signed(caller), b.into())
}: set_dummy (RawOrigin::Root, b.into())
// This will measure the execution time of sorting a vector.
sort_vector {
let x in 0 .. 10000;
let mut m = Vec::<u32>::new();
for i in 0..x {
for i in (0..x).rev() {
m.push(i);
}
}: {
m.sort();
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{new_test_ext, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_accumulate_dummy::<Test>());
assert_ok!(test_benchmark_set_dummy::<Test>());
assert_ok!(test_benchmark_another_set_dummy::<Test>());
assert_ok!(test_benchmark_sort_vector::<Test>());
});
}
}
}
#[cfg(test)]
@@ -764,7 +779,7 @@ mod tests {
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
fn new_test_ext() -> sp_io::TestExternalities {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
// We use default for brevity, but you can configure as desired if needed.
pallet_balances::GenesisConfig::<Test>::default().assimilate_storage(&mut t).unwrap();
@@ -280,3 +280,27 @@ benchmarks! {
}
}: _(RawOrigin::Root, caller_lookup)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{new_test_ext, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_add_registrar::<Test>());
assert_ok!(test_benchmark_set_identity::<Test>());
assert_ok!(test_benchmark_set_subs::<Test>());
assert_ok!(test_benchmark_clear_identity::<Test>());
assert_ok!(test_benchmark_request_judgement::<Test>());
assert_ok!(test_benchmark_cancel_request::<Test>());
assert_ok!(test_benchmark_set_fee::<Test>());
assert_ok!(test_benchmark_set_account_id::<Test>());
assert_ok!(test_benchmark_set_fields::<Test>());
assert_ok!(test_benchmark_provide_judgement::<Test>());
assert_ok!(test_benchmark_kill_identity::<Test>());
});
}
}
+1 -1
View File
@@ -977,7 +977,7 @@ mod tests {
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
fn new_test_ext() -> sp_io::TestExternalities {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
// We use default for brevity, but you can configure as desired if needed.
pallet_balances::GenesisConfig::<Test> {
+5 -36
View File
@@ -79,46 +79,15 @@ benchmarks! {
#[cfg(test)]
mod tests {
use crate::*;
use super::SelectedBenchmark;
use crate::mock::*;
use super::*;
use crate::mock::{new_test_ext, Runtime};
use frame_support::assert_ok;
#[test]
fn test_heartbeat_benchmark() {
fn test_benchmarks() {
new_test_ext().execute_with(|| {
let k = 10;
assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 0);
let selected_benchmark = SelectedBenchmark::heartbeat;
let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)];
let closure_to_benchmark =
<SelectedBenchmark as frame_benchmarking::BenchmarkingSetup<Runtime>>::instance(
&selected_benchmark,
&c
).unwrap();
assert_ok!(closure_to_benchmark());
assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 1);
});
}
#[test]
fn test_validate_unsigned_benchmark() {
new_test_ext().execute_with(|| {
let k = 10;
let selected_benchmark = SelectedBenchmark::validate_unsigned;
let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)];
let closure_to_benchmark =
<SelectedBenchmark as frame_benchmarking::BenchmarkingSetup<Runtime>>::instance(
&selected_benchmark,
&c
).unwrap();
assert_ok!(closure_to_benchmark());
assert_ok!(test_benchmark_heartbeat::<Runtime>());
assert_ok!(test_benchmark_validate_unsigned::<Runtime>());
});
}
}
@@ -13,9 +13,19 @@ sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../..
sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" }
frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../system" }
frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../benchmarking" }
frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../support" }
pallet-staking = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" }
pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../session" }
[dev-dependencies]
serde = { version = "1.0.101" }
codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] }
sp-core = { version = "2.0.0-alpha.5", path = "../../../primitives/core" }
pallet-staking-reward-curve = { version = "2.0.0-alpha.5", path = "../../staking/reward-curve" }
sp-io ={ path = "../../../primitives/io", version = "2.0.0-alpha.5"}
pallet-timestamp = { version = "2.0.0-alpha.5", path = "../../timestamp" }
pallet-balances = { version = "2.0.0-alpha.5", path = "../../balances" }
[features]
default = ["std"]
std = [
@@ -23,6 +33,7 @@ std = [
"sp-runtime/std",
"frame-system/std",
"frame-benchmarking/std",
"frame-support/std",
"pallet-staking/std",
"pallet-session/std",
]
@@ -19,6 +19,8 @@
#![cfg_attr(not(feature = "std"), no_std)]
mod mock;
use sp_std::prelude::*;
use sp_std::vec;
@@ -42,16 +44,33 @@ benchmarks! {
set_keys {
let n in 1 .. MAX_NOMINATIONS as u32;
let validator = create_validator_with_nominators::<T>(n, MAX_NOMINATIONS as u32)?;
let v_stash = create_validator_with_nominators::<T>(n, MAX_NOMINATIONS as u32)?;
let v_controller = pallet_staking::Module::<T>::bonded(&v_stash).ok_or("not stash")?;
let keys = T::Keys::default();
let proof: Vec<u8> = vec![0,1,2,3];
}: _(RawOrigin::Signed(validator), keys, proof)
}: _(RawOrigin::Signed(v_controller), keys, proof)
purge_keys {
let n in 1 .. MAX_NOMINATIONS as u32;
let validator = create_validator_with_nominators::<T>(n, MAX_NOMINATIONS as u32)?;
let v_stash = create_validator_with_nominators::<T>(n, MAX_NOMINATIONS as u32)?;
let v_controller = pallet_staking::Module::<T>::bonded(&v_stash).ok_or("not stash")?;
let keys = T::Keys::default();
let proof: Vec<u8> = vec![0,1,2,3];
Session::<T>::set_keys(RawOrigin::Signed(validator.clone()).into(), keys, proof)?;
}: _(RawOrigin::Signed(validator))
Session::<T>::set_keys(RawOrigin::Signed(v_controller.clone()).into(), keys, proof)?;
}: _(RawOrigin::Signed(v_controller))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{new_test_ext, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_set_keys::<Test>());
assert_ok!(test_benchmark_purge_keys::<Test>());
});
}
}
@@ -0,0 +1,184 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Mock file for staking fuzzing.
#![cfg(test)]
use sp_runtime::traits::{Convert, SaturatedConversion, IdentityLookup};
use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types};
type AccountId = u64;
type AccountIndex = u32;
type BlockNumber = u64;
type Balance = u64;
type System = frame_system::Module<Test>;
type Balances = pallet_balances::Module<Test>;
type Staking = pallet_staking::Module<Test>;
type Session = pallet_session::Module<Test>;
impl_outer_origin! {
pub enum Origin for Test where system = frame_system {}
}
impl_outer_dispatch! {
pub enum Call for Test where origin: Origin {
pallet_staking::Staking,
}
}
pub struct CurrencyToVoteHandler;
impl Convert<u64, u64> for CurrencyToVoteHandler {
fn convert(x: u64) -> u64 {
x
}
}
impl Convert<u128, u64> for CurrencyToVoteHandler {
fn convert(x: u128) -> u64 {
x.saturated_into()
}
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Test;
impl frame_system::Trait for Test {
type Origin = Origin;
type Index = AccountIndex;
type BlockNumber = BlockNumber;
type Call = Call;
type Hash = sp_core::H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = sp_runtime::testing::Header;
type Event = ();
type BlockHashCount = ();
type MaximumBlockWeight = ();
type AvailableBlockRatio = ();
type MaximumBlockLength = ();
type Version = ();
type ModuleToIndex = ();
type AccountData = pallet_balances::AccountData<u64>;
type OnNewAccount = ();
type OnKilledAccount = (Balances,);
}
parameter_types! {
pub const ExistentialDeposit: Balance = 10;
}
impl pallet_balances::Trait for Test {
type Balance = Balance;
type Event = ();
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
}
parameter_types! {
pub const MinimumPeriod: u64 = 5;
}
impl pallet_timestamp::Trait for Test {
type Moment = u64;
type OnTimestampSet = ();
type MinimumPeriod = MinimumPeriod;
}
impl pallet_session::historical::Trait for Test {
type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
type FullIdentificationOf = pallet_staking::ExposureOf<Test>;
}
sp_runtime::impl_opaque_keys! {
pub struct SessionKeys {
pub foo: sp_runtime::testing::UintAuthorityId,
}
}
pub struct TestSessionHandler;
impl pallet_session::SessionHandler<AccountId> for TestSessionHandler {
const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[];
fn on_genesis_session<Ks: sp_runtime::traits::OpaqueKeys>(_validators: &[(AccountId, Ks)]) {}
fn on_new_session<Ks: sp_runtime::traits::OpaqueKeys>(
_: bool,
_: &[(AccountId, Ks)],
_: &[(AccountId, Ks)],
) {}
fn on_disabled(_: usize) {}
}
impl pallet_session::Trait for Test {
type SessionManager = pallet_session::historical::NoteHistoricalRoot<Test, Staking>;
type Keys = SessionKeys;
type ShouldEndSession = pallet_session::PeriodicSessions<(), ()>;
type NextSessionRotation = pallet_session::PeriodicSessions<(), ()>;
type SessionHandler = TestSessionHandler;
type Event = ();
type ValidatorId = AccountId;
type ValidatorIdOf = pallet_staking::StashOf<Test>;
type DisabledValidatorsThreshold = ();
}
pallet_staking_reward_curve::build! {
const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!(
min_inflation: 0_025_000,
max_inflation: 0_100_000,
ideal_stake: 0_500_000,
falloff: 0_050_000,
max_piece_count: 40,
test_precision: 0_005_000,
);
}
parameter_types! {
pub const RewardCurve: &'static sp_runtime::curve::PiecewiseLinear<'static> = &I_NPOS;
pub const MaxNominatorRewardedPerValidator: u32 = 64;
}
pub type Extrinsic = sp_runtime::testing::TestXt<Call, ()>;
type SubmitTransaction = frame_system::offchain::TransactionSubmitter<
sp_runtime::testing::UintAuthorityId,
Test,
Extrinsic,
>;
impl pallet_staking::Trait for Test {
type Currency = Balances;
type UnixTime = pallet_timestamp::Module<Self>;
type CurrencyToVote = CurrencyToVoteHandler;
type RewardRemainder = ();
type Event = ();
type Slash = ();
type Reward = ();
type SessionsPerEra = ();
type SlashDeferDuration = ();
type SlashCancelOrigin = frame_system::EnsureRoot<Self::AccountId>;
type BondingDuration = ();
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type NextNewSession = Session;
type ElectionLookahead = ();
type Call = Call;
type SubmitTransaction = SubmitTransaction;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
}
impl crate::Trait for Test {}
pub fn new_test_ext() -> sp_io::TestExternalities {
let t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
sp_io::TestExternalities::new(t)
}
+10
View File
@@ -150,6 +150,16 @@ pub fn reset_before_session_end_called() {
BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = false);
}
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
GenesisConfig::<Test> {
keys: NEXT_VALIDATORS.with(|l|
l.borrow().iter().cloned().map(|i| (i, i, UintAuthorityId(i).into())).collect()
),
}.assimilate_storage(&mut t).unwrap();
sp_io::TestExternalities::new(t)
}
#[derive(Clone, Eq, PartialEq)]
pub struct Test;
+3 -13
View File
@@ -21,21 +21,11 @@ use frame_support::{traits::OnInitialize, assert_ok};
use sp_core::crypto::key_types::DUMMY;
use sp_runtime::testing::UintAuthorityId;
use mock::{
NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session,
set_next_validators, set_session_length, session_changed, Test, Origin, System, Session,
reset_before_session_end_called, before_session_end_called,
SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session,
set_next_validators, set_session_length, session_changed, Origin, System, Session,
reset_before_session_end_called, before_session_end_called, new_test_ext,
};
fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
GenesisConfig::<Test> {
keys: NEXT_VALIDATORS.with(|l|
l.borrow().iter().cloned().map(|i| (i, i, UintAuthorityId(i).into())).collect()
),
}.assimilate_storage(&mut t).unwrap();
sp_io::TestExternalities::new(t)
}
fn initialize_block(block: u64) {
SESSION_CHANGED.with(|l| *l.borrow_mut() = false);
System::set_block_number(block);
+39 -19
View File
@@ -98,8 +98,8 @@ pub fn create_validators_with_nominators_for_era<T: Trait>(v: u32, n: u32) -> Re
Ok(())
}
// This function generates one validator being nominated by n nominators.
// It starts an era and creates pending payouts.
// This function generates one validator being nominated by n nominators, and returns
//the validator stash account. It also starts an era and creates pending payouts.
pub fn create_validator_with_nominators<T: Trait>(n: u32, upper_bound: u32) -> Result<T::AccountId, &'static str> {
let mut points_total = 0;
let mut points_individual = Vec::new();
@@ -114,7 +114,7 @@ pub fn create_validator_with_nominators<T: Trait>(n: u32, upper_bound: u32) -> R
let stash_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(v_stash.clone());
points_total += 10;
points_individual.push((v_stash, 10));
points_individual.push((v_stash.clone(), 10));
// Give the validator n nominators, but keep total users in the system the same.
for i in 0 .. upper_bound {
@@ -144,7 +144,7 @@ pub fn create_validator_with_nominators<T: Trait>(n: u32, upper_bound: u32) -> R
let total_payout = T::Currency::minimum_balance() * 1000.into();
<ErasValidatorReward<T>>::insert(current_era, total_payout);
Ok(v_controller)
Ok(v_stash)
}
benchmarks! {
@@ -368,16 +368,10 @@ benchmarks! {
#[cfg(test)]
mod tests {
use crate::*;
use crate::mock::*;
use super::*;
use crate::mock::{ExtBuilder, Test, Balances, Staking, Origin};
use frame_support::assert_ok;
use crate::benchmarking::{
create_validators_with_nominators_for_era,
create_validator_with_nominators,
SelectedBenchmark,
};
#[test]
fn create_validators_with_nominators_for_era_works() {
ExtBuilder::default().has_stakers(false).build().execute_with(|| {
@@ -399,19 +393,16 @@ mod tests {
ExtBuilder::default().has_stakers(false).build().execute_with(|| {
let n = 10;
let validator = create_validator_with_nominators::<Test>(
let validator_stash = create_validator_with_nominators::<Test>(
n,
MAX_NOMINATIONS as u32,
).unwrap();
let current_era = CurrentEra::get().unwrap();
let controller = validator;
let ledger = Staking::ledger(&controller).unwrap();
let stash = ledger.stash;
let original_free_balance = Balances::free_balance(&stash);
assert_ok!(Staking::payout_stakers(Origin::signed(1337), stash, current_era));
let new_free_balance = Balances::free_balance(&stash);
let original_free_balance = Balances::free_balance(&validator_stash);
assert_ok!(Staking::payout_stakers(Origin::signed(1337), validator_stash, current_era));
let new_free_balance = Balances::free_balance(&validator_stash);
assert!(original_free_balance < new_free_balance);
});
@@ -434,4 +425,33 @@ mod tests {
assert_ok!(closure_to_benchmark());
});
}
#[test]
fn test_benchmarks() {
ExtBuilder::default().has_stakers(false).build().execute_with(|| {
assert_ok!(test_benchmark_bond::<Test>());
assert_ok!(test_benchmark_bond_extra::<Test>());
assert_ok!(test_benchmark_unbond::<Test>());
assert_ok!(test_benchmark_withdraw_unbonded::<Test>());
assert_ok!(test_benchmark_validate::<Test>());
assert_ok!(test_benchmark_nominate::<Test>());
assert_ok!(test_benchmark_chill::<Test>());
assert_ok!(test_benchmark_set_payee::<Test>());
assert_ok!(test_benchmark_set_controller::<Test>());
assert_ok!(test_benchmark_set_validator_count::<Test>());
assert_ok!(test_benchmark_force_no_eras::<Test>());
assert_ok!(test_benchmark_force_new_era::<Test>());
assert_ok!(test_benchmark_force_new_era_always::<Test>());
assert_ok!(test_benchmark_set_invulnerables::<Test>());
assert_ok!(test_benchmark_force_unstake::<Test>());
assert_ok!(test_benchmark_cancel_deferred_slash::<Test>());
assert_ok!(test_benchmark_payout_stakers::<Test>());
assert_ok!(test_benchmark_rebond::<Test>());
assert_ok!(test_benchmark_set_history_depth::<Test>());
assert_ok!(test_benchmark_reap_stash::<Test>());
assert_ok!(test_benchmark_new_era::<Test>());
assert_ok!(test_benchmark_do_slash::<Test>());
assert_ok!(test_benchmark_payout_all::<Test>());
});
}
}
+2
View File
@@ -140,6 +140,8 @@ macro_rules! ord_parameter_types {
fn contains(t: &$type) -> bool { &$value == t }
fn sorted_members() -> $crate::sp_std::prelude::Vec<$type> { vec![$value] }
fn count() -> usize { 1 }
#[cfg(feature = "runtime-benchmarks")]
fn add(_: &$type) {}
}
}
}
+6 -3
View File
@@ -620,9 +620,12 @@ impl<
#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> O {
let caller: AccountId = Default::default();
// Who::add(&caller);
O::from(RawOrigin::Signed(caller))
let members = Who::sorted_members();
let first_member = match members.get(0) {
Some(account) => account.clone(),
None => Default::default(),
};
O::from(RawOrigin::Signed(first_member.clone()))
}
}
@@ -34,3 +34,17 @@ benchmarks! {
let n in ...;
}: _(RawOrigin::None, n.into())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{new_test_ext, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_set::<Test>());
});
}
}
+8 -6
View File
@@ -271,6 +271,11 @@ mod tests {
use sp_core::H256;
use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header};
pub fn new_test_ext() -> TestExternalities {
let t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
TestExternalities::new(t)
}
impl_outer_origin! {
pub enum Origin for Test where system = frame_system {}
}
@@ -316,8 +321,7 @@ mod tests {
#[test]
fn timestamp_works() {
let t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
TestExternalities::new(t).execute_with(|| {
new_test_ext().execute_with(|| {
Timestamp::set_timestamp(42);
assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE));
assert_eq!(Timestamp::now(), 69);
@@ -327,8 +331,7 @@ mod tests {
#[test]
#[should_panic(expected = "Timestamp must be updated only once in the block")]
fn double_timestamp_should_fail() {
let t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
TestExternalities::new(t).execute_with(|| {
new_test_ext().execute_with(|| {
Timestamp::set_timestamp(42);
assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE));
let _ = Timestamp::dispatch(Call::set(70), Origin::NONE);
@@ -338,8 +341,7 @@ mod tests {
#[test]
#[should_panic(expected = "Timestamp must increment by at least <MinimumPeriod> between sequential blocks")]
fn block_period_minimum_enforced() {
let t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
TestExternalities::new(t).execute_with(|| {
new_test_ext().execute_with(|| {
Timestamp::set_timestamp(42);
let _ = Timestamp::dispatch(Call::set(46), Origin::NONE);
});
@@ -217,3 +217,25 @@ benchmarks! {
Treasury::<T>::on_initialize(T::BlockNumber::zero());
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{new_test_ext, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_propose_spend::<Test>());
assert_ok!(test_benchmark_reject_proposal::<Test>());
assert_ok!(test_benchmark_approve_proposal::<Test>());
assert_ok!(test_benchmark_report_awesome::<Test>());
assert_ok!(test_benchmark_retract_tip::<Test>());
assert_ok!(test_benchmark_tip_new::<Test>());
assert_ok!(test_benchmark_tip::<Test>());
assert_ok!(test_benchmark_close_tip::<Test>());
assert_ok!(test_benchmark_on_initialize::<Test>());
});
}
}
+15 -7
View File
@@ -19,7 +19,7 @@
#![cfg(test)]
use super::*;
use std::cell::RefCell;
use frame_support::{
assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight,
traits::{Contains, OnInitialize}
@@ -74,16 +74,24 @@ impl pallet_balances::Trait for Test {
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
}
thread_local! {
static TEN_TO_FOURTEEN: RefCell<Vec<u64>> = RefCell::new(vec![10,11,12,13,14]);
}
pub struct TenToFourteen;
impl Contains<u64> for TenToFourteen {
fn contains(n: &u64) -> bool {
*n >= 10 && *n <= 14
}
fn sorted_members() -> Vec<u64> {
vec![10, 11, 12, 13, 14]
TEN_TO_FOURTEEN.with(|v| {
v.borrow().clone()
})
}
#[cfg(feature = "runtime-benchmarks")]
fn add(_: &u64) { unimplemented!() }
fn add(new: &u64) {
TEN_TO_FOURTEEN.with(|v| {
let mut members = v.borrow_mut();
members.push(*new);
members.sort();
})
}
}
parameter_types! {
pub const ProposalBond: Permill = Permill::from_percent(5);
@@ -115,7 +123,7 @@ type System = frame_system::Module<Test>;
type Balances = pallet_balances::Module<Test>;
type Treasury = Module<Test>;
fn new_test_ext() -> sp_io::TestExternalities {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test>{
// Total issuance will be 200 with treasury account initialized at ED.
@@ -146,3 +146,24 @@ benchmarks! {
Utility::<T>::as_multi(RawOrigin::Signed(caller.clone()).into(), s as u16, signatories.clone(), None, call.clone())?;
}: _(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{new_test_ext, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_batch::<Test>());
assert_ok!(test_benchmark_as_sub::<Test>());
assert_ok!(test_benchmark_as_multi_create::<Test>());
assert_ok!(test_benchmark_as_multi_approve::<Test>());
assert_ok!(test_benchmark_as_multi_complete::<Test>());
assert_ok!(test_benchmark_approve_as_multi_create::<Test>());
assert_ok!(test_benchmark_approve_as_multi_approve::<Test>());
assert_ok!(test_benchmark_cancel_as_multi::<Test>());
});
}
}
+1 -1
View File
@@ -109,7 +109,7 @@ type Utility = Module<Test>;
use pallet_balances::Call as BalancesCall;
use pallet_balances::Error as BalancesError;
fn new_test_ext() -> sp_io::TestExternalities {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test> {
balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 10)],
@@ -124,3 +124,21 @@ benchmarks! {
}: _(RawOrigin::Signed(from), to_lookup, vesting_schedule)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::{ExtBuilder, Test};
use frame_support::assert_ok;
#[test]
fn test_benchmarks() {
ExtBuilder::default().existential_deposit(256).build().execute_with(|| {
assert_ok!(test_benchmark_vest_locked::<Test>());
assert_ok!(test_benchmark_vest_not_locked::<Test>());
assert_ok!(test_benchmark_vest_other_locked::<Test>());
assert_ok!(test_benchmark_vest_other_not_locked::<Test>());
assert_ok!(test_benchmark_vested_transfer::<Test>());
});
}
}
@@ -364,6 +364,10 @@ impl<H: Hasher> Backend<H> for InMemory<H> where H::Out: Codec {
fn usage_info(&self) -> UsageInfo {
UsageInfo::empty()
}
fn wipe(&self) -> Result<(), Self::Error> {
Ok(())
}
}
#[cfg(test)]