difftreelog
test(xcm) make barrier unit tests cleaner
in: master
15 files changed
runtime/common/mod.rsdiffbeforeafterboth1// 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/>.1617pub mod config;18pub mod construct_runtime;19pub mod dispatch;20pub mod ethereum;21pub mod instance;22pub mod runtime_apis;23pub mod scheduler;24pub mod sponsoring;25pub mod weights;2627#[cfg(test)]28mod tests;2930use sp_core::H160;31use frame_support::traits::{Currency, OnUnbalanced, Imbalance};32use sp_runtime::{33 generic,34 traits::{BlakeTwo256, BlockNumberProvider},35 impl_opaque_keys,36};37use sp_std::vec::Vec;3839#[cfg(feature = "std")]40use sp_version::NativeVersion;4142use crate::{43 Runtime, Call, Balances, Treasury, Aura, Signature, AllPalletsReversedWithSystemFirst,44 InherentDataExt,45};46use up_common::types::{AccountId, BlockNumber};4748#[macro_export]49macro_rules! unsupported {50 () => {51 pallet_common::unsupported!($crate::Runtime)52 };53}5455/// The address format for describing accounts.56pub type Address = sp_runtime::MultiAddress<AccountId, ()>;57/// Block header type as expected by this runtime.58pub type Header = generic::Header<BlockNumber, BlakeTwo256>;59/// Block type as expected by this runtime.60pub type Block = generic::Block<Header, UncheckedExtrinsic>;61/// A Block signed with a Justification62pub type SignedBlock = generic::SignedBlock<Block>;63/// BlockId type as expected by this runtime.64pub type BlockId = generic::BlockId<Block>;6566impl_opaque_keys! {67 pub struct SessionKeys {68 pub aura: Aura,69 }70}7172/// The version information used to identify this runtime when compiled natively.73#[cfg(feature = "std")]74pub fn native_version() -> NativeVersion {75 NativeVersion {76 runtime_version: crate::VERSION,77 can_author_with: Default::default(),78 }79}8081pub type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;8283pub type SignedExtra = (84 frame_system::CheckSpecVersion<Runtime>,85 // system::CheckTxVersion<Runtime>,86 frame_system::CheckGenesis<Runtime>,87 frame_system::CheckEra<Runtime>,88 frame_system::CheckNonce<Runtime>,89 frame_system::CheckWeight<Runtime>,90 ChargeTransactionPayment,91 //pallet_contract_helpers::ContractHelpersExtension<Runtime>,92 pallet_ethereum::FakeTransactionFinalizer<Runtime>,93);9495/// Unchecked extrinsic type as expected by this runtime.96pub type UncheckedExtrinsic =97 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;9899/// Extrinsic type that has already been checked.100pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;101102/// Executive: handles dispatch to the various modules.103pub type Executive = frame_executive::Executive<104 Runtime,105 Block,106 frame_system::ChainContext<Runtime>,107 Runtime,108 AllPalletsReversedWithSystemFirst,109>;110111type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;112113pub struct DealWithFees;114impl OnUnbalanced<NegativeImbalance> for DealWithFees {115 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {116 if let Some(fees) = fees_then_tips.next() {117 // for fees, 100% to treasury118 let mut split = fees.ration(100, 0);119 if let Some(tips) = fees_then_tips.next() {120 // for tips, if any, 100% to treasury121 tips.ration_merge_into(100, 0, &mut split);122 }123 Treasury::on_unbalanced(split.0);124 // Author::on_unbalanced(split.1);125 }126 }127}128129pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);130131impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider132 for RelayChainBlockNumberProvider<T>133{134 type BlockNumber = BlockNumber;135136 fn current_block_number() -> Self::BlockNumber {137 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()138 .map(|d| d.relay_parent_number)139 .unwrap_or_default()140 }141}142143pub(crate) struct CheckInherents;144145impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {146 fn check_inherents(147 block: &Block,148 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,149 ) -> sp_inherents::CheckInherentsResult {150 let relay_chain_slot = relay_state_proof151 .read_slot()152 .expect("Could not read the relay chain slot from the proof");153154 let inherent_data =155 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(156 relay_chain_slot,157 sp_std::time::Duration::from_secs(6),158 )159 .create_inherent_data()160 .expect("Could not create the timestamp inherent data");161162 inherent_data.check_extrinsics(block)163 }164}165166#[derive(codec::Encode, codec::Decode)]167pub enum XCMPMessage<XAccountId, XBalance> {168 /// Transfer tokens to the given account from the Parachain account.169 TransferToken(XAccountId, XBalance),170}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/>.1617pub mod config;18pub mod construct_runtime;19pub mod dispatch;20pub mod ethereum;21pub mod instance;22pub mod runtime_apis;23pub mod scheduler;24pub mod sponsoring;25pub mod weights;2627#[cfg(test)]28pub mod tests;2930use sp_core::H160;31use frame_support::traits::{Currency, OnUnbalanced, Imbalance};32use sp_runtime::{33 generic,34 traits::{BlakeTwo256, BlockNumberProvider},35 impl_opaque_keys,36};37use sp_std::vec::Vec;3839#[cfg(feature = "std")]40use sp_version::NativeVersion;4142use crate::{43 Runtime, Call, Balances, Treasury, Aura, Signature, AllPalletsReversedWithSystemFirst,44 InherentDataExt,45};46use up_common::types::{AccountId, BlockNumber};4748#[macro_export]49macro_rules! unsupported {50 () => {51 pallet_common::unsupported!($crate::Runtime)52 };53}5455/// The address format for describing accounts.56pub type Address = sp_runtime::MultiAddress<AccountId, ()>;57/// Block header type as expected by this runtime.58pub type Header = generic::Header<BlockNumber, BlakeTwo256>;59/// Block type as expected by this runtime.60pub type Block = generic::Block<Header, UncheckedExtrinsic>;61/// A Block signed with a Justification62pub type SignedBlock = generic::SignedBlock<Block>;63/// BlockId type as expected by this runtime.64pub type BlockId = generic::BlockId<Block>;6566impl_opaque_keys! {67 pub struct SessionKeys {68 pub aura: Aura,69 }70}7172/// The version information used to identify this runtime when compiled natively.73#[cfg(feature = "std")]74pub fn native_version() -> NativeVersion {75 NativeVersion {76 runtime_version: crate::VERSION,77 can_author_with: Default::default(),78 }79}8081pub type ChargeTransactionPayment = pallet_charge_transaction::ChargeTransactionPayment<Runtime>;8283pub type SignedExtra = (84 frame_system::CheckSpecVersion<Runtime>,85 // system::CheckTxVersion<Runtime>,86 frame_system::CheckGenesis<Runtime>,87 frame_system::CheckEra<Runtime>,88 frame_system::CheckNonce<Runtime>,89 frame_system::CheckWeight<Runtime>,90 ChargeTransactionPayment,91 //pallet_contract_helpers::ContractHelpersExtension<Runtime>,92 pallet_ethereum::FakeTransactionFinalizer<Runtime>,93);9495/// Unchecked extrinsic type as expected by this runtime.96pub type UncheckedExtrinsic =97 fp_self_contained::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;9899/// Extrinsic type that has already been checked.100pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic<AccountId, Call, SignedExtra, H160>;101102/// Executive: handles dispatch to the various modules.103pub type Executive = frame_executive::Executive<104 Runtime,105 Block,106 frame_system::ChainContext<Runtime>,107 Runtime,108 AllPalletsReversedWithSystemFirst,109>;110111type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;112113pub struct DealWithFees;114impl OnUnbalanced<NegativeImbalance> for DealWithFees {115 fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {116 if let Some(fees) = fees_then_tips.next() {117 // for fees, 100% to treasury118 let mut split = fees.ration(100, 0);119 if let Some(tips) = fees_then_tips.next() {120 // for tips, if any, 100% to treasury121 tips.ration_merge_into(100, 0, &mut split);122 }123 Treasury::on_unbalanced(split.0);124 // Author::on_unbalanced(split.1);125 }126 }127}128129pub struct RelayChainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);130131impl<T: cumulus_pallet_parachain_system::Config> BlockNumberProvider132 for RelayChainBlockNumberProvider<T>133{134 type BlockNumber = BlockNumber;135136 fn current_block_number() -> Self::BlockNumber {137 cumulus_pallet_parachain_system::Pallet::<T>::validation_data()138 .map(|d| d.relay_parent_number)139 .unwrap_or_default()140 }141}142143pub(crate) struct CheckInherents;144145impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {146 fn check_inherents(147 block: &Block,148 relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,149 ) -> sp_inherents::CheckInherentsResult {150 let relay_chain_slot = relay_state_proof151 .read_slot()152 .expect("Could not read the relay chain slot from the proof");153154 let inherent_data =155 cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(156 relay_chain_slot,157 sp_std::time::Duration::from_secs(6),158 )159 .create_inherent_data()160 .expect("Could not create the timestamp inherent data");161162 inherent_data.check_extrinsics(block)163 }164}165166#[derive(codec::Encode, codec::Decode)]167pub enum XCMPMessage<XAccountId, XBalance> {168 /// Transfer tokens to the given account from the Parachain account.169 TransferToken(XAccountId, XBalance),170}runtime/common/tests/mod.rsdiffbeforeafterboth--- a/runtime/common/tests/mod.rs
+++ b/runtime/common/tests/mod.rs
@@ -14,4 +14,35 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-mod xcm;
+use sp_runtime::BuildStorage;
+use sp_core::{Public, Pair};
+use sp_std::vec;
+use up_common::types::AuraId;
+use crate::{GenesisConfig, ParachainInfoConfig, AuraConfig};
+
+pub mod xcm;
+
+fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
+ TPublic::Pair::from_string(&format!("//{}", seed), None)
+ .expect("static values are valid; qed")
+ .public()
+}
+
+fn new_test_ext(para_id: u32) -> sp_io::TestExternalities {
+ let cfg = GenesisConfig {
+ aura: AuraConfig {
+ authorities: vec![
+ get_from_seed::<AuraId>("Alice"),
+ get_from_seed::<AuraId>("Bob"),
+ ],
+ },
+ parachain_info: ParachainInfoConfig {
+ parachain_id: para_id.into(),
+ },
+ ..GenesisConfig::default()
+ };
+
+ cfg.build_storage()
+ .unwrap()
+ .into()
+}
runtime/common/tests/xcm.rsdiffbeforeafterboth--- a/runtime/common/tests/xcm.rs
+++ b/runtime/common/tests/xcm.rs
@@ -17,45 +17,31 @@
use xcm_executor::traits::ShouldExecute;
use xcm::latest::prelude::*;
use logtest::Logger;
-use crate::{
- Call,
- xcm_config::Barrier,
-};
+use crate::Call;
+use super::new_test_ext;
-fn catch_xcm_barrier_log(logger: &mut Logger, expected_msg: &str) {
+fn catch_xcm_barrier_log(
+ logger: &mut Logger,
+ expected_msg: &str
+) -> Result<(), String> {
for record in logger {
if record.target() == "xcm::barrier"
&& record.args() == expected_msg {
- return;
+ return Ok(());
}
}
- panic!("the expected XCM barrier log `{}` is not found", expected_msg);
+ Err(format!("the expected XCM barrier log `{}` is not found", expected_msg))
}
-#[test]
-fn xcm_barrier_denies_transact() {
- // We have a `AllowTopLevelPaidExecutionFrom` barrier,
- // so an XCM program should start from one of the following commands:
- // * `WithdrawAsset`
- // * `ReceiveTeleportedAsset`
- // * `ReserveAssetDeposited`
- // * `ClaimAsset`
- // We use the `WithdrawAsset` in this test
-
+/// WARNING: Uses log capturing
+/// See https://docs.rs/logtest/latest/logtest/index.html#constraints
+pub fn barrier_denies_transact<B: ShouldExecute>(logger: &mut Logger) {
let location = MultiLocation {
parents: 0,
interior: Junctions::Here,
};
- // let id = AssetId::Concrete(location.clone());
- // let fun = Fungibility::Fungible(42);
- // let multiasset = MultiAsset {
- // id,
- // fun,
- // };
- // let withdraw_inst = WithdrawAsset(multiasset.into());
-
// We will never decode this "call",
// so it is irrelevant what we are passing to the `transact` cmd.
let fake_encoded_call = vec![0u8];
@@ -67,13 +53,11 @@
};
let mut xcm_program = Xcm::<Call>(vec![transact_inst]);
-
- let mut logger = Logger::start();
let max_weight = 100_000;
- let mut weight_credit = 0;
+ let mut weight_credit = 100_000_000;
- let result = Barrier::should_execute(
+ let result = B::should_execute(
&location,
&mut xcm_program,
max_weight,
@@ -82,5 +66,108 @@
assert!(result.is_err(), "the barrier should disallow the XCM transact cmd");
- catch_xcm_barrier_log(&mut logger, "transact XCM rejected");
+ catch_xcm_barrier_log(logger, "transact XCM rejected").unwrap();
+}
+
+fn xcm_execute<B: ShouldExecute>(
+ self_para_id: u32,
+ location: &MultiLocation,
+ xcm: &mut Xcm<Call>
+) -> Result<(), ()> {
+ new_test_ext(self_para_id).execute_with(|| {
+ let max_weight = 100_000;
+ let mut weight_credit = 100_000_000;
+
+ B::should_execute(
+ &location,
+ xcm,
+ max_weight,
+ &mut weight_credit
+ )
+ })
+}
+
+fn make_multiassets(location: &MultiLocation) -> MultiAssets {
+ let id = AssetId::Concrete(location.clone());
+ let fun = Fungibility::Fungible(42);
+ let multiasset = MultiAsset {
+ id,
+ fun,
+ };
+
+ multiasset.into()
+}
+
+fn make_transfer_reserve_asset(location: &MultiLocation) -> Xcm<Call> {
+ let assets = make_multiassets(location);
+ let inst = TransferReserveAsset {
+ assets,
+ dest: location.clone(),
+ xcm: Xcm(vec![]),
+ };
+
+ Xcm::<Call>(vec![inst])
+}
+
+fn make_deposit_reserve_asset(location: &MultiLocation) -> Xcm<Call> {
+ let assets = make_multiassets(location);
+ let inst = DepositReserveAsset {
+ assets: assets.into(),
+ max_assets: 42,
+ dest: location.clone(),
+ xcm: Xcm(vec![]),
+ };
+
+ Xcm::<Call>(vec![inst])
+}
+
+fn expect_transfer_location_denied<B: ShouldExecute>(
+ logger: &mut Logger,
+ self_para_id: u32,
+ location: &MultiLocation,
+ xcm: &mut Xcm<Call>
+) -> Result<(), String> {
+ let result = xcm_execute::<B>(self_para_id, location, xcm);
+
+ if result.is_ok() {
+ return Err("the barrier should deny the unknown location".into());
+ }
+
+ catch_xcm_barrier_log(logger, "Unexpected deposit or transfer location")
+}
+
+/// WARNING: Uses log capturing
+/// See https://docs.rs/logtest/latest/logtest/index.html#constraints
+pub fn barrier_denies_transfer_from_unknown_location<B>(
+ logger: &mut Logger,
+ self_para_id: u32,
+) -> Result<(), String>
+where
+ B: ShouldExecute
+{
+ const UNKNOWN_PARACHAIN_ID: u32 = 4057;
+
+ let unknown_location = MultiLocation {
+ parents: 1,
+ interior: X1(Parachain(UNKNOWN_PARACHAIN_ID)),
+ };
+
+ let mut transfer_reserve_asset = make_transfer_reserve_asset(&unknown_location);
+ let mut deposit_reserve_asset = make_deposit_reserve_asset(&unknown_location);
+
+ expect_transfer_location_denied::<B>(
+ logger,
+ self_para_id,
+ &unknown_location,
+ &mut transfer_reserve_asset
+ )?;
+
+ expect_transfer_location_denied::<B>(
+ logger,
+ self_para_id,
+ &unknown_location,
+ &mut deposit_reserve_asset
+ )?;
+
+ Ok(())
}
runtime/opal/src/lib.rsdiffbeforeafterboth--- a/runtime/opal/src/lib.rs
+++ b/runtime/opal/src/lib.rs
@@ -37,6 +37,9 @@
pub mod xcm_config;
+#[cfg(test)]
+mod tests;
+
pub use runtime_common::*;
pub const RUNTIME_NAME: &str = "opal";
runtime/opal/src/tests/logcapture.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/opal/src/tests/logcapture.rs
@@ -0,0 +1,25 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use logtest::Logger;
+use super::xcm::opal_xcm_tests;
+
+#[test]
+fn opal_log_capture_tests() {
+ let mut logger = Logger::start();
+
+ opal_xcm_tests(&mut logger);
+}
runtime/opal/src/tests/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/opal/src/tests/mod.rs
@@ -0,0 +1,18 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+mod xcm;
+mod logcapture;
runtime/opal/src/tests/xcm.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/opal/src/tests/xcm.rs
@@ -0,0 +1,32 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use logtest::Logger;
+use crate::{
+ runtime_common::tests::xcm::*,
+ xcm_config::Barrier,
+};
+
+const OPAL_PARA_ID: u32 = 2095; // Same as Quartz
+
+pub fn opal_xcm_tests(logger: &mut Logger) {
+ barrier_denies_transact::<Barrier>(logger);
+
+ barrier_denies_transfer_from_unknown_location::<Barrier>(
+ logger,
+ OPAL_PARA_ID,
+ ).expect_err("opal runtime allows any location");
+}
runtime/quartz/src/lib.rsdiffbeforeafterboth--- a/runtime/quartz/src/lib.rs
+++ b/runtime/quartz/src/lib.rs
@@ -37,6 +37,9 @@
pub mod xcm_config;
+#[cfg(test)]
+mod tests;
+
pub use runtime_common::*;
pub const RUNTIME_NAME: &str = "quartz";
runtime/quartz/src/tests/logcapture.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/quartz/src/tests/logcapture.rs
@@ -0,0 +1,25 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use logtest::Logger;
+use super::xcm::quartz_xcm_tests;
+
+#[test]
+fn quartz_log_capture_tests() {
+ let mut logger = Logger::start();
+
+ quartz_xcm_tests(&mut logger);
+}
runtime/quartz/src/tests/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/quartz/src/tests/mod.rs
@@ -0,0 +1,18 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+mod xcm;
+mod logcapture;
runtime/quartz/src/tests/xcm.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/quartz/src/tests/xcm.rs
@@ -0,0 +1,32 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use logtest::Logger;
+use crate::{
+ runtime_common::tests::xcm::*,
+ xcm_config::Barrier,
+};
+
+const QUARTZ_PARA_ID: u32 = 2095;
+
+pub fn quartz_xcm_tests(logger: &mut Logger) {
+ barrier_denies_transact::<Barrier>(logger);
+
+ barrier_denies_transfer_from_unknown_location::<Barrier>(
+ logger,
+ QUARTZ_PARA_ID,
+ ).expect("quartz runtime denies an unknown location");
+}
runtime/unique/src/lib.rsdiffbeforeafterboth--- a/runtime/unique/src/lib.rs
+++ b/runtime/unique/src/lib.rs
@@ -37,6 +37,9 @@
pub mod xcm_config;
+#[cfg(test)]
+mod tests;
+
pub use runtime_common::*;
pub const RUNTIME_NAME: &str = "unique";
runtime/unique/src/tests/logcapture.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/unique/src/tests/logcapture.rs
@@ -0,0 +1,25 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use logtest::Logger;
+use super::xcm::unique_xcm_tests;
+
+#[test]
+fn unique_log_capture_tests() {
+ let mut logger = Logger::start();
+
+ unique_xcm_tests(&mut logger);
+}
runtime/unique/src/tests/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/unique/src/tests/mod.rs
@@ -0,0 +1,18 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+mod xcm;
+mod logcapture;
runtime/unique/src/tests/xcm.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/unique/src/tests/xcm.rs
@@ -0,0 +1,32 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use logtest::Logger;
+use crate::{
+ runtime_common::tests::xcm::*,
+ xcm_config::Barrier,
+};
+
+const UNIQUE_PARA_ID: u32 = 2037;
+
+pub fn unique_xcm_tests(logger: &mut Logger) {
+ barrier_denies_transact::<Barrier>(logger);
+
+ barrier_denies_transfer_from_unknown_location::<Barrier>(
+ logger,
+ UNIQUE_PARA_ID,
+ ).expect("unique runtime denies an unknown location");
+}