From fe9f1335c8f6a087a5db0b19a358e325840e3c5e Mon Sep 17 00:00:00 2001
From: cgeek <cem.moreau@gmail.com>
Date: Tue, 27 Jun 2023 13:11:30 +0200
Subject: [PATCH] wip: test: `multiple_authors`
---
pallets/distance/src/mock.rs | 21 +++++--
pallets/distance/src/tests.rs | 107 +++++++++++++++++++++++++++++++---
2 files changed, 113 insertions(+), 15 deletions(-)
diff --git a/pallets/distance/src/mock.rs b/pallets/distance/src/mock.rs
index 0b6fd4647..08ab337c8 100644
--- a/pallets/distance/src/mock.rs
+++ b/pallets/distance/src/mock.rs
@@ -27,7 +27,7 @@ use pallet_session::{ShouldEndSession, TestSessionHandler};
use scale_info::{Type, TypeInfo};
use sp_core::{ConstU128, ConstU32, ConstU64, Get, H256};
use sp_runtime::testing::{TestSignature, UintAuthorityId};
-use sp_runtime::traits::{ConvertInto, IdentifyAccount, IsMember, Verify};
+use sp_runtime::traits::{BlockNumberProvider, ConvertInto, IdentifyAccount, IsMember, Verify};
use sp_runtime::{
impl_opaque_keys,
testing::Header,
@@ -238,18 +238,21 @@ impl pallet_certification::Config for Test {
type ValidityPeriod = ValidityPeriod;
}
-pub struct AuthorGiven;
-impl FindAuthor<u64> for AuthorGiven {
+type SystemPallet = frame_system::Pallet<Test>;
+pub struct AuthorByBlockNumber;
+impl FindAuthor<u64> for AuthorByBlockNumber {
fn find_author<'a, I>(digests: I) -> Option<u64>
where
I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
{
- Some(0)
+ // Round-robin like authoring.
+ // Necessary to test with multiple authors (3 here) for distance results
+ Some(SystemPallet::current_block_number() % 3)
}
}
impl pallet_authorship::Config for Test {
- type FindAuthor = AuthorGiven;
+ type FindAuthor = AuthorByBlockNumber;
type UncleGenerations = ();
type FilterUncle = ();
type EventHandler = ();
@@ -270,7 +273,7 @@ impl pallet_authority_members::Config for Test {
type MaxOfflineSessions = ConstU32<2>;
type MemberId = u64;
type MemberIdOf = ConvertInto;
- type OnNewSession = ();
+ type OnNewSession = Distance;
type OnRemovedMember = ();
type RemoveMemberOrigin = system::EnsureRoot<u64>;
type RuntimeEvent = RuntimeEvent;
@@ -342,6 +345,12 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
.assimilate_storage(&mut t)
.unwrap();
+ pallet_balances::GenesisConfig::<Test> {
+ balances: vec![(0, 1000)],
+ }
+ .assimilate_storage(&mut t)
+ .unwrap();
+
sp_io::TestExternalities::new(t)
// GenesisConfig {
diff --git a/pallets/distance/src/tests.rs b/pallets/distance/src/tests.rs
index 93f433d18..c3e7f6c03 100644
--- a/pallets/distance/src/tests.rs
+++ b/pallets/distance/src/tests.rs
@@ -15,30 +15,119 @@
// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
use crate::mock::*;
-use crate::{pallet, Error};
-use frame_support::{assert_noop, assert_ok};
+use crate::{pallet, Error, MedianAcc, MedianResult};
+use frame_support::traits::Len;
+use frame_support::{assert_err, assert_noop, assert_ok};
use sp_distance::ComputationResult;
use sp_runtime::Perbill;
use sp_std::collections::btree_map::BTreeMap;
// To enable better IDE checks
type Distance = pallet::Pallet<Test, ()>;
+type Identity = pallet_identity::Pallet<Test>;
+type Cert = pallet_certification::Pallet<Test>;
+
+const AUTHOR0: &u64 = &0;
+const AUTHOR1: &u64 = &1;
+const AUTHOR2: &u64 = &2;
+// SESSION_LENGTH = 5
+const SESSION_0_START: u64 = 0;
+const SESSION_1_START: u64 = 5;
+const SESSION_2_START: u64 = 10;
#[test]
-fn test_compilation() {
+fn basic_single_distance() {
new_test_ext().execute_with(|| {
- // Session 1: we ask for evaluation
- run_to_block(1);
+ // Session 0: distance is asked
+ run_to_block(SESSION_0_START);
assert_ok!(Distance::evaluate_distance(RuntimeOrigin::signed(0)));
- // Session 2: distance is being computed
- run_to_block(6); // session 2 wraps blocks [6, 10] because of SESSION_LENGTH
- // Session 3: distance results are supposed to be published
- run_to_block(11); // session 3 wraps blocks [11, 15] because of SESSION_LENGTH
+ // Session 1: distance is being computed
+ // Session 2: results publication
+ run_to_block(SESSION_2_START);
+ assert_ok!(Distance::update_evaluation(
+ RuntimeOrigin::none(),
+ ComputationResult {
+ distances: vec![Perbill::from_percent(100)]
+ }
+ ));
+ let authors_tree = pallet::EvaluationPool2::<Test>::get().1;
+ assert_eq!(authors_tree.len(), 1);
+ assert_eq!(authors_tree.get(AUTHOR0), None);
+ assert_eq!(authors_tree.get(AUTHOR1), Some(AUTHOR1));
+ assert_eq!(authors_tree.get(AUTHOR2), None);
+
+ // Other pools have never been used
+ assert_eq!(pallet::EvaluationPool0::<Test>::get().0.len(), 0);
+ assert_eq!(pallet::EvaluationPool1::<Test>::get().0.len(), 0);
+ });
+}
+
+#[test]
+fn multiple_authors() {
+ new_test_ext().execute_with(|| {
+ run_to_block(SESSION_0_START);
+ assert_ok!(Distance::evaluate_distance(RuntimeOrigin::signed(0)));
+
+ // Evaluation #1
+ run_to_block(SESSION_2_START);
assert_ok!(Distance::update_evaluation(
RuntimeOrigin::none(),
ComputationResult {
distances: vec![Perbill::from_percent(100)]
}
));
+ let authors_tree = pallet::EvaluationPool2::<Test>::get().1;
+ assert_eq!(authors_tree.len(), 1);
+ assert_eq!(authors_tree.get(AUTHOR0), None);
+ assert_eq!(authors_tree.get(AUTHOR1), Some(AUTHOR1));
+ assert_eq!(authors_tree.get(AUTHOR2), None);
+
+ // Evaluation #2
+ run_to_block(SESSION_2_START + 1); // to change author
+ assert_ok!(Distance::update_evaluation(
+ RuntimeOrigin::none(),
+ ComputationResult {
+ distances: vec![Perbill::from_percent(60)]
+ }
+ ));
+ let authors_tree = pallet::EvaluationPool2::<Test>::get().1;
+ assert_eq!(authors_tree.len(), 2);
+ assert_eq!(authors_tree.get(AUTHOR0), None);
+ assert_eq!(authors_tree.get(AUTHOR1), Some(AUTHOR1));
+ assert_eq!(authors_tree.get(AUTHOR2), Some(AUTHOR2));
+
+ // Evaluation #3
+ run_to_block(SESSION_2_START + 2); // to change author
+ assert_ok!(Distance::update_evaluation(
+ RuntimeOrigin::none(),
+ ComputationResult {
+ distances: vec![Perbill::from_percent(20)]
+ }
+ ));
+ let authors_tree = pallet::EvaluationPool2::<Test>::get().1;
+ assert_eq!(authors_tree.len(), 3);
+ assert_eq!(authors_tree.get(AUTHOR0), Some(AUTHOR0));
+ assert_eq!(authors_tree.get(AUTHOR1), Some(AUTHOR1));
+ assert_eq!(authors_tree.get(AUTHOR2), Some(AUTHOR2));
+
+ // Other pools have never been used (because of session number)
+ assert_eq!(pallet::EvaluationPool0::<Test>::get().0.len(), 0);
+ assert_eq!(pallet::EvaluationPool1::<Test>::get().0.len(), 0);
+
+ // Evaluation #2 replay i disallowed
+ assert_err!(
+ Distance::update_evaluation(
+ RuntimeOrigin::none(),
+ ComputationResult {
+ distances: vec![Perbill::from_percent(100)]
+ }
+ ),
+ pallet::Error::<Test>::ManyEvaluationsByAuthor
+ );
});
}
+
+// TODO:
+// #[test]
+// fn evaluation_for_non_asked() {
+// }
--
GitLab