diff --git a/substrate/frame/timestamp/src/benchmarking.rs b/substrate/frame/timestamp/src/benchmarking.rs index 0da71dbdd1..8974eb9569 100644 --- a/substrate/frame/timestamp/src/benchmarking.rs +++ b/substrate/frame/timestamp/src/benchmarking.rs @@ -56,5 +56,5 @@ benchmarks! { ensure!(!DidUpdate::::exists(), "Time was not removed."); } - impl_benchmark_test_suite!(Timestamp, crate::tests::new_test_ext(), crate::tests::Test); + impl_benchmark_test_suite!(Timestamp, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/substrate/frame/timestamp/src/lib.rs b/substrate/frame/timestamp/src/lib.rs index c75a0ac976..81ed67913c 100644 --- a/substrate/frame/timestamp/src/lib.rs +++ b/substrate/frame/timestamp/src/lib.rs @@ -103,6 +103,10 @@ #![cfg_attr(not(feature = "std"), no_std)] mod benchmarking; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; pub mod weights; use frame_support::traits::{OnTimestampSet, Time, UnixTime}; @@ -309,107 +313,3 @@ impl UnixTime for Pallet { core::time::Duration::from_millis(now.saturated_into::()) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate as pallet_timestamp; - - use frame_support::{ - assert_ok, parameter_types, - traits::{ConstU32, ConstU64}, - }; - use sp_core::H256; - use sp_io::TestExternalities; - use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, - }; - - pub fn new_test_ext() -> TestExternalities { - let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - TestExternalities::new(t) - } - - type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; - type Block = frame_system::mocking::MockBlock; - - frame_support::construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - } - ); - - parameter_types! { - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); - } - impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = Call; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type BlockHashCount = ConstU64<250>; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; - } - - impl Config for Test { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = ConstU64<5>; - type WeightInfo = (); - } - - #[test] - fn timestamp_works() { - new_test_ext().execute_with(|| { - Timestamp::set_timestamp(42); - assert_ok!(Timestamp::set(Origin::none(), 69)); - assert_eq!(Timestamp::now(), 69); - }); - } - - #[test] - #[should_panic(expected = "Timestamp must be updated only once in the block")] - fn double_timestamp_should_fail() { - new_test_ext().execute_with(|| { - Timestamp::set_timestamp(42); - assert_ok!(Timestamp::set(Origin::none(), 69)); - let _ = Timestamp::set(Origin::none(), 70); - }); - } - - #[test] - #[should_panic( - expected = "Timestamp must increment by at least between sequential blocks" - )] - fn block_period_minimum_enforced() { - new_test_ext().execute_with(|| { - Timestamp::set_timestamp(42); - let _ = Timestamp::set(Origin::none(), 46); - }); - } -} diff --git a/substrate/frame/timestamp/src/mock.rs b/substrate/frame/timestamp/src/mock.rs new file mode 100644 index 0000000000..9536414c54 --- /dev/null +++ b/substrate/frame/timestamp/src/mock.rs @@ -0,0 +1,111 @@ +// This file is part of Substrate. + +// Copyright (C) 2020-2022 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 Utilities. + +use super::*; +use crate as pallet_timestamp; +use sp_std::cell::RefCell; + +use frame_support::{ + parameter_types, + traits::{ConstU32, ConstU64}, +}; +use sp_core::H256; +use sp_io::TestExternalities; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; +type Moment = u64; + +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + } +); + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); +} +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = Call; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +thread_local! { + pub static CAPTURED_MOMENT: RefCell> = RefCell::new(None); +} + +pub struct MockOnTimestampSet; +impl OnTimestampSet for MockOnTimestampSet { + fn on_timestamp_set(moment: Moment) { + CAPTURED_MOMENT.with(|x| *x.borrow_mut() = Some(moment)); + } +} + +impl Config for Test { + type Moment = Moment; + type OnTimestampSet = MockOnTimestampSet; + type MinimumPeriod = ConstU64<5>; + type WeightInfo = (); +} + +pub(crate) fn clear_captured_moment() { + CAPTURED_MOMENT.with(|x| *x.borrow_mut() = None); +} + +pub(crate) fn get_captured_moment() -> Option { + CAPTURED_MOMENT.with(|x| x.borrow().clone()) +} + +pub(crate) fn new_test_ext() -> TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + clear_captured_moment(); + TestExternalities::new(t) +} diff --git a/substrate/frame/timestamp/src/tests.rs b/substrate/frame/timestamp/src/tests.rs new file mode 100644 index 0000000000..f52ba7849c --- /dev/null +++ b/substrate/frame/timestamp/src/tests.rs @@ -0,0 +1,52 @@ +// This file is part of Substrate. + +// Copyright (C) 2020-2022 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 Timestamp module. + +use crate::mock::*; +use frame_support::assert_ok; + +#[test] +fn timestamp_works() { + new_test_ext().execute_with(|| { + Timestamp::set_timestamp(42); + assert_ok!(Timestamp::set(Origin::none(), 69)); + assert_eq!(Timestamp::now(), 69); + assert_eq!(Some(69), get_captured_moment()); + }); +} + +#[test] +#[should_panic(expected = "Timestamp must be updated only once in the block")] +fn double_timestamp_should_fail() { + new_test_ext().execute_with(|| { + Timestamp::set_timestamp(42); + assert_ok!(Timestamp::set(Origin::none(), 69)); + let _ = Timestamp::set(Origin::none(), 70); + }); +} + +#[test] +#[should_panic( + expected = "Timestamp must increment by at least between sequential blocks" +)] +fn block_period_minimum_enforced() { + new_test_ext().execute_with(|| { + Timestamp::set_timestamp(42); + let _ = Timestamp::set(Origin::none(), 46); + }); +}