// This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! Tests for the benchmark macro for instantiable modules #![cfg(test)] use frame_support::{derive_impl, traits::ConstU32}; use sp_runtime::{ testing::H256, traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; use sp_std::prelude::*; #[frame_support::pallet] mod pallet_test { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; #[pallet::pallet] pub struct Pallet(PhantomData<(T, I)>); pub trait OtherConfig { type OtherEvent; } #[pallet::config] pub trait Config: frame_system::Config + OtherConfig { type RuntimeEvent: From> + IsType<::RuntimeEvent>; type LowerBound: Get; type UpperBound: Get; } #[pallet::storage] pub(crate) type Value, I: 'static = ()> = StorageValue<_, u32, OptionQuery>; #[pallet::event] pub enum Event, I: 'static = ()> {} #[pallet::call] impl, I: 'static> Pallet where ::OtherEvent: Into<>::RuntimeEvent>, { #[pallet::call_index(0)] #[pallet::weight({0})] pub fn set_value(origin: OriginFor, n: u32) -> DispatchResult { let _sender = ensure_signed(origin)?; Value::::put(n); Ok(()) } #[pallet::call_index(1)] #[pallet::weight({0})] pub fn dummy(origin: OriginFor, _n: u32) -> DispatchResult { let _sender = ensure_none(origin)?; Ok(()) } } } type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { System: frame_system::{Pallet, Call, Config, Storage, Event}, TestPallet: pallet_test::{Pallet, Call, Storage, Event}, } ); #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type Nonce = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Block = Block; type RuntimeEvent = RuntimeEvent; type BlockHashCount = (); type DbWeight = (); type Version = (); type PalletInfo = PalletInfo; type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = ConstU32<16>; } impl pallet_test::Config for Test { type RuntimeEvent = RuntimeEvent; type LowerBound = ConstU32<1>; type UpperBound = ConstU32<100>; } impl pallet_test::OtherConfig for Test { type OtherEvent = RuntimeEvent; } fn new_test_ext() -> sp_io::TestExternalities { RuntimeGenesisConfig::default().build_storage().unwrap().into() } mod benchmarks { use super::pallet_test::{self, Value}; use crate::account; use frame_support::ensure; use frame_system::RawOrigin; use sp_std::prelude::*; // Additional used internally by the benchmark macro. use super::pallet_test::{Call, Config, Pallet}; crate::benchmarks_instance_pallet! { where_clause { where ::OtherEvent: Clone + Into<>::RuntimeEvent>, >::RuntimeEvent: Clone, } set_value { let b in 1 .. 1000; let caller = account::("caller", 0, 0); }: _ (RawOrigin::Signed(caller), b.into()) verify { assert_eq!(Value::::get(), Some(b)); } other_name { let b in 1 .. 1000; }: dummy (RawOrigin::None, b.into()) sort_vector { let x in 1 .. 10000; let mut m = Vec::::new(); for i in (0..x).rev() { m.push(i); } }: { m.sort(); } verify { ensure!(m[0] == 0, "You forgot to sort!") } impl_benchmark_test_suite!( Pallet, crate::tests_instance::new_test_ext(), crate::tests_instance::Test ) } }