Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Apr 19, 2023
1 parent 6e21fe8 commit c80e940
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 16 deletions.
21 changes: 20 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions libs/mocks/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ pub mod pallet {
T::Data: Clone,
T::Moment: Clone,
{
fn data(
fn get(
&self,
data_id: &T::DataId,
) -> Result<Option<(T::Data, T::Moment)>, DispatchError> {
Ok(self
.0
.get(&data_id)
.get(data_id)
.ok_or(DispatchError::CannotLookup)?
.clone())
}
Expand Down
2 changes: 1 addition & 1 deletion libs/traits/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ pub trait DataRegistry {
/// Abstration to represent a collection of datas in memory
pub trait DataCollection<DataId, Data, Moment> {
/// Return the last data value for a data id along with the moment it was updated last time
fn data(&self, data_id: &DataId) -> Result<Option<(Data, Moment)>, DispatchError>;
fn get(&self, data_id: &DataId) -> Result<Option<(Data, Moment)>, DispatchError>;
}
5 changes: 2 additions & 3 deletions pallets/collection-data-feed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ cfg-traits = { path = "../../libs/traits", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" }

cfg-mocks = { path = "../../libs/mocks" }
orml-oracle = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.37" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" }

[features]
default = ["std"]
Expand All @@ -48,11 +49,9 @@ runtime-benchmarks = [
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"cfg-traits/runtime-benchmarks",
"cfg-mocks/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"cfg-traits/try-runtime",
"cfg-mocks/try-runtime",
]
22 changes: 13 additions & 9 deletions pallets/collection-data-feed/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
pub use pallet::*;

#[cfg(test)]
mod mock;

#[cfg(test)]
mod tests;

#[frame_support::pallet]
pub mod pallet {
use cfg_traits::data::{DataCollection, DataRegistry};
use frame_support::{pallet_prelude::*, storage::bounded_btree_map::BoundedBTreeMap};
use orml_traits::{DataProviderExtended, OnNewData, TimestampedValue};
use orml_traits::{DataProviderExtended, OnNewData};
use sp_runtime::{
traits::{EnsureAddAssign, EnsureSubAssign},
DispatchError,
Expand Down Expand Up @@ -34,10 +40,7 @@ pub mod pallet {
type Moment: Parameter + MaxEncodedLen;

/// Data provider for initializing data values
type DataProvider: DataProviderExtended<
Self::DataId,
TimestampedValue<Self::Data, Self::Moment>,
>;
type DataProvider: DataProviderExtended<Self::DataId, (Self::Data, Self::Moment)>;

/// Max size of a data collection
#[pallet::constant]
Expand Down Expand Up @@ -89,7 +92,6 @@ pub mod pallet {

fn get(data_id: &T::DataId) -> DataValueOf<T> {
T::DataProvider::get_no_op(data_id)
.map(|timestamped| (timestamped.value, timestamped.timestamp))
}

fn collection(collection_id: &T::CollectionId) -> Self::Collection {
Expand All @@ -104,7 +106,7 @@ pub mod pallet {
Some(counter) => counter.ensure_add_assign(1).map_err(|e| e.into()),
None => {
counters
.try_insert(collection_id.clone(), 0)
.try_insert(collection_id.clone(), 1)
.map_err(|_| Error::<T>::MaxCollectionNumber)?;

Collection::<T>::try_mutate(collection_id, |collection| {
Expand All @@ -121,7 +123,7 @@ pub mod pallet {
data_id: &T::DataId,
collection_id: &T::CollectionId,
) -> DispatchResult {
Listening::<T>::mutate(data_id, |counters| {
Listening::<T>::try_mutate(data_id, |counters| {
let counter = counters
.get_mut(collection_id)
.ok_or(Error::<T>::DataIdNotInCollection)?;
Expand All @@ -139,6 +141,8 @@ pub mod pallet {

impl<T: Config> OnNewData<T::AccountId, T::DataId, T::Data> for Pallet<T> {
fn on_new_data(_: &T::AccountId, data_id: &T::DataId, _: &T::Data) {
// Input Data parameter could not correspond with the data comming from `DataProvider`.
// This implementation use `DataProvider` as a source of truth for Data values.
for collection_id in Listening::<T>::get(data_id).keys() {
Collection::<T>::mutate(collection_id, |collection| {
collection
Expand All @@ -155,7 +159,7 @@ pub mod pallet {
);

impl<T: Config> DataCollection<T::DataId, T::Data, T::Moment> for CachedCollection<T> {
fn data(&self, data_id: &T::DataId) -> Result<DataValueOf<T>, DispatchError> {
fn get(&self, data_id: &T::DataId) -> Result<DataValueOf<T>, DispatchError> {
self.0
.get(data_id)
.cloned()
Expand Down
138 changes: 138 additions & 0 deletions pallets/collection-data-feed/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use frame_support::traits::{ConstU16, ConstU32, ConstU64, IsInVec};
use orml_oracle::{CombineData, DataProviderExtended};
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
};

use crate::pallet as pallet_collection_data_feed;

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
type Block = frame_system::mocking::MockBlock<Runtime>;

pub const BLOCK_TIME_MS: Moment = 10000;
pub const ORACLE_MEMBER: u64 = 42;

pub type CollectionId = u16;
pub type DataId = u32;
pub type Data = u128;
pub type Moment = u64;
pub type AccountId = u64;

frame_support::construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system,
Timer: pallet_timestamp,
Oracle: orml_oracle,
CollectionDataFeed: pallet_collection_data_feed,
}
);

frame_support::parameter_types! {
pub const MaxCollectionSize: u32 = 5;
pub const MaxCollections: u32 = 3;
pub const RootMember: AccountId = 23;
pub static Members: Vec<AccountId> = vec![ORACLE_MEMBER];
pub const MaxHasDispatchedSize: u32 = 1;
}

impl frame_system::Config for Runtime {
type AccountData = ();
type AccountId = AccountId;
type BaseCallFilter = frame_support::traits::Everything;
type BlockHashCount = ConstU64<250>;
type BlockLength = ();
type BlockNumber = u64;
type BlockWeights = ();
type DbWeight = ();
type Hash = H256;
type Hashing = BlakeTwo256;
type Header = Header;
type Index = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type MaxConsumers = ConstU32<16>;
type OnKilledAccount = ();
type OnNewAccount = ();
type OnSetCode = ();
type PalletInfo = PalletInfo;
type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type RuntimeOrigin = RuntimeOrigin;
type SS58Prefix = ConstU16<42>;
type SystemWeightInfo = ();
type Version = ();
}

impl pallet_timestamp::Config for Runtime {
type MinimumPeriod = ConstU64<BLOCK_TIME_MS>;
type Moment = Moment;
type OnTimestampSet = ();
type WeightInfo = ();
}

type OracleValue = orml_oracle::TimestampedValue<Data, Moment>;

pub struct LastData;
impl CombineData<DataId, OracleValue> for LastData {
fn combine_data(
_: &DataId,
values: Vec<OracleValue>,
_: Option<OracleValue>,
) -> Option<OracleValue> {
values
.into_iter()
.max_by(|v1, v2| v1.timestamp.cmp(&v2.timestamp))
}
}

// This part is forced because of https://github.com/open-web3-stack/open-runtime-module-library/issues/904
pub struct DataProviderBridge;
impl DataProviderExtended<DataId, (Data, Moment)> for DataProviderBridge {
fn get_no_op(key: &DataId) -> Option<(Data, Moment)> {
Oracle::get_no_op(key).map(|OracleValue { value, timestamp }| (value, timestamp))
}

fn get_all_values() -> Vec<(DataId, Option<(Data, Moment)>)> {
unimplemented!("unused by this pallet")
}
}

impl orml_oracle::Config for Runtime {
type CombineData = LastData;
type MaxHasDispatchedSize = MaxHasDispatchedSize;
type Members = IsInVec<Members>;
type OnNewData = CollectionDataFeed;
type OracleKey = DataId;
type OracleValue = Data;
type RootOperatorAccountId = RootMember;
type RuntimeEvent = RuntimeEvent;
type Time = Timer;
type WeightInfo = ();
}

impl pallet_collection_data_feed::Config for Runtime {
type CollectionId = CollectionId;
type Data = Data;
type DataId = DataId;
type DataProvider = DataProviderBridge;
type MaxCollectionSize = MaxCollectionSize;
type MaxCollections = MaxCollections;
type Moment = Moment;
}

pub fn new_test_ext() -> sp_io::TestExternalities {
let storage = frame_system::GenesisConfig::default()
.build_storage::<Runtime>()
.unwrap();

sp_io::TestExternalities::new(storage)
}

pub fn advance_time(elapsed: u64) {
Timer::set_timestamp(Timer::get() + elapsed);
}
Loading

0 comments on commit c80e940

Please sign in to comment.