Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Enable testing and benchmarking together in Roles pallet #189

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions pallets/roles/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ try-runtime = ['frame-support/try-runtime']

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
cfg-if = "1.0.0"
scale-info = { version = "2.2.0", default-features = false, features = ["derive"] }

# Local dependencies
Expand Down
81 changes: 51 additions & 30 deletions pallets/roles/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,48 @@

// FIXME: refactor once SpacesInterface is added.

use super::*;
use cfg_if::cfg_if;
use frame_benchmarking::{account, benchmarks};
use frame_support::dispatch::DispatchError;
use frame_support::{dispatch::DispatchError, traits::Get};
use frame_system::RawOrigin;
use pallet_permissions::SpacePermission as SP;
use pallet_spaces::types::Space;
use sp_std::{prelude::Vec, vec};
use subsocial_support::{Content, User};
use subsocial_support::mock_functions::{valid_content_ipfs, another_valid_content_ipfs};

fn create_dummy_space<T: Config + pallet_spaces::Config>(
origin: RawOrigin<T::AccountId>,
) -> Result<Space<T>, DispatchError> {
let space_id = pallet_spaces::NextSpaceId::<T>::get();
use pallet_permissions::SpacePermission as SP;
use subsocial_support::{
mock_functions::{another_valid_content_ipfs, valid_content_ipfs},
Content, User,
};

use super::*;

fn get_dummy_space_id<T: Config + pallet_spaces::Config>(
#[allow(unused_variables)] origin: RawOrigin<T::AccountId>,
) -> Result<SpaceId, DispatchError> {
cfg_if! {
if #[cfg(test)] {
Ok(crate::mock::SPACE1)
} else {
let space_id = pallet_spaces::NextSpaceId::<T>::get();

pallet_spaces::Pallet::<T>::create_space(origin.into(), Content::None, None)?;
pallet_spaces::Pallet::<T>::create_space(origin.into(), Content::None, None)?;

let space = pallet_spaces::SpaceById::<T>::get(space_id)
.ok_or(DispatchError::Other("Space not found"))?;
let space = pallet_spaces::SpaceById::<T>::get(space_id)
.ok_or(DispatchError::Other("Space not found"))?;

Ok(space)
Ok(space.id)
}
}
}

fn get_caller_account<T: Config>() -> T::AccountId {
cfg_if! {
if #[cfg(test)] {
let mut bytes: &[u8] = &crate::mock::ACCOUNT1.to_le_bytes();
T::AccountId::decode(&mut bytes).expect("failed to get caller_account")
} else {
account::<T::AccountId>("Acc1", 1, 0)
}
}
}

fn dummy_list_of_users<T: Config>(num_of_users: u32) -> Vec<User<T::AccountId>> {
Expand Down Expand Up @@ -74,25 +95,25 @@ benchmarks! {
where_clause { where T: pallet_spaces::Config }

create_role {
let caller_origin = RawOrigin::Signed(account::<T::AccountId>("Acc1", 1, 0));
let space = create_dummy_space::<T>(caller_origin.clone())?;
let caller_origin = RawOrigin::Signed(get_caller_account::<T>());
let space_id = get_dummy_space_id::<T>(caller_origin.clone())?;
let time_to_live: Option<T::BlockNumber> = Some(100u32.into());
let content = valid_content_ipfs();
let perms = vec![SP::ManageRoles];
let role_id = NextRoleId::<T>::get();
}: _(caller_origin, space.id, time_to_live, content, perms)
}: _(caller_origin, space_id, time_to_live, content, perms)
verify {
let role = RoleById::<T>::get(role_id).unwrap();
let space_roles_ids = RoleIdsBySpaceId::<T>::get(space.id);
let space_roles_ids = RoleIdsBySpaceId::<T>::get(space_id);

ensure!(role.id == role_id, "Role id doesn't match");
ensure!(space_roles_ids.contains(&role_id), "Role id not in space roles");
}

update_role {
let caller_origin = RawOrigin::Signed(account::<T::AccountId>("Acc1", 1, 0));
let space = create_dummy_space::<T>(caller_origin.clone())?;
let (role, _) = create_dummy_role::<T>(caller_origin.clone(), space.id, 10)?;
let caller_origin = RawOrigin::Signed(get_caller_account::<T>());
let space_id = get_dummy_space_id::<T>(caller_origin.clone())?;
let (role, _) = create_dummy_role::<T>(caller_origin.clone(), space_id, 10)?;

ensure!(!role.disabled, "Role should be enabled");

Expand All @@ -109,9 +130,9 @@ benchmarks! {

delete_role {
let x in 0..T::MaxUsersToProcessPerDeleteRole::get().into();
let caller_origin = RawOrigin::Signed(account::<T::AccountId>("Acc1", 1, 0));
let space = create_dummy_space::<T>(caller_origin.clone())?;
let (role, _) = create_dummy_role::<T>(caller_origin.clone(), space.id, x)?;
let caller_origin = RawOrigin::Signed(get_caller_account::<T>());
let space_id = get_dummy_space_id::<T>(caller_origin.clone())?;
let (role, _) = create_dummy_role::<T>(caller_origin.clone(), space_id, x)?;
}: _(caller_origin, role.id, x)
verify {
let deleted = RoleById::<T>::get(role.id).is_none();
Expand All @@ -120,9 +141,9 @@ benchmarks! {

grant_role {
let x in 1..500;
let caller_origin = RawOrigin::Signed(account::<T::AccountId>("Acc1", 1, 0));
let space = create_dummy_space::<T>(caller_origin.clone())?;
let (role, _) = create_dummy_role::<T>(caller_origin.clone(), space.id, 0)?;
let caller_origin = RawOrigin::Signed(get_caller_account::<T>());
let space_id = get_dummy_space_id::<T>(caller_origin.clone())?;
let (role, _) = create_dummy_role::<T>(caller_origin.clone(), space_id, 0)?;

let users_to_grant = dummy_list_of_users::<T>(x);
}: _(caller_origin, role.id, users_to_grant.clone())
Expand All @@ -135,9 +156,9 @@ benchmarks! {

revoke_role {
let x in 1..500;
let caller_origin = RawOrigin::Signed(account::<T::AccountId>("Acc1", 1, 0));
let space = create_dummy_space::<T>(caller_origin.clone())?;
let (role, users_to_revoke) = create_dummy_role::<T>(caller_origin.clone(), space.id, x)?;
let caller_origin = RawOrigin::Signed(get_caller_account::<T>());
let space_id = get_dummy_space_id::<T>(caller_origin.clone())?;
let (role, users_to_revoke) = create_dummy_role::<T>(caller_origin.clone(), space_id, x)?;
}: _(caller_origin, role.id, users_to_revoke)
verify {
let granted_users = UsersByRoleId::<T>::get(role.id);
Expand Down
19 changes: 11 additions & 8 deletions pallets/roles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

//! # Roles Module
//!
//! This module allow you to create dynalic roles with an associated set of permissions
//! This module allow you to create dynamic roles with an associated set of permissions
//! and grant them to users (accounts or space ids) within a given space.
//!
//! For example if you want to create a space that enables editors in a similar way to Medium,
Expand All @@ -17,12 +17,13 @@
#![cfg_attr(not(feature = "std"), no_std)]

use codec::{Decode, Encode};
use frame_support::{dispatch::DispatchResult, ensure, traits::Get};
use frame_system::{self as system, ensure_signed};
use frame_support::{dispatch::DispatchResult, ensure};
use frame_system::{self as system};
use scale_info::TypeInfo;
use sp_runtime::RuntimeDebug;
use sp_std::{collections::btree_set::BTreeSet, prelude::*};

pub use pallet::*;
use pallet_permissions::{
Pallet as Permissions, PermissionChecker, SpacePermission, SpacePermissionSet,
};
Expand All @@ -31,32 +32,34 @@ use subsocial_support::{
traits::{IsAccountBlocked, IsContentBlocked, SpaceFollowsProvider, SpacePermissionsProvider},
Content, ModerationError, SpaceId, User, WhoAndWhenOf,
};
pub use types::*;

pub use pallet::*;
pub mod functions;

pub mod types;
pub use types::*;
// pub mod rpc;

#[cfg(test)]
mod mock;

#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
#[cfg(all(test, not(feature = "runtime-benchmarks")))]
#[cfg(test)]
mod tests;
pub mod weights;

#[frame_support::pallet]
pub mod pallet {
use super::*;
use crate::weights::WeightInfo;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

use pallet_permissions::SpacePermissionsInfoOf;
use subsocial_support::{remove_from_vec, WhoAndWhen};

use crate::weights::WeightInfo;

use super::*;

#[pallet::config]
pub trait Config:
frame_system::Config + pallet_permissions::Config + pallet_timestamp::Config
Expand Down
21 changes: 9 additions & 12 deletions pallets/roles/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,33 @@
// Full notice is available at https://github.com/dappforce/subsocial-parachain/blob/main/COPYRIGHT
// Full license is available at https://github.com/dappforce/subsocial-parachain/blob/main/LICENSE

use super::*;

use sp_core::H256;
use sp_io::TestExternalities;
use sp_std::{collections::btree_set::BTreeSet, prelude::Vec};

use frame_support::{
assert_ok,
dispatch::{DispatchError, DispatchResult},
parameter_types,
traits::{ConstU32, Everything},
};
use sp_core::H256;
use sp_io::TestExternalities;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
};
use sp_std::{collections::btree_set::BTreeSet, prelude::Vec};

use pallet_permissions::{SpacePermission, SpacePermission as SP, SpacePermissions};
use pallet_permissions::{
default_permissions::DefaultSpacePermissions, SpacePermission, SpacePermission as SP,
SpacePermissions,
};
use subsocial_support::{
traits::{SpaceFollowsProvider, SpacePermissionsProvider as SpacePermissionsProviderT},
Content, SpaceId, SpacePermissionsInfo, User,
};

use crate as roles;

use super::*;

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

Expand Down Expand Up @@ -109,8 +111,6 @@ impl pallet_balances::Config for Test {
type ReserveIdentifier = ();
}

use pallet_permissions::default_permissions::DefaultSpacePermissions;

impl pallet_permissions::Config for Test {
type DefaultSpacePermissions = DefaultSpacePermissions;
}
Expand All @@ -122,9 +122,6 @@ parameter_types! {
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type MaxUsersToProcessPerDeleteRole = MaxUsersToProcessPerDeleteRole;
#[cfg(feature = "runtime-benchmarks")]
type SpacePermissionsProvider = Spaces;
#[cfg(not(feature = "runtime-benchmarks"))]
type SpacePermissionsProvider = Self;
type SpaceFollows = Roles;
type IsAccountBlocked = ();
Expand Down