git.delta.rocks / unique-network / refs/commits / 218082ec0405

difftreelog

tests(collator-selection): further fixes

Fahrrader2022-12-21parent: #33d3cd0.patch.diff
in: master

2 files changed

modifiedpallets/collator-selection/src/tests.rsdiffbeforeafterboth
before · pallets/collator-selection/src/tests.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license:18// Copyright (C) 2021 Parity Technologies (UK) Ltd.19// SPDX-License-Identifier: Apache-2.02021// Licensed under the Apache License, Version 2.0 (the "License");22// you may not use this file except in compliance with the License.23// You may obtain a copy of the License at24//25// 	http://www.apache.org/licenses/LICENSE-2.026//27// Unless required by applicable law or agreed to in writing, software28// distributed under the License is distributed on an "AS IS" BASIS,29// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.30// See the License for the specific language governing permissions and31// limitations under the License.3233use crate as collator_selection;34use crate::{mock::*, CandidateInfo, Error};35use frame_support::{36	assert_noop, assert_ok,37	traits::{Currency, GenesisBuild, OnInitialize},38};39use pallet_balances::Error as BalancesError;40use sp_runtime::traits::BadOrigin;4142#[test]43fn basic_setup_works() {44	new_test_ext().execute_with(|| {45		assert_eq!(CollatorSelection::desired_candidates(), 2);46		assert_eq!(CollatorSelection::candidacy_bond(), 10);4748		assert!(CollatorSelection::candidates().is_empty());49		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);50	});51}5253// todo:collator add more tests later5455#[test]56fn it_should_add_invulnerables() {57	new_test_ext().execute_with(|| {58		assert_ok!(CollatorSelection::add_invulnerable(59			RuntimeOrigin::signed(RootAccount::get()),60			161		));62		assert_ok!(CollatorSelection::add_invulnerable(63			RuntimeOrigin::signed(RootAccount::get()),64			265		));66		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);6768		// cannot set with non-root.69		assert_noop!(70			CollatorSelection::add_invulnerable(RuntimeOrigin::signed(1), 3),71			BadOrigin72		);7374		// cannot set invulnerables without associated validator keys75		assert_noop!(76			CollatorSelection::add_invulnerable(77				RuntimeOrigin::signed(RootAccount::get()),78				779			),80			Error::<Test>::ValidatorNotRegistered81		);82	});83}8485#[test]86fn it_should_remove_invulnerables() {87	new_test_ext().execute_with(|| {88		assert_ok!(CollatorSelection::add_invulnerable(89			RuntimeOrigin::signed(RootAccount::get()),90			191		));92		assert_ok!(CollatorSelection::add_invulnerable(93			RuntimeOrigin::signed(RootAccount::get()),94			295		));9697		// cannot remove with non-root.98		assert_noop!(99			CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(1), 3),100			BadOrigin101		);102103		assert_ok!(CollatorSelection::remove_invulnerable(104			RuntimeOrigin::signed(RootAccount::get()),105			2106		));107		assert_eq!(CollatorSelection::invulnerables(), vec![1]);108109		// cannot remove an invulnerable if there would be 0 invulnerables.110		assert_noop!(111			CollatorSelection::add_invulnerable(112				RuntimeOrigin::signed(RootAccount::get()), 113				1114			),115			Error::<Test>::NotInvulnerable116		);117	});118}119120#[test]121fn set_desired_candidates_works() {122	new_test_ext().execute_with(|| {123		// given124		assert_eq!(CollatorSelection::desired_candidates(), 2);125126		// can set127		assert_ok!(CollatorSelection::set_desired_candidates(128			RuntimeOrigin::signed(RootAccount::get()),129			7130		));131		assert_eq!(CollatorSelection::desired_candidates(), 7);132133		// rejects bad origin134		assert_noop!(135			CollatorSelection::set_desired_candidates(RuntimeOrigin::signed(1), 8),136			BadOrigin137		);138	});139}140141#[test]142fn set_candidacy_bond() {143	new_test_ext().execute_with(|| {144		// given145		assert_eq!(CollatorSelection::candidacy_bond(), 10);146147		// can set148		assert_ok!(CollatorSelection::set_candidacy_bond(149			RuntimeOrigin::signed(RootAccount::get()),150			7151		));152		assert_eq!(CollatorSelection::candidacy_bond(), 7);153154		// rejects bad origin.155		assert_noop!(156			CollatorSelection::set_candidacy_bond(RuntimeOrigin::signed(1), 8),157			BadOrigin158		);159	});160}161162#[test]163fn cannot_register_candidate_if_too_many() {164	new_test_ext().execute_with(|| {165		// reset desired candidates:166		<crate::DesiredCandidates<Test>>::put(0);167168		// can't accept anyone anymore.169		assert_noop!(170			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),171			Error::<Test>::TooManyCandidates,172		);173174		// reset desired candidates:175		<crate::DesiredCandidates<Test>>::put(1);176		assert_ok!(CollatorSelection::register_as_candidate(177			RuntimeOrigin::signed(4)178		));179180		// but no more181		assert_noop!(182			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)),183			Error::<Test>::TooManyCandidates,184		);185	})186}187188#[test]189fn cannot_unregister_candidate_if_too_few() {190	new_test_ext().execute_with(|| {191		// reset desired candidates:192		<crate::DesiredCandidates<Test>>::put(1);193		assert_ok!(CollatorSelection::register_as_candidate(194			RuntimeOrigin::signed(4)195		));196197		// can not remove too few198		assert_noop!(199			CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),200			Error::<Test>::TooFewCandidates,201		);202	})203}204205#[test]206fn cannot_register_as_candidate_if_invulnerable() {207	new_test_ext().execute_with(|| {208		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);209210		// can't 1 because it is invulnerable.211		assert_noop!(212			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(1)),213			Error::<Test>::AlreadyInvulnerable,214		);215	})216}217218#[test]219fn cannot_register_as_candidate_if_keys_not_registered() {220	new_test_ext().execute_with(|| {221		// can't 7 because keys not registered.222		assert_noop!(223			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(7)),224			Error::<Test>::ValidatorNotRegistered225		);226	})227}228229#[test]230fn cannot_register_dupe_candidate() {231	new_test_ext().execute_with(|| {232		// can add 3 as candidate233		assert_ok!(CollatorSelection::register_as_candidate(234			RuntimeOrigin::signed(3)235		));236		let addition = CandidateInfo {237			who: 3,238			deposit: 10,239		};240		assert_eq!(CollatorSelection::candidates(), vec![addition]);241		assert_eq!(CollatorSelection::last_authored_block(3), 10);242		assert_eq!(Balances::free_balance(3), 90);243244		// but no more245		assert_noop!(246			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),247			Error::<Test>::AlreadyCandidate,248		);249	})250}251252#[test]253fn cannot_register_as_candidate_if_poor() {254	new_test_ext().execute_with(|| {255		assert_eq!(Balances::free_balance(&3), 100);256		assert_eq!(Balances::free_balance(&33), 0);257258		// works259		assert_ok!(CollatorSelection::register_as_candidate(260			RuntimeOrigin::signed(3)261		));262263		// poor264		assert_noop!(265			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(33)),266			BalancesError::<Test>::InsufficientBalance,267		);268	});269}270271#[test]272fn register_as_candidate_works() {273	new_test_ext().execute_with(|| {274		// given275		assert_eq!(CollatorSelection::desired_candidates(), 2);276		assert_eq!(CollatorSelection::candidacy_bond(), 10);277		assert_eq!(CollatorSelection::candidates(), Vec::new());278		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);279280		// take two endowed, non-invulnerables accounts.281		assert_eq!(Balances::free_balance(&3), 100);282		assert_eq!(Balances::free_balance(&4), 100);283284		assert_ok!(CollatorSelection::register_as_candidate(285			RuntimeOrigin::signed(3)286		));287		assert_ok!(CollatorSelection::register_as_candidate(288			RuntimeOrigin::signed(4)289		));290291		assert_eq!(Balances::free_balance(&3), 90);292		assert_eq!(Balances::free_balance(&4), 90);293294		assert_eq!(CollatorSelection::candidates().len(), 2);295	});296}297298#[test]299fn leave_intent() {300	new_test_ext().execute_with(|| {301		// register a candidate.302		assert_ok!(CollatorSelection::register_as_candidate(303			RuntimeOrigin::signed(3)304		));305		assert_eq!(Balances::free_balance(3), 90);306307		// register too so can leave above min candidates308		assert_ok!(CollatorSelection::register_as_candidate(309			RuntimeOrigin::signed(5)310		));311		assert_eq!(Balances::free_balance(5), 90);312313		// cannot leave if not candidate.314		assert_noop!(315			CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),316			Error::<Test>::NotCandidate317		);318319		// bond is returned320		assert_ok!(CollatorSelection::leave_intent(RuntimeOrigin::signed(3)));321		assert_eq!(Balances::free_balance(3), 100);322		assert_eq!(CollatorSelection::last_authored_block(3), 0);323	});324}325326#[test]327fn authorship_event_handler() {328	new_test_ext().execute_with(|| {329		// put 100 in the pot + 5 for ED330		Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);331332		// 4 is the default author.333		assert_eq!(Balances::free_balance(4), 100);334		assert_ok!(CollatorSelection::register_as_candidate(335			RuntimeOrigin::signed(4)336		));337		// triggers `note_author`338		Authorship::on_initialize(1);339340		let collator = CandidateInfo {341			who: 4,342			deposit: 10,343		};344345		assert_eq!(CollatorSelection::candidates(), vec![collator]);346		assert_eq!(CollatorSelection::last_authored_block(4), 0);347348		// half of the pot goes to the collator who's the author (4 in tests).349		assert_eq!(Balances::free_balance(4), 140);350		// half + ED stays.351		assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);352	});353}354355#[test]356fn fees_edgecases() {357	new_test_ext().execute_with(|| {358		// Nothing panics, no reward when no ED in balance359		Authorship::on_initialize(1);360		// put some money into the pot at ED361		Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);362		// 4 is the default author.363		assert_eq!(Balances::free_balance(4), 100);364		assert_ok!(CollatorSelection::register_as_candidate(365			RuntimeOrigin::signed(4)366		));367		// triggers `note_author`368		Authorship::on_initialize(1);369370		let collator = CandidateInfo {371			who: 4,372			deposit: 10,373		};374375		assert_eq!(CollatorSelection::candidates(), vec![collator]);376		assert_eq!(CollatorSelection::last_authored_block(4), 0);377		// Nothing received378		assert_eq!(Balances::free_balance(4), 90);379		// all fee stays380		assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);381	});382}383384#[test]385fn session_management_works() {386	new_test_ext().execute_with(|| {387		initialize_to_block(1);388389		assert_eq!(SessionChangeBlock::get(), 0);390		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);391392		initialize_to_block(4);393394		assert_eq!(SessionChangeBlock::get(), 0);395		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);396397		// add a new collator398		assert_ok!(CollatorSelection::register_as_candidate(399			RuntimeOrigin::signed(3)400		));401402		// session won't see this.403		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);404		// but we have a new candidate.405		assert_eq!(CollatorSelection::candidates().len(), 1);406407		initialize_to_block(10);408		assert_eq!(SessionChangeBlock::get(), 10);409		// pallet-session has 1 session delay; current validators are the same.410		assert_eq!(Session::validators(), vec![1, 2]);411		// queued ones are changed, and now we have 3.412		assert_eq!(Session::queued_keys().len(), 3);413		// session handlers (aura, et. al.) cannot see this yet.414		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);415416		initialize_to_block(20);417		assert_eq!(SessionChangeBlock::get(), 20);418		// changed are now reflected to session handlers.419		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3]);420	});421}422423#[test]424fn kick_mechanism() {425	new_test_ext().execute_with(|| {426		// add a new collator427		assert_ok!(CollatorSelection::register_as_candidate(428			RuntimeOrigin::signed(3)429		));430		assert_ok!(CollatorSelection::register_as_candidate(431			RuntimeOrigin::signed(4)432		));433		initialize_to_block(10);434		assert_eq!(CollatorSelection::candidates().len(), 2);435		initialize_to_block(20);436		assert_eq!(SessionChangeBlock::get(), 20);437		// 4 authored this block, gets to stay 3 was kicked438		assert_eq!(CollatorSelection::candidates().len(), 1);439		// 3 will be kicked after 1 session delay440		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);441		let collator = CandidateInfo {442			who: 4,443			deposit: 10,444		};445		assert_eq!(CollatorSelection::candidates(), vec![collator]);446		assert_eq!(CollatorSelection::kick_threshold(), 1);447		assert_eq!(CollatorSelection::last_authored_block(4), 20);448		initialize_to_block(30);449		// 3 gets kicked after 1 session delay450		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);451		// kicked collator gets funds back452		assert_eq!(Balances::free_balance(3), 100);453	});454}455456#[test]457fn should_not_kick_mechanism_too_few() {458	new_test_ext().execute_with(|| {459		// add a new collator460		assert_ok!(CollatorSelection::register_as_candidate(461			RuntimeOrigin::signed(3)462		));463		assert_ok!(CollatorSelection::register_as_candidate(464			RuntimeOrigin::signed(5)465		));466		initialize_to_block(10);467		assert_eq!(CollatorSelection::candidates().len(), 2);468		initialize_to_block(20);469		assert_eq!(SessionChangeBlock::get(), 20);470		// 4 authored this block, 5 gets to stay too few 3 was kicked471		assert_eq!(CollatorSelection::candidates().len(), 1);472		// 3 will be kicked after 1 session delay473		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]);474		let collator = CandidateInfo {475			who: 5,476			deposit: 10,477		};478		assert_eq!(CollatorSelection::candidates(), vec![collator]);479		assert_eq!(CollatorSelection::last_authored_block(4), 20);480		initialize_to_block(30);481		// 3 gets kicked after 1 session delay482		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]);483		// kicked collator gets funds back484		assert_eq!(Balances::free_balance(3), 100);485	});486}487488#[test]489#[should_panic = "duplicate invulnerables in genesis."]490fn cannot_set_genesis_value_twice() {491	sp_tracing::try_init_simple();492	let mut t = frame_system::GenesisConfig::default()493		.build_storage::<Test>()494		.unwrap();495	let invulnerables = vec![1, 1];496497	let collator_selection = collator_selection::GenesisConfig::<Test> {498		desired_candidates: 2,499		candidacy_bond: 10,500		kick_threshold: 1,501		invulnerables,502	};503	// collator selection must be initialized before session.504	collator_selection.assimilate_storage(&mut t).unwrap();505}
after · pallets/collator-selection/src/tests.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license:18// Copyright (C) 2021 Parity Technologies (UK) Ltd.19// SPDX-License-Identifier: Apache-2.02021// Licensed under the Apache License, Version 2.0 (the "License");22// you may not use this file except in compliance with the License.23// You may obtain a copy of the License at24//25// 	http://www.apache.org/licenses/LICENSE-2.026//27// Unless required by applicable law or agreed to in writing, software28// distributed under the License is distributed on an "AS IS" BASIS,29// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.30// See the License for the specific language governing permissions and31// limitations under the License.3233use crate as collator_selection;34use crate::{mock::*, CandidateInfo, Error};35use frame_support::{36	assert_noop, assert_ok,37	traits::{Currency, GenesisBuild, OnInitialize},38};39use pallet_balances::Error as BalancesError;40use sp_runtime::traits::BadOrigin;4142#[test]43fn basic_setup_works() {44	new_test_ext().execute_with(|| {45		assert_eq!(CollatorSelection::desired_candidates(), 2);46		assert_eq!(CollatorSelection::candidacy_bond(), 10);4748		assert!(CollatorSelection::candidates().is_empty());49		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);50	});51}5253// todo:collator add more tests later5455#[test]56fn it_should_add_invulnerables() {57	new_test_ext().execute_with(|| {58		assert_ok!(CollatorSelection::add_invulnerable(59			RuntimeOrigin::signed(RootAccount::get()),60			161		));62		assert_ok!(CollatorSelection::add_invulnerable(63			RuntimeOrigin::signed(RootAccount::get()),64			265		));66		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);6768		// cannot set with non-root.69		assert_noop!(70			CollatorSelection::add_invulnerable(RuntimeOrigin::signed(1), 3),71			BadOrigin72		);7374		// cannot set invulnerables without associated validator keys75		assert_noop!(76			CollatorSelection::add_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 7),77			Error::<Test>::ValidatorNotRegistered78		);79	});80}8182#[test]83fn it_should_remove_invulnerables() {84	new_test_ext().execute_with(|| {85		assert_ok!(CollatorSelection::add_invulnerable(86			RuntimeOrigin::signed(RootAccount::get()),87			188		));89		assert_ok!(CollatorSelection::add_invulnerable(90			RuntimeOrigin::signed(RootAccount::get()),91			292		));9394		// cannot remove with non-root.95		assert_noop!(96			CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(1), 3),97			BadOrigin98		);99100		assert_ok!(CollatorSelection::remove_invulnerable(101			RuntimeOrigin::signed(RootAccount::get()),102			2103		));104		assert_eq!(CollatorSelection::invulnerables(), vec![1]);105106		// cannot remove an invulnerable if there would be 0 invulnerables.107		assert_noop!(108			CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 1),109			Error::<Test>::TooFewInvulnerables110		);111	});112}113114#[test]115fn set_desired_candidates_works() {116	new_test_ext().execute_with(|| {117		// given118		assert_eq!(CollatorSelection::desired_candidates(), 2);119120		// can set121		assert_ok!(CollatorSelection::set_desired_candidates(122			RuntimeOrigin::signed(RootAccount::get()),123			7124		));125		assert_eq!(CollatorSelection::desired_candidates(), 7);126127		// rejects bad origin128		assert_noop!(129			CollatorSelection::set_desired_candidates(RuntimeOrigin::signed(1), 8),130			BadOrigin131		);132	});133}134135#[test]136fn set_candidacy_bond() {137	new_test_ext().execute_with(|| {138		// given139		assert_eq!(CollatorSelection::candidacy_bond(), 10);140141		// can set142		assert_ok!(CollatorSelection::set_candidacy_bond(143			RuntimeOrigin::signed(RootAccount::get()),144			7145		));146		assert_eq!(CollatorSelection::candidacy_bond(), 7);147148		// rejects bad origin.149		assert_noop!(150			CollatorSelection::set_candidacy_bond(RuntimeOrigin::signed(1), 8),151			BadOrigin152		);153	});154}155156#[test]157fn cannot_register_candidate_if_too_many() {158	new_test_ext().execute_with(|| {159		// reset desired candidates:160		<crate::DesiredCandidates<Test>>::put(0);161162		// can't accept anyone anymore.163		assert_noop!(164			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),165			Error::<Test>::TooManyCandidates,166		);167168		// reset desired candidates:169		<crate::DesiredCandidates<Test>>::put(1);170		assert_ok!(CollatorSelection::register_as_candidate(171			RuntimeOrigin::signed(4)172		));173174		// but no more175		assert_noop!(176			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)),177			Error::<Test>::TooManyCandidates,178		);179	})180}181182#[test]183fn cannot_unregister_candidate_if_too_few() {184	new_test_ext().execute_with(|| {185		// reset desired candidates:186		<crate::DesiredCandidates<Test>>::put(1);187		assert_ok!(CollatorSelection::register_as_candidate(188			RuntimeOrigin::signed(4)189		));190191		// can not remove too few192		assert_noop!(193			CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),194			Error::<Test>::TooFewCandidates,195		);196	})197}198199#[test]200fn cannot_register_as_candidate_if_invulnerable() {201	new_test_ext().execute_with(|| {202		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);203204		// can't 1 because it is invulnerable.205		assert_noop!(206			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(1)),207			Error::<Test>::AlreadyInvulnerable,208		);209	})210}211212#[test]213fn cannot_register_as_candidate_if_keys_not_registered() {214	new_test_ext().execute_with(|| {215		// can't 7 because keys not registered.216		assert_noop!(217			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(7)),218			Error::<Test>::ValidatorNotRegistered219		);220	})221}222223#[test]224fn cannot_register_dupe_candidate() {225	new_test_ext().execute_with(|| {226		// can add 3 as candidate227		assert_ok!(CollatorSelection::register_as_candidate(228			RuntimeOrigin::signed(3)229		));230		let addition = CandidateInfo {231			who: 3,232			deposit: 10,233		};234		assert_eq!(CollatorSelection::candidates(), vec![addition]);235		assert_eq!(CollatorSelection::last_authored_block(3), 10);236		assert_eq!(Balances::free_balance(3), 90);237238		// but no more239		assert_noop!(240			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),241			Error::<Test>::AlreadyCandidate,242		);243	})244}245246#[test]247fn cannot_register_as_candidate_if_poor() {248	new_test_ext().execute_with(|| {249		assert_eq!(Balances::free_balance(&3), 100);250		assert_eq!(Balances::free_balance(&33), 0);251252		// works253		assert_ok!(CollatorSelection::register_as_candidate(254			RuntimeOrigin::signed(3)255		));256257		// poor258		assert_noop!(259			CollatorSelection::register_as_candidate(RuntimeOrigin::signed(33)),260			BalancesError::<Test>::InsufficientBalance,261		);262	});263}264265#[test]266fn register_as_candidate_works() {267	new_test_ext().execute_with(|| {268		// given269		assert_eq!(CollatorSelection::desired_candidates(), 2);270		assert_eq!(CollatorSelection::candidacy_bond(), 10);271		assert_eq!(CollatorSelection::candidates(), Vec::new());272		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);273274		// take two endowed, non-invulnerables accounts.275		assert_eq!(Balances::free_balance(&3), 100);276		assert_eq!(Balances::free_balance(&4), 100);277278		assert_ok!(CollatorSelection::register_as_candidate(279			RuntimeOrigin::signed(3)280		));281		assert_ok!(CollatorSelection::register_as_candidate(282			RuntimeOrigin::signed(4)283		));284285		assert_eq!(Balances::free_balance(&3), 90);286		assert_eq!(Balances::free_balance(&4), 90);287288		assert_eq!(CollatorSelection::candidates().len(), 2);289	});290}291292#[test]293fn leave_intent() {294	new_test_ext().execute_with(|| {295		// register a candidate.296		assert_ok!(CollatorSelection::register_as_candidate(297			RuntimeOrigin::signed(3)298		));299		assert_eq!(Balances::free_balance(3), 90);300301		// register too so can leave above min candidates302		assert_ok!(CollatorSelection::register_as_candidate(303			RuntimeOrigin::signed(5)304		));305		assert_eq!(Balances::free_balance(5), 90);306307		// cannot leave if not candidate.308		assert_noop!(309			CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),310			Error::<Test>::NotCandidate311		);312313		// bond is returned314		assert_ok!(CollatorSelection::leave_intent(RuntimeOrigin::signed(3)));315		assert_eq!(Balances::free_balance(3), 100);316		assert_eq!(CollatorSelection::last_authored_block(3), 0);317	});318}319320#[test]321fn authorship_event_handler() {322	new_test_ext().execute_with(|| {323		// put 100 in the pot + 5 for ED324		Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);325326		// 4 is the default author.327		assert_eq!(Balances::free_balance(4), 100);328		assert_ok!(CollatorSelection::register_as_candidate(329			RuntimeOrigin::signed(4)330		));331		// triggers `note_author`332		Authorship::on_initialize(1);333334		let collator = CandidateInfo {335			who: 4,336			deposit: 10,337		};338339		assert_eq!(CollatorSelection::candidates(), vec![collator]);340		assert_eq!(CollatorSelection::last_authored_block(4), 0);341342		// half of the pot goes to the collator who's the author (4 in tests).343		assert_eq!(Balances::free_balance(4), 140);344		// half + ED stays.345		assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);346	});347}348349#[test]350fn fees_edgecases() {351	new_test_ext().execute_with(|| {352		// Nothing panics, no reward when no ED in balance353		Authorship::on_initialize(1);354		// put some money into the pot at ED355		Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);356		// 4 is the default author.357		assert_eq!(Balances::free_balance(4), 100);358		assert_ok!(CollatorSelection::register_as_candidate(359			RuntimeOrigin::signed(4)360		));361		// triggers `note_author`362		Authorship::on_initialize(1);363364		let collator = CandidateInfo {365			who: 4,366			deposit: 10,367		};368369		assert_eq!(CollatorSelection::candidates(), vec![collator]);370		assert_eq!(CollatorSelection::last_authored_block(4), 0);371		// Nothing received372		assert_eq!(Balances::free_balance(4), 90);373		// all fee stays374		assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);375	});376}377378#[test]379fn session_management_works() {380	new_test_ext().execute_with(|| {381		initialize_to_block(1);382383		assert_eq!(SessionChangeBlock::get(), 0);384		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);385386		initialize_to_block(4);387388		assert_eq!(SessionChangeBlock::get(), 0);389		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);390391		// add a new collator392		assert_ok!(CollatorSelection::register_as_candidate(393			RuntimeOrigin::signed(3)394		));395396		// session won't see this.397		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);398		// but we have a new candidate.399		assert_eq!(CollatorSelection::candidates().len(), 1);400401		initialize_to_block(10);402		assert_eq!(SessionChangeBlock::get(), 10);403		// pallet-session has 1 session delay; current validators are the same.404		assert_eq!(Session::validators(), vec![1, 2]);405		// queued ones are changed, and now we have 3.406		assert_eq!(Session::queued_keys().len(), 3);407		// session handlers (aura, et. al.) cannot see this yet.408		assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);409410		initialize_to_block(20);411		assert_eq!(SessionChangeBlock::get(), 20);412		// changed are now reflected to session handlers.413		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3]);414	});415}416417#[test]418fn kick_mechanism() {419	new_test_ext().execute_with(|| {420		// add a new collator421		assert_ok!(CollatorSelection::register_as_candidate(422			RuntimeOrigin::signed(3)423		));424		assert_ok!(CollatorSelection::register_as_candidate(425			RuntimeOrigin::signed(4)426		));427		initialize_to_block(10);428		assert_eq!(CollatorSelection::candidates().len(), 2);429		initialize_to_block(20);430		assert_eq!(SessionChangeBlock::get(), 20);431		// 4 authored this block, gets to stay 3 was kicked432		assert_eq!(CollatorSelection::candidates().len(), 1);433		// 3 will be kicked after 1 session delay434		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);435		let collator = CandidateInfo {436			who: 4,437			deposit: 10,438		};439		assert_eq!(CollatorSelection::candidates(), vec![collator]);440		assert_eq!(CollatorSelection::kick_threshold(), 1);441		assert_eq!(CollatorSelection::last_authored_block(4), 20);442		initialize_to_block(30);443		// 3 gets kicked after 1 session delay444		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);445		// kicked collator gets funds back446		assert_eq!(Balances::free_balance(3), 100);447	});448}449450#[test]451fn should_not_kick_mechanism_too_few() {452	new_test_ext().execute_with(|| {453		// add a new collator454		assert_ok!(CollatorSelection::register_as_candidate(455			RuntimeOrigin::signed(3)456		));457		assert_ok!(CollatorSelection::register_as_candidate(458			RuntimeOrigin::signed(5)459		));460		initialize_to_block(10);461		assert_eq!(CollatorSelection::candidates().len(), 2);462		initialize_to_block(20);463		assert_eq!(SessionChangeBlock::get(), 20);464		// 4 authored this block, 5 gets to stay too few 3 was kicked465		assert_eq!(CollatorSelection::candidates().len(), 1);466		// 3 will be kicked after 1 session delay467		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]);468		let collator = CandidateInfo {469			who: 5,470			deposit: 10,471		};472		assert_eq!(CollatorSelection::candidates(), vec![collator]);473		assert_eq!(CollatorSelection::last_authored_block(4), 20);474		initialize_to_block(30);475		// 3 gets kicked after 1 session delay476		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]);477		// kicked collator gets funds back478		assert_eq!(Balances::free_balance(3), 100);479	});480}481482#[test]483#[should_panic = "duplicate invulnerables in genesis."]484fn cannot_set_genesis_value_twice() {485	sp_tracing::try_init_simple();486	let mut t = frame_system::GenesisConfig::default()487		.build_storage::<Test>()488		.unwrap();489	let invulnerables = vec![1, 1];490491	let collator_selection = collator_selection::GenesisConfig::<Test> {492		desired_candidates: 2,493		candidacy_bond: 10,494		kick_threshold: 1,495		invulnerables,496	};497	// collator selection must be initialized before session.498	collator_selection.assimilate_storage(&mut t).unwrap();499}
modifiedtests/src/collatorSelection.seqtest.tsdiffbeforeafterboth
--- a/tests/src/collatorSelection.seqtest.ts
+++ b/tests/src/collatorSelection.seqtest.ts
@@ -64,6 +64,10 @@
     
     before(async function() {  
       await usingPlaygrounds(async (helper, privateKey) => {
+        // todo:collator see again if blocks start to be finalized in dev mode 
+        // Skip the collator block production in dev mode, since the blocks are sealed automatically.
+        if (await helper.arrange.isDevNode()) this.skip();
+
         alice = await privateKey('//Alice');
         bob = await privateKey('//Bob');
         charlie = await privateKey('//Charlie');
@@ -141,7 +145,7 @@
   
     after(async () => {
       await usingPlaygrounds(async (helper) => {
-        if (helper.fetchMissingPalletNames([Pallets.CollatorSelection]).length != 0) return;
+        if (await helper.arrange.isDevNode()) return;
 
         let nonce = await helper.chain.getNonce(superuser.address);
         await Promise.all([
@@ -161,7 +165,7 @@
   // todo:collator make sure that there is enough session time for a set of tests
   // 28 non-functioning collators, teehee.
 
-  describe.skip('Addition and removal of invulnerables', () => {
+  describe('Addition and removal of invulnerables', () => {
     before(async function() {
       await resetInvulnerables();
     });
@@ -261,7 +265,14 @@
         expect(await helper.collatorSelection.getInvulnerables()).to.have.all.members(invulnerables);
       });
     });
+  
+    after(async () => {
+      // eslint-disable-next-line require-await
+      await usingPlaygrounds(async (helper) => {
+        if (helper.fetchMissingPalletNames([Pallets.CollatorSelection]).length != 0) return;
     
-    // todo:collator after
+        // todo:collator after
+      });
+    });
   });
 });
\ No newline at end of file